@opengeni/react 3.5.1-canary.0 → 3.7.0-canary.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 (52) hide show
  1. package/dist/artifacts.d.ts +1 -1
  2. package/dist/artifacts.js +229 -6
  3. package/dist/artifacts.js.map +1 -1
  4. package/dist/{chunk-IB27C53Y.js → chunk-C6WDLHBA.js} +31 -23
  5. package/dist/chunk-C6WDLHBA.js.map +1 -0
  6. package/dist/{chunk-WY3MELVJ.js → chunk-DOK4KZF2.js} +119 -8
  7. package/dist/chunk-DOK4KZF2.js.map +1 -0
  8. package/dist/{chunk-TJFMMDQU.js → chunk-FJBOU2TH.js} +112 -6
  9. package/dist/chunk-FJBOU2TH.js.map +1 -0
  10. package/dist/{chunk-UNCXXIQR.js → chunk-R55HFTT3.js} +66 -24
  11. package/dist/chunk-R55HFTT3.js.map +1 -0
  12. package/dist/client.d.ts +1 -1
  13. package/dist/components/artifacts/index.d.ts +1 -1
  14. package/dist/components/artifacts/published-html-artifact-frame.d.ts +45 -3
  15. package/dist/components/composer.d.ts +2 -0
  16. package/dist/components/session-chrome.d.ts +1 -1
  17. package/dist/composer.js +1 -1
  18. package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
  19. package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
  20. package/dist/hooks/use-file-attachments.d.ts +6 -0
  21. package/dist/hooks/use-sandbox-files.d.ts +4 -1
  22. package/dist/hooks/use-workspace-edit.d.ts +4 -0
  23. package/dist/index.js +114 -58
  24. package/dist/index.js.map +1 -1
  25. package/dist/session-ui.js +2 -2
  26. package/dist/session.js +2 -2
  27. package/dist/timeline/registry.d.ts +2 -0
  28. package/dist/timeline/types.d.ts +1 -1
  29. package/package.json +2 -2
  30. package/src/artifacts.ts +3 -0
  31. package/src/client.ts +2 -1
  32. package/src/components/artifacts/index.ts +3 -0
  33. package/src/components/artifacts/published-html-artifact-frame.tsx +284 -4
  34. package/src/components/composer.tsx +89 -25
  35. package/src/components/message-timeline.tsx +32 -8
  36. package/src/components/sandbox-workspace.tsx +11 -1
  37. package/src/components/session-chrome.tsx +3 -3
  38. package/src/hooks/use-file-attachments.ts +34 -0
  39. package/src/hooks/use-sandbox-files.ts +68 -20
  40. package/src/hooks/use-session-events.ts +21 -26
  41. package/src/hooks/use-workspace-edit.ts +23 -5
  42. package/src/timeline/fleet-decision-projection.ts +2 -1
  43. package/src/timeline/fleet-decision-row.tsx +1 -0
  44. package/src/timeline/projection.ts +151 -7
  45. package/src/timeline/registry.ts +15 -3
  46. package/src/timeline/tool-renderers.tsx +117 -1
  47. package/src/timeline/types.ts +8 -1
  48. package/dist/chunk-IB27C53Y.js.map +0 -1
  49. package/dist/chunk-TJFMMDQU.js.map +0 -1
  50. package/dist/chunk-UNCXXIQR.js.map +0 -1
  51. package/dist/chunk-WY3MELVJ.js.map +0 -1
  52. package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
package/dist/client.d.ts CHANGED
@@ -26,7 +26,7 @@ export type EmbeddedGoalClientLike = EmbeddedSessionEventClientLike & Pick<OpenG
26
26
  /** Exact client surface required by {@link useSessionLineage}. */
27
27
  export type EmbeddedSessionLineageClientLike = EmbeddedSessionEventClientLike & Pick<OpenGeniClient, "getSessionLineage">;
28
28
  /** Exact client surface required by {@link useFileAttachments}. */
