Download src/bridge/bridgeStatusUtil.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 5.14 kB
-
https://huggingface.co/chenbhao/codev/resolve/afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/bridge/bridgeStatusUtil.ts
- Command line
-
hf download hf://chenbhao/codev@afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/bridge/bridgeStatusUtil.ts
-
curl -L -o bridgeStatusUtil.ts https://huggingface.co/chenbhao/codev/resolve/afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/bridge/bridgeStatusUtil.ts
5.14 kB
| import { | |
| getClaudeAiBaseUrl, | |
| getRemoteSessionUrl, | |
| } from '../constants/product.js' | |
| import { stringWidth } from '../ink/stringWidth.js' | |
| import { formatDuration, truncateToWidth } from '../utils/format.js' | |
| import { getGraphemeSegmenter } from '../utils/intl.js' | |
| /** Bridge status state machine states. */ | |
| export type StatusState = | |
| | 'idle' | |
| | 'attached' | |
| | 'titled' | |
| | 'reconnecting' | |
| | 'failed' | |
| /** How long a tool activity line stays visible after last tool_start (ms). */ | |
| export const TOOL_DISPLAY_EXPIRY_MS = 30_000 | |
| /** Interval for the shimmer animation tick (ms). */ | |
| export const SHIMMER_INTERVAL_MS = 150 | |
| export function timestamp(): string { | |
| const now = new Date() | |
| const h = String(now.getHours()).padStart(2, '0') | |
| const m = String(now.getMinutes()).padStart(2, '0') | |
| const s = String(now.getSeconds()).padStart(2, '0') | |
| return `${h}:${m}:${s}` | |
| } | |
| export { formatDuration, truncateToWidth as truncatePrompt } | |
| /** Abbreviate a tool activity summary for the trail display. */ | |
| export function abbreviateActivity(summary: string): string { | |
| return truncateToWidth(summary, 30) | |
| } | |
| /** Build the connect URL shown when the bridge is idle. */ | |
| export function buildBridgeConnectUrl( | |
| environmentId: string, | |
| ingressUrl?: string, | |
| ): string { | |
| const baseUrl = getClaudeAiBaseUrl(undefined, ingressUrl) | |
| return `${baseUrl}/code?bridge=${environmentId}` | |
| } | |
| /** | |
| * Build the session URL shown when a session is attached. Delegates to | |
| * getRemoteSessionUrl for the cse_→session_ prefix translation, then appends | |
| * the v1-specific ?bridge={environmentId} query. | |
| */ | |
| export function buildBridgeSessionUrl( | |
| sessionId: string, | |
| environmentId: string, | |
| ingressUrl?: string, | |
| ): string { | |
| return `${getRemoteSessionUrl(sessionId, ingressUrl)}?bridge=${environmentId}` | |
| } | |
| /** Compute the glimmer index for a reverse-sweep shimmer animation. */ | |
| export function computeGlimmerIndex( | |
| tick: number, | |
| messageWidth: number, | |
| ): number { | |
| const cycleLength = messageWidth + 20 | |
| return messageWidth + 10 - (tick % cycleLength) | |
| } | |
| /** | |
| * Split text into three segments by visual column position for shimmer rendering. | |
| * | |
| * Uses grapheme segmentation and `stringWidth` so the split is correct for | |
| * multi-byte characters, emoji, and CJK glyphs. | |
| * | |
| * Returns `{ before, shimmer, after }` strings. Both renderers (chalk in | |
| * bridgeUI.ts and React/Ink in bridge.tsx) apply their own coloring to | |
| * these segments. | |
| */ | |
| export function computeShimmerSegments( | |
| text: string, | |
| glimmerIndex: number, | |
| ): { before: string; shimmer: string; after: string } { | |
| const messageWidth = stringWidth(text) | |
| const shimmerStart = glimmerIndex - 1 | |
| const shimmerEnd = glimmerIndex + 1 | |
| // When shimmer is offscreen, return all text as "before" | |
| if (shimmerStart >= messageWidth || shimmerEnd < 0) { | |
| return { before: text, shimmer: '', after: '' } | |
| } | |
| // Split into at most 3 segments by visual column position | |
| const clampedStart = Math.max(0, shimmerStart) | |
| let colPos = 0 | |
| let before = '' | |
| let shimmer = '' | |
| let after = '' | |
| for (const { segment } of getGraphemeSegmenter().segment(text)) { | |
| const segWidth = stringWidth(segment) | |
| if (colPos + segWidth <= clampedStart) { | |
| before += segment | |
| } else if (colPos > shimmerEnd) { | |
| after += segment | |
| } else { | |
| shimmer += segment | |
| } | |
| colPos += segWidth | |
| } | |
| return { before, shimmer, after } | |
| } | |
| /** Computed bridge status label and color from connection state. */ | |
| export type BridgeStatusInfo = { | |
| label: | |
| | 'Remote Control failed' | |
| | 'Remote Control reconnecting' | |
| | 'Remote Control active' | |
| | 'Remote Control connecting\u2026' | |
| color: 'error' | 'warning' | 'success' | |
| } | |
| /** Derive a status label and color from the bridge connection state. */ | |
| export function getBridgeStatus({ | |
| error, | |
| connected, | |
| sessionActive, | |
| reconnecting, | |
| }: { | |
| error: string | undefined | |
| connected: boolean | |
| sessionActive: boolean | |
| reconnecting: boolean | |
| }): BridgeStatusInfo { | |
| if (error) return { label: 'Remote Control failed', color: 'error' } | |
| if (reconnecting) | |
| return { label: 'Remote Control reconnecting', color: 'warning' } | |
| if (sessionActive || connected) | |
| return { label: 'Remote Control active', color: 'success' } | |
| return { label: 'Remote Control connecting\u2026', color: 'warning' } | |
| } | |
| /** Footer text shown when bridge is idle (Ready state). */ | |
| export function buildIdleFooterText(url: string): string { | |
| return `Code everywhere with the Claude app or ${url}` | |
| } | |
| /** Footer text shown when a session is active (Connected state). */ | |
| export function buildActiveFooterText(url: string): string { | |
| return `Continue coding in the Claude app or ${url}` | |
| } | |
| /** Footer text shown when the bridge has failed. */ | |
| export const FAILED_FOOTER_TEXT = 'Something went wrong, please try again' | |
| /** | |
| * Wrap text in an OSC 8 terminal hyperlink. Zero visual width for layout purposes. | |
| * strip-ansi (used by stringWidth) correctly strips these sequences, so | |
| * countVisualLines in bridgeUI.ts remains accurate. | |
| */ | |
| export function wrapWithOsc8Link(text: string, url: string): string { | |
| return `\x1b]8;;${url}\x07${text}\x1b]8;;\x07` | |
| } | |