@tutti-os/workspace-terminal 0.0.21 → 0.0.22

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.
@@ -872,11 +872,7 @@ function createTerminalSurfaceRuntime(input) {
872
872
  terminalScreenStateCache.remove(input.nodeId, input.sessionId);
873
873
  }
874
874
  clearPendingWrites();
875
- input.onPreviewChange?.({
876
- nodeId: input.nodeId,
877
- sessionId: input.sessionId,
878
- snapshot: null
879
- });
875
+ emitTerminalPreviewSnapshot();
880
876
  terminal.dispose();
881
877
  },
882
878
  findNext(query, options) {
@@ -1951,4 +1947,4 @@ export {
1951
1947
  TerminalNodeHeader,
1952
1948
  TerminalCloseGuardDialog
1953
1949
  };
1954
- //# sourceMappingURL=chunk-UWPZ5O4V.js.map
1950
+ //# sourceMappingURL=chunk-TBCIC6JY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/sessionControllerRecovery.ts","../src/core/sessionControllerStore.ts","../src/core/sessionTransportRuntime.ts","../src/core/sessionController.ts","../src/react/TerminalNode.tsx","../src/react/headerActions.ts","../src/react/TerminalSurface.tsx","../src/react/terminalSurfaceRuntime.ts","../src/react/terminalFileLinkProvider.ts","../src/react/terminalSurfaceOutputPlan.ts","../src/react/terminalSurfaceResizePlan.ts","../src/react/terminalSurfaceScreenCachePlan.ts","../src/react/terminalWriteBatch.ts","../src/react/terminalFindShortcut.ts","../src/react/useTerminalFindController.ts","../src/react/useTerminalSessionController.ts"],"sourcesContent":["import type { BufferedTerminalInputQueue } from \"./inputQueue.ts\";\nimport { writeQueuedTerminalInput } from \"./inputQueue.ts\";\nimport type { TerminalTransport } from \"../contracts/index.ts\";\nimport type { TerminalSessionRecoveryDiagnostics } from \"./sessionDiagnostics.ts\";\nimport type { TerminalSessionControllerStore } from \"./sessionControllerStore.ts\";\nimport type { TerminalSessionTransportRuntime } from \"./sessionTransportRuntime.ts\";\n\nexport interface TerminalSessionRecoveryHandle {\n dispose(): void;\n start(): Promise<void>;\n}\n\nexport function createTerminalSessionRecovery(input: {\n diagnostics: TerminalSessionRecoveryDiagnostics;\n inputQueue: BufferedTerminalInputQueue;\n onRecoverableDetach: () => void;\n onWriteReadyChange: (ready: boolean) => void;\n replayGapMessage: string;\n sessionId: string;\n snapshotTruncatedMessage: string;\n store: TerminalSessionControllerStore;\n transport: TerminalTransport;\n transportRuntime: TerminalSessionTransportRuntime;\n}): TerminalSessionRecoveryHandle {\n let disposed = false;\n let hydrationReady = false;\n const hydrationReplayChunks: string[] = [];\n\n const disposeData = input.transportRuntime.onData((event) => {\n if (disposed || event.sessionId !== input.sessionId) {\n return;\n }\n if (!hydrationReady) {\n hydrationReplayChunks.push(event.data);\n return;\n }\n input.store.appendRawOutput(event.data);\n });\n\n const disposeState = input.transportRuntime.onState((event) => {\n if (disposed || event.sessionId !== input.sessionId) {\n return;\n }\n if (\n typeof event.gapStartSeq === \"number\" &&\n typeof event.gapEndSeq === \"number\"\n ) {\n input.diagnostics.hydrationGap({\n fromSeq: event.gapStartSeq,\n toSeq: event.gapEndSeq\n });\n input.store.setSurfaceError(input.replayGapMessage);\n return;\n }\n if (event.error) {\n input.store.setSurfaceError(event.error);\n }\n if (event.status === \"detached\") {\n input.onWriteReadyChange(false);\n input.store.setInputReady(false);\n input.onRecoverableDetach();\n return;\n }\n if (event.status === \"exited\") {\n input.onWriteReadyChange(false);\n input.store.setInputReady(false);\n }\n });\n\n const disposeExit = input.transportRuntime.onExit((event) => {\n if (disposed || event.sessionId !== input.sessionId) {\n return;\n }\n input.onWriteReadyChange(false);\n input.store.setInputReady(false);\n });\n\n const disposeMetadata = input.transportRuntime.onMetadata(() => undefined);\n\n return {\n dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n hydrationReady = false;\n hydrationReplayChunks.length = 0;\n disposeData();\n disposeState();\n disposeExit();\n disposeMetadata();\n },\n async start() {\n input.diagnostics.hydrationStart();\n input.diagnostics.snapshotStart();\n\n try {\n const snapshot = await input.transportRuntime.snapshot();\n if (disposed) {\n return;\n }\n input.store.replaceRawOutput(snapshot.data);\n const snapshotState = input.store.getState();\n input.diagnostics.outputProjected({\n contentEpoch: snapshotState.contentEpoch,\n previewHead: previewTerminalOutput(snapshot.data, \"head\"),\n previewTail: previewTerminalOutput(snapshot.data, \"tail\"),\n rawBytes: snapshotState.rawOutput.length,\n source: \"snapshot\",\n writeBytes: snapshot.data.length\n });\n if (snapshot.truncated) {\n input.store.setSurfaceError(input.snapshotTruncatedMessage);\n } else {\n input.store.setSurfaceError(null);\n }\n input.diagnostics.snapshotComplete({\n toSeq: snapshot.toSeq ?? null,\n truncated: snapshot.truncated ?? false\n });\n input.diagnostics.attachStart(snapshot.toSeq ?? null);\n await input.transportRuntime.attach(snapshot.toSeq);\n if (disposed) {\n return;\n }\n hydrationReady = true;\n const replayChunks = hydrationReplayChunks.splice(0);\n replayChunks.forEach((chunk) => {\n input.store.appendRawOutput(chunk);\n });\n if (replayChunks.length > 0) {\n const replayState = input.store.getState();\n input.diagnostics.outputProjected({\n contentEpoch: replayState.contentEpoch,\n previewHead: previewTerminalOutput(replayChunks.join(\"\"), \"head\"),\n previewTail: previewTerminalOutput(replayChunks.join(\"\"), \"tail\"),\n rawBytes: replayState.rawOutput.length,\n source: \"replay\",\n writeBytes: replayChunks.reduce(\n (total, chunk) => total + chunk.length,\n 0\n )\n });\n }\n input.onWriteReadyChange(true);\n input.store.setInputReady(true);\n await writeQueuedTerminalInput({\n queue: input.inputQueue,\n sessionId: input.sessionId,\n transport: input.transport\n });\n if (disposed) {\n return;\n }\n input.diagnostics.attachComplete();\n input.diagnostics.hydrationComplete(replayChunks.length);\n } catch (error) {\n if (disposed) {\n return;\n }\n input.diagnostics.attachError();\n input.store.setSurfaceError(errorMessage(error));\n }\n }\n };\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction previewTerminalOutput(\n value: string,\n side: \"head\" | \"tail\",\n maxChars = 48\n) {\n const slice =\n side === \"head\"\n ? value.slice(0, maxChars)\n : value.slice(Math.max(0, value.length - maxChars));\n return slice\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"\\r\", \"\\\\r\")\n .replaceAll(\"\\n\", \"\\\\n\");\n}\n","import { truncateTerminalScrollback } from \"./scrollback.ts\";\n\nexport interface TerminalSessionControllerState {\n contentEpoch: number;\n inputReady: boolean;\n rawOutput: string;\n surfaceError: string | null;\n}\n\nexport interface TerminalSessionControllerStore {\n appendRawOutput(data: string): void;\n clearListeners(): void;\n getState(): TerminalSessionControllerState;\n replaceRawOutput(rawOutput: string): void;\n setInputReady(inputReady: boolean): void;\n setSurfaceError(surfaceError: string | null): void;\n subscribe(listener: () => void): () => void;\n}\n\nconst initialState: TerminalSessionControllerState = {\n contentEpoch: 0,\n inputReady: false,\n rawOutput: \"\",\n surfaceError: null\n};\n\nexport function createTerminalSessionControllerStore(input: {\n maxScrollbackChars: number;\n}): TerminalSessionControllerStore {\n let state = initialState;\n const listeners = new Set<() => void>();\n\n return {\n appendRawOutput(data) {\n if (!data) {\n return;\n }\n const nextOutput = truncateTerminalScrollback(\n `${state.rawOutput}${data}`,\n {\n maxChars: input.maxScrollbackChars\n }\n );\n if (nextOutput === state.rawOutput) {\n return;\n }\n state = {\n ...state,\n rawOutput: nextOutput\n };\n emitState(listeners);\n },\n clearListeners() {\n listeners.clear();\n },\n getState() {\n return state;\n },\n replaceRawOutput(rawOutput) {\n state = {\n ...state,\n contentEpoch: state.contentEpoch + 1,\n rawOutput: truncateTerminalScrollback(rawOutput, {\n maxChars: input.maxScrollbackChars\n })\n };\n emitState(listeners);\n },\n setInputReady(inputReady) {\n if (state.inputReady === inputReady) {\n return;\n }\n state = {\n ...state,\n inputReady\n };\n emitState(listeners);\n },\n setSurfaceError(surfaceError) {\n if (state.surfaceError === surfaceError) {\n return;\n }\n state = {\n ...state,\n surfaceError\n };\n emitState(listeners);\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n };\n}\n\nfunction emitState(listeners: Set<() => void>) {\n for (const listener of listeners) {\n listener();\n }\n}\n","import type {\n TerminalDataEvent,\n TerminalExitEvent,\n TerminalMetadataEvent,\n TerminalSnapshot,\n TerminalStateEvent,\n TerminalTransport\n} from \"../contracts/index.ts\";\nimport { createTerminalAttachmentController } from \"./attachmentController.ts\";\n\nexport interface TerminalSessionTransportRuntime {\n attach(afterSeq?: number): Promise<void>;\n onData(listener: (event: TerminalDataEvent) => void): () => void;\n onExit(listener: (event: TerminalExitEvent) => void): () => void;\n onMetadata(listener: (event: TerminalMetadataEvent) => void): () => void;\n onState(listener: (event: TerminalStateEvent) => void): () => void;\n release(): void;\n snapshot(): Promise<TerminalSnapshot>;\n}\n\ninterface TerminalSessionTransportRuntimeEntry {\n attach(afterSeq?: number): Promise<void>;\n dataBuffer: TerminalDataEvent[];\n dataListeners: Set<(event: TerminalDataEvent) => void>;\n detachGraceMs: number;\n detachTimer: ReturnType<typeof setTimeout> | null;\n exitBuffer: TerminalExitEvent[];\n exitListeners: Set<(event: TerminalExitEvent) => void>;\n metadataBuffer: TerminalMetadataEvent[];\n metadataListeners: Set<(event: TerminalMetadataEvent) => void>;\n refCount: number;\n release(): void;\n sessionId: string;\n snapshot(): Promise<TerminalSnapshot>;\n snapshotCache: TerminalSnapshot | null;\n snapshotPromise: Promise<TerminalSnapshot> | null;\n stateBuffer: TerminalStateEvent[];\n stateListeners: Set<(event: TerminalStateEvent) => void>;\n teardown(): void;\n}\n\nconst defaultDetachGraceMs = 200;\nconst runtimeRegistry = new Map<string, TerminalSessionTransportRuntimeEntry>();\nlet runtimeClientSequence = 0;\n\nexport function acquireTerminalSessionTransportRuntime(input: {\n detachGraceMs?: number;\n sessionId: string;\n transport: TerminalTransport;\n}): TerminalSessionTransportRuntime {\n const entry =\n runtimeRegistry.get(input.sessionId) ??\n createTerminalSessionTransportRuntimeEntry(input);\n if (!runtimeRegistry.has(input.sessionId)) {\n runtimeRegistry.set(input.sessionId, entry);\n }\n entry.refCount += 1;\n if (entry.detachTimer !== null) {\n clearTimeout(entry.detachTimer);\n entry.detachTimer = null;\n }\n\n return {\n attach(afterSeq) {\n return entry.attach(afterSeq);\n },\n onData(listener) {\n entry.dataListeners.add(listener);\n flushBufferedEvents(entry.dataBuffer, listener);\n return () => {\n entry.dataListeners.delete(listener);\n };\n },\n onExit(listener) {\n entry.exitListeners.add(listener);\n flushBufferedEvents(entry.exitBuffer, listener);\n return () => {\n entry.exitListeners.delete(listener);\n };\n },\n onMetadata(listener) {\n entry.metadataListeners.add(listener);\n flushBufferedEvents(entry.metadataBuffer, listener);\n return () => {\n entry.metadataListeners.delete(listener);\n };\n },\n onState(listener) {\n entry.stateListeners.add(listener);\n flushBufferedEvents(entry.stateBuffer, listener);\n return () => {\n entry.stateListeners.delete(listener);\n };\n },\n release() {\n entry.release();\n },\n snapshot() {\n return entry.snapshot();\n }\n };\n}\n\nfunction createTerminalSessionTransportRuntimeEntry(input: {\n detachGraceMs?: number;\n sessionId: string;\n transport: TerminalTransport;\n}): TerminalSessionTransportRuntimeEntry {\n const attachmentController = createTerminalAttachmentController({\n clientId: createTerminalTransportClientId(),\n sessionId: input.sessionId,\n transport: input.transport\n });\n\n const entry: TerminalSessionTransportRuntimeEntry = {\n attach(afterSeq) {\n return attachmentController.attach(afterSeq);\n },\n dataBuffer: [],\n dataListeners: new Set(),\n detachGraceMs: input.detachGraceMs ?? defaultDetachGraceMs,\n detachTimer: null,\n exitBuffer: [],\n exitListeners: new Set(),\n metadataBuffer: [],\n metadataListeners: new Set(),\n refCount: 0,\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0 || entry.detachTimer !== null) {\n return;\n }\n entry.detachTimer = setTimeout(() => {\n entry.detachTimer = null;\n if (entry.refCount > 0) {\n return;\n }\n void attachmentController.detach().finally(() => {\n entry.teardown();\n runtimeRegistry.delete(entry.sessionId);\n });\n }, entry.detachGraceMs);\n },\n sessionId: input.sessionId,\n snapshot() {\n if (entry.snapshotPromise) {\n return entry.snapshotPromise;\n }\n if (entry.snapshotCache) {\n return Promise.resolve(entry.snapshotCache);\n }\n entry.snapshotPromise = input.transport\n .snapshot({ sessionId: input.sessionId })\n .then((snapshot) => {\n entry.snapshotCache = snapshot;\n return snapshot;\n })\n .finally(() => {\n entry.snapshotPromise = null;\n });\n return entry.snapshotPromise;\n },\n snapshotCache: null,\n snapshotPromise: null,\n stateBuffer: [],\n stateListeners: new Set(),\n teardown() {\n disposeData();\n disposeState();\n disposeExit();\n disposeMetadata?.();\n entry.dataBuffer.length = 0;\n entry.exitBuffer.length = 0;\n entry.metadataBuffer.length = 0;\n entry.stateBuffer.length = 0;\n entry.snapshotCache = null;\n entry.snapshotPromise = null;\n }\n };\n\n const disposeData = input.transport.onData((event) => {\n if (event.sessionId !== input.sessionId) {\n return;\n }\n entry.snapshotCache = null;\n dispatchOrBuffer(entry.dataListeners, entry.dataBuffer, event);\n });\n const disposeState = input.transport.onState((event) => {\n if (event.sessionId !== input.sessionId) {\n return;\n }\n if (event.status === \"detached\" || event.status === \"exited\") {\n attachmentController.markDetached();\n }\n if (\n typeof event.gapStartSeq === \"number\" ||\n typeof event.gapEndSeq === \"number\"\n ) {\n entry.snapshotCache = null;\n }\n dispatchOrBuffer(entry.stateListeners, entry.stateBuffer, event);\n });\n const disposeExit = input.transport.onExit((event) => {\n if (event.sessionId !== input.sessionId) {\n return;\n }\n dispatchOrBuffer(entry.exitListeners, entry.exitBuffer, event);\n });\n const disposeMetadata = input.transport.onMetadata?.((event) => {\n if (event.sessionId !== input.sessionId) {\n return;\n }\n dispatchOrBuffer(entry.metadataListeners, entry.metadataBuffer, event);\n });\n\n return entry;\n}\n\nfunction createTerminalTransportClientId(): string {\n runtimeClientSequence += 1;\n return `terminal-runtime-${runtimeClientSequence}`;\n}\n\nfunction dispatchOrBuffer<TEvent>(\n listeners: Set<(event: TEvent) => void>,\n buffer: TEvent[],\n event: TEvent\n) {\n if (listeners.size === 0) {\n buffer.push(event);\n return;\n }\n for (const listener of listeners) {\n listener(event);\n }\n}\n\nfunction flushBufferedEvents<TEvent>(\n buffer: TEvent[],\n listener: (event: TEvent) => void\n) {\n if (buffer.length === 0) {\n return;\n }\n const pending = buffer.splice(0);\n for (const event of pending) {\n listener(event);\n }\n}\n","import type {\n TerminalNodeLimits,\n TerminalWriteEncoding\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"./feature.ts\";\nimport {\n createBufferedTerminalInputQueue,\n type BufferedTerminalInputQueue\n} from \"./inputQueue.ts\";\nimport {\n createTerminalSessionRecovery,\n type TerminalSessionRecoveryHandle\n} from \"./sessionControllerRecovery.ts\";\nimport { createTerminalSessionRecoveryDiagnostics } from \"./sessionDiagnostics.ts\";\nimport {\n createTerminalSessionControllerStore,\n type TerminalSessionControllerState,\n type TerminalSessionControllerStore\n} from \"./sessionControllerStore.ts\";\nimport {\n acquireTerminalSessionTransportRuntime,\n type TerminalSessionTransportRuntime\n} from \"./sessionTransportRuntime.ts\";\n\nexport type { TerminalSessionControllerState } from \"./sessionControllerStore.ts\";\n\nexport interface TerminalSessionController {\n getState(): TerminalSessionControllerState;\n retain(): void;\n release(): void;\n resize(input: { cols: number; rows: number }): Promise<void>;\n subscribe(listener: () => void): () => void;\n write(data: string, encoding?: TerminalWriteEncoding): void;\n}\n\ninterface TerminalSessionControllerEntry {\n context: TerminalSessionControllerContext;\n disposed: boolean;\n inputQueue: BufferedTerminalInputQueue;\n recovery: TerminalSessionRecoveryHandle;\n refCount: number;\n release(): void;\n retainTimer: ReturnType<typeof setTimeout> | null;\n runtimeWriteReady: boolean;\n startPromise: Promise<void> | null;\n store: TerminalSessionControllerStore;\n teardown(): void;\n transportRuntime: TerminalSessionTransportRuntime;\n}\n\ninterface TerminalSessionControllerContext {\n feature: TerminalNodeFeature;\n nodeId: string;\n sessionId: string;\n}\n\nconst defaultControllerRetainMs = 5_000;\nconst controllerRegistry = new Map<string, TerminalSessionControllerEntry>();\n\nexport function acquireTerminalSessionController(input: {\n feature: TerminalNodeFeature;\n nodeId: string;\n retainMs?: number;\n sessionId: string;\n}): TerminalSessionController {\n const entry =\n controllerRegistry.get(input.sessionId) ??\n createTerminalSessionControllerEntry({\n feature: input.feature,\n nodeId: input.nodeId,\n retainMs: input.retainMs ?? defaultControllerRetainMs,\n sessionId: input.sessionId\n });\n if (!controllerRegistry.has(input.sessionId)) {\n controllerRegistry.set(input.sessionId, entry);\n }\n\n entry.context = {\n feature: input.feature,\n nodeId: input.nodeId,\n sessionId: input.sessionId\n };\n\n return {\n getState() {\n return entry.store.getState();\n },\n retain() {\n entry.refCount += 1;\n if (entry.retainTimer !== null) {\n clearTimeout(entry.retainTimer);\n entry.retainTimer = null;\n }\n ensureRecoveryStarted(entry);\n },\n release() {\n entry.release();\n },\n resize({ cols, rows }) {\n return entry.context.feature.transport.resize({\n cols,\n rows,\n sessionId: entry.context.sessionId\n });\n },\n subscribe(listener) {\n return entry.store.subscribe(listener);\n },\n write(data, encoding = \"utf8\") {\n if (!entry.runtimeWriteReady) {\n entry.inputQueue.enqueue(data, encoding);\n ensureRecoveryStarted(entry);\n return;\n }\n void writeTerminalInput(entry, data, encoding);\n }\n };\n}\n\nfunction createTerminalSessionControllerEntry(input: {\n feature: TerminalNodeFeature;\n nodeId: string;\n retainMs: number;\n sessionId: string;\n}) {\n const transportRuntime = acquireTerminalSessionTransportRuntime({\n sessionId: input.sessionId,\n transport: input.feature.transport\n });\n const inputQueue = createBufferedTerminalInputQueue();\n const store = createTerminalSessionControllerStore({\n maxScrollbackChars: resolveMaxScrollbackChars(input.feature.limits)\n });\n\n const entry = {\n context: {\n feature: input.feature,\n nodeId: input.nodeId,\n sessionId: input.sessionId\n },\n disposed: false,\n inputQueue,\n recovery: null as unknown as TerminalSessionRecoveryHandle,\n refCount: 0,\n release: () => undefined,\n retainTimer: null,\n runtimeWriteReady: false,\n startPromise: null,\n store,\n teardown: () => undefined,\n transportRuntime\n } as TerminalSessionControllerEntry;\n\n entry.release = () => {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0 || entry.retainTimer !== null) {\n return;\n }\n entry.retainTimer = setTimeout(() => {\n entry.retainTimer = null;\n if (entry.refCount > 0) {\n return;\n }\n entry.teardown();\n controllerRegistry.delete(entry.context.sessionId);\n }, input.retainMs);\n };\n\n entry.teardown = () => {\n if (entry.disposed) {\n return;\n }\n entry.disposed = true;\n inputQueue.reset();\n entry.runtimeWriteReady = false;\n entry.recovery.dispose();\n transportRuntime.release();\n store.clearListeners();\n };\n\n entry.recovery = createTerminalSessionRecovery({\n diagnostics: createTerminalSessionRecoveryDiagnostics({\n diagnostics: input.feature.diagnostics,\n nodeId: input.nodeId,\n sessionId: input.sessionId\n }),\n inputQueue,\n onRecoverableDetach() {\n if (entry.disposed || entry.refCount === 0) {\n return;\n }\n ensureRecoveryStarted(entry);\n },\n onWriteReadyChange(ready) {\n if (entry.disposed) {\n return;\n }\n entry.runtimeWriteReady = ready;\n },\n replayGapMessage: input.feature.i18n.t(\"recovery.replayGap\"),\n sessionId: input.sessionId,\n snapshotTruncatedMessage: input.feature.i18n.t(\n \"recovery.snapshotTruncated\"\n ),\n store,\n transport: input.feature.transport,\n transportRuntime\n });\n\n return entry;\n}\n\nfunction ensureRecoveryStarted(entry: TerminalSessionControllerEntry) {\n if (\n entry.disposed ||\n entry.startPromise !== null ||\n entry.runtimeWriteReady\n ) {\n return;\n }\n entry.startPromise = entry.recovery.start().finally(() => {\n entry.startPromise = null;\n });\n}\n\nfunction resolveMaxScrollbackChars(limits: TerminalNodeLimits) {\n return Math.max(limits.maxScrollbackLines * 160, 400_000);\n}\n\nfunction writeTerminalInput(\n entry: TerminalSessionControllerEntry,\n data: string,\n encoding: TerminalWriteEncoding\n) {\n return entry.context.feature.transport\n .write({\n data,\n encoding,\n provenance: \"user\",\n sessionId: entry.context.sessionId\n })\n .catch((error: unknown) => {\n entry.runtimeWriteReady = false;\n entry.store.setInputReady(false);\n entry.inputQueue.enqueue(data, encoding);\n ensureRecoveryStarted(entry);\n entry.context.feature.diagnostics.log(\"write-error\", {\n nodeId: entry.context.nodeId,\n sessionId: entry.context.sessionId\n });\n entry.store.setSurfaceError(errorMessage(error));\n });\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import { useState } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { Badge, StatusDot } from \"@tutti-os/ui-system\";\nimport type {\n TerminalCloseGuardResult,\n TerminalHeaderAccessoryRenderer,\n TerminalNodeExternalState,\n TerminalPreviewChangeHandler,\n TerminalSessionStatus\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport { createTerminalCloseDiagnostics } from \"../core/sessionDiagnostics.ts\";\nimport { isTerminalSessionEndedStatus } from \"../core/index.ts\";\nimport { hasTerminalHeaderDefaultActions } from \"./headerActions.ts\";\nimport { TerminalSurface } from \"./TerminalSurface.tsx\";\n\nexport interface TerminalNodeProps {\n children?: ReactNode;\n controllerLeaseRetainedExternally?: boolean;\n externalState?: TerminalNodeExternalState | null;\n feature: TerminalNodeFeature;\n headerAccessory?: TerminalHeaderAccessoryRenderer;\n nodeId: string;\n onFocusRequest?: () => void;\n onPreviewChange?: TerminalPreviewChangeHandler;\n sessionId?: string | null;\n showHeader?: boolean;\n}\n\nexport interface TerminalNodeHeaderProps extends HTMLAttributes<HTMLElement> {\n className?: string;\n defaultActions?: ReactNode;\n externalState?: TerminalNodeExternalState | null;\n feature: TerminalNodeFeature;\n headerAccessory?: TerminalHeaderAccessoryRenderer;\n onCloseRequest?: () => void;\n sessionId?: string | null;\n}\n\nexport interface TerminalCloseGuardDialogProps {\n feature: TerminalNodeFeature;\n leaderCommand?: string | null;\n onCancel: () => void;\n onConfirm: () => void;\n open: boolean;\n}\n\nexport function TerminalNode({\n children,\n controllerLeaseRetainedExternally = false,\n externalState = null,\n feature,\n headerAccessory,\n nodeId,\n onFocusRequest,\n onPreviewChange,\n sessionId,\n showHeader = true\n}: TerminalNodeProps) {\n const resolvedSessionId = sessionId ?? externalState?.sessionId ?? null;\n const status = externalState?.status ?? \"created\";\n\n return (\n <section\n className=\"workspace-terminal\"\n data-terminal-node={nodeId}\n data-terminal-session-id={resolvedSessionId ?? undefined}\n onClick={onFocusRequest}\n >\n {showHeader ? (\n <TerminalNodeHeader\n externalState={externalState}\n feature={feature}\n headerAccessory={headerAccessory}\n sessionId={resolvedSessionId}\n />\n ) : null}\n <div className=\"workspace-terminal__body\">\n {children ??\n (resolvedSessionId ? (\n <TerminalSurface\n controllerLeaseRetainedExternally={\n controllerLeaseRetainedExternally\n }\n externalState={externalState}\n feature={feature}\n nodeId={nodeId}\n onPreviewChange={onPreviewChange}\n sessionId={resolvedSessionId}\n status={status}\n />\n ) : (\n <div className=\"workspace-terminal__placeholder\">\n {feature.i18n.t(\"emptySession\")}\n </div>\n ))}\n </div>\n </section>\n );\n}\n\nexport function TerminalNodeHeader({\n className,\n defaultActions,\n externalState = null,\n feature,\n headerAccessory,\n onCloseRequest,\n sessionId,\n ...headerProps\n}: TerminalNodeHeaderProps) {\n const status = externalState?.status ?? \"created\";\n const statusLabel = resolveTerminalStatusLabel(feature, status);\n const resolvedSessionId = sessionId ?? externalState?.sessionId ?? null;\n const hasDefaultActions = hasTerminalHeaderDefaultActions(defaultActions);\n const [pendingCloseGuard, setPendingCloseGuard] =\n useState<TerminalCloseGuardResult | null>(null);\n const [closeError, setCloseError] = useState<string | null>(null);\n const closeDiagnostics = resolvedSessionId\n ? createTerminalCloseDiagnostics({\n diagnostics: feature.diagnostics,\n sessionId: resolvedSessionId\n })\n : null;\n\n const closeTerminal = async (skipConfirmation: boolean) => {\n if (\n !resolvedSessionId ||\n isTerminalSessionEndedStatus(externalState?.status ?? \"created\")\n ) {\n onCloseRequest?.();\n return;\n }\n\n setCloseError(null);\n try {\n if (!skipConfirmation) {\n closeDiagnostics?.requested();\n const guard = await feature.closeGuard.check({\n sessionId: resolvedSessionId\n });\n if (guard.requiresConfirmation) {\n setPendingCloseGuard(guard);\n return;\n }\n }\n\n await feature.launchService.terminate({ sessionId: resolvedSessionId });\n closeDiagnostics?.confirmed();\n setPendingCloseGuard(null);\n onCloseRequest?.();\n } catch (error) {\n setCloseError(errorMessage(error));\n }\n };\n\n return (\n <header\n {...headerProps}\n className={joinClassName(\"workspace-terminal__header\", className)}\n >\n <div className=\"workspace-terminal__header-main\">\n <span className=\"workspace-terminal__title\">\n {externalState?.title?.trim() || feature.i18n.t(\"title\")}\n </span>\n <Badge className=\"workspace-terminal__status-tag\" variant=\"default\">\n <StatusDot\n pulse={status === \"running\" || status === \"starting\"}\n size=\"xs\"\n tone={resolveTerminalStatusTone(status)}\n />\n {statusLabel}\n </Badge>\n </div>\n {headerAccessory?.({\n externalState,\n sessionId: resolvedSessionId\n })}\n <div\n className=\"workspace-terminal__actions\"\n onDoubleClick={(event) => {\n event.stopPropagation();\n }}\n onPointerDown={(event) => {\n event.stopPropagation();\n }}\n >\n {defaultActions}\n {onCloseRequest && !hasDefaultActions ? (\n <button\n aria-label={feature.i18n.t(\"actions.close\")}\n className=\"workspace-terminal__icon-button\"\n onClick={() => {\n void closeTerminal(false);\n }}\n onPointerDown={(event) => {\n event.stopPropagation();\n }}\n type=\"button\"\n >\n x\n </button>\n ) : null}\n </div>\n <TerminalCloseGuardDialog\n feature={feature}\n leaderCommand={pendingCloseGuard?.leaderCommand}\n onCancel={() => setPendingCloseGuard(null)}\n onConfirm={() => {\n void closeTerminal(true);\n }}\n open={Boolean(pendingCloseGuard)}\n />\n {closeError ? (\n <div className=\"workspace-terminal__close-error\" role=\"status\">\n {closeError}\n </div>\n ) : null}\n </header>\n );\n}\n\nexport function TerminalCloseGuardDialog({\n feature,\n leaderCommand,\n onCancel,\n onConfirm,\n open\n}: TerminalCloseGuardDialogProps) {\n if (!open) {\n return null;\n }\n\n return (\n <div className=\"workspace-terminal__close-guard\" role=\"alertdialog\">\n <h2>{feature.i18n.t(\"closeGuard.title\")}</h2>\n <p>{feature.i18n.t(\"closeGuard.description\")}</p>\n {leaderCommand ? <code>{leaderCommand}</code> : null}\n <div className=\"workspace-terminal__close-guard-actions\">\n <button onClick={() => onCancel()} type=\"button\">\n {feature.i18n.t(\"closeGuard.cancel\")}\n </button>\n <button onClick={() => onConfirm()} type=\"button\">\n {feature.i18n.t(\"closeGuard.confirm\")}\n </button>\n </div>\n </div>\n );\n}\n\nfunction resolveTerminalStatusLabel(\n feature: TerminalNodeFeature,\n status: TerminalSessionStatus\n): string {\n return feature.i18n.t(`status.${status}`);\n}\n\nfunction resolveTerminalStatusTone(\n status: TerminalSessionStatus\n): \"amber\" | \"blue\" | \"green\" | \"neutral\" | \"red\" {\n switch (status) {\n case \"running\":\n case \"starting\":\n return \"blue\";\n case \"exited\":\n return \"green\";\n case \"failed\":\n return \"red\";\n case \"detached\":\n return \"amber\";\n case \"created\":\n return \"neutral\";\n }\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction joinClassName(...values: Array<string | undefined>): string {\n return values.filter(Boolean).join(\" \");\n}\n","import type { ReactNode } from \"react\";\n\nexport function hasTerminalHeaderDefaultActions(\n defaultActions: ReactNode\n): boolean {\n return defaultActions !== undefined && defaultActions !== null;\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n TerminalNodeExternalState,\n TerminalPreviewChangeHandler,\n TerminalSessionStatus\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport { createTerminalSurfaceDiagnostics } from \"../core/sessionDiagnostics.ts\";\nimport { createTerminalSurfaceRuntime } from \"./terminalSurfaceRuntime.ts\";\nimport { isTerminalFindShortcut } from \"./terminalFindShortcut.ts\";\nimport { useTerminalFindController } from \"./useTerminalFindController.ts\";\nimport { useTerminalSessionController } from \"./useTerminalSessionController.ts\";\n\nexport interface TerminalSurfaceProps {\n controllerLeaseRetainedExternally?: boolean;\n externalState: TerminalNodeExternalState | null;\n feature: TerminalNodeFeature;\n nodeId: string;\n onPreviewChange?: TerminalPreviewChangeHandler;\n sessionId: string;\n status: TerminalSessionStatus;\n}\n\nexport function TerminalSurface({\n controllerLeaseRetainedExternally = false,\n externalState,\n feature,\n nodeId,\n onPreviewChange,\n sessionId,\n status\n}: TerminalSurfaceProps) {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const currentCwdRef = useRef<string | null>(externalState?.cwd ?? null);\n const featureRef = useRef(feature);\n const findInputRef = useRef<HTMLInputElement | null>(null);\n const runtimeRef = useRef<ReturnType<\n typeof createTerminalSurfaceRuntime\n > | null>(null);\n const [interactionError, setInteractionError] = useState<string | null>(null);\n const { controller, state } = useTerminalSessionController({\n feature,\n nodeId,\n retainLease: !controllerLeaseRetainedExternally,\n sessionId\n });\n const find = useTerminalFindController({\n getRuntime: () => runtimeRef.current\n });\n const theme = useMemo(\n () =>\n feature.resolveTheme({\n runtimeKind: externalState?.runtimeKind ?? \"local\",\n sessionId,\n status\n }),\n [externalState?.runtimeKind, feature, sessionId, status]\n );\n const surfaceDiagnostics = useMemo(\n () =>\n createTerminalSurfaceDiagnostics({\n diagnostics: feature.diagnostics,\n nodeId,\n sessionId\n }),\n [feature.diagnostics, nodeId, sessionId]\n );\n const surfaceError = interactionError ?? state.surfaceError;\n\n useEffect(() => {\n currentCwdRef.current = externalState?.cwd ?? null;\n }, [externalState?.cwd]);\n\n useEffect(() => {\n featureRef.current = feature;\n }, [feature]);\n\n useEffect(() => {\n if (!find.state.open) {\n return;\n }\n const input = findInputRef.current;\n if (!input) {\n return;\n }\n input.focus();\n input.select();\n }, [find.state.open]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n surfaceDiagnostics.mount();\n setInteractionError(null);\n\n const runtime = createTerminalSurfaceRuntime({\n container,\n diagnostics: surfaceDiagnostics,\n feature: featureRef.current,\n getCwd: () => currentCwdRef.current,\n nodeId,\n onResize: ({ cols, rows }) => {\n surfaceDiagnostics.resize({ cols, rows });\n void controller.resize({ cols, rows });\n },\n onPreviewChange,\n onUserInput: (data, encoding) => {\n controller.write(data, encoding);\n },\n sessionId,\n theme\n });\n runtimeRef.current = runtime;\n runtime.syncOutput(state.rawOutput, state.contentEpoch);\n runtime.focus();\n\n return () => {\n surfaceDiagnostics.dispose();\n runtime.dispose();\n if (runtimeRef.current === runtime) {\n runtimeRef.current = null;\n }\n };\n }, [controller, nodeId, sessionId, surfaceDiagnostics]);\n\n useEffect(() => {\n runtimeRef.current?.setTheme(theme);\n }, [theme]);\n\n useEffect(() => {\n runtimeRef.current?.syncOutput(state.rawOutput, state.contentEpoch);\n }, [state.contentEpoch, state.rawOutput]);\n\n const writeInput = (data: string) => {\n controller.write(data);\n };\n\n return (\n <div\n className=\"workspace-terminal__surface-shell\"\n onKeyDownCapture={(event) => {\n if (!isTerminalFindShortcut(event)) {\n if (event.key === \"Escape\" && find.state.open) {\n find.actions.close();\n runtimeRef.current?.focus();\n }\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n find.actions.open();\n }}\n onDragOver={(event) => {\n if (feature.dropInput) {\n event.preventDefault();\n }\n }}\n onDrop={(event) => {\n if (!feature.dropInput) {\n return;\n }\n event.preventDefault();\n void Promise.resolve(\n feature.dropInput({\n cwd: externalState?.cwd ?? null,\n dataTransfer: event.dataTransfer,\n sessionId\n })\n )\n .then((input) => {\n if (input) {\n writeInput(input);\n }\n })\n .catch((error: unknown) => setInteractionError(errorMessage(error)));\n }}\n >\n {find.state.open ? (\n <form\n className=\"workspace-terminal__find\"\n onSubmit={(event) => {\n event.preventDefault();\n find.actions.onSubmit();\n }}\n >\n <input\n aria-label={feature.i18n.t(\"findPlaceholder\")}\n ref={findInputRef}\n onChange={(event) => {\n find.actions.onQueryChange(event.currentTarget.value);\n }}\n placeholder={feature.i18n.t(\"findPlaceholder\")}\n type=\"search\"\n value={find.state.query}\n />\n <button\n className=\"workspace-terminal__find-toggle\"\n aria-label={feature.i18n.t(\"actions.caseSensitive\")}\n aria-pressed={find.state.caseSensitive}\n onClick={() => find.actions.toggleCaseSensitive()}\n type=\"button\"\n >\n Aa\n </button>\n <button\n className=\"workspace-terminal__find-toggle\"\n aria-label={feature.i18n.t(\"actions.regex\")}\n aria-pressed={find.state.regex}\n onClick={() => find.actions.toggleRegex()}\n type=\"button\"\n >\n .*\n </button>\n <button\n className=\"workspace-terminal__find-nav workspace-terminal__find-nav--previous\"\n aria-label={feature.i18n.t(\"actions.previous\")}\n onClick={() => find.actions.findPrevious()}\n type=\"button\"\n />\n <button\n className=\"workspace-terminal__find-nav workspace-terminal__find-nav--next\"\n aria-label={feature.i18n.t(\"actions.next\")}\n onClick={() => find.actions.findNext()}\n type=\"submit\"\n />\n </form>\n ) : null}\n <div\n className=\"workspace-terminal__xterm\"\n data-terminal-xterm=\"\"\n ref={containerRef}\n />\n {surfaceError ? (\n <div className=\"workspace-terminal__surface-error\" role=\"status\">\n {surfaceError}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import { FitAddon } from \"@xterm/addon-fit\";\nimport { SearchAddon } from \"@xterm/addon-search\";\nimport { SerializeAddon } from \"@xterm/addon-serialize\";\nimport { WebLinksAddon } from \"@xterm/addon-web-links\";\nimport { Terminal, type IBufferCell, type IBufferLine } from \"@xterm/xterm\";\nimport type {\n TerminalPreviewChangeHandler,\n TerminalPreviewLine,\n TerminalPreviewSegment,\n TerminalPreviewSegmentStyle,\n TerminalPreviewSnapshot,\n TerminalTheme,\n TerminalWriteEncoding\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport { createTerminalScreenStateCache } from \"../core/index.ts\";\nimport type { TerminalSurfaceDiagnostics } from \"../core/sessionDiagnostics.ts\";\nimport { createTerminalFileLinkProvider } from \"./terminalFileLinkProvider.ts\";\nimport { resolveTerminalSurfaceOutputPlan } from \"./terminalSurfaceOutputPlan.ts\";\nimport { resolveTerminalSurfaceResizePlan } from \"./terminalSurfaceResizePlan.ts\";\nimport { resolveTerminalSurfaceScreenCachePlan } from \"./terminalSurfaceScreenCachePlan.ts\";\nimport { drainTerminalWriteBatch } from \"./terminalWriteBatch.ts\";\nimport type { TerminalFindRuntime } from \"./useTerminalFindController.ts\";\n\nconst terminalScreenStateCache = createTerminalScreenStateCache();\nconst terminalPreviewMaxRows = 24;\nconst terminalPreviewMaxCols = 160;\nconst terminalPreviewAnsiColors = [\n \"#2e3436\",\n \"#cc0000\",\n \"#4e9a06\",\n \"#c4a000\",\n \"#3465a4\",\n \"#75507b\",\n \"#06989a\",\n \"#d3d7cf\",\n \"#555753\",\n \"#ef2929\",\n \"#8ae234\",\n \"#fce94f\",\n \"#729fcf\",\n \"#ad7fa8\",\n \"#34e2e2\",\n \"#eeeeec\"\n] as const;\nconst terminalPreviewColorSteps = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n\nexport interface TerminalSurfaceRuntime extends TerminalFindRuntime {\n dispose(): void;\n focus(): void;\n setTheme(theme: TerminalTheme): void;\n syncOutput(rawOutput: string, contentEpoch: number): void;\n}\n\nexport function createTerminalSurfaceRuntime(input: {\n container: HTMLElement;\n diagnostics: TerminalSurfaceDiagnostics;\n feature: TerminalNodeFeature;\n getCwd: () => string | null;\n nodeId: string;\n onResize: (size: { cols: number; rows: number }) => void;\n onPreviewChange?: TerminalPreviewChangeHandler;\n onUserInput: (data: string, encoding?: TerminalWriteEncoding) => void;\n sessionId: string;\n theme: TerminalTheme;\n}): TerminalSurfaceRuntime {\n let contentEpoch = 0;\n let committedRawOutput = \"\";\n let initialLayoutFrame: number | null = null;\n let initialLayoutTimeout: number | null = null;\n let lastSize: { cols: number; rows: number } | null = null;\n let pendingRevealFinalizeFrame: number | null = null;\n let pendingRevealStartFrame: number | null = null;\n let pendingRevealWrite: {\n bytes: number;\n mode: \"cache\" | \"replace\";\n remainingChunkCount: number;\n } | null = null;\n let pendingWriteFrame: number | null = null;\n let pendingWriteChunks: string[] = [];\n let pendingRenderedWrite: {\n bytes: number;\n mode: \"append\" | \"cache\" | \"replace\";\n remainingChunkCount: number;\n } | null = null;\n let lastPreviewRevision: string | null = null;\n\n const terminal = new Terminal({\n allowProposedApi: false,\n convertEol: true,\n cursorBlink: true,\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontSize: 13,\n scrollback: input.feature.limits.maxScrollbackLines,\n theme: resolveXtermTheme(input.theme)\n });\n const fitAddon = new FitAddon();\n const searchAddon = new SearchAddon();\n const serializeAddon = new SerializeAddon();\n const webLinksAddon = new WebLinksAddon((_event, uri) => {\n void input.feature.linkHandler?.open({ url: uri });\n });\n terminal.loadAddon(fitAddon);\n terminal.loadAddon(searchAddon);\n terminal.loadAddon(serializeAddon);\n terminal.loadAddon(webLinksAddon);\n const fileLinkDisposable = terminal.registerLinkProvider(\n createTerminalFileLinkProvider({\n feature: input.feature,\n getCwd: input.getCwd,\n terminal\n })\n );\n terminal.open(input.container);\n\n const dataSubscription = terminal.onData((data) => {\n input.onUserInput(data);\n });\n const binarySubscription = terminal.onBinary((data) => {\n input.onUserInput(data, \"binary\");\n });\n const writeParsedSubscription =\n typeof terminal.onWriteParsed === \"function\"\n ? terminal.onWriteParsed(() => {\n if (!pendingRenderedWrite) {\n refreshTerminalSurface();\n return;\n }\n const renderedWrite = pendingRenderedWrite;\n pendingRenderedWrite = null;\n if (\n renderedWrite.mode === \"cache\" ||\n renderedWrite.mode === \"replace\"\n ) {\n scheduleHydratedReveal({\n bytes: renderedWrite.bytes,\n mode: renderedWrite.mode,\n remainingChunkCount: renderedWrite.remainingChunkCount\n });\n return;\n }\n refreshTerminalSurface();\n logSurfaceWrite(\n renderedWrite.mode,\n renderedWrite.bytes,\n renderedWrite.remainingChunkCount\n );\n })\n : { dispose: () => undefined };\n\n const resizeTerminal = () => {\n try {\n fitAddon.fit();\n } catch {\n return;\n }\n const plan = resolveTerminalSurfaceResizePlan({\n lastSize,\n nextSize: { cols: terminal.cols, rows: terminal.rows }\n });\n if (!plan) {\n return;\n }\n lastSize = plan;\n input.onResize(plan);\n };\n\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(() => resizeTerminal());\n resizeObserver?.observe(input.container);\n scheduleInitialLayoutSync();\n\n const cached = terminalScreenStateCache.get(input.nodeId, input.sessionId);\n if (cached) {\n terminal.write(cached.serialized, () => {\n queueRenderedWrite(\"cache\", cached.serialized.length, 0);\n });\n committedRawOutput = cached.rawSnapshot;\n }\n\n return {\n dispose() {\n resizeObserver?.disconnect();\n dataSubscription.dispose();\n binarySubscription.dispose();\n writeParsedSubscription.dispose();\n fileLinkDisposable.dispose();\n clearInitialLayoutSync();\n clearPendingReveal();\n const hasPendingWrites =\n pendingWriteFrame !== null || pendingWriteChunks.length > 0;\n const cachePlan = resolveTerminalSurfaceScreenCachePlan({\n hasPendingWrites,\n rawSnapshot: committedRawOutput,\n serialized: hasPendingWrites ? \"\" : serializeAddon.serialize()\n });\n if (cachePlan.action === \"save\") {\n terminalScreenStateCache.set(input.nodeId, {\n cols: terminal.cols,\n rawSnapshot: cachePlan.rawSnapshot,\n rows: terminal.rows,\n serialized: cachePlan.serialized,\n sessionId: input.sessionId\n });\n } else if (cachePlan.action === \"remove\") {\n terminalScreenStateCache.remove(input.nodeId, input.sessionId);\n }\n clearPendingWrites();\n emitTerminalPreviewSnapshot();\n terminal.dispose();\n },\n findNext(query, options) {\n searchAddon.findNext(query, options);\n },\n findPrevious(query, options) {\n searchAddon.findPrevious(query, options);\n },\n focus() {\n terminal.focus();\n resizeTerminal();\n },\n setTheme(theme) {\n terminal.options.theme = resolveXtermTheme(theme);\n emitTerminalPreviewSnapshot();\n },\n syncOutput(rawOutput, nextContentEpoch) {\n const plan = resolveTerminalSurfaceOutputPlan({\n committedRawOutput,\n contentEpoch,\n nextContentEpoch,\n rawOutput\n });\n input.diagnostics.outputSync({\n contentEpoch: nextContentEpoch,\n nextCommittedBytes:\n plan?.nextCommittedRawOutput.length ?? committedRawOutput.length,\n plan: resolveOutputSyncPlan(plan),\n previousCommittedBytes: committedRawOutput.length,\n rawBytes: rawOutput.length,\n writeBytes: plan?.write?.length ?? 0\n });\n if (!plan) {\n return;\n }\n contentEpoch = plan.nextContentEpoch;\n if (plan.reset && plan.write) {\n replaceTerminalView(plan.write, { reset: true });\n } else if (plan.reset) {\n resetTerminalView();\n }\n if (plan.write && !plan.reset) {\n writeToTerminal(plan.write);\n }\n committedRawOutput = plan.nextCommittedRawOutput;\n }\n };\n\n function clearPendingWrites() {\n pendingWriteChunks = [];\n if (pendingWriteFrame === null) {\n return;\n }\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(pendingWriteFrame);\n } else {\n clearTimeout(pendingWriteFrame);\n }\n pendingWriteFrame = null;\n }\n\n function clearInitialLayoutSync() {\n if (initialLayoutFrame !== null) {\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(initialLayoutFrame);\n } else {\n clearTimeout(initialLayoutFrame);\n }\n initialLayoutFrame = null;\n }\n if (initialLayoutTimeout !== null) {\n clearTimeout(initialLayoutTimeout);\n initialLayoutTimeout = null;\n }\n }\n\n function clearPendingReveal() {\n if (pendingRevealStartFrame !== null) {\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(pendingRevealStartFrame);\n } else {\n clearTimeout(pendingRevealStartFrame);\n }\n pendingRevealStartFrame = null;\n }\n if (pendingRevealFinalizeFrame !== null) {\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(pendingRevealFinalizeFrame);\n } else {\n clearTimeout(pendingRevealFinalizeFrame);\n }\n pendingRevealFinalizeFrame = null;\n }\n pendingRevealWrite = null;\n }\n\n function flushPendingWrites() {\n pendingWriteFrame = null;\n const batch = drainTerminalWriteBatch(\n pendingWriteChunks,\n input.feature.limits.maxWriteBatchBytes\n );\n pendingWriteChunks = batch.remainingChunks;\n\n if (!batch.nextWrite) {\n return;\n }\n terminal.write(batch.nextWrite, () => {\n queueRenderedWrite(\n \"append\",\n batch.nextWrite.length,\n pendingWriteChunks.length\n );\n if (pendingWriteChunks.length > 0) {\n requestWriteFlush();\n }\n });\n }\n\n function requestWriteFlush() {\n if (pendingWriteFrame !== null) {\n return;\n }\n if (typeof requestAnimationFrame === \"function\") {\n pendingWriteFrame = requestAnimationFrame(flushPendingWrites);\n return;\n }\n pendingWriteFrame = window.setTimeout(flushPendingWrites, 0);\n }\n\n function resetTerminalView() {\n clearPendingReveal();\n clearPendingWrites();\n terminal.reset();\n refreshTerminalSurface();\n logSurfaceWrite(\"reset\", 0, 0);\n }\n\n function replaceTerminalView(\n data: string,\n options?: {\n reset?: boolean;\n }\n ) {\n const transformed =\n input.feature.outputTransform?.({\n data,\n sessionId: input.sessionId\n }) ?? data;\n if (transformed == null || transformed === \"\") {\n return;\n }\n clearPendingReveal();\n clearPendingWrites();\n if (options?.reset) {\n terminal.reset();\n }\n terminal.write(transformed, () => {\n queueRenderedWrite(\"replace\", transformed.length, 0);\n });\n }\n\n function refreshTerminalSurface() {\n if (terminal.rows <= 0) {\n return;\n }\n terminal.refresh(0, terminal.rows - 1);\n emitTerminalPreviewSnapshot();\n }\n\n function emitTerminalPreviewSnapshot() {\n if (!input.onPreviewChange || terminal.cols <= 0 || terminal.rows <= 0) {\n return;\n }\n const snapshot = createTerminalPreviewSnapshot(terminal);\n if (snapshot.revision === lastPreviewRevision) {\n return;\n }\n lastPreviewRevision = snapshot.revision;\n input.onPreviewChange({\n nodeId: input.nodeId,\n sessionId: input.sessionId,\n snapshot\n });\n }\n\n function scheduleInitialLayoutSync() {\n resizeTerminal();\n if (typeof requestAnimationFrame === \"function\") {\n initialLayoutFrame = requestAnimationFrame(() => {\n initialLayoutFrame = null;\n resizeTerminal();\n refreshTerminalSurface();\n });\n } else {\n initialLayoutFrame = window.setTimeout(() => {\n initialLayoutFrame = null;\n resizeTerminal();\n refreshTerminalSurface();\n }, 0);\n }\n initialLayoutTimeout = window.setTimeout(() => {\n initialLayoutTimeout = null;\n resizeTerminal();\n refreshTerminalSurface();\n }, 32);\n }\n\n function scheduleTerminalWrite(data: string) {\n pendingWriteChunks.push(data);\n requestWriteFlush();\n }\n\n function writeToTerminal(data: string) {\n const transformed =\n input.feature.outputTransform?.({\n data,\n sessionId: input.sessionId\n }) ?? data;\n if (transformed == null || transformed === \"\") {\n return;\n }\n scheduleTerminalWrite(transformed);\n }\n\n function queueRenderedWrite(\n mode: \"append\" | \"cache\" | \"replace\",\n bytes: number,\n remainingChunkCount: number\n ) {\n if (pendingRenderedWrite && pendingRenderedWrite.mode === mode) {\n pendingRenderedWrite = {\n bytes: pendingRenderedWrite.bytes + bytes,\n mode,\n remainingChunkCount\n };\n return;\n }\n pendingRenderedWrite = {\n bytes,\n mode,\n remainingChunkCount\n };\n }\n\n function scheduleHydratedReveal(write: {\n bytes: number;\n mode: \"cache\" | \"replace\";\n remainingChunkCount: number;\n }) {\n if (pendingRevealWrite) {\n pendingRevealWrite = {\n bytes: pendingRevealWrite.bytes + write.bytes,\n mode: write.mode,\n remainingChunkCount: write.remainingChunkCount\n };\n } else {\n pendingRevealWrite = write;\n }\n if (\n pendingRevealStartFrame !== null ||\n pendingRevealFinalizeFrame !== null\n ) {\n return;\n }\n pendingRevealStartFrame = requestTerminalFrame(() => {\n pendingRevealStartFrame = null;\n resizeTerminal();\n pendingRevealFinalizeFrame = requestTerminalFrame(() => {\n pendingRevealFinalizeFrame = null;\n refreshTerminalSurface();\n const revealWrite = pendingRevealWrite;\n pendingRevealWrite = null;\n if (!revealWrite) {\n return;\n }\n logSurfaceWrite(\n revealWrite.mode,\n revealWrite.bytes,\n revealWrite.remainingChunkCount\n );\n });\n });\n }\n\n function logSurfaceWrite(\n mode: \"append\" | \"cache\" | \"replace\" | \"reset\",\n bytes: number,\n remainingChunkCount: number\n ) {\n const buffer = terminal.buffer.active;\n const xtermElement =\n input.container.querySelector(\".xterm\") instanceof HTMLElement\n ? (input.container.querySelector(\".xterm\") as HTMLElement)\n : null;\n const screenElement =\n input.container.querySelector(\".xterm-screen\") instanceof HTMLElement\n ? (input.container.querySelector(\".xterm-screen\") as HTMLElement)\n : null;\n const helperElement =\n input.container.querySelector(\".xterm-helpers\") instanceof HTMLElement\n ? (input.container.querySelector(\".xterm-helpers\") as HTMLElement)\n : null;\n const rowContainerElement =\n input.container.querySelector(\".xterm-rows\") instanceof HTMLElement\n ? (input.container.querySelector(\".xterm-rows\") as HTMLElement)\n : null;\n const firstCanvas =\n screenElement?.querySelector(\"canvas\") instanceof HTMLCanvasElement\n ? (screenElement.querySelector(\"canvas\") as HTMLCanvasElement)\n : null;\n const firstLine = buffer.getLine(0)?.translateToString(true) ?? \"\";\n const cursorLine =\n buffer.getLine(buffer.cursorY)?.translateToString(true) ?? \"\";\n const xtermStyle = xtermElement\n ? window.getComputedStyle(xtermElement)\n : null;\n const screenStyle = screenElement\n ? window.getComputedStyle(screenElement)\n : null;\n const renderDimensions = resolveXtermRenderDimensions(terminal);\n input.diagnostics.outputWritten({\n bufferCursorX: buffer.cursorX,\n bufferCursorY: buffer.cursorY,\n bufferLength: buffer.length,\n bytes,\n canvasClientHeight: firstCanvas?.clientHeight ?? 0,\n canvasClientWidth: firstCanvas?.clientWidth ?? 0,\n canvasCount: screenElement?.querySelectorAll(\"canvas\").length ?? 0,\n cols: terminal.cols,\n containerClientHeight: input.container.clientHeight,\n containerClientWidth: input.container.clientWidth,\n cursorLinePreview: previewTerminalLine(cursorLine),\n firstLinePreview: previewTerminalLine(firstLine),\n helperChildCount: helperElement?.childElementCount ?? 0,\n mode,\n remainingChunkCount,\n renderDimensionsReady: renderDimensions !== undefined,\n rowContainerChildCount: rowContainerElement?.childElementCount ?? 0,\n rowContainerTextPreview: previewTerminalLine(\n rowContainerElement?.textContent ?? \"\"\n ),\n rows: terminal.rows,\n screenChildCount: screenElement?.childElementCount ?? 0,\n screenClientHeight: screenElement?.clientHeight ?? 0,\n screenClientWidth: screenElement?.clientWidth ?? 0,\n screenDisplay: screenStyle?.display ?? \"\",\n screenOpacity: screenStyle?.opacity ?? \"\",\n screenVisibility: screenStyle?.visibility ?? \"\",\n serializedBytes: serializeAddon.serialize().length,\n xtermClientHeight: xtermElement?.clientHeight ?? 0,\n xtermClientWidth: xtermElement?.clientWidth ?? 0,\n xtermDisplay: xtermStyle?.display ?? \"\",\n xtermOpacity: xtermStyle?.opacity ?? \"\",\n xtermVisibility: xtermStyle?.visibility ?? \"\"\n });\n }\n}\n\nfunction requestTerminalFrame(callback: () => void) {\n if (typeof requestAnimationFrame === \"function\") {\n return requestAnimationFrame(callback);\n }\n return window.setTimeout(callback, 0);\n}\n\nfunction resolveOutputSyncPlan(\n plan: ReturnType<typeof resolveTerminalSurfaceOutputPlan>\n): \"append\" | \"replace\" | \"reset\" | \"skip\" {\n if (!plan) {\n return \"skip\";\n }\n if (plan.reset && plan.write) {\n return \"replace\";\n }\n if (plan.reset) {\n return \"reset\";\n }\n return \"append\";\n}\n\nfunction resolveXtermRenderDimensions(terminal: Terminal): unknown {\n const core: unknown = Reflect.get(terminal, \"_core\");\n if (core == null || typeof core !== \"object\") {\n return undefined;\n }\n const renderService: unknown = Reflect.get(core, \"_renderService\");\n if (renderService == null || typeof renderService !== \"object\") {\n return undefined;\n }\n return Reflect.get(renderService, \"dimensions\");\n}\n\nfunction previewTerminalLine(value: string, maxChars = 80) {\n return value\n .slice(0, maxChars)\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"\\r\", \"\\\\r\")\n .replaceAll(\"\\n\", \"\\\\n\");\n}\n\nfunction resolveXtermTheme(theme: TerminalTheme) {\n return {\n background: theme.background,\n cursor: theme.cursor,\n foreground: theme.foreground,\n selectionBackground: theme.selectionBackground\n };\n}\n\nfunction createTerminalPreviewSnapshot(\n terminal: Terminal\n): TerminalPreviewSnapshot {\n const buffer = terminal.buffer.active;\n const rowCount = Math.min(terminal.rows, terminalPreviewMaxRows);\n const colCount = Math.min(terminal.cols, terminalPreviewMaxCols);\n const viewportY = Math.max(0, buffer.viewportY);\n const theme = terminal.options.theme as TerminalTheme;\n const lines: TerminalPreviewLine[] = [];\n const scratchCell = buffer.getNullCell();\n\n for (let index = 0; index < rowCount; index += 1) {\n lines.push(\n createTerminalPreviewLine({\n colCount,\n line: buffer.getLine(viewportY + index) ?? null,\n scratchCell,\n theme\n })\n );\n }\n\n const revision = [\n terminal.cols,\n terminal.rows,\n buffer.cursorX,\n buffer.cursorY,\n viewportY,\n JSON.stringify(lines)\n ].join(\"\\n\");\n\n return {\n cols: terminal.cols,\n cursorX: buffer.cursorX,\n cursorY: buffer.cursorY,\n lines,\n revision,\n rows: terminal.rows,\n updatedAtUnixMs: Date.now()\n };\n}\n\nfunction createTerminalPreviewLine(input: {\n colCount: number;\n line: IBufferLine | null;\n scratchCell: IBufferCell;\n theme: TerminalTheme;\n}): TerminalPreviewLine {\n const line = input.line;\n if (!line || input.colCount <= 0) {\n return { segments: [] };\n }\n\n const segments: TerminalPreviewSegment[] = [];\n let currentStyle: TerminalPreviewSegmentStyle | undefined;\n let currentText = \"\";\n const lastColumn = resolveTerminalPreviewLastColumn({\n colCount: input.colCount,\n line,\n scratchCell: input.scratchCell,\n theme: input.theme\n });\n\n for (let column = 0; column < lastColumn; column += 1) {\n const cell = line.getCell(column, input.scratchCell);\n if (!cell) {\n continue;\n }\n const width = cell.getWidth();\n if (width === 0) {\n continue;\n }\n const style = resolveTerminalPreviewCellStyle(cell, input.theme);\n const text = cell.isInvisible()\n ? \" \".repeat(Math.max(1, width))\n : cell.getChars() || \" \".repeat(Math.max(1, width));\n\n if (currentText && areTerminalPreviewStylesEqual(currentStyle, style)) {\n currentText += text;\n continue;\n }\n if (currentText) {\n segments.push(createTerminalPreviewSegment(currentText, currentStyle));\n }\n currentStyle = style;\n currentText = text;\n }\n\n if (currentText) {\n segments.push(createTerminalPreviewSegment(currentText, currentStyle));\n }\n\n return { segments };\n}\n\nfunction createTerminalPreviewSegment(\n text: string,\n style: TerminalPreviewSegmentStyle | undefined\n): TerminalPreviewSegment {\n if (!style) {\n return { text };\n }\n return { style, text };\n}\n\nfunction resolveTerminalPreviewLastColumn(input: {\n colCount: number;\n line: IBufferLine;\n scratchCell: IBufferCell;\n theme: TerminalTheme;\n}) {\n for (let column = input.colCount - 1; column >= 0; column -= 1) {\n const cell = input.line.getCell(column, input.scratchCell);\n if (!cell || cell.getWidth() === 0) {\n continue;\n }\n if (!isTerminalPreviewCellEmptyDefault(cell, input.theme)) {\n return column + 1;\n }\n }\n return 0;\n}\n\nfunction isTerminalPreviewCellEmptyDefault(\n cell: IBufferCell,\n theme: TerminalTheme\n) {\n const style = resolveTerminalPreviewCellStyle(cell, theme);\n return (cell.getChars() || \" \") === \" \" && !style;\n}\n\nfunction resolveTerminalPreviewCellStyle(\n cell: IBufferCell,\n theme: TerminalTheme\n): TerminalPreviewSegmentStyle | undefined {\n const style: TerminalPreviewSegmentStyle = {};\n const inverse = Boolean(cell.isInverse());\n const foreground = resolveTerminalPreviewColor(cell, \"foreground\", theme);\n const background = resolveTerminalPreviewColor(cell, \"background\", theme);\n const color = inverse ? (background ?? theme.background) : foreground;\n const backgroundColor = inverse\n ? (foreground ?? theme.foreground)\n : background;\n\n if (color) {\n style.color = color;\n }\n if (backgroundColor) {\n style.background = backgroundColor;\n }\n if (cell.isBold()) {\n style.bold = true;\n }\n if (cell.isDim()) {\n style.dim = true;\n }\n if (cell.isItalic()) {\n style.italic = true;\n }\n if (cell.isUnderline()) {\n style.underline = true;\n }\n if (cell.isStrikethrough()) {\n style.strikethrough = true;\n }\n if (cell.isOverline()) {\n style.overline = true;\n }\n\n return Object.keys(style).length > 0 ? style : undefined;\n}\n\nfunction resolveTerminalPreviewColor(\n cell: IBufferCell,\n channel: \"background\" | \"foreground\",\n theme: TerminalTheme\n) {\n const isDefault =\n channel === \"foreground\" ? cell.isFgDefault() : cell.isBgDefault();\n if (isDefault) {\n return undefined;\n }\n const isRgb = channel === \"foreground\" ? cell.isFgRGB() : cell.isBgRGB();\n const isPalette =\n channel === \"foreground\" ? cell.isFgPalette() : cell.isBgPalette();\n const rawColor =\n channel === \"foreground\" ? cell.getFgColor() : cell.getBgColor();\n\n if (isRgb) {\n return terminalPreviewColorToHex(rawColor);\n }\n if (!isPalette) {\n return undefined;\n }\n\n const paletteIndex =\n channel === \"foreground\" && cell.isBold() && rawColor >= 0 && rawColor <= 7\n ? rawColor + 8\n : rawColor;\n const paletteColor = resolveTerminalPreviewPaletteColor(paletteIndex);\n if (paletteColor) {\n return paletteColor;\n }\n return channel === \"foreground\" ? theme.foreground : theme.background;\n}\n\nfunction resolveTerminalPreviewPaletteColor(index: number) {\n if (index >= 0 && index < terminalPreviewAnsiColors.length) {\n return terminalPreviewAnsiColors[index];\n }\n if (index >= 16 && index <= 231) {\n const offset = index - 16;\n const red = terminalPreviewColorSteps[Math.floor(offset / 36) % 6] ?? 0;\n const green = terminalPreviewColorSteps[Math.floor(offset / 6) % 6] ?? 0;\n const blue = terminalPreviewColorSteps[offset % 6] ?? 0;\n return terminalPreviewRgbToHex(red, green, blue);\n }\n if (index >= 232 && index <= 255) {\n const value = 8 + (index - 232) * 10;\n return terminalPreviewRgbToHex(value, value, value);\n }\n return undefined;\n}\n\nfunction terminalPreviewColorToHex(color: number) {\n return `#${color.toString(16).padStart(6, \"0\").slice(-6)}`;\n}\n\nfunction terminalPreviewRgbToHex(red: number, green: number, blue: number) {\n return `#${[red, green, blue]\n .map((value) => value.toString(16).padStart(2, \"0\"))\n .join(\"\")}`;\n}\n\nfunction areTerminalPreviewStylesEqual(\n left: TerminalPreviewSegmentStyle | undefined,\n right: TerminalPreviewSegmentStyle | undefined\n) {\n if (left === right) {\n return true;\n }\n if (!left || !right) {\n return false;\n }\n return (\n left.background === right.background &&\n left.bold === right.bold &&\n left.color === right.color &&\n left.dim === right.dim &&\n left.italic === right.italic &&\n left.overline === right.overline &&\n left.strikethrough === right.strikethrough &&\n left.underline === right.underline\n );\n}\n","import type { ILink, ILinkProvider, Terminal } from \"@xterm/xterm\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport {\n detectTerminalFileLinks,\n toTerminalLinkTarget\n} from \"../core/index.ts\";\n\nexport function createTerminalFileLinkProvider(input: {\n feature: TerminalNodeFeature;\n getCwd: () => string | null;\n terminal: Terminal;\n}): ILinkProvider {\n return {\n provideLinks(bufferLineNumber, callback) {\n if (!input.feature.linkHandler) {\n callback(undefined);\n return;\n }\n\n const line = input.terminal.buffer.active.getLine(bufferLineNumber - 1);\n if (!line) {\n callback(undefined);\n return;\n }\n\n const text = line.translateToString(true);\n const links = detectTerminalFileLinks(text).map<ILink>((link) => ({\n activate: () => {\n void input.feature.linkHandler?.open({\n ...toTerminalLinkTarget(link),\n cwd: input.getCwd()\n });\n },\n range: {\n end: {\n x: link.index + link.text.length,\n y: bufferLineNumber\n },\n start: {\n x: link.index + 1,\n y: bufferLineNumber\n }\n },\n text: link.text\n }));\n\n callback(links.length > 0 ? links : undefined);\n }\n };\n}\n","import { resolveTerminalScrollbackDelta } from \"../core/index.ts\";\n\nexport interface TerminalSurfaceOutputPlanInput {\n committedRawOutput: string;\n contentEpoch: number;\n nextContentEpoch: number;\n rawOutput: string;\n}\n\nexport interface TerminalSurfaceOutputPlan {\n nextCommittedRawOutput: string;\n nextContentEpoch: number;\n reset: boolean;\n write: string | null;\n}\n\nexport function resolveTerminalSurfaceOutputPlan(\n input: TerminalSurfaceOutputPlanInput\n): TerminalSurfaceOutputPlan | null {\n if (\n input.nextContentEpoch === 0 &&\n input.rawOutput.length === 0 &&\n input.committedRawOutput.length > 0\n ) {\n return null;\n }\n\n if (input.nextContentEpoch !== input.contentEpoch) {\n if (input.rawOutput === input.committedRawOutput) {\n return {\n nextCommittedRawOutput: input.committedRawOutput,\n nextContentEpoch: input.nextContentEpoch,\n reset: false,\n write: null\n };\n }\n\n return {\n nextCommittedRawOutput: input.rawOutput,\n nextContentEpoch: input.nextContentEpoch,\n reset: true,\n write: input.rawOutput || null\n };\n }\n\n if (input.rawOutput === input.committedRawOutput) {\n return null;\n }\n\n const delta = resolveTerminalScrollbackDelta(\n input.committedRawOutput,\n input.rawOutput\n );\n\n return {\n nextCommittedRawOutput: input.rawOutput,\n nextContentEpoch: input.nextContentEpoch,\n reset: !delta,\n write: delta || input.rawOutput || null\n };\n}\n","export interface TerminalSurfaceSize {\n cols: number;\n rows: number;\n}\n\nexport function resolveTerminalSurfaceResizePlan(input: {\n lastSize: TerminalSurfaceSize | null;\n nextSize: TerminalSurfaceSize;\n}): TerminalSurfaceSize | null {\n if (\n input.lastSize?.cols === input.nextSize.cols &&\n input.lastSize.rows === input.nextSize.rows\n ) {\n return null;\n }\n return input.nextSize;\n}\n","export type TerminalSurfaceScreenCachePlan =\n | { action: \"remove\" }\n | {\n action: \"save\";\n rawSnapshot: string;\n serialized: string;\n }\n | { action: \"skip\" };\n\nexport function resolveTerminalSurfaceScreenCachePlan(input: {\n hasPendingWrites: boolean;\n rawSnapshot: string;\n serialized: string;\n}): TerminalSurfaceScreenCachePlan {\n if (input.hasPendingWrites) {\n return {\n action: input.serialized ? \"skip\" : \"remove\"\n };\n }\n\n if (!input.serialized) {\n return { action: \"skip\" };\n }\n\n return {\n action: \"save\",\n rawSnapshot: input.rawSnapshot,\n serialized: input.serialized\n };\n}\n","export interface TerminalWriteBatch {\n nextWrite: string;\n remainingChunks: string[];\n}\n\nexport function drainTerminalWriteBatch(\n chunks: string[],\n maxBytes: number\n): TerminalWriteBatch {\n let remaining = maxBytes;\n let nextWrite = \"\";\n const remainingChunks = chunks.slice();\n\n while (remaining > 0 && remainingChunks.length > 0) {\n const chunk = remainingChunks.shift() ?? \"\";\n if (chunk.length <= remaining) {\n nextWrite += chunk;\n remaining -= chunk.length;\n continue;\n }\n nextWrite += chunk.slice(0, remaining);\n remainingChunks.unshift(chunk.slice(remaining));\n remaining = 0;\n }\n\n return {\n nextWrite,\n remainingChunks\n };\n}\n","export function isTerminalFindShortcut(\n event: Pick<KeyboardEvent, \"altKey\" | \"ctrlKey\" | \"key\" | \"metaKey\">\n): boolean {\n if (event.altKey) {\n return false;\n }\n\n if (!(event.metaKey || event.ctrlKey)) {\n return false;\n }\n\n return event.key.toLowerCase() === \"f\";\n}\n","import { useState } from \"react\";\n\nexport interface TerminalFindRuntime {\n findNext(\n query: string,\n options: {\n caseSensitive: boolean;\n incremental?: boolean;\n regex: boolean;\n }\n ): void;\n findPrevious(\n query: string,\n options: {\n caseSensitive: boolean;\n regex: boolean;\n }\n ): void;\n}\n\nexport interface TerminalFindController {\n actions: {\n close(): void;\n findNext(): void;\n findPrevious(): void;\n open(): void;\n onQueryChange(query: string): void;\n onSubmit(): void;\n toggleCaseSensitive(): void;\n toggleOpen(): void;\n toggleRegex(): void;\n };\n state: {\n caseSensitive: boolean;\n open: boolean;\n query: string;\n regex: boolean;\n };\n}\n\nexport function useTerminalFindController(input: {\n getRuntime: () => TerminalFindRuntime | null;\n}): TerminalFindController {\n const [open, setOpen] = useState(false);\n const [caseSensitive, setCaseSensitive] = useState(false);\n const [query, setQuery] = useState(\"\");\n const [regex, setRegex] = useState(false);\n\n const resolveFindOptions = () => ({\n caseSensitive,\n regex\n });\n\n return {\n actions: {\n close() {\n setOpen(false);\n },\n findNext() {\n input.getRuntime()?.findNext(query, resolveFindOptions());\n },\n findPrevious() {\n input.getRuntime()?.findPrevious(query, resolveFindOptions());\n },\n open() {\n setOpen(true);\n },\n onQueryChange(nextQuery) {\n setQuery(nextQuery);\n if (!nextQuery) {\n return;\n }\n input.getRuntime()?.findNext(nextQuery, {\n ...resolveFindOptions(),\n incremental: true\n });\n },\n onSubmit() {\n input.getRuntime()?.findNext(query, resolveFindOptions());\n },\n toggleCaseSensitive() {\n setCaseSensitive((enabled) => !enabled);\n },\n toggleOpen() {\n setOpen((enabled) => !enabled);\n },\n toggleRegex() {\n setRegex((enabled) => !enabled);\n }\n },\n state: {\n caseSensitive,\n open,\n query,\n regex\n }\n };\n}\n","import { useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@tutti-os/ui-react-hooks\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport {\n acquireTerminalSessionController,\n type TerminalSessionControllerState\n} from \"../core/sessionController.ts\";\n\nexport function useTerminalSessionController(input: {\n feature: TerminalNodeFeature;\n nodeId: string;\n retainLease?: boolean;\n sessionId: string;\n}) {\n const controller = useMemo(\n () =>\n acquireTerminalSessionController({\n feature: input.feature,\n nodeId: input.nodeId,\n sessionId: input.sessionId\n }),\n [input.nodeId, input.sessionId]\n );\n\n useEffect(() => {\n if (input.retainLease === false) {\n return;\n }\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller, input.retainLease]);\n const state = useExternalStoreSnapshot<TerminalSessionControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n return {\n controller,\n state\n };\n}\n"],"mappings":"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","names":["errorMessage","useState","useEffect","useMemo","useState","useState","useMemo","useEffect","errorMessage","jsx","jsxs","useState","errorMessage"]}
@@ -41,11 +41,12 @@ interface TerminalDockPreviewProps {
41
41
  frame?: TerminalDockPreviewFrame | null;
42
42
  snapshot: TerminalPreviewSnapshot;
43
43
  theme?: TerminalTheme | null;
44
+ viewport?: TerminalDockPreviewFrame | null;
44
45
  }
45
46
  interface TerminalDockPreviewFrame {
46
47
  height: number;
47
48
  width: number;
48
49
  }
49
- declare function TerminalDockPreview({ frame, snapshot, theme }: TerminalDockPreviewProps): react_jsx_runtime.JSX.Element;
50
+ declare function TerminalDockPreview({ frame, snapshot, theme, viewport }: TerminalDockPreviewProps): react_jsx_runtime.JSX.Element;
50
51
 
51
52
  export { TerminalCloseGuardDialog, type TerminalCloseGuardDialogProps, TerminalDockPreview, type TerminalDockPreviewProps, TerminalNode, TerminalNodeHeader, type TerminalNodeHeaderProps, type TerminalNodeProps };
@@ -2,7 +2,7 @@ import {
2
2
  TerminalCloseGuardDialog,
3
3
  TerminalNode,
4
4
  TerminalNodeHeader
5
- } from "../chunk-UWPZ5O4V.js";
5
+ } from "../chunk-TBCIC6JY.js";
6
6
  import "../chunk-56B5GYMU.js";