29
- export type EmbeddedFileAttachmentClientLike = Pick<OpenGeniClient, "uploadFile">;
29
+ export type EmbeddedFileAttachmentClientLike = Pick<OpenGeniClient, "uploadFile"> & Partial<Pick<OpenGeniClient, "createFileDownloadUrl">>;
30
30
  /** Exact client surface required by structured human-input hooks. */
31
31
  export type EmbeddedHumanInputSessionClientLike = EmbeddedSessionEventClientLike & Pick<OpenGeniClient, "listHumanInputRequests" | "submitHumanInputResponse">;
32
32
  /** Exact client surface required by MCP approval-policy hooks. */
@@ -1,5 +1,5 @@
1
1
  export { ArtifactSurface, type ArtifactModality, type ArtifactSurfaceProps, } from "./artifact-surface.js";
2
- export { PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX, PublishedHtmlArtifactFrame, type PublishedHtmlArtifactFrameProps, } from "./published-html-artifact-frame.js";
2
+ export { PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX, PublishedHtmlArtifactFrame, openGeniSiteBridgePortFromBootstrap, publishedHtmlArtifactDocument, type PublishedHtmlArtifactFrameProps, type PublishedHtmlArtifactToolBridge, } from "./published-html-artifact-frame.js";
3
3
  export { SpreadsheetArtifactSurface, SpreadsheetGrid, SpreadsheetProjectionGrid, type SpreadsheetArtifactSurfaceProps, type SpreadsheetCommit, type SpreadsheetRangeCommit, type SpreadsheetGridProps, type SpreadsheetGridProjection, type SpreadsheetProjectionCell, type SpreadsheetProjectionGridProps, type SpreadsheetSelection, type SpreadsheetViewport, } from "./spreadsheet-grid.js";
4
4
  export { EditableSpreadsheetArtifactSurface, EditableSpreadsheetGrid, type EditableSpreadsheetArtifactSurfaceProps, type EditableSpreadsheetGridProps, } from "./editable-spreadsheet.js";
5
5
  export { BrowserEditableArtifactWorkbench, EditableArtifactWorkbench, EditableArtifactWorkbenchHost, type BrowserEditableArtifactWorkbenchOptions, type BrowserEditableArtifactWorkbenchProps, type EditableArtifactWorkbenchHostProps, type EditableArtifactWorkbenchProps, } from "./editable-artifact-workbench.js";
@@ -1,14 +1,56 @@
1
- import type { CSSProperties } from "react";
1
+ import { type OpenGeniSiteToolCatalog } from "@opengeni/sdk/site";
2
+ import type { ToolGatewayCallRequest, ToolGatewayCallResponse, ToolGatewayDeclarationsResponse } from "@opengeni/sdk";
3
+ import { type CSSProperties } from "react";
2
4
  export declare const PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX: string;
3
5
  export type PublishedHtmlArtifactFrameProps = {
4
6
  html: string;
5
7
  title: string;
6
8
  className?: string;
7
9
  style?: CSSProperties;
10
+ toolBridge?: PublishedHtmlArtifactToolBridge;
8
11
  };
12
+ export type PublishedHtmlArtifactToolBridge = {
13
+ catalog: (options: {
14
+ signal: AbortSignal;
15
+ }) => Promise<OpenGeniSiteToolCatalog>;
16
+ call: (request: ToolGatewayCallRequest, options: {
17
+ signal: AbortSignal;
18
+ }) => Promise<ToolGatewayCallResponse>;
19
+ declarations?: (options: {
20
+ signal: AbortSignal;
21
+ }) => Promise<ToolGatewayDeclarationsResponse>;
22
+ };
23
+ export declare function publishedHtmlArtifactDocument(html: string, toolBridgeEnabled: boolean): string;
9
24
  /**
10
25
  * Render exact published HTML in an opaque-origin iframe. Artifact scripts,
11
- * external resources, forms, popups, and downloads work without granting
12
- * parent-origin authority, shared cookies/storage, or top-level navigation.
26
+ * external resources, forms, popups, downloads, and the host-filtered tool
27
+ * bridge work without granting parent-origin authority, shared cookies/storage,
28
+ * or top-level navigation.
13
29
  */
