@hediet/linkrpc-cli 0.0.3-next.20261022.2 → 0.0.3-next.20261022.3

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.
@@ -1,5 +1,5 @@
1
- import { f as observableValue, l as approvalDetailLines } from "./cli-C0AV_fi4.js";
2
- import { n as useObservable, t as useScroll } from "./scroll-B5tGRXDE.js";
1
+ import { f as observableValue, l as approvalDetailLines } from "./cli-DJREb0Dm.js";
2
+ import { n as useObservable, t as useScroll } from "./scroll-BSzq6cdj.js";
3
3
  import { jcsCanonicalize } from "@hediet/linkrpc";
4
4
  import React from "react";
5
5
  import { Box, Text, render, useApp, useInput, useStdout } from "ink";
@@ -712,4 +712,4 @@ function raceAbort(promise, signal) {
712
712
  //#endregion
713
713
  export { runApprovalUi };
714
714
 
715
- //# sourceMappingURL=runApprovalUi-CkT1KK-X.js.map
715
+ //# sourceMappingURL=runApprovalUi-CdC5_Qoo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runApprovalUi-CkT1KK-X.js","names":[],"sources":["../../src/approval-ui/ApprovalApp.tsx","../../src/approval-ui/ApprovalUiModel.ts","../../src/approval-ui/runApprovalUi.tsx"],"sourcesContent":["import React from 'react';\nimport { Box, Text, useApp, useInput, useStdout } from 'ink';\nimport TextInput from 'ink-text-input';\nimport type { PendingApprovalRequest } from '@hediet/linkrpc-infra/approval';\nimport {\n approvalDetailLines,\n type ApprovalPresentationLine as DetailLine,\n} from '../approvalPresentation';\nimport { useObservable } from '../ui/useObservable';\nimport { useScroll } from '../ui/scroll';\nimport { ApprovalUiModel, type ApprovalUiMessageKind } from './ApprovalUiModel';\n\nexport { approvalDetailLines } from '../approvalPresentation';\n\nexport interface ApprovalAppProps {\n readonly model: ApprovalUiModel;\n}\n\ninterface TerminalSize {\n readonly columns: number;\n readonly rows: number;\n}\n\nconst HEADER_HEIGHT = 2;\nconst FOOTER_HEIGHT = 2;\nconst PANE_CHROME_HEIGHT = 3;\nconst MIN_FULL_HEIGHT = 13;\nconst SPLIT_COLUMNS = 96;\n\nexport const ApprovalApp: React.FC<ApprovalAppProps> = ({ model }) => {\n const requests = useObservable(model.requests);\n const selectedId = useObservable(model.selectedRequestId);\n const connectionState = useObservable(model.connectionState);\n const mode = useObservable(model.mode);\n const busy = useObservable(model.busy);\n const message = useObservable(model.message);\n const denialReason = useObservable(model.denialReason);\n const detailOffset = useObservable(model.detailOffset);\n const preparedApproval = useObservable(model.preparedApproval);\n const size = useTerminalSize();\n const { exit } = useApp();\n\n const selectedIndex = requests.findIndex((item) => item.id === selectedId);\n const selected = selectedIndex >= 0 ? requests[selectedIndex] : undefined;\n const rawDetails = selected === undefined\n ? []\n : approvalDetailLines(selected, mode === 'approve' ? preparedApproval : undefined);\n const bodyHeight = Math.max(1, size.rows - HEADER_HEIGHT - FOOTER_HEIGHT);\n const sideBySide = size.columns >= SPLIT_COLUMNS;\n const listPaneHeight = sideBySide ? bodyHeight : Math.max(5, Math.floor(bodyHeight * 0.42));\n const detailPaneHeight = sideBySide ? bodyHeight : Math.max(1, bodyHeight - listPaneHeight);\n const detailViewport = Math.max(1, detailPaneHeight - PANE_CHROME_HEIGHT);\n const detailPaneWidth = sideBySide ? Math.floor(size.columns * 0.62) : size.columns;\n const details = wrapDetailLines(rawDetails, Math.max(1, detailPaneWidth - 6));\n const approvalReviewed = mode === 'approve'\n && preparedApproval !== undefined\n && details.length > 0\n && detailOffset + detailViewport >= details.length;\n\n useInput((input, key) => {\n const canReviewAuthority = size.rows >= MIN_FULL_HEIGHT;\n if (busy) return;\n if (mode === 'deny') {\n if (key.escape) model.cancelMode();\n return;\n }\n if (mode === 'approve') {\n if (key.escape) {\n model.cancelMode();\n } else if (key.pageUp) {\n model.scrollDetails(-detailViewport, details.length, detailViewport);\n } else if (key.pageDown) {\n model.scrollDetails(detailViewport, details.length, detailViewport);\n } else if (key.return && canReviewAuthority && approvalReviewed) {\n void model.confirmCurrentMode();\n }\n return;\n }\n if (mode === 'help') {\n if (key.escape || input === '?' || input === 'q') model.cancelMode();\n return;\n }\n if (input === 'q') {\n exit();\n } else if (input === '?' || key.f1) {\n model.showHelp();\n } else if (input === 'a' && canReviewAuthority) {\n void model.beginApprove();\n } else if (input === 'd' && canReviewAuthority) {\n model.beginDeny();\n } else if (input === 'r') {\n void model.refresh();\n } else if (key.upArrow || input === 'k') {\n model.selectBy(-1);\n } else if (key.downArrow || input === 'j') {\n model.selectBy(1);\n } else if (key.pageUp) {\n model.scrollDetails(-detailViewport, details.length, detailViewport);\n } else if (key.pageDown) {\n model.scrollDetails(detailViewport, details.length, detailViewport);\n }\n });\n\n if (size.rows < MIN_FULL_HEIGHT) {\n return (\n <CompactApprovalApp\n model={model}\n selected={selected}\n requestCount={requests.length}\n connectionState={connectionState}\n mode={mode}\n busy={busy}\n message={message}\n rows={size.rows}\n />\n );\n }\n\n return (\n <Box flexDirection=\"column\" height={size.rows} width={size.columns}>\n <Header\n principalId={model.principalId}\n state={connectionState}\n requestCount={requests.length}\n />\n {mode === 'help' ? (\n <Help height={bodyHeight} />\n ) : (\n <Box\n flexDirection={sideBySide ? 'row' : 'column'}\n height={bodyHeight}\n >\n <RequestList\n requests={requests}\n selectedIndex={selectedIndex}\n height={listPaneHeight}\n width={sideBySide ? '38%' : '100%'}\n />\n <RequestDetails\n selected={selected}\n lines={details}\n offset={detailOffset}\n height={detailPaneHeight}\n width={sideBySide ? '62%' : '100%'}\n />\n </Box>\n )}\n <Footer\n mode={mode}\n busy={busy}\n message={message}\n selected={selected}\n denialReason={denialReason}\n approvalReviewed={approvalReviewed}\n onReasonChange={(value) => model.setDenialReason(value)}\n onDeny={() => void model.confirmCurrentMode()}\n />\n </Box>\n );\n};\n\nconst Header: React.FC<{\n principalId: string;\n state: 'connecting' | 'live' | 'stale';\n requestCount: number;\n}> = ({ principalId, state, requestCount }) => (\n <Box flexDirection=\"column\" height={HEADER_HEIGHT}>\n <Box justifyContent=\"space-between\">\n <Text bold>Hub access approvals</Text>\n <Text color={state === 'live' ? 'green' : state === 'stale' ? 'yellow' : 'cyan'}>\n {state === 'live' ? '● live' : state === 'stale' ? '● reconnecting' : '○ connecting'}\n <Text color=\"white\"> {requestCount} pending</Text>\n </Text>\n </Box>\n <Text dimColor wrap=\"truncate-end\">approver: {safeTerminalText(principalId)}</Text>\n </Box>\n);\n\nconst RequestList: React.FC<{\n requests: readonly PendingApprovalRequest[];\n selectedIndex: number;\n height: number;\n width: number | `${number}%`;\n}> = ({ requests, selectedIndex, height, width }) => {\n const viewport = Math.max(1, height - PANE_CHROME_HEIGHT);\n const window = useScroll(requests.length, Math.max(0, selectedIndex), viewport);\n\n return (\n <Pane title=\"Requests\" height={height} width={width}>\n {requests.length === 0 ? (\n <Box flexDirection=\"column\">\n <Text color=\"green\">No pending access requests.</Text>\n <Text dimColor>Watching the Hub for new requests...</Text>\n </Box>\n ) : (\n <>\n <ScrollMarker direction=\"up\" count={window.above} />\n {requests.slice(window.start, window.end).map((item, index) => {\n const actualIndex = window.start + index;\n const selected = actualIndex === selectedIndex;\n const duration = item.request.duration ?? 'unspecified';\n return (\n <Text\n key={item.id}\n color={selected ? 'cyan' : undefined}\n bold={selected}\n inverse={selected}\n wrap=\"truncate-end\"\n >\n {selected ? '› ' : ' '}\n {safeTerminalText(item.request.consumer.name)}\n <Text dimColor>\n {' '}{safeTerminalText(item.request.kind)} / {safeTerminalText(duration)}\n </Text>\n </Text>\n );\n })}\n <ScrollMarker direction=\"down\" count={window.below} />\n </>\n )}\n </Pane>\n );\n};\n\nconst RequestDetails: React.FC<{\n selected: PendingApprovalRequest | undefined;\n lines: readonly DetailLine[];\n offset: number;\n height: number;\n width: number | `${number}%`;\n}> = ({ selected, lines, offset, height, width }) => {\n const viewport = Math.max(1, height - PANE_CHROME_HEIGHT);\n const safeOffset = Math.min(offset, Math.max(0, lines.length - viewport));\n const visible = lines.slice(safeOffset, safeOffset + viewport);\n const range = lines.length > viewport\n ? ` (${safeOffset + 1}-${safeOffset + visible.length} of ${lines.length})`\n : '';\n\n return (\n <Pane title={`Request details${range}`} height={height} width={width}>\n {selected === undefined ? (\n <Text dimColor>Select a request to inspect its exact authority.</Text>\n ) : (\n <>\n {visible.map((line, index) => (\n <Text\n key={`${safeOffset + index}:${line.label ?? ''}:${line.text}`}\n color={line.tone === 'warning' ? 'yellow' : undefined}\n dimColor={line.tone === 'muted'}\n wrap=\"truncate-end\"\n >\n {line.label !== undefined && <Text bold>{safeTerminalText(line.label)}: </Text>}\n {safeTerminalText(line.text) || '—'}\n </Text>\n ))}\n </>\n )}\n </Pane>\n );\n};\n\nconst Footer: React.FC<{\n mode: 'browse' | 'approve' | 'deny' | 'help';\n busy: boolean;\n message: { readonly kind: ApprovalUiMessageKind; readonly text: string } | undefined;\n selected: PendingApprovalRequest | undefined;\n denialReason: string;\n approvalReviewed: boolean;\n onReasonChange(value: string): void;\n onDeny(): void;\n}> = ({\n mode,\n busy,\n message,\n selected,\n denialReason,\n approvalReviewed,\n onReasonChange,\n onDeny,\n}) => {\n if (busy) {\n return (\n <Box flexDirection=\"column\" height={FOOTER_HEIGHT}>\n <Text color=\"cyan\">Working... The manifest will be rechecked before the decision is applied.</Text>\n <Text dimColor>Please wait.</Text>\n </Box>\n );\n }\n if (mode === 'approve') {\n return (\n <Box flexDirection=\"column\" height={FOOTER_HEIGHT}>\n <Text color=\"yellow\" wrap=\"truncate-end\">\n Approve all displayed authority for{' '}\n <Text bold>{safeTerminalText(selected?.request.consumer.name ?? '')}</Text>?\n </Text>\n {approvalReviewed ? (\n <Text><Text bold>Enter</Text> confirm <Text bold>Esc</Text> cancel</Text>\n ) : (\n <Text><Text bold>PgDn</Text> review all authority before confirming <Text bold>Esc</Text> cancel</Text>\n )}\n </Box>\n );\n }\n if (mode === 'deny') {\n return (\n <Box flexDirection=\"column\" height={FOOTER_HEIGHT}>\n <Box>\n <Text color=\"red\">Denial reason (optional): </Text>\n <TextInput value={denialReason} onChange={onReasonChange} onSubmit={onDeny} />\n </Box>\n <Text><Text bold>Enter</Text> deny <Text bold>Esc</Text> cancel</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" height={FOOTER_HEIGHT}>\n <Text\n color={messageColor(message?.kind)}\n dimColor={message === undefined}\n wrap=\"truncate-end\"\n >\n {safeTerminalText(message?.text ?? 'Review the exact authority before approving.')}\n </Text>\n <Text dimColor wrap=\"truncate-end\">\n ↑/↓ or j/k select a approve d deny PgUp/PgDn details r refresh ? help q quit\n </Text>\n </Box>\n );\n};\n\nconst Help: React.FC<{ height: number }> = ({ height }) => (\n <Pane title=\"Keyboard help\" height={height} width=\"100%\">\n <Text><Text bold>↑/↓, j/k</Text> Move through pending requests</Text>\n <Text><Text bold>PgUp/PgDn</Text> Scroll long request details</Text>\n <Text><Text bold>a</Text> Review and confirm approval</Text>\n <Text><Text bold>d</Text> Deny with an optional reason</Text>\n <Text><Text bold>r</Text> Refresh the authoritative manifest snapshot</Text>\n <Text><Text bold>?, F1</Text> Toggle this help</Text>\n <Text><Text bold>q</Text> Quit without deciding remaining requests</Text>\n <Text dimColor>Press Esc, ?, or q to return.</Text>\n </Pane>\n);\n\nconst CompactApprovalApp: React.FC<{\n model: ApprovalUiModel;\n selected: PendingApprovalRequest | undefined;\n requestCount: number;\n connectionState: 'connecting' | 'live' | 'stale';\n mode: 'browse' | 'approve' | 'deny' | 'help';\n busy: boolean;\n message: { readonly kind: ApprovalUiMessageKind; readonly text: string } | undefined;\n rows: number;\n}> = ({\n model,\n selected,\n requestCount,\n connectionState,\n mode,\n busy,\n message,\n rows,\n}) => (\n <Box flexDirection=\"column\" height={Math.max(1, rows)}>\n <Text bold wrap=\"truncate-end\">Hub approvals {connectionState} {requestCount} pending</Text>\n <Text wrap=\"truncate-end\">\n {selected === undefined\n ? 'No pending access requests.'\n : safeTerminalText(\n `${selected.request.consumer.name} · ${selected.request.kind} · ${selected.request.duration ?? 'unspecified'}`,\n )}\n </Text>\n {rows >= 4 && (\n <Text color={messageColor(message?.kind)} wrap=\"truncate-end\">\n {safeTerminalText(busy ? 'Resolving request...' : message?.text ?? model.principalId)}\n </Text>\n )}\n {rows >= 5 && (\n <Text color=\"yellow\" wrap=\"truncate-end\">\n Enlarge to at least {MIN_FULL_HEIGHT} rows to review and decide. ↑/↓ select q quit\n </Text>\n )}\n </Box>\n);\n\nconst Pane: React.FC<{\n title: string;\n height: number;\n width: number | `${number}%`;\n children: React.ReactNode;\n}> = ({ title, height, width, children }) => (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"gray\"\n height={height}\n width={width}\n paddingX={1}\n overflow=\"hidden\"\n >\n <Text bold>{title}</Text>\n {children}\n </Box>\n);\n\nconst ScrollMarker: React.FC<{ direction: 'up' | 'down'; count: number }> = ({ direction, count }) => {\n if (count === 0) return null;\n return <Text dimColor>{direction === 'up' ? '▲' : '▼'} {count} more</Text>;\n};\n\nfunction wrapDetailLines(lines: readonly DetailLine[], width: number): readonly DetailLine[] {\n return lines.flatMap((line) => {\n const text = safeTerminalText(`${line.label === undefined ? '' : `${line.label}: `}${line.text || '—'}`);\n return wrapTerminalText(text, width).map((chunk) => ({\n text: chunk,\n ...(line.tone === undefined ? {} : { tone: line.tone }),\n }));\n });\n}\n\nfunction wrapTerminalText(text: string, width: number): readonly string[] {\n const lines: string[] = [];\n let current = '';\n let currentWidth = 0;\n for (const character of text) {\n const characterWidth = terminalCharacterWidth(character);\n if (current.length > 0 && currentWidth + characterWidth > width) {\n lines.push(current);\n current = '';\n currentWidth = 0;\n }\n current += character;\n currentWidth += characterWidth;\n }\n if (current.length > 0 || lines.length === 0) lines.push(current);\n return lines;\n}\n\nfunction terminalCharacterWidth(character: string): number {\n if (/^\\p{Mark}$/u.test(character)) return 0;\n return character.codePointAt(0)! <= 0x7e ? 1 : 2;\n}\n\nexport function safeTerminalText(text: string): string {\n let result = '';\n for (const character of text) {\n result += /^[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}]$/u.test(character)\n ? `\\\\u{${character.codePointAt(0)!.toString(16).padStart(4, '0')}}`\n : character;\n }\n return result;\n}\n\nfunction messageColor(kind: ApprovalUiMessageKind | undefined): 'red' | 'green' | 'cyan' | undefined {\n if (kind === 'error') return 'red';\n if (kind === 'success') return 'green';\n if (kind === 'info') return 'cyan';\n return undefined;\n}\n\nfunction useTerminalSize(): TerminalSize {\n const { stdout } = useStdout();\n const [size, setSize] = React.useState<TerminalSize>({\n columns: stdout.columns ?? 100,\n rows: stdout.rows ?? 30,\n });\n React.useEffect(() => {\n const onResize = () => setSize({\n columns: stdout.columns ?? 100,\n rows: stdout.rows ?? 30,\n });\n stdout.on('resize', onResize);\n return () => stdout.off('resize', onResize);\n }, [stdout]);\n return size;\n}\n","import { jcsCanonicalize } from '@hediet/linkrpc';\nimport { observableValue, type IObservable, type ISettableObservable } from '@vscode/observables';\nimport type {\n ApprovalSnapshot,\n ApprovalDecisionOutcome,\n PendingApprovalRequest,\n PreparedApproval,\n} from '@hediet/linkrpc-infra/approval';\nimport type { ApprovalSubscription } from '../commands/approval';\n\nexport type ApprovalUiMode = 'browse' | 'approve' | 'deny' | 'help';\nexport type ApprovalUiMessageKind = 'info' | 'success' | 'error';\n\nexport interface ApprovalUiMessage {\n readonly kind: ApprovalUiMessageKind;\n readonly text: string;\n}\n\nexport interface ApprovalUiClient {\n readonly principalId: string;\n watch(listener: (snapshot: ApprovalSnapshot) => void): ApprovalSubscription;\n refresh(): Promise<void>;\n prepareApproval(requestId: string): Promise<PreparedApproval>;\n approvePrepared(prepared: PreparedApproval): Promise<ApprovalDecisionOutcome>;\n deny(\n requestId: string,\n reason?: string,\n expected?: PendingApprovalRequest,\n ): Promise<ApprovalDecisionOutcome>;\n}\n\nexport class ApprovalUiModel {\n private readonly _requests: ISettableObservable<readonly PendingApprovalRequest[]>;\n public readonly requests: IObservable<readonly PendingApprovalRequest[]>;\n private readonly _connectionState: ISettableObservable<ApprovalSnapshot['state']>;\n public readonly connectionState: IObservable<ApprovalSnapshot['state']>;\n private readonly _selectedRequestId: ISettableObservable<string | undefined>;\n public readonly selectedRequestId: IObservable<string | undefined>;\n private readonly _mode: ISettableObservable<ApprovalUiMode>;\n public readonly mode: IObservable<ApprovalUiMode>;\n private readonly _busy: ISettableObservable<boolean>;\n public readonly busy: IObservable<boolean>;\n private readonly _message: ISettableObservable<ApprovalUiMessage | undefined>;\n public readonly message: IObservable<ApprovalUiMessage | undefined>;\n private readonly _denialReason: ISettableObservable<string>;\n public readonly denialReason: IObservable<string>;\n private readonly _detailOffset: ISettableObservable<number>;\n public readonly detailOffset: IObservable<number>;\n private readonly _preparedApproval: ISettableObservable<PreparedApproval | undefined>;\n public readonly preparedApproval: IObservable<PreparedApproval | undefined>;\n\n private readonly _client: ApprovalUiClient;\n private readonly _subscription: ApprovalSubscription;\n private _disposed = false;\n\n constructor(client: ApprovalUiClient) {\n this._client = client;\n this._requests = observableValue(this, []);\n this.requests = this._requests;\n this._connectionState = observableValue(this, 'connecting');\n this.connectionState = this._connectionState;\n this._selectedRequestId = observableValue(this, undefined);\n this.selectedRequestId = this._selectedRequestId;\n this._mode = observableValue(this, 'browse');\n this.mode = this._mode;\n this._busy = observableValue(this, false);\n this.busy = this._busy;\n this._message = observableValue(this, undefined);\n this.message = this._message;\n this._denialReason = observableValue(this, '');\n this.denialReason = this._denialReason;\n this._detailOffset = observableValue(this, 0);\n this.detailOffset = this._detailOffset;\n this._preparedApproval = observableValue(this, undefined);\n this.preparedApproval = this._preparedApproval;\n this._subscription = client.watch((snapshot) => this._applySnapshot(snapshot));\n }\n\n public get principalId(): string {\n return this._client.principalId;\n }\n\n public get selectedRequest(): PendingApprovalRequest | undefined {\n const selectedId = this._selectedRequestId.get();\n return this._requests.get().find((item) => item.id === selectedId);\n }\n\n public selectBy(delta: number): void {\n if (this._busy.get() || this._mode.get() !== 'browse') return;\n const requests = this._requests.get();\n if (requests.length === 0) return;\n const currentIndex = Math.max(\n 0,\n requests.findIndex((item) => item.id === this._selectedRequestId.get()),\n );\n const nextIndex = Math.max(0, Math.min(requests.length - 1, currentIndex + delta));\n if (nextIndex === currentIndex) return;\n this._selectedRequestId.set(requests[nextIndex].id, undefined);\n this._detailOffset.set(0, undefined);\n }\n\n public showHelp(): void {\n if (this._busy.get()) return;\n this._mode.set('help', undefined);\n }\n\n public async beginApprove(): Promise<void> {\n if (!this._canDecide()) return;\n const selected = this.selectedRequest;\n if (selected === undefined) return;\n this._busy.set(true, undefined);\n this._message.set({ kind: 'info', text: 'Resolving exact authority...' }, undefined);\n try {\n const prepared = await this._client.prepareApproval(selected.id);\n if (\n this.selectedRequest?.id !== selected.id\n || jcsCanonicalize(this.selectedRequest.request)\n !== jcsCanonicalize(prepared.pending.request)\n ) {\n this._message.set({\n kind: 'info',\n text: 'The request changed while its authority was being resolved. Review it again.',\n }, undefined);\n return;\n }\n this._preparedApproval.set(prepared, undefined);\n this._detailOffset.set(0, undefined);\n this._mode.set('approve', undefined);\n this._message.set(undefined, undefined);\n } catch (error) {\n this._message.set({\n kind: 'error',\n text: error instanceof Error ? error.message : String(error),\n }, undefined);\n } finally {\n this._busy.set(false, undefined);\n }\n }\n\n public beginDeny(): void {\n if (!this._canDecide()) return;\n this._denialReason.set('', undefined);\n this._mode.set('deny', undefined);\n }\n\n public setDenialReason(reason: string): void {\n this._denialReason.set(reason, undefined);\n }\n\n public cancelMode(): void {\n if (this._busy.get()) return;\n this._mode.set('browse', undefined);\n this._denialReason.set('', undefined);\n this._preparedApproval.set(undefined, undefined);\n }\n\n public async confirmCurrentMode(): Promise<void> {\n const mode = this._mode.get();\n const selected = this.selectedRequest;\n if (this._busy.get() || selected === undefined || (mode !== 'approve' && mode !== 'deny')) return;\n\n this._busy.set(true, undefined);\n this._message.set({\n kind: 'info',\n text: mode === 'approve' ? 'Approving request...' : 'Denying request...',\n }, undefined);\n try {\n let outcome: ApprovalDecisionOutcome;\n if (mode === 'approve') {\n const prepared = this._preparedApproval.get();\n if (prepared === undefined) {\n throw new Error('approval details are no longer available; review the request again');\n }\n outcome = await this._client.approvePrepared(prepared);\n } else {\n const reason = this._denialReason.get().trim();\n outcome = await this._client.deny(\n selected.id,\n reason.length > 0 ? reason : undefined,\n selected,\n );\n }\n this._message.set({\n kind: outcome === 'applied' ? 'success' : 'info',\n text: outcome === 'applied'\n ? `${mode === 'approve' ? 'Approved' : 'Denied'} ${selected.request.consumer.name}.`\n : `Decision accepted for ${selected.request.consumer.name}, `\n + 'but a matching request is still pending. The consumer may have retried.',\n }, undefined);\n } catch (error) {\n this._message.set({\n kind: 'error',\n text: error instanceof Error ? error.message : String(error),\n }, undefined);\n } finally {\n this._busy.set(false, undefined);\n this._mode.set('browse', undefined);\n this._denialReason.set('', undefined);\n this._preparedApproval.set(undefined, undefined);\n }\n }\n\n public async refresh(): Promise<void> {\n if (this._busy.get()) return;\n this._message.set({ kind: 'info', text: 'Refreshing approval requests...' }, undefined);\n try {\n await this._client.refresh();\n if (this._connectionState.get() === 'live') {\n this._message.set({ kind: 'info', text: 'Approval requests are up to date.' }, undefined);\n }\n } catch (error) {\n this._message.set({\n kind: 'error',\n text: error instanceof Error ? error.message : String(error),\n }, undefined);\n }\n }\n\n public scrollDetails(delta: number, lineCount: number, viewportSize: number): void {\n const maxOffset = Math.max(0, lineCount - Math.max(1, viewportSize));\n const next = Math.max(0, Math.min(maxOffset, this._detailOffset.get() + delta));\n this._detailOffset.set(next, undefined);\n }\n\n public dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n this._subscription.dispose();\n }\n\n private _canDecide(): boolean {\n if (this._busy.get() || this.selectedRequest === undefined) return false;\n if (this._connectionState.get() !== 'live') {\n this._message.set({\n kind: 'error',\n text: 'Cannot decide requests while the approval connection is stale.',\n }, undefined);\n return false;\n }\n return true;\n }\n\n private _applySnapshot(snapshot: ApprovalSnapshot): void {\n const previous = this._requests.get();\n const selectedId = this._selectedRequestId.get();\n const previousSelected = previous.find((item) => item.id === selectedId);\n const previousIndex = Math.max(0, previous.findIndex((item) => item.id === selectedId));\n const selectedStillExists = snapshot.requests.some((item) => item.id === selectedId);\n const nextSelected = snapshot.requests.find((item) => item.id === selectedId);\n const selectedChanged = previousSelected !== undefined\n && nextSelected !== undefined\n && jcsCanonicalize(previousSelected.request) !== jcsCanonicalize(nextSelected.request);\n\n this._requests.set(snapshot.requests, undefined);\n this._connectionState.set(snapshot.state, undefined);\n\n if (snapshot.requests.length === 0) {\n this._selectedRequestId.set(undefined, undefined);\n this._detailOffset.set(0, undefined);\n } else if (!selectedStillExists) {\n const nextIndex = Math.min(previousIndex, snapshot.requests.length - 1);\n this._selectedRequestId.set(snapshot.requests[nextIndex].id, undefined);\n this._detailOffset.set(0, undefined);\n this._preparedApproval.set(undefined, undefined);\n }\n\n if (\n ((!selectedStillExists && selectedId !== undefined) || selectedChanged)\n && this._mode.get() !== 'browse'\n ) {\n this._mode.set('browse', undefined);\n this._denialReason.set('', undefined);\n this._preparedApproval.set(undefined, undefined);\n this._message.set({\n kind: 'info',\n text: selectedChanged\n ? 'The selected request changed. Review it again before deciding.'\n : 'The selected request is no longer pending.',\n }, undefined);\n }\n if (snapshot.state === 'stale' && snapshot.error !== undefined) {\n this._message.set({ kind: 'error', text: snapshot.error }, undefined);\n }\n }\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport type { ApprovalCommandClient } from '../commands/approval';\nimport { ApprovalApp } from './ApprovalApp';\nimport { ApprovalUiModel } from './ApprovalUiModel';\n\nexport interface RunApprovalUiOptions {\n readonly client: ApprovalCommandClient;\n readonly signal: AbortSignal;\n}\n\nexport async function runApprovalUi(options: RunApprovalUiOptions): Promise<void> {\n const model = new ApprovalUiModel(options.client);\n const instance = render(<ApprovalApp model={model} />);\n const onAbort = () => instance.unmount();\n options.signal.addEventListener('abort', onAbort, { once: true });\n if (options.signal.aborted) onAbort();\n try {\n await raceAbort(model.refresh(), options.signal);\n if (options.signal.aborted) return;\n await instance.waitUntilExit();\n } finally {\n options.signal.removeEventListener('abort', onAbort);\n instance.unmount();\n model.dispose();\n }\n}\n\nfunction raceAbort<T>(promise: Promise<T>, signal: AbortSignal): Promise<T | undefined> {\n if (signal.aborted) return Promise.resolve(undefined);\n return new Promise<T | undefined>((resolve, reject) => {\n const onAbort = () => {\n signal.removeEventListener('abort', onAbort);\n resolve(undefined);\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', onAbort);\n reject(error);\n },\n );\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runApprovalUi-CdC5_Qoo.js","names":[],"sources":["../../src/approval-ui/ApprovalApp.tsx","../../src/approval-ui/ApprovalUiModel.ts","../../src/approval-ui/runApprovalUi.tsx"],"sourcesContent":["import React from 'react';\nimport { Box, Text, useApp, useInput, useStdout } from 'ink';\nimport TextInput from 'ink-text-input';\nimport type { PendingApprovalRequest } from '@hediet/linkrpc-infra/approval';\nimport {\n approvalDetailLines,\n type ApprovalPresentationLine as DetailLine,\n} from '../approvalPresentation';\nimport { useObservable } from '../ui/useObservable';\nimport { useScroll } from '../ui/scroll';\nimport { ApprovalUiModel, type ApprovalUiMessageKind } from './ApprovalUiModel';\n\nexport { approvalDetailLines } from '../approvalPresentation';\n\nexport interface ApprovalAppProps {\n readonly model: ApprovalUiModel;\n}\n\ninterface TerminalSize {\n readonly columns: number;\n readonly rows: number;\n}\n\nconst HEADER_HEIGHT = 2;\nconst FOOTER_HEIGHT = 2;\nconst PANE_CHROME_HEIGHT = 3;\nconst MIN_FULL_HEIGHT = 13;\nconst SPLIT_COLUMNS = 96;\n\nexport const ApprovalApp: React.FC<ApprovalAppProps> = ({ model }) => {\n const requests = useObservable(model.requests);\n const selectedId = useObservable(model.selectedRequestId);\n const connectionState = useObservable(model.connectionState);\n const mode = useObservable(model.mode);\n const busy = useObservable(model.busy);\n const message = useObservable(model.message);\n const denialReason = useObservable(model.denialReason);\n const detailOffset = useObservable(model.detailOffset);\n const preparedApproval = useObservable(model.preparedApproval);\n const size = useTerminalSize();\n const { exit } = useApp();\n\n const selectedIndex = requests.findIndex((item) => item.id === selectedId);\n const selected = selectedIndex >= 0 ? requests[selectedIndex] : undefined;\n const rawDetails = selected === undefined\n ? []\n : approvalDetailLines(selected, mode === 'approve' ? preparedApproval : undefined);\n const bodyHeight = Math.max(1, size.rows - HEADER_HEIGHT - FOOTER_HEIGHT);\n const sideBySide = size.columns >= SPLIT_COLUMNS;\n const listPaneHeight = sideBySide ? bodyHeight : Math.max(5, Math.floor(bodyHeight * 0.42));\n const detailPaneHeight = sideBySide ? bodyHeight : Math.max(1, bodyHeight - listPaneHeight);\n const detailViewport = Math.max(1, detailPaneHeight - PANE_CHROME_HEIGHT);\n const detailPaneWidth = sideBySide ? Math.floor(size.columns * 0.62) : size.columns;\n const details = wrapDetailLines(rawDetails, Math.max(1, detailPaneWidth - 6));\n const approvalReviewed = mode === 'approve'\n && preparedApproval !== undefined\n && details.length > 0\n && detailOffset + detailViewport >= details.length;\n\n useInput((input, key) => {\n const canReviewAuthority = size.rows >= MIN_FULL_HEIGHT;\n if (busy) return;\n if (mode === 'deny') {\n if (key.escape) model.cancelMode();\n return;\n }\n if (mode === 'approve') {\n if (key.escape) {\n model.cancelMode();\n } else if (key.pageUp) {\n model.scrollDetails(-detailViewport, details.length, detailViewport);\n } else if (key.pageDown) {\n model.scrollDetails(detailViewport, details.length, detailViewport);\n } else if (key.return && canReviewAuthority && approvalReviewed) {\n void model.confirmCurrentMode();\n }\n return;\n }\n if (mode === 'help') {\n if (key.escape || input === '?' || input === 'q') model.cancelMode();\n return;\n }\n if (input === 'q') {\n exit();\n } else if (input === '?' || key.f1) {\n model.showHelp();\n } else if (input === 'a' && canReviewAuthority) {\n void model.beginApprove();\n } else if (input === 'd' && canReviewAuthority) {\n model.beginDeny();\n } else if (input === 'r') {\n void model.refresh();\n } else if (key.upArrow || input === 'k') {\n model.selectBy(-1);\n } else if (key.downArrow || input === 'j') {\n model.selectBy(1);\n } else if (key.pageUp) {\n model.scrollDetails(-detailViewport, details.length, detailViewport);\n } else if (key.pageDown) {\n model.scrollDetails(detailViewport, details.length, detailViewport);\n }\n });\n\n if (size.rows < MIN_FULL_HEIGHT) {\n return (\n <CompactApprovalApp\n model={model}\n selected={selected}\n requestCount={requests.length}\n connectionState={connectionState}\n mode={mode}\n busy={busy}\n message={message}\n rows={size.rows}\n />\n );\n }\n\n return (\n <Box flexDirection=\"column\" height={size.rows} width={size.columns}>\n <Header\n principalId={model.principalId}\n state={connectionState}\n requestCount={requests.length}\n />\n {mode === 'help' ? (\n <Help height={bodyHeight} />\n ) : (\n <Box\n flexDirection={sideBySide ? 'row' : 'column'}\n height={bodyHeight}\n >\n <RequestList\n requests={requests}\n selectedIndex={selectedIndex}\n height={listPaneHeight}\n width={sideBySide ? '38%' : '100%'}\n />\n <RequestDetails\n selected={selected}\n lines={details}\n offset={detailOffset}\n height={detailPaneHeight}\n width={sideBySide ? '62%' : '100%'}\n />\n </Box>\n )}\n <Footer\n mode={mode}\n busy={busy}\n message={message}\n selected={selected}\n denialReason={denialReason}\n approvalReviewed={approvalReviewed}\n onReasonChange={(value) => model.setDenialReason(value)}\n onDeny={() => void model.confirmCurrentMode()}\n />\n </Box>\n );\n};\n\nconst Header: React.FC<{\n principalId: string;\n state: 'connecting' | 'live' | 'stale';\n requestCount: number;\n}> = ({ principalId, state, requestCount }) => (\n <Box flexDirection=\"column\" height={HEADER_HEIGHT}>\n <Box justifyContent=\"space-between\">\n <Text bold>Hub access approvals</Text>\n <Text color={state === 'live' ? 'green' : state === 'stale' ? 'yellow' : 'cyan'}>\n {state === 'live' ? '● live' : state === 'stale' ? '● reconnecting' : '○ connecting'}\n <Text color=\"white\"> {requestCount} pending</Text>\n </Text>\n </Box>\n <Text dimColor wrap=\"truncate-end\">approver: {safeTerminalText(principalId)}</Text>\n </Box>\n);\n\nconst RequestList: React.FC<{\n requests: readonly PendingApprovalRequest[];\n selectedIndex: number;\n height: number;\n width: number | `${number}%`;\n}> = ({ requests, selectedIndex, height, width }) => {\n const viewport = Math.max(1, height - PANE_CHROME_HEIGHT);\n const window = useScroll(requests.length, Math.max(0, selectedIndex), viewport);\n\n return (\n <Pane title=\"Requests\" height={height} width={width}>\n {requests.length === 0 ? (\n <Box flexDirection=\"column\">\n <Text color=\"green\">No pending access requests.</Text>\n <Text dimColor>Watching the Hub for new requests...</Text>\n </Box>\n ) : (\n <>\n <ScrollMarker direction=\"up\" count={window.above} />\n {requests.slice(window.start, window.end).map((item, index) => {\n const actualIndex = window.start + index;\n const selected = actualIndex === selectedIndex;\n const duration = item.request.duration ?? 'unspecified';\n return (\n <Text\n key={item.id}\n color={selected ? 'cyan' : undefined}\n bold={selected}\n inverse={selected}\n wrap=\"truncate-end\"\n >\n {selected ? '› ' : ' '}\n {safeTerminalText(item.request.consumer.name)}\n <Text dimColor>\n {' '}{safeTerminalText(item.request.kind)} / {safeTerminalText(duration)}\n </Text>\n </Text>\n );\n })}\n <ScrollMarker direction=\"down\" count={window.below} />\n </>\n )}\n </Pane>\n );\n};\n\nconst RequestDetails: React.FC<{\n selected: PendingApprovalRequest | undefined;\n lines: readonly DetailLine[];\n offset: number;\n height: number;\n width: number | `${number}%`;\n}> = ({ selected, lines, offset, height, width }) => {\n const viewport = Math.max(1, height - PANE_CHROME_HEIGHT);\n const safeOffset = Math.min(offset, Math.max(0, lines.length - viewport));\n const visible = lines.slice(safeOffset, safeOffset + viewport);\n const range = lines.length > viewport\n ? ` (${safeOffset + 1}-${safeOffset + visible.length} of ${lines.length})`\n : '';\n\n return (\n <Pane title={`Request details${range}`} height={height} width={width}>\n {selected === undefined ? (\n <Text dimColor>Select a request to inspect its exact authority.</Text>\n ) : (\n <>\n {visible.map((line, index) => (\n <Text\n key={`${safeOffset + index}:${line.label ?? ''}:${line.text}`}\n color={line.tone === 'warning' ? 'yellow' : undefined}\n dimColor={line.tone === 'muted'}\n wrap=\"truncate-end\"\n >\n {line.label !== undefined && <Text bold>{safeTerminalText(line.label)}: </Text>}\n {safeTerminalText(line.text) || '—'}\n </Text>\n ))}\n </>\n )}\n </Pane>\n );\n};\n\nconst Footer: React.FC<{\n mode: 'browse' | 'approve' | 'deny' | 'help';\n busy: boolean;\n message: { readonly kind: ApprovalUiMessageKind; readonly text: string } | undefined;\n selected: PendingApprovalRequest | undefined;\n denialReason: string;\n approvalReviewed: boolean;\n onReasonChange(value: string): void;\n onDeny(): void;\n}> = ({\n mode,\n busy,\n message,\n selected,\n denialReason,\n approvalReviewed,\n onReasonChange,\n onDeny,\n}) => {\n if (busy) {\n return (\n <Box flexDirection=\"column\" height={FOOTER_HEIGHT}>\n <Text color=\"cyan\">Working... The manifest will be rechecked before the decision is applied.</Text>\n <Text dimColor>Please wait.</Text>\n </Box>\n );\n }\n if (mode === 'approve') {\n return (\n <Box flexDirection=\"column\" height={FOOTER_HEIGHT}>\n <Text color=\"yellow\" wrap=\"truncate-end\">\n Approve all displayed authority for{' '}\n <Text bold>{safeTerminalText(selected?.request.consumer.name ?? '')}</Text>?\n </Text>\n {approvalReviewed ? (\n <Text><Text bold>Enter</Text> confirm <Text bold>Esc</Text> cancel</Text>\n ) : (\n <Text><Text bold>PgDn</Text> review all authority before confirming <Text bold>Esc</Text> cancel</Text>\n )}\n </Box>\n );\n }\n if (mode === 'deny') {\n return (\n <Box flexDirection=\"column\" height={FOOTER_HEIGHT}>\n <Box>\n <Text color=\"red\">Denial reason (optional): </Text>\n <TextInput value={denialReason} onChange={onReasonChange} onSubmit={onDeny} />\n </Box>\n <Text><Text bold>Enter</Text> deny <Text bold>Esc</Text> cancel</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" height={FOOTER_HEIGHT}>\n <Text\n color={messageColor(message?.kind)}\n dimColor={message === undefined}\n wrap=\"truncate-end\"\n >\n {safeTerminalText(message?.text ?? 'Review the exact authority before approving.')}\n </Text>\n <Text dimColor wrap=\"truncate-end\">\n ↑/↓ or j/k select a approve d deny PgUp/PgDn details r refresh ? help q quit\n </Text>\n </Box>\n );\n};\n\nconst Help: React.FC<{ height: number }> = ({ height }) => (\n <Pane title=\"Keyboard help\" height={height} width=\"100%\">\n <Text><Text bold>↑/↓, j/k</Text> Move through pending requests</Text>\n <Text><Text bold>PgUp/PgDn</Text> Scroll long request details</Text>\n <Text><Text bold>a</Text> Review and confirm approval</Text>\n <Text><Text bold>d</Text> Deny with an optional reason</Text>\n <Text><Text bold>r</Text> Refresh the authoritative manifest snapshot</Text>\n <Text><Text bold>?, F1</Text> Toggle this help</Text>\n <Text><Text bold>q</Text> Quit without deciding remaining requests</Text>\n <Text dimColor>Press Esc, ?, or q to return.</Text>\n </Pane>\n);\n\nconst CompactApprovalApp: React.FC<{\n model: ApprovalUiModel;\n selected: PendingApprovalRequest | undefined;\n requestCount: number;\n connectionState: 'connecting' | 'live' | 'stale';\n mode: 'browse' | 'approve' | 'deny' | 'help';\n busy: boolean;\n message: { readonly kind: ApprovalUiMessageKind; readonly text: string } | undefined;\n rows: number;\n}> = ({\n model,\n selected,\n requestCount,\n connectionState,\n mode,\n busy,\n message,\n rows,\n}) => (\n <Box flexDirection=\"column\" height={Math.max(1, rows)}>\n <Text bold wrap=\"truncate-end\">Hub approvals {connectionState} {requestCount} pending</Text>\n <Text wrap=\"truncate-end\">\n {selected === undefined\n ? 'No pending access requests.'\n : safeTerminalText(\n `${selected.request.consumer.name} · ${selected.request.kind} · ${selected.request.duration ?? 'unspecified'}`,\n )}\n </Text>\n {rows >= 4 && (\n <Text color={messageColor(message?.kind)} wrap=\"truncate-end\">\n {safeTerminalText(busy ? 'Resolving request...' : message?.text ?? model.principalId)}\n </Text>\n )}\n {rows >= 5 && (\n <Text color=\"yellow\" wrap=\"truncate-end\">\n Enlarge to at least {MIN_FULL_HEIGHT} rows to review and decide. ↑/↓ select q quit\n </Text>\n )}\n </Box>\n);\n\nconst Pane: React.FC<{\n title: string;\n height: number;\n width: number | `${number}%`;\n children: React.ReactNode;\n}> = ({ title, height, width, children }) => (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"gray\"\n height={height}\n width={width}\n paddingX={1}\n overflow=\"hidden\"\n >\n <Text bold>{title}</Text>\n {children}\n </Box>\n);\n\nconst ScrollMarker: React.FC<{ direction: 'up' | 'down'; count: number }> = ({ direction, count }) => {\n if (count === 0) return null;\n return <Text dimColor>{direction === 'up' ? '▲' : '▼'} {count} more</Text>;\n};\n\nfunction wrapDetailLines(lines: readonly DetailLine[], width: number): readonly DetailLine[] {\n return lines.flatMap((line) => {\n const text = safeTerminalText(`${line.label === undefined ? '' : `${line.label}: `}${line.text || '—'}`);\n return wrapTerminalText(text, width).map((chunk) => ({\n text: chunk,\n ...(line.tone === undefined ? {} : { tone: line.tone }),\n }));\n });\n}\n\nfunction wrapTerminalText(text: string, width: number): readonly string[] {\n const lines: string[] = [];\n let current = '';\n let currentWidth = 0;\n for (const character of text) {\n const characterWidth = terminalCharacterWidth(character);\n if (current.length > 0 && currentWidth + characterWidth > width) {\n lines.push(current);\n current = '';\n currentWidth = 0;\n }\n current += character;\n currentWidth += characterWidth;\n }\n if (current.length > 0 || lines.length === 0) lines.push(current);\n return lines;\n}\n\nfunction terminalCharacterWidth(character: string): number {\n if (/^\\p{Mark}$/u.test(character)) return 0;\n return character.codePointAt(0)! <= 0x7e ? 1 : 2;\n}\n\nexport function safeTerminalText(text: string): string {\n let result = '';\n for (const character of text) {\n result += /^[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}]$/u.test(character)\n ? `\\\\u{${character.codePointAt(0)!.toString(16).padStart(4, '0')}}`\n : character;\n }\n return result;\n}\n\nfunction messageColor(kind: ApprovalUiMessageKind | undefined): 'red' | 'green' | 'cyan' | undefined {\n if (kind === 'error') return 'red';\n if (kind === 'success') return 'green';\n if (kind === 'info') return 'cyan';\n return undefined;\n}\n\nfunction useTerminalSize(): TerminalSize {\n const { stdout } = useStdout();\n const [size, setSize] = React.useState<TerminalSize>({\n columns: stdout.columns ?? 100,\n rows: stdout.rows ?? 30,\n });\n React.useEffect(() => {\n const onResize = () => setSize({\n columns: stdout.columns ?? 100,\n rows: stdout.rows ?? 30,\n });\n stdout.on('resize', onResize);\n return () => stdout.off('resize', onResize);\n }, [stdout]);\n return size;\n}\n","import { jcsCanonicalize } from '@hediet/linkrpc';\nimport { observableValue, type IObservable, type ISettableObservable } from '@vscode/observables';\nimport type {\n ApprovalSnapshot,\n ApprovalDecisionOutcome,\n PendingApprovalRequest,\n PreparedApproval,\n} from '@hediet/linkrpc-infra/approval';\nimport type { ApprovalSubscription } from '../commands/approval';\n\nexport type ApprovalUiMode = 'browse' | 'approve' | 'deny' | 'help';\nexport type ApprovalUiMessageKind = 'info' | 'success' | 'error';\n\nexport interface ApprovalUiMessage {\n readonly kind: ApprovalUiMessageKind;\n readonly text: string;\n}\n\nexport interface ApprovalUiClient {\n readonly principalId: string;\n watch(listener: (snapshot: ApprovalSnapshot) => void): ApprovalSubscription;\n refresh(): Promise<void>;\n prepareApproval(requestId: string): Promise<PreparedApproval>;\n approvePrepared(prepared: PreparedApproval): Promise<ApprovalDecisionOutcome>;\n deny(\n requestId: string,\n reason?: string,\n expected?: PendingApprovalRequest,\n ): Promise<ApprovalDecisionOutcome>;\n}\n\nexport class ApprovalUiModel {\n private readonly _requests: ISettableObservable<readonly PendingApprovalRequest[]>;\n public readonly requests: IObservable<readonly PendingApprovalRequest[]>;\n private readonly _connectionState: ISettableObservable<ApprovalSnapshot['state']>;\n public readonly connectionState: IObservable<ApprovalSnapshot['state']>;\n private readonly _selectedRequestId: ISettableObservable<string | undefined>;\n public readonly selectedRequestId: IObservable<string | undefined>;\n private readonly _mode: ISettableObservable<ApprovalUiMode>;\n public readonly mode: IObservable<ApprovalUiMode>;\n private readonly _busy: ISettableObservable<boolean>;\n public readonly busy: IObservable<boolean>;\n private readonly _message: ISettableObservable<ApprovalUiMessage | undefined>;\n public readonly message: IObservable<ApprovalUiMessage | undefined>;\n private readonly _denialReason: ISettableObservable<string>;\n public readonly denialReason: IObservable<string>;\n private readonly _detailOffset: ISettableObservable<number>;\n public readonly detailOffset: IObservable<number>;\n private readonly _preparedApproval: ISettableObservable<PreparedApproval | undefined>;\n public readonly preparedApproval: IObservable<PreparedApproval | undefined>;\n\n private readonly _client: ApprovalUiClient;\n private readonly _subscription: ApprovalSubscription;\n private _disposed = false;\n\n constructor(client: ApprovalUiClient) {\n this._client = client;\n this._requests = observableValue(this, []);\n this.requests = this._requests;\n this._connectionState = observableValue(this, 'connecting');\n this.connectionState = this._connectionState;\n this._selectedRequestId = observableValue(this, undefined);\n this.selectedRequestId = this._selectedRequestId;\n this._mode = observableValue(this, 'browse');\n this.mode = this._mode;\n this._busy = observableValue(this, false);\n this.busy = this._busy;\n this._message = observableValue(this, undefined);\n this.message = this._message;\n this._denialReason = observableValue(this, '');\n this.denialReason = this._denialReason;\n this._detailOffset = observableValue(this, 0);\n this.detailOffset = this._detailOffset;\n this._preparedApproval = observableValue(this, undefined);\n this.preparedApproval = this._preparedApproval;\n this._subscription = client.watch((snapshot) => this._applySnapshot(snapshot));\n }\n\n public get principalId(): string {\n return this._client.principalId;\n }\n\n public get selectedRequest(): PendingApprovalRequest | undefined {\n const selectedId = this._selectedRequestId.get();\n return this._requests.get().find((item) => item.id === selectedId);\n }\n\n public selectBy(delta: number): void {\n if (this._busy.get() || this._mode.get() !== 'browse') return;\n const requests = this._requests.get();\n if (requests.length === 0) return;\n const currentIndex = Math.max(\n 0,\n requests.findIndex((item) => item.id === this._selectedRequestId.get()),\n );\n const nextIndex = Math.max(0, Math.min(requests.length - 1, currentIndex + delta));\n if (nextIndex === currentIndex) return;\n this._selectedRequestId.set(requests[nextIndex].id, undefined);\n this._detailOffset.set(0, undefined);\n }\n\n public showHelp(): void {\n if (this._busy.get()) return;\n this._mode.set('help', undefined);\n }\n\n public async beginApprove(): Promise<void> {\n if (!this._canDecide()) return;\n const selected = this.selectedRequest;\n if (selected === undefined) return;\n this._busy.set(true, undefined);\n this._message.set({ kind: 'info', text: 'Resolving exact authority...' }, undefined);\n try {\n const prepared = await this._client.prepareApproval(selected.id);\n if (\n this.selectedRequest?.id !== selected.id\n || jcsCanonicalize(this.selectedRequest.request)\n !== jcsCanonicalize(prepared.pending.request)\n ) {\n this._message.set({\n kind: 'info',\n text: 'The request changed while its authority was being resolved. Review it again.',\n }, undefined);\n return;\n }\n this._preparedApproval.set(prepared, undefined);\n this._detailOffset.set(0, undefined);\n this._mode.set('approve', undefined);\n this._message.set(undefined, undefined);\n } catch (error) {\n this._message.set({\n kind: 'error',\n text: error instanceof Error ? error.message : String(error),\n }, undefined);\n } finally {\n this._busy.set(false, undefined);\n }\n }\n\n public beginDeny(): void {\n if (!this._canDecide()) return;\n this._denialReason.set('', undefined);\n this._mode.set('deny', undefined);\n }\n\n public setDenialReason(reason: string): void {\n this._denialReason.set(reason, undefined);\n }\n\n public cancelMode(): void {\n if (this._busy.get()) return;\n this._mode.set('browse', undefined);\n this._denialReason.set('', undefined);\n this._preparedApproval.set(undefined, undefined);\n }\n\n public async confirmCurrentMode(): Promise<void> {\n const mode = this._mode.get();\n const selected = this.selectedRequest;\n if (this._busy.get() || selected === undefined || (mode !== 'approve' && mode !== 'deny')) return;\n\n this._busy.set(true, undefined);\n this._message.set({\n kind: 'info',\n text: mode === 'approve' ? 'Approving request...' : 'Denying request...',\n }, undefined);\n try {\n let outcome: ApprovalDecisionOutcome;\n if (mode === 'approve') {\n const prepared = this._preparedApproval.get();\n if (prepared === undefined) {\n throw new Error('approval details are no longer available; review the request again');\n }\n outcome = await this._client.approvePrepared(prepared);\n } else {\n const reason = this._denialReason.get().trim();\n outcome = await this._client.deny(\n selected.id,\n reason.length > 0 ? reason : undefined,\n selected,\n );\n }\n this._message.set({\n kind: outcome === 'applied' ? 'success' : 'info',\n text: outcome === 'applied'\n ? `${mode === 'approve' ? 'Approved' : 'Denied'} ${selected.request.consumer.name}.`\n : `Decision accepted for ${selected.request.consumer.name}, `\n + 'but a matching request is still pending. The consumer may have retried.',\n }, undefined);\n } catch (error) {\n this._message.set({\n kind: 'error',\n text: error instanceof Error ? error.message : String(error),\n }, undefined);\n } finally {\n this._busy.set(false, undefined);\n this._mode.set('browse', undefined);\n this._denialReason.set('', undefined);\n this._preparedApproval.set(undefined, undefined);\n }\n }\n\n public async refresh(): Promise<void> {\n if (this._busy.get()) return;\n this._message.set({ kind: 'info', text: 'Refreshing approval requests...' }, undefined);\n try {\n await this._client.refresh();\n if (this._connectionState.get() === 'live') {\n this._message.set({ kind: 'info', text: 'Approval requests are up to date.' }, undefined);\n }\n } catch (error) {\n this._message.set({\n kind: 'error',\n text: error instanceof Error ? error.message : String(error),\n }, undefined);\n }\n }\n\n public scrollDetails(delta: number, lineCount: number, viewportSize: number): void {\n const maxOffset = Math.max(0, lineCount - Math.max(1, viewportSize));\n const next = Math.max(0, Math.min(maxOffset, this._detailOffset.get() + delta));\n this._detailOffset.set(next, undefined);\n }\n\n public dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n this._subscription.dispose();\n }\n\n private _canDecide(): boolean {\n if (this._busy.get() || this.selectedRequest === undefined) return false;\n if (this._connectionState.get() !== 'live') {\n this._message.set({\n kind: 'error',\n text: 'Cannot decide requests while the approval connection is stale.',\n }, undefined);\n return false;\n }\n return true;\n }\n\n private _applySnapshot(snapshot: ApprovalSnapshot): void {\n const previous = this._requests.get();\n const selectedId = this._selectedRequestId.get();\n const previousSelected = previous.find((item) => item.id === selectedId);\n const previousIndex = Math.max(0, previous.findIndex((item) => item.id === selectedId));\n const selectedStillExists = snapshot.requests.some((item) => item.id === selectedId);\n const nextSelected = snapshot.requests.find((item) => item.id === selectedId);\n const selectedChanged = previousSelected !== undefined\n && nextSelected !== undefined\n && jcsCanonicalize(previousSelected.request) !== jcsCanonicalize(nextSelected.request);\n\n this._requests.set(snapshot.requests, undefined);\n this._connectionState.set(snapshot.state, undefined);\n\n if (snapshot.requests.length === 0) {\n this._selectedRequestId.set(undefined, undefined);\n this._detailOffset.set(0, undefined);\n } else if (!selectedStillExists) {\n const nextIndex = Math.min(previousIndex, snapshot.requests.length - 1);\n this._selectedRequestId.set(snapshot.requests[nextIndex].id, undefined);\n this._detailOffset.set(0, undefined);\n this._preparedApproval.set(undefined, undefined);\n }\n\n if (\n ((!selectedStillExists && selectedId !== undefined) || selectedChanged)\n && this._mode.get() !== 'browse'\n ) {\n this._mode.set('browse', undefined);\n this._denialReason.set('', undefined);\n this._preparedApproval.set(undefined, undefined);\n this._message.set({\n kind: 'info',\n text: selectedChanged\n ? 'The selected request changed. Review it again before deciding.'\n : 'The selected request is no longer pending.',\n }, undefined);\n }\n if (snapshot.state === 'stale' && snapshot.error !== undefined) {\n this._message.set({ kind: 'error', text: snapshot.error }, undefined);\n }\n }\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport type { ApprovalCommandClient } from '../commands/approval';\nimport { ApprovalApp } from './ApprovalApp';\nimport { ApprovalUiModel } from './ApprovalUiModel';\n\nexport interface RunApprovalUiOptions {\n readonly client: ApprovalCommandClient;\n readonly signal: AbortSignal;\n}\n\nexport async function runApprovalUi(options: RunApprovalUiOptions): Promise<void> {\n const model = new ApprovalUiModel(options.client);\n const instance = render(<ApprovalApp model={model} />);\n const onAbort = () => instance.unmount();\n options.signal.addEventListener('abort', onAbort, { once: true });\n if (options.signal.aborted) onAbort();\n try {\n await raceAbort(model.refresh(), options.signal);\n if (options.signal.aborted) return;\n await instance.waitUntilExit();\n } finally {\n options.signal.removeEventListener('abort', onAbort);\n instance.unmount();\n model.dispose();\n }\n}\n\nfunction raceAbort<T>(promise: Promise<T>, signal: AbortSignal): Promise<T | undefined> {\n if (signal.aborted) return Promise.resolve(undefined);\n return new Promise<T | undefined>((resolve, reject) => {\n const onAbort = () => {\n signal.removeEventListener('abort', onAbort);\n resolve(undefined);\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', onAbort);\n reject(error);\n },\n );\n });\n}\n"],"mappings":"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"}
@@ -3578,9 +3578,13 @@ async function proxyCommand(opts) {
3578
3578
  if (opts.outbound !== "none") opts.participant.setRequestHandler(createForwardingHandler(opts.hub, opts.outbound));
3579
3579
  if (opts.claimServiceId !== void 0) {
3580
3580
  await _claimServiceId(opts.hub, opts.claimServiceId);
3581
- log(`proxy: claimed '${opts.claimServiceId}' — forwarding its requests to the participant`);
3581
+ log(`proxy: claimed '${opts.claimServiceId}' — forwarding its requests to the participant unchanged`);
3582
3582
  }
3583
- if (opts.outbound !== "none") log(`proxy: forwarding participant calls to the hub (${opts.outbound})`);
3583
+ log({
3584
+ signed: "proxy: forwarding participant calls to the hub, signed as the identity above",
3585
+ verbatim: "proxy: forwarding participant calls to the hub as they are (not signed by the proxy)",
3586
+ none: "proxy: dropping participant calls"
3587
+ }[opts.outbound]);
3584
3588
  await (opts.stop ?? _untilSignalled());
3585
3589
  log("proxy: stopping");
3586
3590
  }
@@ -5089,4 +5093,4 @@ function _endpointCacheKey(endpoint, staticSchema) {
5089
5093
  //#endregion
5090
5094
  export { requestTopologyAccess as $, CallRecordLevelSchema as A, proxyCommand as B, LogLineSchema as C, CallFilterSchema as D, hubDaemonManagementInterface as E, disconnectBroker as F, parseDuration as G, withStaticHubReflection as H, getBrokerStatus as I, resolveSlot as J, complete as K, readBrokerNotifications as L, readEndpointDiscovery as M, ContextStore as N, CallLogLevelSchema as O, formatContextReference as P, requestReflectionAccess as Q, stopConnectionBroker as R, DaemonStatusSchema as S, mcpForwardInterface as St, ServiceStatusSchema as T, parseConnectionLimit as U, tunnelCommand as V, parseConnectionLimitMilliseconds as W, parseLine as X, COMMAND_TREE as Y, ChannelDirectorySource as Z, runParams as _, validateValueAgainstSchema as _t, resolveInvocationEndpoint as a, walkHubDetailed as at, LINKRPC_HUB_HOME_VAR as b, parseParamOverride as bt, resolveLocalEndpoint as c, parsePrincipalSpec as ct, endpointAddress as d, connectViaTransport as dt, setupSigning as et, endpointDefinition as f, resolveTargetEndpoint as ft, runEvent as g, explainValidation as gt, processSource as h, describeSchema as ht, resolveInvocationContext as i, walkHub as it, CallRecordSchema as j, CallPeerSchema as k, connectToHubManagement as l, connect as lt, managedEndpointsInterface as m, describeObjectParams as mt, loadStaticHubSchema as n, fetchSchema$1 as nt, resolveSigning as o, logoutCliIdentity as ot, endpointStatus as p, resolvedEndpointToConfig as pt, resolveCliInvocation as q, resolveStaticHubSchemaSource as r, findMethodInSchema as rt, validationDefault as s, formatPrincipalSource as st, completeForLine as t, fetchDefaults as tt, consoleAddress as u, connectViaRootOverlay as ut, watchEvent as v, valueToConstSchema as vt, ServiceStateSchema as w, ConfigDocumentSchema as x, MethodRefWithOptHash as xt, HubHome as y, mergeParams as yt, ConnectionBroker as z };
5091
5095
 
5092
- //# sourceMappingURL=runComplete-HH0NuvsL.js.map
5096
+ //# sourceMappingURL=runComplete-C9LMCMk7.js.map