7
7
  import "../chunk-65BWWZQV.js";
8
8
 
@@ -16,16 +16,18 @@ var terminalDockPreviewPadding = 16;
16
16
  function TerminalDockPreview({
17
17
  frame = null,
18
18
  snapshot,
19
- theme = null
19
+ theme = null,
20
+ viewport = null
20
21
  }) {
21
22
  const containerRef = useRef(null);
22
- const [layout, setLayout] = useState({
23
- height: 0,
24
- scale: 1,
25
- sourceHeight: 0,
26
- sourceWidth: 0,
27
- width: 0
28
- });
23
+ const [layout, setLayout] = useState(
24
+ () => resolveTerminalDockPreviewLayout({
25
+ availableSize: viewport,
26
+ fitMode: viewport ? "cover" : "contain",
27
+ frame,
28
+ snapshot
29
+ })
30
+ );
29
31
  const style = {};
30
32
  if (theme?.background) {
31
33
  style["--workspace-terminal-dock-preview-background"] = theme.background;
@@ -33,9 +35,9 @@ function TerminalDockPreview({
33
35
  if (theme?.foreground) {
34
36
  style["--workspace-terminal-dock-preview-foreground"] = theme.foreground;
35
37
  }
36
- if (layout.width > 0 && layout.height > 0) {
37
- style["--workspace-terminal-dock-preview-height"] = `${layout.height}px`;
38
- style["--workspace-terminal-dock-preview-width"] = `${layout.width}px`;
38
+ if (layout.viewportWidth > 0 && layout.viewportHeight > 0) {
39
+ style["--workspace-terminal-dock-preview-height"] = `${layout.viewportHeight}px`;
40
+ style["--workspace-terminal-dock-preview-width"] = `${layout.viewportWidth}px`;
39
41
  style["--workspace-terminal-dock-preview-scale"] = String(layout.scale);
40
42
  style["--workspace-terminal-dock-preview-source-height"] = `${layout.sourceHeight}px`;
41
43
  style["--workspace-terminal-dock-preview-source-width"] = `${layout.sourceWidth}px`;
@@ -46,31 +48,17 @@ function TerminalDockPreview({
46
48
  return;
47
49
  }
48
50
  const updateFontSize = () => {
49
- const availableSize = readTerminalDockPreviewAvailableSize(container);
50
- const availableWidth = availableSize.width;
51
- const availableHeight = availableSize.height;
52
- const previewRatio = resolveTerminalDockPreviewRatio(frame, snapshot);
53
- const sourceSize = resolveTerminalDockPreviewSourceSize(frame, snapshot);
54
- const fittedSize = fitTerminalDockPreviewSize({
55
- availableHeight,
56
- availableWidth,
57
- ratio: previewRatio
51
+ const nextLayout = resolveTerminalDockPreviewLayout({
52
+ availableSize: viewport ?? readTerminalDockPreviewAvailableSize(container),
53
+ fitMode: viewport ? "cover" : "contain",
54
+ frame,
55
+ snapshot
58
56
  });
59
- const nextScale = sourceSize.width > 0 && sourceSize.height > 0 ? Math.min(
60
- fittedSize.width / sourceSize.width,
61
- fittedSize.height / sourceSize.height
62
- ) : 1;
63
57
  setLayout((current) => {
64
- if (Math.abs(current.height - fittedSize.height) < 0.5 && Math.abs(current.scale - nextScale) < 1e-3 && Math.abs(current.sourceHeight - sourceSize.height) < 0.5 && Math.abs(current.sourceWidth - sourceSize.width) < 0.5 && Math.abs(current.width - fittedSize.width) < 0.5) {
58
+ if (Math.abs(current.scale - nextLayout.scale) < 1e-3 && Math.abs(current.sourceHeight - nextLayout.sourceHeight) < 0.5 && Math.abs(current.sourceWidth - nextLayout.sourceWidth) < 0.5 && Math.abs(current.viewportHeight - nextLayout.viewportHeight) < 0.5 && Math.abs(current.viewportWidth - nextLayout.viewportWidth) < 0.5) {
65
59
  return current;
66
60
  }
67
- return {
68
- height: fittedSize.height,
69
- scale: nextScale,
70
- sourceHeight: sourceSize.height,
71
- sourceWidth: sourceSize.width,
72
- width: fittedSize.width
73
- };
61
+ return nextLayout;
74
62
  });
75
63
  };
76
64
  updateFontSize();
@@ -79,14 +67,15 @@ function TerminalDockPreview({
79
67
  return () => {
80
68
  observer.disconnect();
81
69
  };
82
- }, [frame, snapshot.cols, snapshot.lines.length]);
70
+ }, [frame, snapshot.cols, snapshot.lines.length, viewport]);
83
71
  return /* @__PURE__ */ jsx(
84
72
  "span",
85
73
  {
86
74
  className: "workspace-terminal__dock-preview-frame",
87
75
  "data-terminal-dock-preview": "",
88
76
  ref: containerRef,
89
- children: /* @__PURE__ */ jsx("span", { className: "workspace-terminal__dock-preview-viewport", style, children: /* @__PURE__ */ jsx("span", { className: "workspace-terminal__dock-preview", children: snapshot.lines.map((line, index) => /* @__PURE__ */ jsx("span", { className: "workspace-terminal__dock-preview-line", children: line.segments.length > 0 ? line.segments.map((segment, segmentIndex) => /* @__PURE__ */ jsx(
77
+ style,
78
+ children: /* @__PURE__ */ jsx("span", { className: "workspace-terminal__dock-preview-viewport", children: /* @__PURE__ */ jsx("span", { className: "workspace-terminal__dock-preview", children: snapshot.lines.map((line, index) => /* @__PURE__ */ jsx("span", { className: "workspace-terminal__dock-preview-line", children: line.segments.length > 0 ? line.segments.map((segment, segmentIndex) => /* @__PURE__ */ jsx(
90
79
  "span",
91
80
  {
92
81
  className: "workspace-terminal__dock-preview-segment",
@@ -100,6 +89,39 @@ function TerminalDockPreview({
100
89
  }
101
90
  );
102
91
  }
92
+ function resolveTerminalDockPreviewLayout({
93
+ availableSize,
94
+ fitMode,
95
+ frame,
96
+ snapshot
97
+ }) {
98
+ const availableWidth = availableSize?.width ?? 0;
99
+ const availableHeight = availableSize?.height ?? 0;
100
+ const previewRatio = resolveTerminalDockPreviewRatio(frame, snapshot);
101
+ const sourceSize = resolveTerminalDockPreviewSourceSize(frame, snapshot);
102
+ const viewportSize = fitMode === "cover" ? {
103
+ height: availableHeight > 0 ? availableHeight : 0,
104
+ width: availableWidth > 0 ? availableWidth : 0
105
+ } : fitTerminalDockPreviewSize({
106
+ availableHeight,
107
+ availableWidth,
108
+ ratio: previewRatio
109
+ });
110
+ const scale = resolveTerminalDockPreviewScale({
111
+ availableHeight: viewportSize.height,
112
+ availableWidth: viewportSize.width,
113
+ fitMode,
114
+ sourceHeight: sourceSize.height,
115
+ sourceWidth: sourceSize.width
116
+ });
117
+ return {
118
+ scale,
119
+ sourceHeight: sourceSize.height,
120
+ sourceWidth: sourceSize.width,
121
+ viewportHeight: viewportSize.height,
122
+ viewportWidth: viewportSize.width
123
+ };
124
+ }
103
125
  function readTerminalDockPreviewAvailableSize(element) {
104
126
  const computedStyle = window.getComputedStyle(element);
105
127
  const computedWidth = Number.parseFloat(computedStyle.width);
@@ -142,6 +164,7 @@ function fitTerminalDockPreviewSize(input) {
142
164
  return { height: 0, width: 0 };
143
165
  }
144
166
  const widthFromFullHeight = input.availableHeight * input.ratio;
167
+ const heightFromFullWidth = input.availableWidth / input.ratio;
145
168
  if (widthFromFullHeight <= input.availableWidth) {
146
169
  return {
147
170
  height: input.availableHeight,
@@ -149,10 +172,18 @@ function fitTerminalDockPreviewSize(input) {
149
172
  };
150
173
  }
151
174
  return {
152
- height: input.availableWidth / input.ratio,
175
+ height: heightFromFullWidth,
153
176
  width: input.availableWidth
154
177
  };
155
178
  }
179
+ function resolveTerminalDockPreviewScale(input) {
180
+ if (input.availableHeight <= 0 || input.availableWidth <= 0 || input.sourceHeight <= 0 || input.sourceWidth <= 0) {
181
+ return 1;
182
+ }
183
+ const widthScale = input.availableWidth / input.sourceWidth;
184
+ const heightScale = input.availableHeight / input.sourceHeight;
185
+ return input.fitMode === "cover" ? Math.max(widthScale, heightScale) : Math.min(widthScale, heightScale);
186
+ }
156
187
  function resolveTerminalDockPreviewSegmentStyle(segmentStyle) {
157
188
  if (!segmentStyle) {
158
189
  return void 0;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/TerminalDockPreview.tsx"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport type {\n TerminalPreviewSegmentStyle,\n TerminalPreviewSnapshot,\n TerminalTheme\n} from \"../contracts/index.ts\";\n\nexport interface TerminalDockPreviewProps {\n frame?: TerminalDockPreviewFrame | null;\n snapshot: TerminalPreviewSnapshot;\n theme?: TerminalTheme | null;\n}\n\nexport interface TerminalDockPreviewFrame {\n height: number;\n width: number;\n}\n\ninterface TerminalDockPreviewStyle extends CSSProperties {\n \"--workspace-terminal-dock-preview-background\"?: string;\n \"--workspace-terminal-dock-preview-foreground\"?: string;\n \"--workspace-terminal-dock-preview-scale\"?: string;\n \"--workspace-terminal-dock-preview-source-height\"?: string;\n \"--workspace-terminal-dock-preview-source-width\"?: string;\n \"--workspace-terminal-dock-preview-height\"?: string;\n \"--workspace-terminal-dock-preview-width\"?: string;\n}\n\nconst terminalDockPreviewLineHeight = 1.35;\nconst terminalDockPreviewCharacterWidth = 0.62;\nconst terminalDockPreviewFontSize = 13;\nconst terminalDockPreviewPadding = 16;\n\nexport function TerminalDockPreview({\n frame = null,\n snapshot,\n theme = null\n}: TerminalDockPreviewProps) {\n const containerRef = useRef<HTMLSpanElement | null>(null);\n const [layout, setLayout] = useState({\n height: 0,\n scale: 1,\n sourceHeight: 0,\n sourceWidth: 0,\n width: 0\n });\n const style: TerminalDockPreviewStyle = {};\n if (theme?.background) {\n style[\"--workspace-terminal-dock-preview-background\"] = theme.background;\n }\n if (theme?.foreground) {\n style[\"--workspace-terminal-dock-preview-foreground\"] = theme.foreground;\n }\n if (layout.width > 0 && layout.height > 0) {\n style[\"--workspace-terminal-dock-preview-height\"] = `${layout.height}px`;\n style[\"--workspace-terminal-dock-preview-width\"] = `${layout.width}px`;\n style[\"--workspace-terminal-dock-preview-scale\"] = String(layout.scale);\n style[\"--workspace-terminal-dock-preview-source-height\"] =\n `${layout.sourceHeight}px`;\n style[\"--workspace-terminal-dock-preview-source-width\"] =\n `${layout.sourceWidth}px`;\n }\n\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container || typeof ResizeObserver === \"undefined\") {\n return;\n }\n const updateFontSize = () => {\n const availableSize = readTerminalDockPreviewAvailableSize(container);\n const availableWidth = availableSize.width;\n const availableHeight = availableSize.height;\n const previewRatio = resolveTerminalDockPreviewRatio(frame, snapshot);\n const sourceSize = resolveTerminalDockPreviewSourceSize(frame, snapshot);\n const fittedSize = fitTerminalDockPreviewSize({\n availableHeight,\n availableWidth,\n ratio: previewRatio\n });\n const nextScale =\n sourceSize.width > 0 && sourceSize.height > 0\n ? Math.min(\n fittedSize.width / sourceSize.width,\n fittedSize.height / sourceSize.height\n )\n : 1;\n setLayout((current) => {\n if (\n Math.abs(current.height - fittedSize.height) < 0.5 &&\n Math.abs(current.scale - nextScale) < 0.001 &&\n Math.abs(current.sourceHeight - sourceSize.height) < 0.5 &&\n Math.abs(current.sourceWidth - sourceSize.width) < 0.5 &&\n Math.abs(current.width - fittedSize.width) < 0.5\n ) {\n return current;\n }\n return {\n height: fittedSize.height,\n scale: nextScale,\n sourceHeight: sourceSize.height,\n sourceWidth: sourceSize.width,\n width: fittedSize.width\n };\n });\n };\n updateFontSize();\n const observer = new ResizeObserver(updateFontSize);\n observer.observe(container);\n return () => {\n observer.disconnect();\n };\n }, [frame, snapshot.cols, snapshot.lines.length]);\n\n return (\n <span\n className=\"workspace-terminal__dock-preview-frame\"\n data-terminal-dock-preview=\"\"\n ref={containerRef}\n >\n <span className=\"workspace-terminal__dock-preview-viewport\" style={style}>\n <span className=\"workspace-terminal__dock-preview\">\n {snapshot.lines.map((line, index) => (\n <span className=\"workspace-terminal__dock-preview-line\" key={index}>\n {line.segments.length > 0\n ? line.segments.map((segment, segmentIndex) => (\n <span\n className=\"workspace-terminal__dock-preview-segment\"\n key={segmentIndex}\n style={resolveTerminalDockPreviewSegmentStyle(\n segment.style\n )}\n >\n {segment.text}\n </span>\n ))\n : \" \"}\n </span>\n ))}\n </span>\n </span>\n </span>\n );\n}\n\nfunction readTerminalDockPreviewAvailableSize(element: HTMLElement) {\n const computedStyle = window.getComputedStyle(element);\n const computedWidth = Number.parseFloat(computedStyle.width);\n const computedHeight = Number.parseFloat(computedStyle.height);\n if (\n Number.isFinite(computedWidth) &&\n computedWidth > 0 &&\n Number.isFinite(computedHeight) &&\n computedHeight > 0\n ) {\n return {\n height: computedHeight,\n width: computedWidth\n };\n }\n\n return {\n height: Math.max(0, element.clientHeight),\n width: Math.max(0, element.clientWidth)\n };\n}\n\nfunction resolveTerminalDockPreviewRatio(\n frame: TerminalDockPreviewFrame | null,\n snapshot: TerminalPreviewSnapshot\n) {\n if (frame && frame.width > 0 && frame.height > 0) {\n return frame.width / frame.height;\n }\n const rowCount = Math.max(1, snapshot.lines.length);\n const colCount = Math.max(1, Math.min(snapshot.cols, 160));\n return (\n (colCount * terminalDockPreviewCharacterWidth) /\n (rowCount * terminalDockPreviewLineHeight)\n );\n}\n\nfunction resolveTerminalDockPreviewSourceSize(\n frame: TerminalDockPreviewFrame | null,\n snapshot: TerminalPreviewSnapshot\n) {\n if (frame && frame.width > 0 && frame.height > 0) {\n return {\n height: frame.height,\n width: frame.width\n };\n }\n\n const rowCount = Math.max(1, snapshot.lines.length);\n const colCount = Math.max(1, Math.min(snapshot.cols, 160));\n return {\n height:\n rowCount * terminalDockPreviewFontSize * terminalDockPreviewLineHeight +\n terminalDockPreviewPadding,\n width:\n colCount *\n terminalDockPreviewFontSize *\n terminalDockPreviewCharacterWidth +\n terminalDockPreviewPadding\n };\n}\n\nfunction fitTerminalDockPreviewSize(input: {\n availableHeight: number;\n availableWidth: number;\n ratio: number;\n}) {\n if (\n input.availableHeight <= 0 ||\n input.availableWidth <= 0 ||\n !Number.isFinite(input.ratio) ||\n input.ratio <= 0\n ) {\n return { height: 0, width: 0 };\n }\n\n const widthFromFullHeight = input.availableHeight * input.ratio;\n if (widthFromFullHeight <= input.availableWidth) {\n return {\n height: input.availableHeight,\n width: widthFromFullHeight\n };\n }\n\n return {\n height: input.availableWidth / input.ratio,\n width: input.availableWidth\n };\n}\n\nfunction resolveTerminalDockPreviewSegmentStyle(\n segmentStyle: TerminalPreviewSegmentStyle | undefined\n): CSSProperties | undefined {\n if (!segmentStyle) {\n return undefined;\n }\n\n const style: CSSProperties = {};\n if (segmentStyle.background) {\n style.backgroundColor = segmentStyle.background;\n }\n if (segmentStyle.color) {\n style.color = segmentStyle.color;\n }\n if (segmentStyle.bold) {\n style.fontWeight = 700;\n }\n if (segmentStyle.dim) {\n style.opacity = 0.64;\n }\n if (segmentStyle.italic) {\n style.fontStyle = \"italic\";\n }\n\n const decorations: string[] = [];\n if (segmentStyle.underline) {\n decorations.push(\"underline\");\n }\n if (segmentStyle.strikethrough) {\n decorations.push(\"line-through\");\n }\n if (segmentStyle.overline) {\n decorations.push(\"overline\");\n }\n if (decorations.length > 0) {\n style.textDecorationLine = decorations.join(\" \");\n }\n\n return style;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/react/TerminalDockPreview.tsx"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport type {\n TerminalPreviewSegmentStyle,\n TerminalPreviewSnapshot,\n TerminalTheme\n} from \"../contracts/index.ts\";\n\nexport interface TerminalDockPreviewProps {\n frame?: TerminalDockPreviewFrame | null;\n snapshot: TerminalPreviewSnapshot;\n theme?: TerminalTheme | null;\n viewport?: TerminalDockPreviewFrame | null;\n}\n\nexport interface TerminalDockPreviewFrame {\n height: number;\n width: number;\n}\n\ninterface TerminalDockPreviewStyle extends CSSProperties {\n \"--workspace-terminal-dock-preview-background\"?: string;\n \"--workspace-terminal-dock-preview-foreground\"?: string;\n \"--workspace-terminal-dock-preview-scale\"?: string;\n \"--workspace-terminal-dock-preview-source-height\"?: string;\n \"--workspace-terminal-dock-preview-source-width\"?: string;\n \"--workspace-terminal-dock-preview-height\"?: string;\n \"--workspace-terminal-dock-preview-width\"?: string;\n}\n\nconst terminalDockPreviewLineHeight = 1.35;\nconst terminalDockPreviewCharacterWidth = 0.62;\nconst terminalDockPreviewFontSize = 13;\nconst terminalDockPreviewPadding = 16;\n\nexport function TerminalDockPreview({\n frame = null,\n snapshot,\n theme = null,\n viewport = null\n}: TerminalDockPreviewProps) {\n const containerRef = useRef<HTMLSpanElement | null>(null);\n const [layout, setLayout] = useState(() =>\n resolveTerminalDockPreviewLayout({\n availableSize: viewport,\n fitMode: viewport ? \"cover\" : \"contain\",\n frame,\n snapshot\n })\n );\n const style: TerminalDockPreviewStyle = {};\n if (theme?.background) {\n style[\"--workspace-terminal-dock-preview-background\"] = theme.background;\n }\n if (theme?.foreground) {\n style[\"--workspace-terminal-dock-preview-foreground\"] = theme.foreground;\n }\n if (layout.viewportWidth > 0 && layout.viewportHeight > 0) {\n style[\"--workspace-terminal-dock-preview-height\"] =\n `${layout.viewportHeight}px`;\n style[\"--workspace-terminal-dock-preview-width\"] =\n `${layout.viewportWidth}px`;\n style[\"--workspace-terminal-dock-preview-scale\"] = String(layout.scale);\n style[\"--workspace-terminal-dock-preview-source-height\"] =\n `${layout.sourceHeight}px`;\n style[\"--workspace-terminal-dock-preview-source-width\"] =\n `${layout.sourceWidth}px`;\n }\n\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container || typeof ResizeObserver === \"undefined\") {\n return;\n }\n const updateFontSize = () => {\n const nextLayout = resolveTerminalDockPreviewLayout({\n availableSize:\n viewport ?? readTerminalDockPreviewAvailableSize(container),\n fitMode: viewport ? \"cover\" : \"contain\",\n frame,\n snapshot\n });\n setLayout((current) => {\n if (\n Math.abs(current.scale - nextLayout.scale) < 0.001 &&\n Math.abs(current.sourceHeight - nextLayout.sourceHeight) < 0.5 &&\n Math.abs(current.sourceWidth - nextLayout.sourceWidth) < 0.5 &&\n Math.abs(current.viewportHeight - nextLayout.viewportHeight) < 0.5 &&\n Math.abs(current.viewportWidth - nextLayout.viewportWidth) < 0.5\n ) {\n return current;\n }\n return nextLayout;\n });\n };\n updateFontSize();\n const observer = new ResizeObserver(updateFontSize);\n observer.observe(container);\n return () => {\n observer.disconnect();\n };\n }, [frame, snapshot.cols, snapshot.lines.length, viewport]);\n\n return (\n <span\n className=\"workspace-terminal__dock-preview-frame\"\n data-terminal-dock-preview=\"\"\n ref={containerRef}\n style={style}\n >\n <span className=\"workspace-terminal__dock-preview-viewport\">\n <span className=\"workspace-terminal__dock-preview\">\n {snapshot.lines.map((line, index) => (\n <span className=\"workspace-terminal__dock-preview-line\" key={index}>\n {line.segments.length > 0\n ? line.segments.map((segment, segmentIndex) => (\n <span\n className=\"workspace-terminal__dock-preview-segment\"\n key={segmentIndex}\n style={resolveTerminalDockPreviewSegmentStyle(\n segment.style\n )}\n >\n {segment.text}\n </span>\n ))\n : \" \"}\n </span>\n ))}\n </span>\n </span>\n </span>\n );\n}\n\nfunction resolveTerminalDockPreviewLayout({\n availableSize,\n fitMode,\n frame,\n snapshot\n}: {\n availableSize: TerminalDockPreviewFrame | null;\n fitMode: \"contain\" | \"cover\";\n frame: TerminalDockPreviewFrame | null;\n snapshot: TerminalPreviewSnapshot;\n}) {\n const availableWidth = availableSize?.width ?? 0;\n const availableHeight = availableSize?.height ?? 0;\n const previewRatio = resolveTerminalDockPreviewRatio(frame, snapshot);\n const sourceSize = resolveTerminalDockPreviewSourceSize(frame, snapshot);\n const viewportSize =\n fitMode === \"cover\"\n ? {\n height: availableHeight > 0 ? availableHeight : 0,\n width: availableWidth > 0 ? availableWidth : 0\n }\n : fitTerminalDockPreviewSize({\n availableHeight,\n availableWidth,\n ratio: previewRatio\n });\n const scale = resolveTerminalDockPreviewScale({\n availableHeight: viewportSize.height,\n availableWidth: viewportSize.width,\n fitMode,\n sourceHeight: sourceSize.height,\n sourceWidth: sourceSize.width\n });\n return {\n scale,\n sourceHeight: sourceSize.height,\n sourceWidth: sourceSize.width,\n viewportHeight: viewportSize.height,\n viewportWidth: viewportSize.width\n };\n}\n\nfunction readTerminalDockPreviewAvailableSize(element: HTMLElement) {\n const computedStyle = window.getComputedStyle(element);\n const computedWidth = Number.parseFloat(computedStyle.width);\n const computedHeight = Number.parseFloat(computedStyle.height);\n if (\n Number.isFinite(computedWidth) &&\n computedWidth > 0 &&\n Number.isFinite(computedHeight) &&\n computedHeight > 0\n ) {\n return {\n height: computedHeight,\n width: computedWidth\n };\n }\n\n return {\n height: Math.max(0, element.clientHeight),\n width: Math.max(0, element.clientWidth)\n };\n}\n\nfunction resolveTerminalDockPreviewRatio(\n frame: TerminalDockPreviewFrame | null,\n snapshot: TerminalPreviewSnapshot\n) {\n if (frame && frame.width > 0 && frame.height > 0) {\n return frame.width / frame.height;\n }\n const rowCount = Math.max(1, snapshot.lines.length);\n const colCount = Math.max(1, Math.min(snapshot.cols, 160));\n return (\n (colCount * terminalDockPreviewCharacterWidth) /\n (rowCount * terminalDockPreviewLineHeight)\n );\n}\n\nfunction resolveTerminalDockPreviewSourceSize(\n frame: TerminalDockPreviewFrame | null,\n snapshot: TerminalPreviewSnapshot\n) {\n if (frame && frame.width > 0 && frame.height > 0) {\n return {\n height: frame.height,\n width: frame.width\n };\n }\n\n const rowCount = Math.max(1, snapshot.lines.length);\n const colCount = Math.max(1, Math.min(snapshot.cols, 160));\n return {\n height:\n rowCount * terminalDockPreviewFontSize * terminalDockPreviewLineHeight +\n terminalDockPreviewPadding,\n width:\n colCount *\n terminalDockPreviewFontSize *\n terminalDockPreviewCharacterWidth +\n terminalDockPreviewPadding\n };\n}\n\nfunction fitTerminalDockPreviewSize(input: {\n availableHeight: number;\n availableWidth: number;\n ratio: number;\n}) {\n if (\n input.availableHeight <= 0 ||\n input.availableWidth <= 0 ||\n !Number.isFinite(input.ratio) ||\n input.ratio <= 0\n ) {\n return { height: 0, width: 0 };\n }\n\n const widthFromFullHeight = input.availableHeight * input.ratio;\n const heightFromFullWidth = input.availableWidth / input.ratio;\n if (widthFromFullHeight <= input.availableWidth) {\n return {\n height: input.availableHeight,\n width: widthFromFullHeight\n };\n }\n\n return {\n height: heightFromFullWidth,\n width: input.availableWidth\n };\n}\n\nfunction resolveTerminalDockPreviewScale(input: {\n availableHeight: number;\n availableWidth: number;\n fitMode: \"contain\" | \"cover\";\n sourceHeight: number;\n sourceWidth: number;\n}) {\n if (\n input.availableHeight <= 0 ||\n input.availableWidth <= 0 ||\n input.sourceHeight <= 0 ||\n input.sourceWidth <= 0\n ) {\n return 1;\n }\n\n const widthScale = input.availableWidth / input.sourceWidth;\n const heightScale = input.availableHeight / input.sourceHeight;\n return input.fitMode === \"cover\"\n ? Math.max(widthScale, heightScale)\n : Math.min(widthScale, heightScale);\n}\n\nfunction resolveTerminalDockPreviewSegmentStyle(\n segmentStyle: TerminalPreviewSegmentStyle | undefined\n): CSSProperties | undefined {\n if (!segmentStyle) {\n return undefined;\n }\n\n const style: CSSProperties = {};\n if (segmentStyle.background) {\n style.backgroundColor = segmentStyle.background;\n }\n if (segmentStyle.color) {\n style.color = segmentStyle.color;\n }\n if (segmentStyle.bold) {\n style.fontWeight = 700;\n }\n if (segmentStyle.dim) {\n style.opacity = 0.64;\n }\n if (segmentStyle.italic) {\n style.fontStyle = \"italic\";\n }\n\n const decorations: string[] = [];\n if (segmentStyle.underline) {\n decorations.push(\"underline\");\n }\n if (segmentStyle.strikethrough) {\n decorations.push(\"line-through\");\n }\n if (segmentStyle.overline) {\n decorations.push(\"overline\");\n }\n if (decorations.length > 0) {\n style.textDecorationLine = decorations.join(\" \");\n }\n\n return style;\n}\n"],"mappings":"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","names":[]}
@@ -309,23 +309,28 @@
309
309
  min-width: 0;
310
310
  min-height: 0;
311
311
  overflow: hidden;
312
+ background: var(--workspace-terminal-dock-preview-background, #000);
312
313
  place-items: center;
313
314
  }
314
315
 
315
316
  .workspace-terminal__dock-preview-viewport {
317
+ position: relative;
316
318
  display: block;
317
319
  width: var(--workspace-terminal-dock-preview-width, 100%);
318
320
  height: var(--workspace-terminal-dock-preview-height, 100%);
319
321
  overflow: hidden;
320
- background: var(--workspace-terminal-dock-preview-background, #111);
322
+ background: var(--workspace-terminal-dock-preview-background, #000);
321
323
  }
322
324
 
323
325
  .workspace-terminal__dock-preview {
326
+ position: absolute;
327
+ top: 50%;
328
+ left: 50%;
324
329
  display: block;
325
330
  width: var(--workspace-terminal-dock-preview-source-width, 100%);
326
331
  height: var(--workspace-terminal-dock-preview-source-height, 100%);
327
332
  overflow: hidden;
328
- background: var(--workspace-terminal-dock-preview-background, #111);
333
+ background: var(--workspace-terminal-dock-preview-background, #000);
329
334
  color: var(--workspace-terminal-dock-preview-foreground, #f4f4f5);
330
335
  font-family:
331
336
  ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
@@ -334,8 +339,10 @@
334
339
  line-height: 1.35;
335
340
  padding: 8px;
336
341
  pointer-events: none;
337
- transform: scale(var(--workspace-terminal-dock-preview-scale, 1));
338
- transform-origin: top left;
342
+ text-align: left;
343
+ transform: translate(-50%, -50%)
344
+ scale(var(--workspace-terminal-dock-preview-scale, 1));
345
+ transform-origin: center;
339
346
  user-select: none;
340
347
  }
341
348
 
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { WorkbenchHostExternalStateSource, WorkbenchFrame, WorkbenchHostLaunchRequest, WorkbenchHostDockEntry, WorkbenchContribution, WorkbenchHostLaunchResult, WorkbenchHostNodeDefinition } from '@tutti-os/workbench-surface';
2
+ import { WorkbenchHostExternalStateSource, WorkbenchFrame, WorkbenchHostNodeMinimizedDockCapability, WorkbenchHostLaunchRequest, WorkbenchHostDockEntry, WorkbenchContribution, WorkbenchHostLaunchResult, WorkbenchHostNodeDefinition } from '@tutti-os/workbench-surface';
3
3
  import { TerminalNodeExternalState, TerminalHeaderAccessoryRenderer, TerminalPreviewChangeHandler, TerminalCloseGuardResult, TerminalLaunchInput } from '../contracts/index.js';
4
4
  import { T as TerminalNodeFeature } from '../feature-sh6KDO7B.js';
5
5
  import '@tutti-os/ui-i18n-runtime';
@@ -10,11 +10,15 @@ interface TerminalWorkbenchIntent {
10
10
  initialInput?: string | null;
11
11
  profileId?: string | null;
12
12
  }
13
+ type TerminalMinimizedPreviewProvider = Extract<WorkbenchHostNodeMinimizedDockCapability, {
14
+ kind: "component";
15
+ }>["providePreview"];
13
16
  interface CreateTerminalWorkbenchNodeDefinitionInput {
14
17
  feature: TerminalNodeFeature;
15
18
  frame?: WorkbenchFrame;
16
19
  headerAccessory?: TerminalHeaderAccessoryRenderer;
17
20
  onPreviewChange?: TerminalPreviewChangeHandler;
21
+ provideMinimizedPreview?: TerminalMinimizedPreviewProvider;
18
22
  title?: string;
19
23
  typeId?: string;
20
24
  }
@@ -52,7 +56,7 @@ interface CreateTerminalWorkbenchContributionInput {
52
56
  typeId?: string;
53
57
  }
54
58
  declare const defaultTerminalWorkbenchTypeId = "workspace-terminal";
55
- declare function createTerminalWorkbenchNodeDefinition({ feature, frame, headerAccessory, onPreviewChange, title, typeId }: CreateTerminalWorkbenchNodeDefinitionInput): WorkbenchHostNodeDefinition<TerminalNodeExternalState>;
59
+ declare function createTerminalWorkbenchNodeDefinition({ feature, frame, headerAccessory, onPreviewChange, provideMinimizedPreview, title, typeId }: CreateTerminalWorkbenchNodeDefinitionInput): WorkbenchHostNodeDefinition<TerminalNodeExternalState>;
56
60
  declare function createTerminalDockEntry({ dockIcon, feature, id, order, sectionId, typeId }: CreateTerminalDockEntryInput): WorkbenchHostDockEntry;
57
61
  declare function createTerminalWorkbenchLaunchHandler({ feature, frame, resolveLaunchInput, typeId }: CreateTerminalWorkbenchLaunchHandlerInput): (request: WorkbenchHostLaunchRequest) => Promise<WorkbenchHostLaunchResult | null>;
58
62
  declare function createTerminalWorkbenchContribution({ contributionId, dockEntry, externalStateSource, feature, getTerminalState, node, onCloseFailure, onConfirmClose, resolveLaunchInput, shouldCloseAfterCloseFailure, typeId }: CreateTerminalWorkbenchContributionInput): WorkbenchContribution;
@@ -2,7 +2,7 @@ import {
2
2
  TerminalNode,
3
3
  TerminalNodeHeader,
4
4
  acquireTerminalSessionController
5
- } from "../chunk-UWPZ5O4V.js";
5
+ } from "../chunk-TBCIC6JY.js";
6
6
  import {
7
7
  closeTerminalSession,
8
8
  isTerminalSessionEndedStatus
@@ -97,6 +97,7 @@ function createTerminalWorkbenchNodeDefinition({
97
97
  frame = defaultTerminalNodeFrame,
98
98
  headerAccessory,
99
99
  onPreviewChange,
100
+ provideMinimizedPreview,
100
101
  title,
101
102
  typeId = defaultTerminalWorkbenchTypeId
102
103
  }) {
@@ -162,9 +163,10 @@ function createTerminalWorkbenchNodeDefinition({
162
163
  window: {
163
164
  closable: true,
164
165
  defaultOpen: false,
165
- minimizedDock: {
166
- kind: "snapshot"
167
- },
166
+ minimizedDock: provideMinimizedPreview ? {
167
+ kind: "component",
168
+ providePreview: provideMinimizedPreview
169
+ } : void 0,
168
170
  minimizable: true,
169
171
  restoreOnLoad: true
170
172
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/workbench/index.ts","../../src/workbench/bodyProps.ts","../../src/workbench/launchAnalytics.ts","../../src/workbench/windowCloseEffect.ts"],"sourcesContent":["import { createElement, type PointerEvent, type ReactNode } from \"react\";\nimport type {\n WorkbenchContribution,\n WorkbenchFrame,\n WorkbenchHostDockEntry,\n WorkbenchHostExternalStateSource,\n WorkbenchHostLaunchRequest,\n WorkbenchHostLaunchResult,\n WorkbenchHostNodeCloseDecision,\n WorkbenchHostNodeCloseRequest,\n WorkbenchHostNodeDefinition\n} from \"@tutti-os/workbench-surface\";\nimport type {\n TerminalCloseGuardResult,\n TerminalHeaderAccessoryRenderer,\n TerminalLaunchInput,\n TerminalNodeExternalState,\n TerminalPreviewChangeHandler\n} from \"../contracts/index.ts\";\nimport { closeTerminalSession } from \"../core/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport { acquireTerminalSessionController } from \"../core/sessionController.ts\";\nimport { resolveTerminalWorkbenchBodyProps } from \"./bodyProps.ts\";\nimport { resolveTerminalLaunchAnalyticsTrigger } from \"./launchAnalytics.ts\";\nimport { resolveTerminalWindowCloseEffect } from \"./windowCloseEffect.ts\";\nimport { TerminalNode, TerminalNodeHeader } from \"../react/TerminalNode.tsx\";\n\nexport interface TerminalWorkbenchIntent {\n cwd?: string | null;\n initialInput?: string | null;\n profileId?: string | null;\n}\n\nexport interface CreateTerminalWorkbenchNodeDefinitionInput {\n feature: TerminalNodeFeature;\n frame?: WorkbenchFrame;\n headerAccessory?: TerminalHeaderAccessoryRenderer;\n onPreviewChange?: TerminalPreviewChangeHandler;\n title?: string;\n typeId?: string;\n}\n\nexport type TerminalWorkbenchLaunchInputResolver = (\n request: WorkbenchHostLaunchRequest\n) =>\n | Promise<Partial<Omit<TerminalLaunchInput, \"reason\" | \"workspaceId\">>>\n | Partial<Omit<TerminalLaunchInput, \"reason\" | \"workspaceId\">>;\n\nexport interface CreateTerminalWorkbenchLaunchHandlerInput {\n feature: TerminalNodeFeature;\n frame?: WorkbenchFrame;\n resolveLaunchInput?: TerminalWorkbenchLaunchInputResolver;\n typeId?: string;\n}\n\nexport interface CreateTerminalDockEntryInput {\n dockIcon?: ReactNode;\n feature: TerminalNodeFeature;\n id?: string;\n order?: number;\n sectionId?: string;\n typeId?: string;\n}\n\nexport interface TerminalWorkbenchContributionCloseFailure {\n error: unknown;\n sessionId: string;\n status?: TerminalNodeExternalState[\"status\"];\n}\n\nexport interface CreateTerminalWorkbenchContributionInput {\n contributionId?: string;\n dockEntry?: Omit<CreateTerminalDockEntryInput, \"feature\">;\n externalStateSource?: WorkbenchHostExternalStateSource<\n TerminalNodeExternalState | null,\n unknown\n >;\n feature: TerminalNodeFeature;\n getTerminalState?: (sessionId: string) => TerminalNodeExternalState | null;\n node?: Omit<CreateTerminalWorkbenchNodeDefinitionInput, \"feature\">;\n onCloseFailure?: (failure: TerminalWorkbenchContributionCloseFailure) => void;\n onConfirmClose?: (\n guard: TerminalCloseGuardResult\n ) => Promise<boolean> | boolean;\n resolveLaunchInput?: TerminalWorkbenchLaunchInputResolver;\n shouldCloseAfterCloseFailure?: (\n failure: TerminalWorkbenchContributionCloseFailure\n ) => boolean;\n typeId?: string;\n}\n\nexport const defaultTerminalWorkbenchTypeId = \"workspace-terminal\";\n\nconst defaultTerminalNodeFrame: WorkbenchFrame = {\n height: 520,\n width: 860,\n x: 260,\n y: 140\n};\n\nexport function createTerminalWorkbenchNodeDefinition({\n feature,\n frame = defaultTerminalNodeFrame,\n headerAccessory,\n onPreviewChange,\n title,\n typeId = defaultTerminalWorkbenchTypeId\n}: CreateTerminalWorkbenchNodeDefinitionInput): WorkbenchHostNodeDefinition<TerminalNodeExternalState> {\n return {\n frame,\n instance: {\n mode: \"multi\"\n },\n renderBody: (context) =>\n createElement(\n TerminalNode,\n resolveTerminalWorkbenchBodyProps({ context, feature, onPreviewChange })\n ),\n createLease: ({ node }) => {\n const sessionId = node.data.instanceKey ?? null;\n if (!sessionId) {\n return null;\n }\n const controller = acquireTerminalSessionController({\n feature,\n nodeId: node.id,\n sessionId\n });\n controller.retain();\n return {\n release() {\n controller.release();\n }\n };\n },\n getWindowCloseEffect: ({ externalNodeState, node }) =>\n resolveTerminalWindowCloseEffect({\n closeGuard: feature.closeGuard,\n description: feature.i18n.t(\"closeGuard.description\"),\n externalNodeState,\n nodeId: node.id,\n sessionId: node.data.instanceKey ?? null,\n title: node.title,\n typeId\n }),\n renderHeader: ({\n defaultActions,\n dragHandleProps,\n externalNodeState,\n isFocused,\n node,\n windowActions\n }) =>\n createElement(TerminalNodeHeader, {\n defaultActions,\n externalState: externalNodeState,\n feature,\n headerAccessory,\n onCloseRequest: () => windowActions.close(),\n sessionId: node.data.instanceKey ?? null,\n ...dragHandleProps,\n onPointerDown: (event: PointerEvent<HTMLElement>) => {\n dragHandleProps.onPointerDown?.(event);\n if (!isFocused) {\n windowActions.focus();\n }\n }\n }),\n title: title ?? feature.i18n.t(\"title\"),\n typeId,\n window: {\n closable: true,\n defaultOpen: false,\n minimizedDock: {\n kind: \"snapshot\"\n },\n minimizable: true,\n restoreOnLoad: true\n }\n };\n}\n\nexport function createTerminalDockEntry({\n dockIcon,\n feature,\n id,\n order,\n sectionId,\n typeId = defaultTerminalWorkbenchTypeId\n}: CreateTerminalDockEntryInput): WorkbenchHostDockEntry {\n return {\n icon: dockIcon ?? createElement(DefaultTerminalDockIcon),\n id: id ?? typeId,\n label: feature.i18n.t(\"dockLabel\"),\n launchBehavior: \"enabled\",\n matchNode: (node) => node.data.typeId === typeId,\n order,\n resolvePopupItem: ({ node }) => {\n const subtitle = node.data.instanceKey ?? node.data.instanceId;\n return {\n revision: `${node.title}\\n${subtitle}`,\n subtitle,\n title: node.title\n };\n },\n sectionId,\n typeId,\n visibility: \"always\"\n };\n}\n\nexport function createTerminalWorkbenchLaunchHandler({\n feature,\n frame = defaultTerminalNodeFrame,\n resolveLaunchInput,\n typeId = defaultTerminalWorkbenchTypeId\n}: CreateTerminalWorkbenchLaunchHandlerInput): (\n request: WorkbenchHostLaunchRequest\n) => Promise<WorkbenchHostLaunchResult | null> {\n return async (request) => {\n if (request.typeId !== typeId) {\n return null;\n }\n\n const resolved = (await resolveLaunchInput?.(request)) ?? {};\n const descriptor = await feature.launchService.create({\n cwd: resolved.cwd,\n initialInput: resolved.initialInput,\n profileId: resolved.profileId,\n reason: request.reason === \"dock\" ? \"dock\" : \"intent\",\n workspaceId: request.workspaceId\n });\n\n return {\n activation: {\n payload: {\n trigger: resolveTerminalLaunchAnalyticsTrigger(request)\n },\n type: \"terminal-launch\"\n },\n defaultFrame: frame,\n dockEntryId: request.dockEntryId ?? typeId,\n framePolicy: \"cascade\",\n instanceId: descriptor.sessionId,\n instanceKey: descriptor.sessionId,\n title: descriptor.title,\n typeId\n };\n };\n}\n\nexport function createTerminalWorkbenchContribution({\n contributionId,\n dockEntry,\n externalStateSource,\n feature,\n getTerminalState,\n node,\n onCloseFailure,\n onConfirmClose,\n resolveLaunchInput,\n shouldCloseAfterCloseFailure,\n typeId = defaultTerminalWorkbenchTypeId\n}: CreateTerminalWorkbenchContributionInput): WorkbenchContribution {\n return {\n dockEntries: [\n createTerminalDockEntry({\n ...dockEntry,\n feature,\n typeId\n })\n ],\n externalStateSource,\n id: contributionId ?? typeId,\n nodes: [\n createTerminalWorkbenchNodeDefinition({\n ...node,\n feature,\n typeId\n })\n ],\n onLaunchRequest: createTerminalWorkbenchLaunchHandler({\n feature,\n frame: node?.frame,\n resolveLaunchInput,\n typeId\n }),\n onNodeCloseRequest: onConfirmClose\n ? (request) =>\n handleTerminalContributionNodeCloseRequest({\n feature,\n getTerminalState,\n onCloseFailure,\n onConfirmClose,\n request,\n shouldCloseAfterCloseFailure,\n typeId\n })\n : undefined\n };\n}\n\nasync function handleTerminalContributionNodeCloseRequest(input: {\n feature: TerminalNodeFeature;\n getTerminalState?: (sessionId: string) => TerminalNodeExternalState | null;\n onCloseFailure?: (failure: TerminalWorkbenchContributionCloseFailure) => void;\n onConfirmClose: (\n guard: TerminalCloseGuardResult\n ) => Promise<boolean> | boolean;\n request: WorkbenchHostNodeCloseRequest;\n shouldCloseAfterCloseFailure?: (\n failure: TerminalWorkbenchContributionCloseFailure\n ) => boolean;\n typeId: string;\n}): Promise<WorkbenchHostNodeCloseDecision | void> {\n if (input.request.typeId !== input.typeId) {\n return undefined;\n }\n\n const sessionId = input.request.instanceKey ?? input.request.instanceId;\n const terminalState = input.getTerminalState?.(sessionId) ?? null;\n try {\n const result = await closeTerminalSession({\n confirm: input.onConfirmClose,\n feature: input.feature,\n sessionId,\n status: terminalState?.status\n });\n return result === \"closed\" ? \"close\" : \"keep-open\";\n } catch (error) {\n const failure = {\n error,\n sessionId,\n status: terminalState?.status\n };\n input.onCloseFailure?.(failure);\n return input.shouldCloseAfterCloseFailure?.(failure)\n ? \"close\"\n : \"keep-open\";\n }\n}\n\nfunction DefaultTerminalDockIcon() {\n return createElement(\n \"span\",\n {\n \"aria-hidden\": \"true\",\n className: \"workspace-terminal__dock-icon\"\n },\n \">\"\n );\n}\n","import type { WorkbenchHostNodeBodyContext } from \"@tutti-os/workbench-surface\";\nimport type {\n TerminalNodeExternalState,\n TerminalPreviewChangeHandler\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\n\nexport interface TerminalWorkbenchBodyProps {\n externalState: TerminalNodeExternalState | null;\n feature: TerminalNodeFeature;\n nodeId: string;\n onFocusRequest?: () => void;\n onPreviewChange?: TerminalPreviewChangeHandler;\n sessionId: string | null;\n showHeader: boolean;\n}\n\nexport function resolveTerminalWorkbenchBodyProps({\n context,\n feature,\n onPreviewChange\n}: {\n context: WorkbenchHostNodeBodyContext<\n TerminalNodeExternalState | null,\n unknown\n >;\n feature: TerminalNodeFeature;\n onPreviewChange?: TerminalPreviewChangeHandler;\n}): TerminalWorkbenchBodyProps {\n // Keep this resolver narrower than TerminalNodeProps on purpose. The workbench\n // lease keeps the session alive while the node exists, but the mounted surface\n // must still retain the controller so snapshot hydration starts immediately.\n // Passing controllerLeaseRetainedExternally here makes a newly opened terminal\n // render blank until the first user input triggers controller.write().\n return {\n externalState: context.externalNodeState,\n feature,\n nodeId: context.node.id,\n onFocusRequest: context.isFocused ? undefined : () => context.focus(),\n onPreviewChange,\n sessionId: context.node.data.instanceKey ?? null,\n showHeader: false\n };\n}\n","import type { WorkbenchHostLaunchRequest } from \"@tutti-os/workbench-surface\";\n\nexport type TerminalLaunchAnalyticsTrigger =\n | \"agent_command\"\n | \"dock\"\n | \"keyboard\"\n | \"launchpad\";\n\nexport function resolveTerminalLaunchAnalyticsTrigger(\n request: WorkbenchHostLaunchRequest\n): TerminalLaunchAnalyticsTrigger {\n switch (request.reason) {\n case \"dock\":\n return \"dock\";\n case \"launchpad\":\n return \"launchpad\";\n case \"shortcut\":\n return \"keyboard\";\n case \"host\":\n return hasInitialInput(request.payload) ? \"agent_command\" : \"launchpad\";\n default:\n return \"launchpad\";\n }\n}\n\nfunction hasInitialInput(payload: unknown): boolean {\n if (!payload || typeof payload !== \"object\") {\n return false;\n }\n const typed = payload as { initialInput?: unknown };\n return (\n typeof typed.initialInput === \"string\" &&\n typed.initialInput.trim().length > 0\n );\n}\n","import type {\n TerminalCloseGuardService,\n TerminalNodeExternalState\n} from \"../contracts/index.ts\";\nimport { isTerminalSessionEndedStatus } from \"../core/sessionProjection.ts\";\n\nexport interface ResolveTerminalWindowCloseEffectInput {\n closeGuard: TerminalCloseGuardService;\n description: string;\n externalNodeState: TerminalNodeExternalState | null;\n nodeId: string;\n sessionId?: string | null;\n title: string;\n typeId: string;\n}\n\nexport async function resolveTerminalWindowCloseEffect({\n closeGuard,\n description,\n externalNodeState,\n nodeId,\n sessionId,\n title,\n typeId\n}: ResolveTerminalWindowCloseEffectInput) {\n const status = externalNodeState?.status ?? \"created\";\n if (status === \"created\" || isTerminalSessionEndedStatus(status)) {\n return null;\n }\n\n const resolvedSessionId = sessionId ?? externalNodeState?.sessionId ?? null;\n if (resolvedSessionId) {\n try {\n const guard = await closeGuard.check({ sessionId: resolvedSessionId });\n if (\n !guard.requiresConfirmation ||\n guard.reason === \"not-running\" ||\n isTerminalSessionEndedStatus(guard.status)\n ) {\n return null;\n }\n } catch {\n // Fall back to a conservative close effect when guard lookup fails.\n }\n }\n\n return {\n description,\n nodeId,\n title: externalNodeState?.title?.trim() || title,\n typeId\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/workbench/index.ts","../../src/workbench/bodyProps.ts","../../src/workbench/launchAnalytics.ts","../../src/workbench/windowCloseEffect.ts"],"sourcesContent":["import { createElement, type PointerEvent, type ReactNode } from \"react\";\nimport type {\n WorkbenchContribution,\n WorkbenchFrame,\n WorkbenchHostDockEntry,\n WorkbenchHostExternalStateSource,\n WorkbenchHostLaunchRequest,\n WorkbenchHostLaunchResult,\n WorkbenchHostNodeCloseDecision,\n WorkbenchHostNodeCloseRequest,\n WorkbenchHostNodeDefinition,\n WorkbenchHostNodeMinimizedDockCapability\n} from \"@tutti-os/workbench-surface\";\nimport type {\n TerminalCloseGuardResult,\n TerminalHeaderAccessoryRenderer,\n TerminalLaunchInput,\n TerminalNodeExternalState,\n TerminalPreviewChangeHandler\n} from \"../contracts/index.ts\";\nimport { closeTerminalSession } from \"../core/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport { acquireTerminalSessionController } from \"../core/sessionController.ts\";\nimport { resolveTerminalWorkbenchBodyProps } from \"./bodyProps.ts\";\nimport { resolveTerminalLaunchAnalyticsTrigger } from \"./launchAnalytics.ts\";\nimport { resolveTerminalWindowCloseEffect } from \"./windowCloseEffect.ts\";\nimport { TerminalNode, TerminalNodeHeader } from \"../react/TerminalNode.tsx\";\n\nexport interface TerminalWorkbenchIntent {\n cwd?: string | null;\n initialInput?: string | null;\n profileId?: string | null;\n}\n\ntype TerminalMinimizedPreviewProvider = Extract<\n WorkbenchHostNodeMinimizedDockCapability,\n { kind: \"component\" }\n>[\"providePreview\"];\n\nexport interface CreateTerminalWorkbenchNodeDefinitionInput {\n feature: TerminalNodeFeature;\n frame?: WorkbenchFrame;\n headerAccessory?: TerminalHeaderAccessoryRenderer;\n onPreviewChange?: TerminalPreviewChangeHandler;\n provideMinimizedPreview?: TerminalMinimizedPreviewProvider;\n title?: string;\n typeId?: string;\n}\n\nexport type TerminalWorkbenchLaunchInputResolver = (\n request: WorkbenchHostLaunchRequest\n) =>\n | Promise<Partial<Omit<TerminalLaunchInput, \"reason\" | \"workspaceId\">>>\n | Partial<Omit<TerminalLaunchInput, \"reason\" | \"workspaceId\">>;\n\nexport interface CreateTerminalWorkbenchLaunchHandlerInput {\n feature: TerminalNodeFeature;\n frame?: WorkbenchFrame;\n resolveLaunchInput?: TerminalWorkbenchLaunchInputResolver;\n typeId?: string;\n}\n\nexport interface CreateTerminalDockEntryInput {\n dockIcon?: ReactNode;\n feature: TerminalNodeFeature;\n id?: string;\n order?: number;\n sectionId?: string;\n typeId?: string;\n}\n\nexport interface TerminalWorkbenchContributionCloseFailure {\n error: unknown;\n sessionId: string;\n status?: TerminalNodeExternalState[\"status\"];\n}\n\nexport interface CreateTerminalWorkbenchContributionInput {\n contributionId?: string;\n dockEntry?: Omit<CreateTerminalDockEntryInput, \"feature\">;\n externalStateSource?: WorkbenchHostExternalStateSource<\n TerminalNodeExternalState | null,\n unknown\n >;\n feature: TerminalNodeFeature;\n getTerminalState?: (sessionId: string) => TerminalNodeExternalState | null;\n node?: Omit<CreateTerminalWorkbenchNodeDefinitionInput, \"feature\">;\n onCloseFailure?: (failure: TerminalWorkbenchContributionCloseFailure) => void;\n onConfirmClose?: (\n guard: TerminalCloseGuardResult\n ) => Promise<boolean> | boolean;\n resolveLaunchInput?: TerminalWorkbenchLaunchInputResolver;\n shouldCloseAfterCloseFailure?: (\n failure: TerminalWorkbenchContributionCloseFailure\n ) => boolean;\n typeId?: string;\n}\n\nexport const defaultTerminalWorkbenchTypeId = \"workspace-terminal\";\n\nconst defaultTerminalNodeFrame: WorkbenchFrame = {\n height: 520,\n width: 860,\n x: 260,\n y: 140\n};\n\nexport function createTerminalWorkbenchNodeDefinition({\n feature,\n frame = defaultTerminalNodeFrame,\n headerAccessory,\n onPreviewChange,\n provideMinimizedPreview,\n title,\n typeId = defaultTerminalWorkbenchTypeId\n}: CreateTerminalWorkbenchNodeDefinitionInput): WorkbenchHostNodeDefinition<TerminalNodeExternalState> {\n return {\n frame,\n instance: {\n mode: \"multi\"\n },\n renderBody: (context) =>\n createElement(\n TerminalNode,\n resolveTerminalWorkbenchBodyProps({ context, feature, onPreviewChange })\n ),\n createLease: ({ node }) => {\n const sessionId = node.data.instanceKey ?? null;\n if (!sessionId) {\n return null;\n }\n const controller = acquireTerminalSessionController({\n feature,\n nodeId: node.id,\n sessionId\n });\n controller.retain();\n return {\n release() {\n controller.release();\n }\n };\n },\n getWindowCloseEffect: ({ externalNodeState, node }) =>\n resolveTerminalWindowCloseEffect({\n closeGuard: feature.closeGuard,\n description: feature.i18n.t(\"closeGuard.description\"),\n externalNodeState,\n nodeId: node.id,\n sessionId: node.data.instanceKey ?? null,\n title: node.title,\n typeId\n }),\n renderHeader: ({\n defaultActions,\n dragHandleProps,\n externalNodeState,\n isFocused,\n node,\n windowActions\n }) =>\n createElement(TerminalNodeHeader, {\n defaultActions,\n externalState: externalNodeState,\n feature,\n headerAccessory,\n onCloseRequest: () => windowActions.close(),\n sessionId: node.data.instanceKey ?? null,\n ...dragHandleProps,\n onPointerDown: (event: PointerEvent<HTMLElement>) => {\n dragHandleProps.onPointerDown?.(event);\n if (!isFocused) {\n windowActions.focus();\n }\n }\n }),\n title: title ?? feature.i18n.t(\"title\"),\n typeId,\n window: {\n closable: true,\n defaultOpen: false,\n minimizedDock: provideMinimizedPreview\n ? {\n kind: \"component\",\n providePreview: provideMinimizedPreview\n }\n : undefined,\n minimizable: true,\n restoreOnLoad: true\n }\n };\n}\n\nexport function createTerminalDockEntry({\n dockIcon,\n feature,\n id,\n order,\n sectionId,\n typeId = defaultTerminalWorkbenchTypeId\n}: CreateTerminalDockEntryInput): WorkbenchHostDockEntry {\n return {\n icon: dockIcon ?? createElement(DefaultTerminalDockIcon),\n id: id ?? typeId,\n label: feature.i18n.t(\"dockLabel\"),\n launchBehavior: \"enabled\",\n matchNode: (node) => node.data.typeId === typeId,\n order,\n resolvePopupItem: ({ node }) => {\n const subtitle = node.data.instanceKey ?? node.data.instanceId;\n return {\n revision: `${node.title}\\n${subtitle}`,\n subtitle,\n title: node.title\n };\n },\n sectionId,\n typeId,\n visibility: \"always\"\n };\n}\n\nexport function createTerminalWorkbenchLaunchHandler({\n feature,\n frame = defaultTerminalNodeFrame,\n resolveLaunchInput,\n typeId = defaultTerminalWorkbenchTypeId\n}: CreateTerminalWorkbenchLaunchHandlerInput): (\n request: WorkbenchHostLaunchRequest\n) => Promise<WorkbenchHostLaunchResult | null> {\n return async (request) => {\n if (request.typeId !== typeId) {\n return null;\n }\n\n const resolved = (await resolveLaunchInput?.(request)) ?? {};\n const descriptor = await feature.launchService.create({\n cwd: resolved.cwd,\n initialInput: resolved.initialInput,\n profileId: resolved.profileId,\n reason: request.reason === \"dock\" ? \"dock\" : \"intent\",\n workspaceId: request.workspaceId\n });\n\n return {\n activation: {\n payload: {\n trigger: resolveTerminalLaunchAnalyticsTrigger(request)\n },\n type: \"terminal-launch\"\n },\n defaultFrame: frame,\n dockEntryId: request.dockEntryId ?? typeId,\n framePolicy: \"cascade\",\n instanceId: descriptor.sessionId,\n instanceKey: descriptor.sessionId,\n title: descriptor.title,\n typeId\n };\n };\n}\n\nexport function createTerminalWorkbenchContribution({\n contributionId,\n dockEntry,\n externalStateSource,\n feature,\n getTerminalState,\n node,\n onCloseFailure,\n onConfirmClose,\n resolveLaunchInput,\n shouldCloseAfterCloseFailure,\n typeId = defaultTerminalWorkbenchTypeId\n}: CreateTerminalWorkbenchContributionInput): WorkbenchContribution {\n return {\n dockEntries: [\n createTerminalDockEntry({\n ...dockEntry,\n feature,\n typeId\n })\n ],\n externalStateSource,\n id: contributionId ?? typeId,\n nodes: [\n createTerminalWorkbenchNodeDefinition({\n ...node,\n feature,\n typeId\n })\n ],\n onLaunchRequest: createTerminalWorkbenchLaunchHandler({\n feature,\n frame: node?.frame,\n resolveLaunchInput,\n typeId\n }),\n onNodeCloseRequest: onConfirmClose\n ? (request) =>\n handleTerminalContributionNodeCloseRequest({\n feature,\n getTerminalState,\n onCloseFailure,\n onConfirmClose,\n request,\n shouldCloseAfterCloseFailure,\n typeId\n })\n : undefined\n };\n}\n\nasync function handleTerminalContributionNodeCloseRequest(input: {\n feature: TerminalNodeFeature;\n getTerminalState?: (sessionId: string) => TerminalNodeExternalState | null;\n onCloseFailure?: (failure: TerminalWorkbenchContributionCloseFailure) => void;\n onConfirmClose: (\n guard: TerminalCloseGuardResult\n ) => Promise<boolean> | boolean;\n request: WorkbenchHostNodeCloseRequest;\n shouldCloseAfterCloseFailure?: (\n failure: TerminalWorkbenchContributionCloseFailure\n ) => boolean;\n typeId: string;\n}): Promise<WorkbenchHostNodeCloseDecision | void> {\n if (input.request.typeId !== input.typeId) {\n return undefined;\n }\n\n const sessionId = input.request.instanceKey ?? input.request.instanceId;\n const terminalState = input.getTerminalState?.(sessionId) ?? null;\n try {\n const result = await closeTerminalSession({\n confirm: input.onConfirmClose,\n feature: input.feature,\n sessionId,\n status: terminalState?.status\n });\n return result === \"closed\" ? \"close\" : \"keep-open\";\n } catch (error) {\n const failure = {\n error,\n sessionId,\n status: terminalState?.status\n };\n input.onCloseFailure?.(failure);\n return input.shouldCloseAfterCloseFailure?.(failure)\n ? \"close\"\n : \"keep-open\";\n }\n}\n\nfunction DefaultTerminalDockIcon() {\n return createElement(\n \"span\",\n {\n \"aria-hidden\": \"true\",\n className: \"workspace-terminal__dock-icon\"\n },\n \">\"\n );\n}\n","import type { WorkbenchHostNodeBodyContext } from \"@tutti-os/workbench-surface\";\nimport type {\n TerminalNodeExternalState,\n TerminalPreviewChangeHandler\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\n\nexport interface TerminalWorkbenchBodyProps {\n externalState: TerminalNodeExternalState | null;\n feature: TerminalNodeFeature;\n nodeId: string;\n onFocusRequest?: () => void;\n onPreviewChange?: TerminalPreviewChangeHandler;\n sessionId: string | null;\n showHeader: boolean;\n}\n\nexport function resolveTerminalWorkbenchBodyProps({\n context,\n feature,\n onPreviewChange\n}: {\n context: WorkbenchHostNodeBodyContext<\n TerminalNodeExternalState | null,\n unknown\n >;\n feature: TerminalNodeFeature;\n onPreviewChange?: TerminalPreviewChangeHandler;\n}): TerminalWorkbenchBodyProps {\n // Keep this resolver narrower than TerminalNodeProps on purpose. The workbench\n // lease keeps the session alive while the node exists, but the mounted surface\n // must still retain the controller so snapshot hydration starts immediately.\n // Passing controllerLeaseRetainedExternally here makes a newly opened terminal\n // render blank until the first user input triggers controller.write().\n return {\n externalState: context.externalNodeState,\n feature,\n nodeId: context.node.id,\n onFocusRequest: context.isFocused ? undefined : () => context.focus(),\n onPreviewChange,\n sessionId: context.node.data.instanceKey ?? null,\n showHeader: false\n };\n}\n","import type { WorkbenchHostLaunchRequest } from \"@tutti-os/workbench-surface\";\n\nexport type TerminalLaunchAnalyticsTrigger =\n | \"agent_command\"\n | \"dock\"\n | \"keyboard\"\n | \"launchpad\";\n\nexport function resolveTerminalLaunchAnalyticsTrigger(\n request: WorkbenchHostLaunchRequest\n): TerminalLaunchAnalyticsTrigger {\n switch (request.reason) {\n case \"dock\":\n return \"dock\";\n case \"launchpad\":\n return \"launchpad\";\n case \"shortcut\":\n return \"keyboard\";\n case \"host\":\n return hasInitialInput(request.payload) ? \"agent_command\" : \"launchpad\";\n default:\n return \"launchpad\";\n }\n}\n\nfunction hasInitialInput(payload: unknown): boolean {\n if (!payload || typeof payload !== \"object\") {\n return false;\n }\n const typed = payload as { initialInput?: unknown };\n return (\n typeof typed.initialInput === \"string\" &&\n typed.initialInput.trim().length > 0\n );\n}\n","import type {\n TerminalCloseGuardService,\n TerminalNodeExternalState\n} from \"../contracts/index.ts\";\nimport { isTerminalSessionEndedStatus } from \"../core/sessionProjection.ts\";\n\nexport interface ResolveTerminalWindowCloseEffectInput {\n closeGuard: TerminalCloseGuardService;\n description: string;\n externalNodeState: TerminalNodeExternalState | null;\n nodeId: string;\n sessionId?: string | null;\n title: string;\n typeId: string;\n}\n\nexport async function resolveTerminalWindowCloseEffect({\n closeGuard,\n description,\n externalNodeState,\n nodeId,\n sessionId,\n title,\n typeId\n}: ResolveTerminalWindowCloseEffectInput) {\n const status = externalNodeState?.status ?? \"created\";\n if (status === \"created\" || isTerminalSessionEndedStatus(status)) {\n return null;\n }\n\n const resolvedSessionId = sessionId ?? externalNodeState?.sessionId ?? null;\n if (resolvedSessionId) {\n try {\n const guard = await closeGuard.check({ sessionId: resolvedSessionId });\n if (\n !guard.requiresConfirmation ||\n guard.reason === \"not-running\" ||\n isTerminalSessionEndedStatus(guard.status)\n ) {\n return null;\n }\n } catch {\n // Fall back to a conservative close effect when guard lookup fails.\n }\n }\n\n return {\n description,\n nodeId,\n title: externalNodeState?.title?.trim() || title,\n typeId\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tutti-os/workspace-terminal",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -37,10 +37,10 @@
37
37
  "directory": "packages/workspace/terminal"
38
38
  },
39
39
  "dependencies": {
40
- "@tutti-os/ui-i18n-runtime": "0.0.21",
41
- "@tutti-os/ui-react-hooks": "0.0.21",
42
- "@tutti-os/ui-system": "0.0.21",
43
- "@tutti-os/workbench-surface": "0.0.21",
40
+ "@tutti-os/ui-i18n-runtime": "0.0.22",
41
+ "@tutti-os/ui-react-hooks": "0.0.22",
42
+ "@tutti-os/ui-system": "0.0.22",
43
+ "@tutti-os/workbench-surface": "0.0.22",
44
44
  "@xterm/addon-fit": "^0.11.0",
45
45
  "@xterm/addon-search": "^0.16.0",
46
46
  "@xterm/addon-serialize": "^0.14.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/sessionControllerRecovery.ts","../src/core/sessionControllerStore.ts","../src/core/sessionTransportRuntime.ts","../src/core/sessionController.ts","../src/react/TerminalNode.tsx","../src/react/headerActions.ts","../src/react/TerminalSurface.tsx","../src/react/terminalSurfaceRuntime.ts","../src/react/terminalFileLinkProvider.ts","../src/react/terminalSurfaceOutputPlan.ts","../src/react/terminalSurfaceResizePlan.ts","../src/react/terminalSurfaceScreenCachePlan.ts","../src/react/terminalWriteBatch.ts","../src/react/terminalFindShortcut.ts","../src/react/useTerminalFindController.ts","../src/react/useTerminalSessionController.ts"],"sourcesContent":["import type { BufferedTerminalInputQueue } from \"./inputQueue.ts\";\nimport { writeQueuedTerminalInput } from \"./inputQueue.ts\";\nimport type { TerminalTransport } from \"../contracts/index.ts\";\nimport type { TerminalSessionRecoveryDiagnostics } from \"./sessionDiagnostics.ts\";\nimport type { TerminalSessionControllerStore } from \"./sessionControllerStore.ts\";\nimport type { TerminalSessionTransportRuntime } from \"./sessionTransportRuntime.ts\";\n\nexport interface TerminalSessionRecoveryHandle {\n dispose(): void;\n start(): Promise<void>;\n}\n\nexport function createTerminalSessionRecovery(input: {\n diagnostics: TerminalSessionRecoveryDiagnostics;\n inputQueue: BufferedTerminalInputQueue;\n onRecoverableDetach: () => void;\n onWriteReadyChange: (ready: boolean) => void;\n replayGapMessage: string;\n sessionId: string;\n snapshotTruncatedMessage: string;\n store: TerminalSessionControllerStore;\n transport: TerminalTransport;\n transportRuntime: TerminalSessionTransportRuntime;\n}): TerminalSessionRecoveryHandle {\n let disposed = false;\n let hydrationReady = false;\n const hydrationReplayChunks: string[] = [];\n\n const disposeData = input.transportRuntime.onData((event) => {\n if (disposed || event.sessionId !== input.sessionId) {\n return;\n }\n if (!hydrationReady) {\n hydrationReplayChunks.push(event.data);\n return;\n }\n input.store.appendRawOutput(event.data);\n });\n\n const disposeState = input.transportRuntime.onState((event) => {\n if (disposed || event.sessionId !== input.sessionId) {\n return;\n }\n if (\n typeof event.gapStartSeq === \"number\" &&\n typeof event.gapEndSeq === \"number\"\n ) {\n input.diagnostics.hydrationGap({\n fromSeq: event.gapStartSeq,\n toSeq: event.gapEndSeq\n });\n input.store.setSurfaceError(input.replayGapMessage);\n return;\n }\n if (event.error) {\n input.store.setSurfaceError(event.error);\n }\n if (event.status === \"detached\") {\n input.onWriteReadyChange(false);\n input.store.setInputReady(false);\n input.onRecoverableDetach();\n return;\n }\n if (event.status === \"exited\") {\n input.onWriteReadyChange(false);\n input.store.setInputReady(false);\n }\n });\n\n const disposeExit = input.transportRuntime.onExit((event) => {\n if (disposed || event.sessionId !== input.sessionId) {\n return;\n }\n input.onWriteReadyChange(false);\n input.store.setInputReady(false);\n });\n\n const disposeMetadata = input.transportRuntime.onMetadata(() => undefined);\n\n return {\n dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n hydrationReady = false;\n hydrationReplayChunks.length = 0;\n disposeData();\n disposeState();\n disposeExit();\n disposeMetadata();\n },\n async start() {\n input.diagnostics.hydrationStart();\n input.diagnostics.snapshotStart();\n\n try {\n const snapshot = await input.transportRuntime.snapshot();\n if (disposed) {\n return;\n }\n input.store.replaceRawOutput(snapshot.data);\n const snapshotState = input.store.getState();\n input.diagnostics.outputProjected({\n contentEpoch: snapshotState.contentEpoch,\n previewHead: previewTerminalOutput(snapshot.data, \"head\"),\n previewTail: previewTerminalOutput(snapshot.data, \"tail\"),\n rawBytes: snapshotState.rawOutput.length,\n source: \"snapshot\",\n writeBytes: snapshot.data.length\n });\n if (snapshot.truncated) {\n input.store.setSurfaceError(input.snapshotTruncatedMessage);\n } else {\n input.store.setSurfaceError(null);\n }\n input.diagnostics.snapshotComplete({\n toSeq: snapshot.toSeq ?? null,\n truncated: snapshot.truncated ?? false\n });\n input.diagnostics.attachStart(snapshot.toSeq ?? null);\n await input.transportRuntime.attach(snapshot.toSeq);\n if (disposed) {\n return;\n }\n hydrationReady = true;\n const replayChunks = hydrationReplayChunks.splice(0);\n replayChunks.forEach((chunk) => {\n input.store.appendRawOutput(chunk);\n });\n if (replayChunks.length > 0) {\n const replayState = input.store.getState();\n input.diagnostics.outputProjected({\n contentEpoch: replayState.contentEpoch,\n previewHead: previewTerminalOutput(replayChunks.join(\"\"), \"head\"),\n previewTail: previewTerminalOutput(replayChunks.join(\"\"), \"tail\"),\n rawBytes: replayState.rawOutput.length,\n source: \"replay\",\n writeBytes: replayChunks.reduce(\n (total, chunk) => total + chunk.length,\n 0\n )\n });\n }\n input.onWriteReadyChange(true);\n input.store.setInputReady(true);\n await writeQueuedTerminalInput({\n queue: input.inputQueue,\n sessionId: input.sessionId,\n transport: input.transport\n });\n if (disposed) {\n return;\n }\n input.diagnostics.attachComplete();\n input.diagnostics.hydrationComplete(replayChunks.length);\n } catch (error) {\n if (disposed) {\n return;\n }\n input.diagnostics.attachError();\n input.store.setSurfaceError(errorMessage(error));\n }\n }\n };\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction previewTerminalOutput(\n value: string,\n side: \"head\" | \"tail\",\n maxChars = 48\n) {\n const slice =\n side === \"head\"\n ? value.slice(0, maxChars)\n : value.slice(Math.max(0, value.length - maxChars));\n return slice\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"\\r\", \"\\\\r\")\n .replaceAll(\"\\n\", \"\\\\n\");\n}\n","import { truncateTerminalScrollback } from \"./scrollback.ts\";\n\nexport interface TerminalSessionControllerState {\n contentEpoch: number;\n inputReady: boolean;\n rawOutput: string;\n surfaceError: string | null;\n}\n\nexport interface TerminalSessionControllerStore {\n appendRawOutput(data: string): void;\n clearListeners(): void;\n getState(): TerminalSessionControllerState;\n replaceRawOutput(rawOutput: string): void;\n setInputReady(inputReady: boolean): void;\n setSurfaceError(surfaceError: string | null): void;\n subscribe(listener: () => void): () => void;\n}\n\nconst initialState: TerminalSessionControllerState = {\n contentEpoch: 0,\n inputReady: false,\n rawOutput: \"\",\n surfaceError: null\n};\n\nexport function createTerminalSessionControllerStore(input: {\n maxScrollbackChars: number;\n}): TerminalSessionControllerStore {\n let state = initialState;\n const listeners = new Set<() => void>();\n\n return {\n appendRawOutput(data) {\n if (!data) {\n return;\n }\n const nextOutput = truncateTerminalScrollback(\n `${state.rawOutput}${data}`,\n {\n maxChars: input.maxScrollbackChars\n }\n );\n if (nextOutput === state.rawOutput) {\n return;\n }\n state = {\n ...state,\n rawOutput: nextOutput\n };\n emitState(listeners);\n },\n clearListeners() {\n listeners.clear();\n },\n getState() {\n return state;\n },\n replaceRawOutput(rawOutput) {\n state = {\n ...state,\n contentEpoch: state.contentEpoch + 1,\n rawOutput: truncateTerminalScrollback(rawOutput, {\n maxChars: input.maxScrollbackChars\n })\n };\n emitState(listeners);\n },\n setInputReady(inputReady) {\n if (state.inputReady === inputReady) {\n return;\n }\n state = {\n ...state,\n inputReady\n };\n emitState(listeners);\n },\n setSurfaceError(surfaceError) {\n if (state.surfaceError === surfaceError) {\n return;\n }\n state = {\n ...state,\n surfaceError\n };\n emitState(listeners);\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n };\n}\n\nfunction emitState(listeners: Set<() => void>) {\n for (const listener of listeners) {\n listener();\n }\n}\n","import type {\n TerminalDataEvent,\n TerminalExitEvent,\n TerminalMetadataEvent,\n TerminalSnapshot,\n TerminalStateEvent,\n TerminalTransport\n} from \"../contracts/index.ts\";\nimport { createTerminalAttachmentController } from \"./attachmentController.ts\";\n\nexport interface TerminalSessionTransportRuntime {\n attach(afterSeq?: number): Promise<void>;\n onData(listener: (event: TerminalDataEvent) => void): () => void;\n onExit(listener: (event: TerminalExitEvent) => void): () => void;\n onMetadata(listener: (event: TerminalMetadataEvent) => void): () => void;\n onState(listener: (event: TerminalStateEvent) => void): () => void;\n release(): void;\n snapshot(): Promise<TerminalSnapshot>;\n}\n\ninterface TerminalSessionTransportRuntimeEntry {\n attach(afterSeq?: number): Promise<void>;\n dataBuffer: TerminalDataEvent[];\n dataListeners: Set<(event: TerminalDataEvent) => void>;\n detachGraceMs: number;\n detachTimer: ReturnType<typeof setTimeout> | null;\n exitBuffer: TerminalExitEvent[];\n exitListeners: Set<(event: TerminalExitEvent) => void>;\n metadataBuffer: TerminalMetadataEvent[];\n metadataListeners: Set<(event: TerminalMetadataEvent) => void>;\n refCount: number;\n release(): void;\n sessionId: string;\n snapshot(): Promise<TerminalSnapshot>;\n snapshotCache: TerminalSnapshot | null;\n snapshotPromise: Promise<TerminalSnapshot> | null;\n stateBuffer: TerminalStateEvent[];\n stateListeners: Set<(event: TerminalStateEvent) => void>;\n teardown(): void;\n}\n\nconst defaultDetachGraceMs = 200;\nconst runtimeRegistry = new Map<string, TerminalSessionTransportRuntimeEntry>();\nlet runtimeClientSequence = 0;\n\nexport function acquireTerminalSessionTransportRuntime(input: {\n detachGraceMs?: number;\n sessionId: string;\n transport: TerminalTransport;\n}): TerminalSessionTransportRuntime {\n const entry =\n runtimeRegistry.get(input.sessionId) ??\n createTerminalSessionTransportRuntimeEntry(input);\n if (!runtimeRegistry.has(input.sessionId)) {\n runtimeRegistry.set(input.sessionId, entry);\n }\n entry.refCount += 1;\n if (entry.detachTimer !== null) {\n clearTimeout(entry.detachTimer);\n entry.detachTimer = null;\n }\n\n return {\n attach(afterSeq) {\n return entry.attach(afterSeq);\n },\n onData(listener) {\n entry.dataListeners.add(listener);\n flushBufferedEvents(entry.dataBuffer, listener);\n return () => {\n entry.dataListeners.delete(listener);\n };\n },\n onExit(listener) {\n entry.exitListeners.add(listener);\n flushBufferedEvents(entry.exitBuffer, listener);\n return () => {\n entry.exitListeners.delete(listener);\n };\n },\n onMetadata(listener) {\n entry.metadataListeners.add(listener);\n flushBufferedEvents(entry.metadataBuffer, listener);\n return () => {\n entry.metadataListeners.delete(listener);\n };\n },\n onState(listener) {\n entry.stateListeners.add(listener);\n flushBufferedEvents(entry.stateBuffer, listener);\n return () => {\n entry.stateListeners.delete(listener);\n };\n },\n release() {\n entry.release();\n },\n snapshot() {\n return entry.snapshot();\n }\n };\n}\n\nfunction createTerminalSessionTransportRuntimeEntry(input: {\n detachGraceMs?: number;\n sessionId: string;\n transport: TerminalTransport;\n}): TerminalSessionTransportRuntimeEntry {\n const attachmentController = createTerminalAttachmentController({\n clientId: createTerminalTransportClientId(),\n sessionId: input.sessionId,\n transport: input.transport\n });\n\n const entry: TerminalSessionTransportRuntimeEntry = {\n attach(afterSeq) {\n return attachmentController.attach(afterSeq);\n },\n dataBuffer: [],\n dataListeners: new Set(),\n detachGraceMs: input.detachGraceMs ?? defaultDetachGraceMs,\n detachTimer: null,\n exitBuffer: [],\n exitListeners: new Set(),\n metadataBuffer: [],\n metadataListeners: new Set(),\n refCount: 0,\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0 || entry.detachTimer !== null) {\n return;\n }\n entry.detachTimer = setTimeout(() => {\n entry.detachTimer = null;\n if (entry.refCount > 0) {\n return;\n }\n void attachmentController.detach().finally(() => {\n entry.teardown();\n runtimeRegistry.delete(entry.sessionId);\n });\n }, entry.detachGraceMs);\n },\n sessionId: input.sessionId,\n snapshot() {\n if (entry.snapshotPromise) {\n return entry.snapshotPromise;\n }\n if (entry.snapshotCache) {\n return Promise.resolve(entry.snapshotCache);\n }\n entry.snapshotPromise = input.transport\n .snapshot({ sessionId: input.sessionId })\n .then((snapshot) => {\n entry.snapshotCache = snapshot;\n return snapshot;\n })\n .finally(() => {\n entry.snapshotPromise = null;\n });\n return entry.snapshotPromise;\n },\n snapshotCache: null,\n snapshotPromise: null,\n stateBuffer: [],\n stateListeners: new Set(),\n teardown() {\n disposeData();\n disposeState();\n disposeExit();\n disposeMetadata?.();\n entry.dataBuffer.length = 0;\n entry.exitBuffer.length = 0;\n entry.metadataBuffer.length = 0;\n entry.stateBuffer.length = 0;\n entry.snapshotCache = null;\n entry.snapshotPromise = null;\n }\n };\n\n const disposeData = input.transport.onData((event) => {\n if (event.sessionId !== input.sessionId) {\n return;\n }\n entry.snapshotCache = null;\n dispatchOrBuffer(entry.dataListeners, entry.dataBuffer, event);\n });\n const disposeState = input.transport.onState((event) => {\n if (event.sessionId !== input.sessionId) {\n return;\n }\n if (event.status === \"detached\" || event.status === \"exited\") {\n attachmentController.markDetached();\n }\n if (\n typeof event.gapStartSeq === \"number\" ||\n typeof event.gapEndSeq === \"number\"\n ) {\n entry.snapshotCache = null;\n }\n dispatchOrBuffer(entry.stateListeners, entry.stateBuffer, event);\n });\n const disposeExit = input.transport.onExit((event) => {\n if (event.sessionId !== input.sessionId) {\n return;\n }\n dispatchOrBuffer(entry.exitListeners, entry.exitBuffer, event);\n });\n const disposeMetadata = input.transport.onMetadata?.((event) => {\n if (event.sessionId !== input.sessionId) {\n return;\n }\n dispatchOrBuffer(entry.metadataListeners, entry.metadataBuffer, event);\n });\n\n return entry;\n}\n\nfunction createTerminalTransportClientId(): string {\n runtimeClientSequence += 1;\n return `terminal-runtime-${runtimeClientSequence}`;\n}\n\nfunction dispatchOrBuffer<TEvent>(\n listeners: Set<(event: TEvent) => void>,\n buffer: TEvent[],\n event: TEvent\n) {\n if (listeners.size === 0) {\n buffer.push(event);\n return;\n }\n for (const listener of listeners) {\n listener(event);\n }\n}\n\nfunction flushBufferedEvents<TEvent>(\n buffer: TEvent[],\n listener: (event: TEvent) => void\n) {\n if (buffer.length === 0) {\n return;\n }\n const pending = buffer.splice(0);\n for (const event of pending) {\n listener(event);\n }\n}\n","import type {\n TerminalNodeLimits,\n TerminalWriteEncoding\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"./feature.ts\";\nimport {\n createBufferedTerminalInputQueue,\n type BufferedTerminalInputQueue\n} from \"./inputQueue.ts\";\nimport {\n createTerminalSessionRecovery,\n type TerminalSessionRecoveryHandle\n} from \"./sessionControllerRecovery.ts\";\nimport { createTerminalSessionRecoveryDiagnostics } from \"./sessionDiagnostics.ts\";\nimport {\n createTerminalSessionControllerStore,\n type TerminalSessionControllerState,\n type TerminalSessionControllerStore\n} from \"./sessionControllerStore.ts\";\nimport {\n acquireTerminalSessionTransportRuntime,\n type TerminalSessionTransportRuntime\n} from \"./sessionTransportRuntime.ts\";\n\nexport type { TerminalSessionControllerState } from \"./sessionControllerStore.ts\";\n\nexport interface TerminalSessionController {\n getState(): TerminalSessionControllerState;\n retain(): void;\n release(): void;\n resize(input: { cols: number; rows: number }): Promise<void>;\n subscribe(listener: () => void): () => void;\n write(data: string, encoding?: TerminalWriteEncoding): void;\n}\n\ninterface TerminalSessionControllerEntry {\n context: TerminalSessionControllerContext;\n disposed: boolean;\n inputQueue: BufferedTerminalInputQueue;\n recovery: TerminalSessionRecoveryHandle;\n refCount: number;\n release(): void;\n retainTimer: ReturnType<typeof setTimeout> | null;\n runtimeWriteReady: boolean;\n startPromise: Promise<void> | null;\n store: TerminalSessionControllerStore;\n teardown(): void;\n transportRuntime: TerminalSessionTransportRuntime;\n}\n\ninterface TerminalSessionControllerContext {\n feature: TerminalNodeFeature;\n nodeId: string;\n sessionId: string;\n}\n\nconst defaultControllerRetainMs = 5_000;\nconst controllerRegistry = new Map<string, TerminalSessionControllerEntry>();\n\nexport function acquireTerminalSessionController(input: {\n feature: TerminalNodeFeature;\n nodeId: string;\n retainMs?: number;\n sessionId: string;\n}): TerminalSessionController {\n const entry =\n controllerRegistry.get(input.sessionId) ??\n createTerminalSessionControllerEntry({\n feature: input.feature,\n nodeId: input.nodeId,\n retainMs: input.retainMs ?? defaultControllerRetainMs,\n sessionId: input.sessionId\n });\n if (!controllerRegistry.has(input.sessionId)) {\n controllerRegistry.set(input.sessionId, entry);\n }\n\n entry.context = {\n feature: input.feature,\n nodeId: input.nodeId,\n sessionId: input.sessionId\n };\n\n return {\n getState() {\n return entry.store.getState();\n },\n retain() {\n entry.refCount += 1;\n if (entry.retainTimer !== null) {\n clearTimeout(entry.retainTimer);\n entry.retainTimer = null;\n }\n ensureRecoveryStarted(entry);\n },\n release() {\n entry.release();\n },\n resize({ cols, rows }) {\n return entry.context.feature.transport.resize({\n cols,\n rows,\n sessionId: entry.context.sessionId\n });\n },\n subscribe(listener) {\n return entry.store.subscribe(listener);\n },\n write(data, encoding = \"utf8\") {\n if (!entry.runtimeWriteReady) {\n entry.inputQueue.enqueue(data, encoding);\n ensureRecoveryStarted(entry);\n return;\n }\n void writeTerminalInput(entry, data, encoding);\n }\n };\n}\n\nfunction createTerminalSessionControllerEntry(input: {\n feature: TerminalNodeFeature;\n nodeId: string;\n retainMs: number;\n sessionId: string;\n}) {\n const transportRuntime = acquireTerminalSessionTransportRuntime({\n sessionId: input.sessionId,\n transport: input.feature.transport\n });\n const inputQueue = createBufferedTerminalInputQueue();\n const store = createTerminalSessionControllerStore({\n maxScrollbackChars: resolveMaxScrollbackChars(input.feature.limits)\n });\n\n const entry = {\n context: {\n feature: input.feature,\n nodeId: input.nodeId,\n sessionId: input.sessionId\n },\n disposed: false,\n inputQueue,\n recovery: null as unknown as TerminalSessionRecoveryHandle,\n refCount: 0,\n release: () => undefined,\n retainTimer: null,\n runtimeWriteReady: false,\n startPromise: null,\n store,\n teardown: () => undefined,\n transportRuntime\n } as TerminalSessionControllerEntry;\n\n entry.release = () => {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0 || entry.retainTimer !== null) {\n return;\n }\n entry.retainTimer = setTimeout(() => {\n entry.retainTimer = null;\n if (entry.refCount > 0) {\n return;\n }\n entry.teardown();\n controllerRegistry.delete(entry.context.sessionId);\n }, input.retainMs);\n };\n\n entry.teardown = () => {\n if (entry.disposed) {\n return;\n }\n entry.disposed = true;\n inputQueue.reset();\n entry.runtimeWriteReady = false;\n entry.recovery.dispose();\n transportRuntime.release();\n store.clearListeners();\n };\n\n entry.recovery = createTerminalSessionRecovery({\n diagnostics: createTerminalSessionRecoveryDiagnostics({\n diagnostics: input.feature.diagnostics,\n nodeId: input.nodeId,\n sessionId: input.sessionId\n }),\n inputQueue,\n onRecoverableDetach() {\n if (entry.disposed || entry.refCount === 0) {\n return;\n }\n ensureRecoveryStarted(entry);\n },\n onWriteReadyChange(ready) {\n if (entry.disposed) {\n return;\n }\n entry.runtimeWriteReady = ready;\n },\n replayGapMessage: input.feature.i18n.t(\"recovery.replayGap\"),\n sessionId: input.sessionId,\n snapshotTruncatedMessage: input.feature.i18n.t(\n \"recovery.snapshotTruncated\"\n ),\n store,\n transport: input.feature.transport,\n transportRuntime\n });\n\n return entry;\n}\n\nfunction ensureRecoveryStarted(entry: TerminalSessionControllerEntry) {\n if (\n entry.disposed ||\n entry.startPromise !== null ||\n entry.runtimeWriteReady\n ) {\n return;\n }\n entry.startPromise = entry.recovery.start().finally(() => {\n entry.startPromise = null;\n });\n}\n\nfunction resolveMaxScrollbackChars(limits: TerminalNodeLimits) {\n return Math.max(limits.maxScrollbackLines * 160, 400_000);\n}\n\nfunction writeTerminalInput(\n entry: TerminalSessionControllerEntry,\n data: string,\n encoding: TerminalWriteEncoding\n) {\n return entry.context.feature.transport\n .write({\n data,\n encoding,\n provenance: \"user\",\n sessionId: entry.context.sessionId\n })\n .catch((error: unknown) => {\n entry.runtimeWriteReady = false;\n entry.store.setInputReady(false);\n entry.inputQueue.enqueue(data, encoding);\n ensureRecoveryStarted(entry);\n entry.context.feature.diagnostics.log(\"write-error\", {\n nodeId: entry.context.nodeId,\n sessionId: entry.context.sessionId\n });\n entry.store.setSurfaceError(errorMessage(error));\n });\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import { useState } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { Badge, StatusDot } from \"@tutti-os/ui-system\";\nimport type {\n TerminalCloseGuardResult,\n TerminalHeaderAccessoryRenderer,\n TerminalNodeExternalState,\n TerminalPreviewChangeHandler,\n TerminalSessionStatus\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport { createTerminalCloseDiagnostics } from \"../core/sessionDiagnostics.ts\";\nimport { isTerminalSessionEndedStatus } from \"../core/index.ts\";\nimport { hasTerminalHeaderDefaultActions } from \"./headerActions.ts\";\nimport { TerminalSurface } from \"./TerminalSurface.tsx\";\n\nexport interface TerminalNodeProps {\n children?: ReactNode;\n controllerLeaseRetainedExternally?: boolean;\n externalState?: TerminalNodeExternalState | null;\n feature: TerminalNodeFeature;\n headerAccessory?: TerminalHeaderAccessoryRenderer;\n nodeId: string;\n onFocusRequest?: () => void;\n onPreviewChange?: TerminalPreviewChangeHandler;\n sessionId?: string | null;\n showHeader?: boolean;\n}\n\nexport interface TerminalNodeHeaderProps extends HTMLAttributes<HTMLElement> {\n className?: string;\n defaultActions?: ReactNode;\n externalState?: TerminalNodeExternalState | null;\n feature: TerminalNodeFeature;\n headerAccessory?: TerminalHeaderAccessoryRenderer;\n onCloseRequest?: () => void;\n sessionId?: string | null;\n}\n\nexport interface TerminalCloseGuardDialogProps {\n feature: TerminalNodeFeature;\n leaderCommand?: string | null;\n onCancel: () => void;\n onConfirm: () => void;\n open: boolean;\n}\n\nexport function TerminalNode({\n children,\n controllerLeaseRetainedExternally = false,\n externalState = null,\n feature,\n headerAccessory,\n nodeId,\n onFocusRequest,\n onPreviewChange,\n sessionId,\n showHeader = true\n}: TerminalNodeProps) {\n const resolvedSessionId = sessionId ?? externalState?.sessionId ?? null;\n const status = externalState?.status ?? \"created\";\n\n return (\n <section\n className=\"workspace-terminal\"\n data-terminal-node={nodeId}\n data-terminal-session-id={resolvedSessionId ?? undefined}\n onClick={onFocusRequest}\n >\n {showHeader ? (\n <TerminalNodeHeader\n externalState={externalState}\n feature={feature}\n headerAccessory={headerAccessory}\n sessionId={resolvedSessionId}\n />\n ) : null}\n <div className=\"workspace-terminal__body\">\n {children ??\n (resolvedSessionId ? (\n <TerminalSurface\n controllerLeaseRetainedExternally={\n controllerLeaseRetainedExternally\n }\n externalState={externalState}\n feature={feature}\n nodeId={nodeId}\n onPreviewChange={onPreviewChange}\n sessionId={resolvedSessionId}\n status={status}\n />\n ) : (\n <div className=\"workspace-terminal__placeholder\">\n {feature.i18n.t(\"emptySession\")}\n </div>\n ))}\n </div>\n </section>\n );\n}\n\nexport function TerminalNodeHeader({\n className,\n defaultActions,\n externalState = null,\n feature,\n headerAccessory,\n onCloseRequest,\n sessionId,\n ...headerProps\n}: TerminalNodeHeaderProps) {\n const status = externalState?.status ?? \"created\";\n const statusLabel = resolveTerminalStatusLabel(feature, status);\n const resolvedSessionId = sessionId ?? externalState?.sessionId ?? null;\n const hasDefaultActions = hasTerminalHeaderDefaultActions(defaultActions);\n const [pendingCloseGuard, setPendingCloseGuard] =\n useState<TerminalCloseGuardResult | null>(null);\n const [closeError, setCloseError] = useState<string | null>(null);\n const closeDiagnostics = resolvedSessionId\n ? createTerminalCloseDiagnostics({\n diagnostics: feature.diagnostics,\n sessionId: resolvedSessionId\n })\n : null;\n\n const closeTerminal = async (skipConfirmation: boolean) => {\n if (\n !resolvedSessionId ||\n isTerminalSessionEndedStatus(externalState?.status ?? \"created\")\n ) {\n onCloseRequest?.();\n return;\n }\n\n setCloseError(null);\n try {\n if (!skipConfirmation) {\n closeDiagnostics?.requested();\n const guard = await feature.closeGuard.check({\n sessionId: resolvedSessionId\n });\n if (guard.requiresConfirmation) {\n setPendingCloseGuard(guard);\n return;\n }\n }\n\n await feature.launchService.terminate({ sessionId: resolvedSessionId });\n closeDiagnostics?.confirmed();\n setPendingCloseGuard(null);\n onCloseRequest?.();\n } catch (error) {\n setCloseError(errorMessage(error));\n }\n };\n\n return (\n <header\n {...headerProps}\n className={joinClassName(\"workspace-terminal__header\", className)}\n >\n <div className=\"workspace-terminal__header-main\">\n <span className=\"workspace-terminal__title\">\n {externalState?.title?.trim() || feature.i18n.t(\"title\")}\n </span>\n <Badge className=\"workspace-terminal__status-tag\" variant=\"default\">\n <StatusDot\n pulse={status === \"running\" || status === \"starting\"}\n size=\"xs\"\n tone={resolveTerminalStatusTone(status)}\n />\n {statusLabel}\n </Badge>\n </div>\n {headerAccessory?.({\n externalState,\n sessionId: resolvedSessionId\n })}\n <div\n className=\"workspace-terminal__actions\"\n onDoubleClick={(event) => {\n event.stopPropagation();\n }}\n onPointerDown={(event) => {\n event.stopPropagation();\n }}\n >\n {defaultActions}\n {onCloseRequest && !hasDefaultActions ? (\n <button\n aria-label={feature.i18n.t(\"actions.close\")}\n className=\"workspace-terminal__icon-button\"\n onClick={() => {\n void closeTerminal(false);\n }}\n onPointerDown={(event) => {\n event.stopPropagation();\n }}\n type=\"button\"\n >\n x\n </button>\n ) : null}\n </div>\n <TerminalCloseGuardDialog\n feature={feature}\n leaderCommand={pendingCloseGuard?.leaderCommand}\n onCancel={() => setPendingCloseGuard(null)}\n onConfirm={() => {\n void closeTerminal(true);\n }}\n open={Boolean(pendingCloseGuard)}\n />\n {closeError ? (\n <div className=\"workspace-terminal__close-error\" role=\"status\">\n {closeError}\n </div>\n ) : null}\n </header>\n );\n}\n\nexport function TerminalCloseGuardDialog({\n feature,\n leaderCommand,\n onCancel,\n onConfirm,\n open\n}: TerminalCloseGuardDialogProps) {\n if (!open) {\n return null;\n }\n\n return (\n <div className=\"workspace-terminal__close-guard\" role=\"alertdialog\">\n <h2>{feature.i18n.t(\"closeGuard.title\")}</h2>\n <p>{feature.i18n.t(\"closeGuard.description\")}</p>\n {leaderCommand ? <code>{leaderCommand}</code> : null}\n <div className=\"workspace-terminal__close-guard-actions\">\n <button onClick={() => onCancel()} type=\"button\">\n {feature.i18n.t(\"closeGuard.cancel\")}\n </button>\n <button onClick={() => onConfirm()} type=\"button\">\n {feature.i18n.t(\"closeGuard.confirm\")}\n </button>\n </div>\n </div>\n );\n}\n\nfunction resolveTerminalStatusLabel(\n feature: TerminalNodeFeature,\n status: TerminalSessionStatus\n): string {\n return feature.i18n.t(`status.${status}`);\n}\n\nfunction resolveTerminalStatusTone(\n status: TerminalSessionStatus\n): \"amber\" | \"blue\" | \"green\" | \"neutral\" | \"red\" {\n switch (status) {\n case \"running\":\n case \"starting\":\n return \"blue\";\n case \"exited\":\n return \"green\";\n case \"failed\":\n return \"red\";\n case \"detached\":\n return \"amber\";\n case \"created\":\n return \"neutral\";\n }\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction joinClassName(...values: Array<string | undefined>): string {\n return values.filter(Boolean).join(\" \");\n}\n","import type { ReactNode } from \"react\";\n\nexport function hasTerminalHeaderDefaultActions(\n defaultActions: ReactNode\n): boolean {\n return defaultActions !== undefined && defaultActions !== null;\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n TerminalNodeExternalState,\n TerminalPreviewChangeHandler,\n TerminalSessionStatus\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport { createTerminalSurfaceDiagnostics } from \"../core/sessionDiagnostics.ts\";\nimport { createTerminalSurfaceRuntime } from \"./terminalSurfaceRuntime.ts\";\nimport { isTerminalFindShortcut } from \"./terminalFindShortcut.ts\";\nimport { useTerminalFindController } from \"./useTerminalFindController.ts\";\nimport { useTerminalSessionController } from \"./useTerminalSessionController.ts\";\n\nexport interface TerminalSurfaceProps {\n controllerLeaseRetainedExternally?: boolean;\n externalState: TerminalNodeExternalState | null;\n feature: TerminalNodeFeature;\n nodeId: string;\n onPreviewChange?: TerminalPreviewChangeHandler;\n sessionId: string;\n status: TerminalSessionStatus;\n}\n\nexport function TerminalSurface({\n controllerLeaseRetainedExternally = false,\n externalState,\n feature,\n nodeId,\n onPreviewChange,\n sessionId,\n status\n}: TerminalSurfaceProps) {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const currentCwdRef = useRef<string | null>(externalState?.cwd ?? null);\n const featureRef = useRef(feature);\n const findInputRef = useRef<HTMLInputElement | null>(null);\n const runtimeRef = useRef<ReturnType<\n typeof createTerminalSurfaceRuntime\n > | null>(null);\n const [interactionError, setInteractionError] = useState<string | null>(null);\n const { controller, state } = useTerminalSessionController({\n feature,\n nodeId,\n retainLease: !controllerLeaseRetainedExternally,\n sessionId\n });\n const find = useTerminalFindController({\n getRuntime: () => runtimeRef.current\n });\n const theme = useMemo(\n () =>\n feature.resolveTheme({\n runtimeKind: externalState?.runtimeKind ?? \"local\",\n sessionId,\n status\n }),\n [externalState?.runtimeKind, feature, sessionId, status]\n );\n const surfaceDiagnostics = useMemo(\n () =>\n createTerminalSurfaceDiagnostics({\n diagnostics: feature.diagnostics,\n nodeId,\n sessionId\n }),\n [feature.diagnostics, nodeId, sessionId]\n );\n const surfaceError = interactionError ?? state.surfaceError;\n\n useEffect(() => {\n currentCwdRef.current = externalState?.cwd ?? null;\n }, [externalState?.cwd]);\n\n useEffect(() => {\n featureRef.current = feature;\n }, [feature]);\n\n useEffect(() => {\n if (!find.state.open) {\n return;\n }\n const input = findInputRef.current;\n if (!input) {\n return;\n }\n input.focus();\n input.select();\n }, [find.state.open]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n surfaceDiagnostics.mount();\n setInteractionError(null);\n\n const runtime = createTerminalSurfaceRuntime({\n container,\n diagnostics: surfaceDiagnostics,\n feature: featureRef.current,\n getCwd: () => currentCwdRef.current,\n nodeId,\n onResize: ({ cols, rows }) => {\n surfaceDiagnostics.resize({ cols, rows });\n void controller.resize({ cols, rows });\n },\n onPreviewChange,\n onUserInput: (data, encoding) => {\n controller.write(data, encoding);\n },\n sessionId,\n theme\n });\n runtimeRef.current = runtime;\n runtime.syncOutput(state.rawOutput, state.contentEpoch);\n runtime.focus();\n\n return () => {\n surfaceDiagnostics.dispose();\n runtime.dispose();\n if (runtimeRef.current === runtime) {\n runtimeRef.current = null;\n }\n };\n }, [controller, nodeId, sessionId, surfaceDiagnostics]);\n\n useEffect(() => {\n runtimeRef.current?.setTheme(theme);\n }, [theme]);\n\n useEffect(() => {\n runtimeRef.current?.syncOutput(state.rawOutput, state.contentEpoch);\n }, [state.contentEpoch, state.rawOutput]);\n\n const writeInput = (data: string) => {\n controller.write(data);\n };\n\n return (\n <div\n className=\"workspace-terminal__surface-shell\"\n onKeyDownCapture={(event) => {\n if (!isTerminalFindShortcut(event)) {\n if (event.key === \"Escape\" && find.state.open) {\n find.actions.close();\n runtimeRef.current?.focus();\n }\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n find.actions.open();\n }}\n onDragOver={(event) => {\n if (feature.dropInput) {\n event.preventDefault();\n }\n }}\n onDrop={(event) => {\n if (!feature.dropInput) {\n return;\n }\n event.preventDefault();\n void Promise.resolve(\n feature.dropInput({\n cwd: externalState?.cwd ?? null,\n dataTransfer: event.dataTransfer,\n sessionId\n })\n )\n .then((input) => {\n if (input) {\n writeInput(input);\n }\n })\n .catch((error: unknown) => setInteractionError(errorMessage(error)));\n }}\n >\n {find.state.open ? (\n <form\n className=\"workspace-terminal__find\"\n onSubmit={(event) => {\n event.preventDefault();\n find.actions.onSubmit();\n }}\n >\n <input\n aria-label={feature.i18n.t(\"findPlaceholder\")}\n ref={findInputRef}\n onChange={(event) => {\n find.actions.onQueryChange(event.currentTarget.value);\n }}\n placeholder={feature.i18n.t(\"findPlaceholder\")}\n type=\"search\"\n value={find.state.query}\n />\n <button\n className=\"workspace-terminal__find-toggle\"\n aria-label={feature.i18n.t(\"actions.caseSensitive\")}\n aria-pressed={find.state.caseSensitive}\n onClick={() => find.actions.toggleCaseSensitive()}\n type=\"button\"\n >\n Aa\n </button>\n <button\n className=\"workspace-terminal__find-toggle\"\n aria-label={feature.i18n.t(\"actions.regex\")}\n aria-pressed={find.state.regex}\n onClick={() => find.actions.toggleRegex()}\n type=\"button\"\n >\n .*\n </button>\n <button\n className=\"workspace-terminal__find-nav workspace-terminal__find-nav--previous\"\n aria-label={feature.i18n.t(\"actions.previous\")}\n onClick={() => find.actions.findPrevious()}\n type=\"button\"\n />\n <button\n className=\"workspace-terminal__find-nav workspace-terminal__find-nav--next\"\n aria-label={feature.i18n.t(\"actions.next\")}\n onClick={() => find.actions.findNext()}\n type=\"submit\"\n />\n </form>\n ) : null}\n <div\n className=\"workspace-terminal__xterm\"\n data-terminal-xterm=\"\"\n ref={containerRef}\n />\n {surfaceError ? (\n <div className=\"workspace-terminal__surface-error\" role=\"status\">\n {surfaceError}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import { FitAddon } from \"@xterm/addon-fit\";\nimport { SearchAddon } from \"@xterm/addon-search\";\nimport { SerializeAddon } from \"@xterm/addon-serialize\";\nimport { WebLinksAddon } from \"@xterm/addon-web-links\";\nimport { Terminal, type IBufferCell, type IBufferLine } from \"@xterm/xterm\";\nimport type {\n TerminalPreviewChangeHandler,\n TerminalPreviewLine,\n TerminalPreviewSegment,\n TerminalPreviewSegmentStyle,\n TerminalPreviewSnapshot,\n TerminalTheme,\n TerminalWriteEncoding\n} from \"../contracts/index.ts\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport { createTerminalScreenStateCache } from \"../core/index.ts\";\nimport type { TerminalSurfaceDiagnostics } from \"../core/sessionDiagnostics.ts\";\nimport { createTerminalFileLinkProvider } from \"./terminalFileLinkProvider.ts\";\nimport { resolveTerminalSurfaceOutputPlan } from \"./terminalSurfaceOutputPlan.ts\";\nimport { resolveTerminalSurfaceResizePlan } from \"./terminalSurfaceResizePlan.ts\";\nimport { resolveTerminalSurfaceScreenCachePlan } from \"./terminalSurfaceScreenCachePlan.ts\";\nimport { drainTerminalWriteBatch } from \"./terminalWriteBatch.ts\";\nimport type { TerminalFindRuntime } from \"./useTerminalFindController.ts\";\n\nconst terminalScreenStateCache = createTerminalScreenStateCache();\nconst terminalPreviewMaxRows = 24;\nconst terminalPreviewMaxCols = 160;\nconst terminalPreviewAnsiColors = [\n \"#2e3436\",\n \"#cc0000\",\n \"#4e9a06\",\n \"#c4a000\",\n \"#3465a4\",\n \"#75507b\",\n \"#06989a\",\n \"#d3d7cf\",\n \"#555753\",\n \"#ef2929\",\n \"#8ae234\",\n \"#fce94f\",\n \"#729fcf\",\n \"#ad7fa8\",\n \"#34e2e2\",\n \"#eeeeec\"\n] as const;\nconst terminalPreviewColorSteps = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n\nexport interface TerminalSurfaceRuntime extends TerminalFindRuntime {\n dispose(): void;\n focus(): void;\n setTheme(theme: TerminalTheme): void;\n syncOutput(rawOutput: string, contentEpoch: number): void;\n}\n\nexport function createTerminalSurfaceRuntime(input: {\n container: HTMLElement;\n diagnostics: TerminalSurfaceDiagnostics;\n feature: TerminalNodeFeature;\n getCwd: () => string | null;\n nodeId: string;\n onResize: (size: { cols: number; rows: number }) => void;\n onPreviewChange?: TerminalPreviewChangeHandler;\n onUserInput: (data: string, encoding?: TerminalWriteEncoding) => void;\n sessionId: string;\n theme: TerminalTheme;\n}): TerminalSurfaceRuntime {\n let contentEpoch = 0;\n let committedRawOutput = \"\";\n let initialLayoutFrame: number | null = null;\n let initialLayoutTimeout: number | null = null;\n let lastSize: { cols: number; rows: number } | null = null;\n let pendingRevealFinalizeFrame: number | null = null;\n let pendingRevealStartFrame: number | null = null;\n let pendingRevealWrite: {\n bytes: number;\n mode: \"cache\" | \"replace\";\n remainingChunkCount: number;\n } | null = null;\n let pendingWriteFrame: number | null = null;\n let pendingWriteChunks: string[] = [];\n let pendingRenderedWrite: {\n bytes: number;\n mode: \"append\" | \"cache\" | \"replace\";\n remainingChunkCount: number;\n } | null = null;\n let lastPreviewRevision: string | null = null;\n\n const terminal = new Terminal({\n allowProposedApi: false,\n convertEol: true,\n cursorBlink: true,\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontSize: 13,\n scrollback: input.feature.limits.maxScrollbackLines,\n theme: resolveXtermTheme(input.theme)\n });\n const fitAddon = new FitAddon();\n const searchAddon = new SearchAddon();\n const serializeAddon = new SerializeAddon();\n const webLinksAddon = new WebLinksAddon((_event, uri) => {\n void input.feature.linkHandler?.open({ url: uri });\n });\n terminal.loadAddon(fitAddon);\n terminal.loadAddon(searchAddon);\n terminal.loadAddon(serializeAddon);\n terminal.loadAddon(webLinksAddon);\n const fileLinkDisposable = terminal.registerLinkProvider(\n createTerminalFileLinkProvider({\n feature: input.feature,\n getCwd: input.getCwd,\n terminal\n })\n );\n terminal.open(input.container);\n\n const dataSubscription = terminal.onData((data) => {\n input.onUserInput(data);\n });\n const binarySubscription = terminal.onBinary((data) => {\n input.onUserInput(data, \"binary\");\n });\n const writeParsedSubscription =\n typeof terminal.onWriteParsed === \"function\"\n ? terminal.onWriteParsed(() => {\n if (!pendingRenderedWrite) {\n refreshTerminalSurface();\n return;\n }\n const renderedWrite = pendingRenderedWrite;\n pendingRenderedWrite = null;\n if (\n renderedWrite.mode === \"cache\" ||\n renderedWrite.mode === \"replace\"\n ) {\n scheduleHydratedReveal({\n bytes: renderedWrite.bytes,\n mode: renderedWrite.mode,\n remainingChunkCount: renderedWrite.remainingChunkCount\n });\n return;\n }\n refreshTerminalSurface();\n logSurfaceWrite(\n renderedWrite.mode,\n renderedWrite.bytes,\n renderedWrite.remainingChunkCount\n );\n })\n : { dispose: () => undefined };\n\n const resizeTerminal = () => {\n try {\n fitAddon.fit();\n } catch {\n return;\n }\n const plan = resolveTerminalSurfaceResizePlan({\n lastSize,\n nextSize: { cols: terminal.cols, rows: terminal.rows }\n });\n if (!plan) {\n return;\n }\n lastSize = plan;\n input.onResize(plan);\n };\n\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(() => resizeTerminal());\n resizeObserver?.observe(input.container);\n scheduleInitialLayoutSync();\n\n const cached = terminalScreenStateCache.get(input.nodeId, input.sessionId);\n if (cached) {\n terminal.write(cached.serialized, () => {\n queueRenderedWrite(\"cache\", cached.serialized.length, 0);\n });\n committedRawOutput = cached.rawSnapshot;\n }\n\n return {\n dispose() {\n resizeObserver?.disconnect();\n dataSubscription.dispose();\n binarySubscription.dispose();\n writeParsedSubscription.dispose();\n fileLinkDisposable.dispose();\n clearInitialLayoutSync();\n clearPendingReveal();\n const hasPendingWrites =\n pendingWriteFrame !== null || pendingWriteChunks.length > 0;\n const cachePlan = resolveTerminalSurfaceScreenCachePlan({\n hasPendingWrites,\n rawSnapshot: committedRawOutput,\n serialized: hasPendingWrites ? \"\" : serializeAddon.serialize()\n });\n if (cachePlan.action === \"save\") {\n terminalScreenStateCache.set(input.nodeId, {\n cols: terminal.cols,\n rawSnapshot: cachePlan.rawSnapshot,\n rows: terminal.rows,\n serialized: cachePlan.serialized,\n sessionId: input.sessionId\n });\n } else if (cachePlan.action === \"remove\") {\n terminalScreenStateCache.remove(input.nodeId, input.sessionId);\n }\n clearPendingWrites();\n input.onPreviewChange?.({\n nodeId: input.nodeId,\n sessionId: input.sessionId,\n snapshot: null\n });\n terminal.dispose();\n },\n findNext(query, options) {\n searchAddon.findNext(query, options);\n },\n findPrevious(query, options) {\n searchAddon.findPrevious(query, options);\n },\n focus() {\n terminal.focus();\n resizeTerminal();\n },\n setTheme(theme) {\n terminal.options.theme = resolveXtermTheme(theme);\n emitTerminalPreviewSnapshot();\n },\n syncOutput(rawOutput, nextContentEpoch) {\n const plan = resolveTerminalSurfaceOutputPlan({\n committedRawOutput,\n contentEpoch,\n nextContentEpoch,\n rawOutput\n });\n input.diagnostics.outputSync({\n contentEpoch: nextContentEpoch,\n nextCommittedBytes:\n plan?.nextCommittedRawOutput.length ?? committedRawOutput.length,\n plan: resolveOutputSyncPlan(plan),\n previousCommittedBytes: committedRawOutput.length,\n rawBytes: rawOutput.length,\n writeBytes: plan?.write?.length ?? 0\n });\n if (!plan) {\n return;\n }\n contentEpoch = plan.nextContentEpoch;\n if (plan.reset && plan.write) {\n replaceTerminalView(plan.write, { reset: true });\n } else if (plan.reset) {\n resetTerminalView();\n }\n if (plan.write && !plan.reset) {\n writeToTerminal(plan.write);\n }\n committedRawOutput = plan.nextCommittedRawOutput;\n }\n };\n\n function clearPendingWrites() {\n pendingWriteChunks = [];\n if (pendingWriteFrame === null) {\n return;\n }\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(pendingWriteFrame);\n } else {\n clearTimeout(pendingWriteFrame);\n }\n pendingWriteFrame = null;\n }\n\n function clearInitialLayoutSync() {\n if (initialLayoutFrame !== null) {\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(initialLayoutFrame);\n } else {\n clearTimeout(initialLayoutFrame);\n }\n initialLayoutFrame = null;\n }\n if (initialLayoutTimeout !== null) {\n clearTimeout(initialLayoutTimeout);\n initialLayoutTimeout = null;\n }\n }\n\n function clearPendingReveal() {\n if (pendingRevealStartFrame !== null) {\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(pendingRevealStartFrame);\n } else {\n clearTimeout(pendingRevealStartFrame);\n }\n pendingRevealStartFrame = null;\n }\n if (pendingRevealFinalizeFrame !== null) {\n if (typeof cancelAnimationFrame === \"function\") {\n cancelAnimationFrame(pendingRevealFinalizeFrame);\n } else {\n clearTimeout(pendingRevealFinalizeFrame);\n }\n pendingRevealFinalizeFrame = null;\n }\n pendingRevealWrite = null;\n }\n\n function flushPendingWrites() {\n pendingWriteFrame = null;\n const batch = drainTerminalWriteBatch(\n pendingWriteChunks,\n input.feature.limits.maxWriteBatchBytes\n );\n pendingWriteChunks = batch.remainingChunks;\n\n if (!batch.nextWrite) {\n return;\n }\n terminal.write(batch.nextWrite, () => {\n queueRenderedWrite(\n \"append\",\n batch.nextWrite.length,\n pendingWriteChunks.length\n );\n if (pendingWriteChunks.length > 0) {\n requestWriteFlush();\n }\n });\n }\n\n function requestWriteFlush() {\n if (pendingWriteFrame !== null) {\n return;\n }\n if (typeof requestAnimationFrame === \"function\") {\n pendingWriteFrame = requestAnimationFrame(flushPendingWrites);\n return;\n }\n pendingWriteFrame = window.setTimeout(flushPendingWrites, 0);\n }\n\n function resetTerminalView() {\n clearPendingReveal();\n clearPendingWrites();\n terminal.reset();\n refreshTerminalSurface();\n logSurfaceWrite(\"reset\", 0, 0);\n }\n\n function replaceTerminalView(\n data: string,\n options?: {\n reset?: boolean;\n }\n ) {\n const transformed =\n input.feature.outputTransform?.({\n data,\n sessionId: input.sessionId\n }) ?? data;\n if (transformed == null || transformed === \"\") {\n return;\n }\n clearPendingReveal();\n clearPendingWrites();\n if (options?.reset) {\n terminal.reset();\n }\n terminal.write(transformed, () => {\n queueRenderedWrite(\"replace\", transformed.length, 0);\n });\n }\n\n function refreshTerminalSurface() {\n if (terminal.rows <= 0) {\n return;\n }\n terminal.refresh(0, terminal.rows - 1);\n emitTerminalPreviewSnapshot();\n }\n\n function emitTerminalPreviewSnapshot() {\n if (!input.onPreviewChange || terminal.cols <= 0 || terminal.rows <= 0) {\n return;\n }\n const snapshot = createTerminalPreviewSnapshot(terminal);\n if (snapshot.revision === lastPreviewRevision) {\n return;\n }\n lastPreviewRevision = snapshot.revision;\n input.onPreviewChange({\n nodeId: input.nodeId,\n sessionId: input.sessionId,\n snapshot\n });\n }\n\n function scheduleInitialLayoutSync() {\n resizeTerminal();\n if (typeof requestAnimationFrame === \"function\") {\n initialLayoutFrame = requestAnimationFrame(() => {\n initialLayoutFrame = null;\n resizeTerminal();\n refreshTerminalSurface();\n });\n } else {\n initialLayoutFrame = window.setTimeout(() => {\n initialLayoutFrame = null;\n resizeTerminal();\n refreshTerminalSurface();\n }, 0);\n }\n initialLayoutTimeout = window.setTimeout(() => {\n initialLayoutTimeout = null;\n resizeTerminal();\n refreshTerminalSurface();\n }, 32);\n }\n\n function scheduleTerminalWrite(data: string) {\n pendingWriteChunks.push(data);\n requestWriteFlush();\n }\n\n function writeToTerminal(data: string) {\n const transformed =\n input.feature.outputTransform?.({\n data,\n sessionId: input.sessionId\n }) ?? data;\n if (transformed == null || transformed === \"\") {\n return;\n }\n scheduleTerminalWrite(transformed);\n }\n\n function queueRenderedWrite(\n mode: \"append\" | \"cache\" | \"replace\",\n bytes: number,\n remainingChunkCount: number\n ) {\n if (pendingRenderedWrite && pendingRenderedWrite.mode === mode) {\n pendingRenderedWrite = {\n bytes: pendingRenderedWrite.bytes + bytes,\n mode,\n remainingChunkCount\n };\n return;\n }\n pendingRenderedWrite = {\n bytes,\n mode,\n remainingChunkCount\n };\n }\n\n function scheduleHydratedReveal(write: {\n bytes: number;\n mode: \"cache\" | \"replace\";\n remainingChunkCount: number;\n }) {\n if (pendingRevealWrite) {\n pendingRevealWrite = {\n bytes: pendingRevealWrite.bytes + write.bytes,\n mode: write.mode,\n remainingChunkCount: write.remainingChunkCount\n };\n } else {\n pendingRevealWrite = write;\n }\n if (\n pendingRevealStartFrame !== null ||\n pendingRevealFinalizeFrame !== null\n ) {\n return;\n }\n pendingRevealStartFrame = requestTerminalFrame(() => {\n pendingRevealStartFrame = null;\n resizeTerminal();\n pendingRevealFinalizeFrame = requestTerminalFrame(() => {\n pendingRevealFinalizeFrame = null;\n refreshTerminalSurface();\n const revealWrite = pendingRevealWrite;\n pendingRevealWrite = null;\n if (!revealWrite) {\n return;\n }\n logSurfaceWrite(\n revealWrite.mode,\n revealWrite.bytes,\n revealWrite.remainingChunkCount\n );\n });\n });\n }\n\n function logSurfaceWrite(\n mode: \"append\" | \"cache\" | \"replace\" | \"reset\",\n bytes: number,\n remainingChunkCount: number\n ) {\n const buffer = terminal.buffer.active;\n const xtermElement =\n input.container.querySelector(\".xterm\") instanceof HTMLElement\n ? (input.container.querySelector(\".xterm\") as HTMLElement)\n : null;\n const screenElement =\n input.container.querySelector(\".xterm-screen\") instanceof HTMLElement\n ? (input.container.querySelector(\".xterm-screen\") as HTMLElement)\n : null;\n const helperElement =\n input.container.querySelector(\".xterm-helpers\") instanceof HTMLElement\n ? (input.container.querySelector(\".xterm-helpers\") as HTMLElement)\n : null;\n const rowContainerElement =\n input.container.querySelector(\".xterm-rows\") instanceof HTMLElement\n ? (input.container.querySelector(\".xterm-rows\") as HTMLElement)\n : null;\n const firstCanvas =\n screenElement?.querySelector(\"canvas\") instanceof HTMLCanvasElement\n ? (screenElement.querySelector(\"canvas\") as HTMLCanvasElement)\n : null;\n const firstLine = buffer.getLine(0)?.translateToString(true) ?? \"\";\n const cursorLine =\n buffer.getLine(buffer.cursorY)?.translateToString(true) ?? \"\";\n const xtermStyle = xtermElement\n ? window.getComputedStyle(xtermElement)\n : null;\n const screenStyle = screenElement\n ? window.getComputedStyle(screenElement)\n : null;\n const renderDimensions = resolveXtermRenderDimensions(terminal);\n input.diagnostics.outputWritten({\n bufferCursorX: buffer.cursorX,\n bufferCursorY: buffer.cursorY,\n bufferLength: buffer.length,\n bytes,\n canvasClientHeight: firstCanvas?.clientHeight ?? 0,\n canvasClientWidth: firstCanvas?.clientWidth ?? 0,\n canvasCount: screenElement?.querySelectorAll(\"canvas\").length ?? 0,\n cols: terminal.cols,\n containerClientHeight: input.container.clientHeight,\n containerClientWidth: input.container.clientWidth,\n cursorLinePreview: previewTerminalLine(cursorLine),\n firstLinePreview: previewTerminalLine(firstLine),\n helperChildCount: helperElement?.childElementCount ?? 0,\n mode,\n remainingChunkCount,\n renderDimensionsReady: renderDimensions !== undefined,\n rowContainerChildCount: rowContainerElement?.childElementCount ?? 0,\n rowContainerTextPreview: previewTerminalLine(\n rowContainerElement?.textContent ?? \"\"\n ),\n rows: terminal.rows,\n screenChildCount: screenElement?.childElementCount ?? 0,\n screenClientHeight: screenElement?.clientHeight ?? 0,\n screenClientWidth: screenElement?.clientWidth ?? 0,\n screenDisplay: screenStyle?.display ?? \"\",\n screenOpacity: screenStyle?.opacity ?? \"\",\n screenVisibility: screenStyle?.visibility ?? \"\",\n serializedBytes: serializeAddon.serialize().length,\n xtermClientHeight: xtermElement?.clientHeight ?? 0,\n xtermClientWidth: xtermElement?.clientWidth ?? 0,\n xtermDisplay: xtermStyle?.display ?? \"\",\n xtermOpacity: xtermStyle?.opacity ?? \"\",\n xtermVisibility: xtermStyle?.visibility ?? \"\"\n });\n }\n}\n\nfunction requestTerminalFrame(callback: () => void) {\n if (typeof requestAnimationFrame === \"function\") {\n return requestAnimationFrame(callback);\n }\n return window.setTimeout(callback, 0);\n}\n\nfunction resolveOutputSyncPlan(\n plan: ReturnType<typeof resolveTerminalSurfaceOutputPlan>\n): \"append\" | \"replace\" | \"reset\" | \"skip\" {\n if (!plan) {\n return \"skip\";\n }\n if (plan.reset && plan.write) {\n return \"replace\";\n }\n if (plan.reset) {\n return \"reset\";\n }\n return \"append\";\n}\n\nfunction resolveXtermRenderDimensions(terminal: Terminal): unknown {\n const core: unknown = Reflect.get(terminal, \"_core\");\n if (core == null || typeof core !== \"object\") {\n return undefined;\n }\n const renderService: unknown = Reflect.get(core, \"_renderService\");\n if (renderService == null || typeof renderService !== \"object\") {\n return undefined;\n }\n return Reflect.get(renderService, \"dimensions\");\n}\n\nfunction previewTerminalLine(value: string, maxChars = 80) {\n return value\n .slice(0, maxChars)\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"\\r\", \"\\\\r\")\n .replaceAll(\"\\n\", \"\\\\n\");\n}\n\nfunction resolveXtermTheme(theme: TerminalTheme) {\n return {\n background: theme.background,\n cursor: theme.cursor,\n foreground: theme.foreground,\n selectionBackground: theme.selectionBackground\n };\n}\n\nfunction createTerminalPreviewSnapshot(\n terminal: Terminal\n): TerminalPreviewSnapshot {\n const buffer = terminal.buffer.active;\n const rowCount = Math.min(terminal.rows, terminalPreviewMaxRows);\n const colCount = Math.min(terminal.cols, terminalPreviewMaxCols);\n const viewportY = Math.max(0, buffer.viewportY);\n const theme = terminal.options.theme as TerminalTheme;\n const lines: TerminalPreviewLine[] = [];\n const scratchCell = buffer.getNullCell();\n\n for (let index = 0; index < rowCount; index += 1) {\n lines.push(\n createTerminalPreviewLine({\n colCount,\n line: buffer.getLine(viewportY + index) ?? null,\n scratchCell,\n theme\n })\n );\n }\n\n const revision = [\n terminal.cols,\n terminal.rows,\n buffer.cursorX,\n buffer.cursorY,\n viewportY,\n JSON.stringify(lines)\n ].join(\"\\n\");\n\n return {\n cols: terminal.cols,\n cursorX: buffer.cursorX,\n cursorY: buffer.cursorY,\n lines,\n revision,\n rows: terminal.rows,\n updatedAtUnixMs: Date.now()\n };\n}\n\nfunction createTerminalPreviewLine(input: {\n colCount: number;\n line: IBufferLine | null;\n scratchCell: IBufferCell;\n theme: TerminalTheme;\n}): TerminalPreviewLine {\n const line = input.line;\n if (!line || input.colCount <= 0) {\n return { segments: [] };\n }\n\n const segments: TerminalPreviewSegment[] = [];\n let currentStyle: TerminalPreviewSegmentStyle | undefined;\n let currentText = \"\";\n const lastColumn = resolveTerminalPreviewLastColumn({\n colCount: input.colCount,\n line,\n scratchCell: input.scratchCell,\n theme: input.theme\n });\n\n for (let column = 0; column < lastColumn; column += 1) {\n const cell = line.getCell(column, input.scratchCell);\n if (!cell) {\n continue;\n }\n const width = cell.getWidth();\n if (width === 0) {\n continue;\n }\n const style = resolveTerminalPreviewCellStyle(cell, input.theme);\n const text = cell.isInvisible()\n ? \" \".repeat(Math.max(1, width))\n : cell.getChars() || \" \".repeat(Math.max(1, width));\n\n if (currentText && areTerminalPreviewStylesEqual(currentStyle, style)) {\n currentText += text;\n continue;\n }\n if (currentText) {\n segments.push(createTerminalPreviewSegment(currentText, currentStyle));\n }\n currentStyle = style;\n currentText = text;\n }\n\n if (currentText) {\n segments.push(createTerminalPreviewSegment(currentText, currentStyle));\n }\n\n return { segments };\n}\n\nfunction createTerminalPreviewSegment(\n text: string,\n style: TerminalPreviewSegmentStyle | undefined\n): TerminalPreviewSegment {\n if (!style) {\n return { text };\n }\n return { style, text };\n}\n\nfunction resolveTerminalPreviewLastColumn(input: {\n colCount: number;\n line: IBufferLine;\n scratchCell: IBufferCell;\n theme: TerminalTheme;\n}) {\n for (let column = input.colCount - 1; column >= 0; column -= 1) {\n const cell = input.line.getCell(column, input.scratchCell);\n if (!cell || cell.getWidth() === 0) {\n continue;\n }\n if (!isTerminalPreviewCellEmptyDefault(cell, input.theme)) {\n return column + 1;\n }\n }\n return 0;\n}\n\nfunction isTerminalPreviewCellEmptyDefault(\n cell: IBufferCell,\n theme: TerminalTheme\n) {\n const style = resolveTerminalPreviewCellStyle(cell, theme);\n return (cell.getChars() || \" \") === \" \" && !style;\n}\n\nfunction resolveTerminalPreviewCellStyle(\n cell: IBufferCell,\n theme: TerminalTheme\n): TerminalPreviewSegmentStyle | undefined {\n const style: TerminalPreviewSegmentStyle = {};\n const inverse = Boolean(cell.isInverse());\n const foreground = resolveTerminalPreviewColor(cell, \"foreground\", theme);\n const background = resolveTerminalPreviewColor(cell, \"background\", theme);\n const color = inverse ? (background ?? theme.background) : foreground;\n const backgroundColor = inverse\n ? (foreground ?? theme.foreground)\n : background;\n\n if (color) {\n style.color = color;\n }\n if (backgroundColor) {\n style.background = backgroundColor;\n }\n if (cell.isBold()) {\n style.bold = true;\n }\n if (cell.isDim()) {\n style.dim = true;\n }\n if (cell.isItalic()) {\n style.italic = true;\n }\n if (cell.isUnderline()) {\n style.underline = true;\n }\n if (cell.isStrikethrough()) {\n style.strikethrough = true;\n }\n if (cell.isOverline()) {\n style.overline = true;\n }\n\n return Object.keys(style).length > 0 ? style : undefined;\n}\n\nfunction resolveTerminalPreviewColor(\n cell: IBufferCell,\n channel: \"background\" | \"foreground\",\n theme: TerminalTheme\n) {\n const isDefault =\n channel === \"foreground\" ? cell.isFgDefault() : cell.isBgDefault();\n if (isDefault) {\n return undefined;\n }\n const isRgb = channel === \"foreground\" ? cell.isFgRGB() : cell.isBgRGB();\n const isPalette =\n channel === \"foreground\" ? cell.isFgPalette() : cell.isBgPalette();\n const rawColor =\n channel === \"foreground\" ? cell.getFgColor() : cell.getBgColor();\n\n if (isRgb) {\n return terminalPreviewColorToHex(rawColor);\n }\n if (!isPalette) {\n return undefined;\n }\n\n const paletteIndex =\n channel === \"foreground\" && cell.isBold() && rawColor >= 0 && rawColor <= 7\n ? rawColor + 8\n : rawColor;\n const paletteColor = resolveTerminalPreviewPaletteColor(paletteIndex);\n if (paletteColor) {\n return paletteColor;\n }\n return channel === \"foreground\" ? theme.foreground : theme.background;\n}\n\nfunction resolveTerminalPreviewPaletteColor(index: number) {\n if (index >= 0 && index < terminalPreviewAnsiColors.length) {\n return terminalPreviewAnsiColors[index];\n }\n if (index >= 16 && index <= 231) {\n const offset = index - 16;\n const red = terminalPreviewColorSteps[Math.floor(offset / 36) % 6] ?? 0;\n const green = terminalPreviewColorSteps[Math.floor(offset / 6) % 6] ?? 0;\n const blue = terminalPreviewColorSteps[offset % 6] ?? 0;\n return terminalPreviewRgbToHex(red, green, blue);\n }\n if (index >= 232 && index <= 255) {\n const value = 8 + (index - 232) * 10;\n return terminalPreviewRgbToHex(value, value, value);\n }\n return undefined;\n}\n\nfunction terminalPreviewColorToHex(color: number) {\n return `#${color.toString(16).padStart(6, \"0\").slice(-6)}`;\n}\n\nfunction terminalPreviewRgbToHex(red: number, green: number, blue: number) {\n return `#${[red, green, blue]\n .map((value) => value.toString(16).padStart(2, \"0\"))\n .join(\"\")}`;\n}\n\nfunction areTerminalPreviewStylesEqual(\n left: TerminalPreviewSegmentStyle | undefined,\n right: TerminalPreviewSegmentStyle | undefined\n) {\n if (left === right) {\n return true;\n }\n if (!left || !right) {\n return false;\n }\n return (\n left.background === right.background &&\n left.bold === right.bold &&\n left.color === right.color &&\n left.dim === right.dim &&\n left.italic === right.italic &&\n left.overline === right.overline &&\n left.strikethrough === right.strikethrough &&\n left.underline === right.underline\n );\n}\n","import type { ILink, ILinkProvider, Terminal } from \"@xterm/xterm\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport {\n detectTerminalFileLinks,\n toTerminalLinkTarget\n} from \"../core/index.ts\";\n\nexport function createTerminalFileLinkProvider(input: {\n feature: TerminalNodeFeature;\n getCwd: () => string | null;\n terminal: Terminal;\n}): ILinkProvider {\n return {\n provideLinks(bufferLineNumber, callback) {\n if (!input.feature.linkHandler) {\n callback(undefined);\n return;\n }\n\n const line = input.terminal.buffer.active.getLine(bufferLineNumber - 1);\n if (!line) {\n callback(undefined);\n return;\n }\n\n const text = line.translateToString(true);\n const links = detectTerminalFileLinks(text).map<ILink>((link) => ({\n activate: () => {\n void input.feature.linkHandler?.open({\n ...toTerminalLinkTarget(link),\n cwd: input.getCwd()\n });\n },\n range: {\n end: {\n x: link.index + link.text.length,\n y: bufferLineNumber\n },\n start: {\n x: link.index + 1,\n y: bufferLineNumber\n }\n },\n text: link.text\n }));\n\n callback(links.length > 0 ? links : undefined);\n }\n };\n}\n","import { resolveTerminalScrollbackDelta } from \"../core/index.ts\";\n\nexport interface TerminalSurfaceOutputPlanInput {\n committedRawOutput: string;\n contentEpoch: number;\n nextContentEpoch: number;\n rawOutput: string;\n}\n\nexport interface TerminalSurfaceOutputPlan {\n nextCommittedRawOutput: string;\n nextContentEpoch: number;\n reset: boolean;\n write: string | null;\n}\n\nexport function resolveTerminalSurfaceOutputPlan(\n input: TerminalSurfaceOutputPlanInput\n): TerminalSurfaceOutputPlan | null {\n if (\n input.nextContentEpoch === 0 &&\n input.rawOutput.length === 0 &&\n input.committedRawOutput.length > 0\n ) {\n return null;\n }\n\n if (input.nextContentEpoch !== input.contentEpoch) {\n if (input.rawOutput === input.committedRawOutput) {\n return {\n nextCommittedRawOutput: input.committedRawOutput,\n nextContentEpoch: input.nextContentEpoch,\n reset: false,\n write: null\n };\n }\n\n return {\n nextCommittedRawOutput: input.rawOutput,\n nextContentEpoch: input.nextContentEpoch,\n reset: true,\n write: input.rawOutput || null\n };\n }\n\n if (input.rawOutput === input.committedRawOutput) {\n return null;\n }\n\n const delta = resolveTerminalScrollbackDelta(\n input.committedRawOutput,\n input.rawOutput\n );\n\n return {\n nextCommittedRawOutput: input.rawOutput,\n nextContentEpoch: input.nextContentEpoch,\n reset: !delta,\n write: delta || input.rawOutput || null\n };\n}\n","export interface TerminalSurfaceSize {\n cols: number;\n rows: number;\n}\n\nexport function resolveTerminalSurfaceResizePlan(input: {\n lastSize: TerminalSurfaceSize | null;\n nextSize: TerminalSurfaceSize;\n}): TerminalSurfaceSize | null {\n if (\n input.lastSize?.cols === input.nextSize.cols &&\n input.lastSize.rows === input.nextSize.rows\n ) {\n return null;\n }\n return input.nextSize;\n}\n","export type TerminalSurfaceScreenCachePlan =\n | { action: \"remove\" }\n | {\n action: \"save\";\n rawSnapshot: string;\n serialized: string;\n }\n | { action: \"skip\" };\n\nexport function resolveTerminalSurfaceScreenCachePlan(input: {\n hasPendingWrites: boolean;\n rawSnapshot: string;\n serialized: string;\n}): TerminalSurfaceScreenCachePlan {\n if (input.hasPendingWrites) {\n return {\n action: input.serialized ? \"skip\" : \"remove\"\n };\n }\n\n if (!input.serialized) {\n return { action: \"skip\" };\n }\n\n return {\n action: \"save\",\n rawSnapshot: input.rawSnapshot,\n serialized: input.serialized\n };\n}\n","export interface TerminalWriteBatch {\n nextWrite: string;\n remainingChunks: string[];\n}\n\nexport function drainTerminalWriteBatch(\n chunks: string[],\n maxBytes: number\n): TerminalWriteBatch {\n let remaining = maxBytes;\n let nextWrite = \"\";\n const remainingChunks = chunks.slice();\n\n while (remaining > 0 && remainingChunks.length > 0) {\n const chunk = remainingChunks.shift() ?? \"\";\n if (chunk.length <= remaining) {\n nextWrite += chunk;\n remaining -= chunk.length;\n continue;\n }\n nextWrite += chunk.slice(0, remaining);\n remainingChunks.unshift(chunk.slice(remaining));\n remaining = 0;\n }\n\n return {\n nextWrite,\n remainingChunks\n };\n}\n","export function isTerminalFindShortcut(\n event: Pick<KeyboardEvent, \"altKey\" | \"ctrlKey\" | \"key\" | \"metaKey\">\n): boolean {\n if (event.altKey) {\n return false;\n }\n\n if (!(event.metaKey || event.ctrlKey)) {\n return false;\n }\n\n return event.key.toLowerCase() === \"f\";\n}\n","import { useState } from \"react\";\n\nexport interface TerminalFindRuntime {\n findNext(\n query: string,\n options: {\n caseSensitive: boolean;\n incremental?: boolean;\n regex: boolean;\n }\n ): void;\n findPrevious(\n query: string,\n options: {\n caseSensitive: boolean;\n regex: boolean;\n }\n ): void;\n}\n\nexport interface TerminalFindController {\n actions: {\n close(): void;\n findNext(): void;\n findPrevious(): void;\n open(): void;\n onQueryChange(query: string): void;\n onSubmit(): void;\n toggleCaseSensitive(): void;\n toggleOpen(): void;\n toggleRegex(): void;\n };\n state: {\n caseSensitive: boolean;\n open: boolean;\n query: string;\n regex: boolean;\n };\n}\n\nexport function useTerminalFindController(input: {\n getRuntime: () => TerminalFindRuntime | null;\n}): TerminalFindController {\n const [open, setOpen] = useState(false);\n const [caseSensitive, setCaseSensitive] = useState(false);\n const [query, setQuery] = useState(\"\");\n const [regex, setRegex] = useState(false);\n\n const resolveFindOptions = () => ({\n caseSensitive,\n regex\n });\n\n return {\n actions: {\n close() {\n setOpen(false);\n },\n findNext() {\n input.getRuntime()?.findNext(query, resolveFindOptions());\n },\n findPrevious() {\n input.getRuntime()?.findPrevious(query, resolveFindOptions());\n },\n open() {\n setOpen(true);\n },\n onQueryChange(nextQuery) {\n setQuery(nextQuery);\n if (!nextQuery) {\n return;\n }\n input.getRuntime()?.findNext(nextQuery, {\n ...resolveFindOptions(),\n incremental: true\n });\n },\n onSubmit() {\n input.getRuntime()?.findNext(query, resolveFindOptions());\n },\n toggleCaseSensitive() {\n setCaseSensitive((enabled) => !enabled);\n },\n toggleOpen() {\n setOpen((enabled) => !enabled);\n },\n toggleRegex() {\n setRegex((enabled) => !enabled);\n }\n },\n state: {\n caseSensitive,\n open,\n query,\n regex\n }\n };\n}\n","import { useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@tutti-os/ui-react-hooks\";\nimport type { TerminalNodeFeature } from \"../core/feature.ts\";\nimport {\n acquireTerminalSessionController,\n type TerminalSessionControllerState\n} from \"../core/sessionController.ts\";\n\nexport function useTerminalSessionController(input: {\n feature: TerminalNodeFeature;\n nodeId: string;\n retainLease?: boolean;\n sessionId: string;\n}) {\n const controller = useMemo(\n () =>\n acquireTerminalSessionController({\n feature: input.feature,\n nodeId: input.nodeId,\n sessionId: input.sessionId\n }),\n [input.nodeId, input.sessionId]\n );\n\n useEffect(() => {\n if (input.retainLease === false) {\n return;\n }\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller, input.retainLease]);\n const state = useExternalStoreSnapshot<TerminalSessionControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n return {\n controller,\n state\n };\n}\n"],"mappings":"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","names":["errorMessage","useState","useEffect","useMemo","useState","useState","useMemo","useEffect","errorMessage","jsx","jsxs","useState","errorMessage"]}