14
30
  export declare function PublishedHtmlArtifactFrame(props: PublishedHtmlArtifactFrameProps): import("react").JSX.Element;
31
+ export declare class SiteBridgeRequestRegistry {
32
+ private readonly controllersByPort;
33
+ replacePort(port: MessagePort): void;
34
+ start(port: MessagePort, requestId: string): AbortController | null;
35
+ cancel(port: MessagePort, requestId: string): void;
36
+ complete(port: MessagePort, requestId: string, controller: AbortController): void;
37
+ closePort(port: MessagePort): void;
38
+ closeAll(): void;
39
+ }
40
+ export declare class SiteBridgeDocumentLease {
41
+ private readonly attachToolPort;
42
+ private readonly closeActivePorts;
43
+ private readonly createMessageChannel;
44
+ private loaded;
45
+ private bootstrapPort;
46
+ constructor(attachToolPort: (data: unknown, ports: readonly MessagePort[]) => void, closeActivePorts: () => void, createMessageChannel?: () => MessageChannel);
47
+ load(frameWindow: Pick<Window, "postMessage">): boolean;
48
+ close(): void;
49
+ }
50
+ export declare function openGeniSiteBridgePortFromBootstrap(data: unknown, ports: readonly MessagePort[]): MessagePort | null;
51
+ export declare function siteBridgeError(error: unknown): {
52
+ code: string;
53
+ message: string;
54
+ retryable: boolean;
55
+ outcomeUnknown: boolean;
56
+ };
@@ -57,6 +57,7 @@ export type ChatComposerMessages = {
57
57
  uploading: string;
58
58
  uploadFailed: string;
59
59
  previewAttachment: (name: string) => string;
60
+ previewUnavailable?: string | undefined;
60
61
  attachmentPreviewLabel: string;
61
62
  downloadAttachment: (name: string) => string;
62
63
  closeAttachmentPreview: string;
@@ -165,6 +166,7 @@ export declare function useChatComposerController({ delivery, draft, control, ef
165
166
  uploading: string;
166
167
  uploadFailed: string;
167
168
  previewAttachment: (name: string) => string;
169
+ previewUnavailable?: string | undefined;
168
170
  attachmentPreviewLabel: string;
169
171
  downloadAttachment: (name: string) => string;
170
172
  closeAttachmentPreview: string;
@@ -73,7 +73,7 @@ type GoalPillRecord = Pick<SessionGoal, "status" | "pausedReason"> & {
73
73
  export declare function sessionChromeGoalPillLabel(state: GoalPillState, record: GoalPillRecord | null | undefined): string;
74
74
  /**
75
75
  * One human sentence explaining WHY the goal is not pursuing right now: the
76
- * pause reason, the agent's own `goal_wait` hold (reason + deadline), or the
76
+ * pause reason, the agent's own `wait_for_input` hold (reason + deadline), or the
77
77
  * next idle-backoff check time. Null when the state needs no explanation.
78
78
  */
79
79
  export declare function sessionChromeGoalPillExplanation(state: GoalPillState, record: GoalPillRecord | null | undefined): string | null;
package/dist/composer.js CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  useChatComposer,
38
38
  useChatComposerController,
39
39
  useVoiceInput
40
- } from "./chunk-UNCXXIQR.js";
40
+ } from "./chunk-R55HFTT3.js";
41
41
  import {
42
42
  BillingClassMark,
43
43
  ModelPolicyPicker,
@@ -23,6 +23,7 @@ var FLEET_ACTUAL_REASON_LABEL = {
23
23
  rotation: "Rotated for capacity",
24
24
  active: "Used the active subscription",
25
25
  all_capped: "All observed subscriptions were capped",
26
+ allocator_disabled: "The policy-selected subscription was disabled for new allocations",
26
27
  none: "No production candidate was selected"
27
28
  };
28
29
  var FLEET_SHADOW_REASON_LABEL = {
@@ -348,4 +349,4 @@ function formatFleetScore(value) {
348
349
  export {
349
350
  FleetDecisionRow as default
350
351
  };
351
- //# sourceMappingURL=fleet-decision-row-GGCAT4E4.js.map
352
+ //# sourceMappingURL=fleet-decision-row-YZ3ZKWMM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/timeline/fleet-decision-row.tsx"],"sourcesContent":["import type { FleetDecisionItem } from \"./types\";\n\ntype RowJsx = typeof import(\"react/jsx-runtime\").jsx;\ntype RowJsxs = typeof import(\"react/jsx-runtime\").jsxs;\n\nfunction GaugeMark({ className, j, s }: { className: string; j: RowJsx; s: RowJsxs }) {\n return s(\"svg\", {\n \"aria-hidden\": \"true\",\n className,\n fill: \"none\",\n height: \"24\",\n stroke: \"currentColor\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n strokeWidth: \"2\",\n viewBox: \"0 0 24 24\",\n width: \"24\",\n children: [\n j(\"path\", { d: \"m 12 14 4-4\" }, \"needle\"),\n j(\"path\", { d: \"M3.34 19a10 10 0 1 1 17.32 0\" }, \"arc\"),\n ],\n });\n}\n\nconst FLEET_ACTUAL_REASON_LABEL: Record<FleetDecisionItem[\"actualReason\"], string> = {\n lease_reused: \"Reused the fenced lease\",\n pin: \"Kept the session pin\",\n rotation: \"Rotated for capacity\",\n active: \"Used the active subscription\",\n all_capped: \"All observed subscriptions were capped\",\n allocator_disabled: \"The policy-selected subscription was disabled for new allocations\",\n none: \"No production candidate was selected\",\n};\n\nconst FLEET_SHADOW_REASON_LABEL: Record<FleetDecisionItem[\"shadowReason\"], string> = {\n fenced_in_flight: \"Kept the fenced in-flight assignment\",\n fenced_candidate_missing: \"The fenced assignment was missing from the snapshot\",\n admission_paced: \"Admission would have been paced\",\n no_eligible_candidate: \"No candidate passed the policy checks\",\n overlay_isolated_empty: \"Explicit isolation left no eligible candidate\",\n best_score: \"Selected the lowest-pressure candidate\",\n affinity_best: \"Session affinity was already best\",\n hysteresis_hold: \"Hysteresis avoided a low-value switch\",\n};\n\nconst FLEET_COMPARISON_LABEL: Record<FleetDecisionItem[\"comparison\"], string> = {\n match: \"Production and shadow matched\",\n different_candidate: \"Shadow preferred another candidate\",\n different_outcome: \"Production and shadow outcomes differed\",\n not_comparable_truncated: \"Comparison limited by bounded candidate data\",\n};\n\nconst FLEET_ADMISSION_REASON_LABEL: Record<FleetDecisionItem[\"admissionReason\"], string> = {\n fenced_in_flight: \"In-flight assignment was fenced\",\n pacing_disabled: \"Admission pacing was disabled\",\n capacity_unknown: \"Capacity was unknown, so work remained admissible\",\n capacity_available: \"Observed capacity was available\",\n work_conserving_borrow: \"Idle capacity was borrowed for standard work\",\n manager_priority: \"Standard work was paced for queued manager demand\",\n standard_starvation_bound: \"The standard-work starvation bound was reached\",\n capacity_saturated: \"Observed dynamic capacity was saturated\",\n emergency_fuse: \"The emergency fuse blocked new work\",\n};\n\nconst FLEET_REJECTION_LABEL: Record<\n Exclude<FleetDecisionItem[\"scores\"][number][\"rejectionReason\"], null>,\n string\n> = {\n allocator_disabled: \"Allocator disabled\",\n unavailable: \"Unavailable\",\n cooling: \"Cooling down\",\n quota_ceiling: \"Quota ceiling reached\",\n overlay_isolation: \"Outside explicit isolation\",\n};\n\nconst FLEET_CONFIDENCE_LABEL: Record<FleetDecisionItem[\"confidence\"], string> = {\n unknown: \"Unknown confidence\",\n low: \"Low confidence\",\n medium: \"Medium confidence\",\n high: \"High confidence\",\n};\n\nexport default function FleetDecisionRow({\n item,\n d: ActivityDisclosure,\n b: BodyNote,\n j,\n s,\n}: {\n item: FleetDecisionItem;\n d: typeof import(\"./shared\").ActivityDisclosure;\n b: typeof import(\"./shared\").BodyNote;\n j: RowJsx;\n s: RowJsxs;\n}) {\n const scoreRowsHidden = item.scoreRowsTruncatedCount > 0;\n const scores =\n item.scores.length > 0\n ? j(\n \"div\",\n {\n className: \"min-w-0\",\n children: [\n j(\n \"h4\",\n {\n className: \"text-og-sm font-medium text-og-fg\",\n children: \"Bounded candidate scores\",\n },\n \"heading\",\n ),\n j(\n \"p\",\n {\n className: \"mt-0.5 text-og-xs leading-5 text-og-fg-subtle\",\n children:\n \"Lower scores rank first. Candidate aliases are temporary and local to this event.\",\n },\n \"description\",\n ),\n j(\n \"ul\",\n {\n className: \"mt-2 flex min-w-0 flex-col gap-1.5\",\n \"aria-label\": \"Candidate scores\",\n children: item.scores.map((score) =>\n s(\n \"li\",\n {\n className:\n \"flex min-w-0 flex-col gap-1 rounded-og-sm bg-og-surface-1 px-2.5 py-2 text-og-sm sm:flex-row sm:items-center sm:gap-3\",\n children: [\n j(\n \"span\",\n {\n className: \"font-og-mono text-og-fg\",\n children: score.candidateKey,\n },\n \"candidate\",\n ),\n j(\n \"span\",\n {\n className: \"min-w-0 text-og-fg-muted sm:flex-1\",\n children: score.eligible\n ? \"Eligible\"\n : score.rejectionReason\n ? FLEET_REJECTION_LABEL[score.rejectionReason]\n : \"Unavailable\",\n },\n \"eligibility\",\n ),\n s(\n \"span\",\n {\n className: \"font-og-mono text-og-fg-subtle\",\n children: [\n \"score \",\n formatFleetScore(score.total),\n \" ·\",\n \" \",\n FLEET_CONFIDENCE_LABEL[score.confidence],\n ],\n },\n \"score\",\n ),\n ],\n },\n score.candidateKey,\n ),\n ),\n },\n \"rows\",\n ),\n ],\n },\n \"score-list\",\n )\n : null;\n const truncated =\n item.truncatedCandidateCount > 0\n ? j(\n BodyNote,\n {\n tone: \"muted\",\n children: [\n item.truncatedCandidateCount,\n \" additional \",\n item.truncatedCandidateCount === 1 ? \"candidate was\" : \"candidates were\",\n \" excluded from this bounded replay record.\",\n ],\n },\n \"truncated\",\n )\n : null;\n const hidden = scoreRowsHidden\n ? j(\n BodyNote,\n {\n tone: \"muted\",\n children: [\n item.scoreRowsTruncatedCount,\n \" additional \",\n item.scoreRowsTruncatedCount === 1 ? \"score row was\" : \"score rows were\",\n \" hidden by this view’s safety limit.\",\n ],\n },\n \"hidden\",\n )\n : null;\n return j(ActivityDisclosure, {\n icon: j(GaugeMark, { className: \"size-3.5\", j, s }),\n iconTone: \"muted\",\n title: \"Fleet policy shadow\",\n preview: FLEET_COMPARISON_LABEL[item.comparison],\n chip: {\n tone: \"muted\",\n text:\n item.comparison === \"match\"\n ? \"matched\"\n : item.comparison === \"not_comparable_truncated\"\n ? \"limited\"\n : \"different\",\n },\n children: s(\"section\", {\n \"aria-label\": \"Fleet policy shadow details\",\n className: \"flex min-w-0 flex-col gap-3\",\n children: [\n j(\n BodyNote,\n {\n tone: \"muted\",\n children:\n \"Shadow observation only — it did not change the subscription serving this turn.\",\n },\n \"observation\",\n ),\n j(\n \"dl\",\n {\n className: \"grid min-w-0 grid-cols-1 gap-x-5 gap-y-3 sm:grid-cols-2\",\n children: [\n j(\n FleetDetail,\n {\n term: \"Production\",\n value: fleetOutcomeLabel(item.actualOutcome, item.actualCandidateKey),\n note: FLEET_ACTUAL_REASON_LABEL[item.actualReason],\n j,\n s,\n },\n \"production\",\n ),\n j(\n FleetDetail,\n {\n term: \"Shadow policy\",\n value: fleetOutcomeLabel(item.shadowOutcome, item.shadowCandidateKey),\n note: FLEET_SHADOW_REASON_LABEL[item.shadowReason],\n j,\n s,\n },\n \"shadow\",\n ),\n j(\n FleetDetail,\n {\n term: \"Comparison\",\n value: FLEET_COMPARISON_LABEL[item.comparison],\n j,\n s,\n },\n \"comparison\",\n ),\n j(\n FleetDetail,\n {\n term: \"Decision confidence\",\n value: FLEET_CONFIDENCE_LABEL[item.confidence],\n j,\n s,\n },\n \"confidence\",\n ),\n j(\n FleetDetail,\n {\n term: \"Admission\",\n value:\n item.admissionOutcome === \"admit\"\n ? \"Would admit new work\"\n : \"Would pace new work\",\n note: FLEET_ADMISSION_REASON_LABEL[item.admissionReason],\n j,\n s,\n },\n \"admission\",\n ),\n j(\n FleetDetail,\n {\n term: \"Observed candidates\",\n value: `${item.candidateCount} in the bounded replay`,\n j,\n s,\n },\n \"candidate-count\",\n ),\n j(\n FleetDetail,\n {\n term: \"Idle-capacity borrowing\",\n value: item.borrowedIdleCapacity ? \"Borrowed for standard work\" : \"Not borrowed\",\n j,\n s,\n },\n \"idle-capacity\",\n ),\n j(\n FleetDetail,\n {\n term: \"Named-policy borrowing\",\n value: item.borrowedOverlayCapacity\n ? \"Borrowed outside the preferred group\"\n : \"Not borrowed\",\n j,\n s,\n },\n \"named-policy\",\n ),\n j(\n FleetDetail,\n {\n term: \"Stranded capacity\",\n value:\n item.strandedEligibleCount === 0\n ? \"None\"\n : `${item.strandedEligibleCount} eligible ${item.strandedEligibleCount === 1 ? \"candidate\" : \"candidates\"}`,\n note:\n item.strandedEligibleCount > 0\n ? \"Capacity excluded by explicit isolation; existing fenced turns are unchanged.\"\n : undefined,\n j,\n s,\n },\n \"stranded-capacity\",\n ),\n ],\n },\n \"details\",\n ),\n scores,\n truncated,\n hidden,\n ],\n }),\n });\n}\n\nfunction FleetDetail({\n term,\n value,\n note,\n j,\n s,\n}: {\n term: string;\n value: string;\n note?: string | undefined;\n j: RowJsx;\n s: RowJsxs;\n}) {\n return j(\"div\", {\n className: \"min-w-0\",\n children: [\n j(\n \"dt\",\n {\n className: \"text-og-xs font-medium uppercase tracking-wide text-og-fg-subtle\",\n children: term,\n },\n \"term\",\n ),\n s(\n \"dd\",\n {\n className: \"mt-0.5 break-words text-og-sm text-og-fg-muted\",\n children: [\n j(\"span\", { className: \"text-og-fg\", children: value }, \"value\"),\n note\n ? j(\"span\", { className: \"mt-0.5 block leading-5\", children: note }, \"note\")\n : null,\n ],\n },\n \"description\",\n ),\n ],\n });\n}\n\nfunction fleetOutcomeLabel(\n outcome: FleetDecisionItem[\"actualOutcome\"] | FleetDecisionItem[\"shadowOutcome\"],\n candidateKey: string | null,\n): string {\n if (outcome === \"selected\" && candidateKey) return `Selected ${candidateKey}`;\n if (outcome === \"waiting\") return \"Waiting for capacity\";\n if (outcome === \"paced\") return \"Paced before placement\";\n return \"No candidate selected\";\n}\n\nfunction formatFleetScore(value: number): string {\n return new Intl.NumberFormat(\"en-US\", { maximumFractionDigits: 2 }).format(value);\n}\n"],"mappings":"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","names":[]}
@@ -47,6 +47,12 @@ export type UseFileAttachmentsResult = {
47
47
  }) => void;
48
48
  /** Restore already-ready server assets without recreating browser-local bytes. */
49
49
  restoreReadyFiles: (files: Iterable<FileAsset>) => void;
50
+ /**
51
+ * Resolve a ready image's short-lived server preview URL on demand. Optional
52
+ * for upload-only embedded clients; local object-URL previews remain usable
53
+ * without it.
54
+ */
55
+ loadPreview?: ((id: string, signal?: AbortSignal) => Promise<string | undefined>) | undefined;
50
56
  /**
51
57
  * Re-run the upload for a `failed` attachment, in place (same id, same
52
58
  * source file). No-op for an id that isn't a known failed upload.
@@ -1,4 +1,4 @@
1
- import type { FsReadResponse, FsWriteResponse, OpenGeniRequestOptions, SessionCapabilities, SessionEvent, WorkspaceCaptureManifest } from "@opengeni/sdk";
1
+ import type { FileSystemRouteIdentity, FsReadResponse, FsWriteResponse, OpenGeniRequestOptions, SessionCapabilities, SessionEvent, WorkspaceCaptureManifest } from "@opengeni/sdk";
2
2
  import { type ClientOverride } from "../provider.js";
3
3
  /** The git-status overlay a file row may carry (tints modified files in the tree). */
4
4
  export type FileTreeStatus = "added" | "modified" | "deleted" | "renamed" | "untracked";
@@ -47,6 +47,9 @@ export type UseSandboxFilesOptions = ClientOverride & {
47
47
  events?: SessionEvent[] | undefined;
48
48
  /** Initial path to list (workspace root by default). */
49
49
  rootPath?: string | undefined;
50
+ /** Exact capability identity for the selected filesystem route. A route/root
51
+ * change resets this hook and makes stale provider requests fail retryably. */
52
+ route?: FileSystemRouteIdentity | undefined;
50
53
  /** Hold off the initial list (e.g. panel collapsed). Default true. */
51
54
  enabled?: boolean | undefined;
52
55
  /** Pause live reads/invalidation while preserving the last rendered result. */
@@ -1,3 +1,4 @@
1
+ import type { FileSystemRouteIdentity } from "@opengeni/sdk";
1
2
  import { type ClientOverride } from "../provider.js";
2
3
  /**
3
4
  * The wake-on-edit state machine. This hook owns the logic and the UI renders
@@ -27,6 +28,9 @@ export type UseWorkspaceEditOptions = ClientOverride & {
27
28
  path?: string | null | undefined;
28
29
  /** The capture-served content loaded into the editor — the flush base (C2). */
29
30
  baseContent?: string | null | undefined;
31
+ /** Exact capability identity for the selected filesystem route. A route/root
32
+ * change discards the buffered edit and makes stale flushes fail retryably. */
33
+ route?: FileSystemRouteIdentity | undefined;
30
34
  /** `capabilities.liveness` — "warm" | "draining" | "cold". Drives the flush. */
31
35
  liveness?: string | undefined;
32
36
  /** True while the host is actively warming the box (attach in flight, not warm