@bastani/atomic 0.9.20-alpha.2 → 0.9.20-alpha.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.
- package/CHANGELOG.md +17 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/CHANGELOG.md +6 -0
- package/dist/builtin/web-access/index.bundle.mjs +5 -5
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +78 -31
- package/dist/bun/split-loader.js +13 -0
- package/dist/bun/split-loader.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +12 -6
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/compaction/compaction-boundary.d.ts +29 -1
- package/dist/core/compaction/compaction-boundary.d.ts.map +1 -1
- package/dist/core/compaction/compaction-boundary.js +35 -3
- package/dist/core/compaction/compaction-boundary.js.map +1 -1
- package/dist/core/compaction/compaction-runner.d.ts.map +1 -1
- package/dist/core/compaction/compaction-runner.js +18 -5
- package/dist/core/compaction/compaction-runner.js.map +1 -1
- package/dist/core/compaction/compaction-types.d.ts +7 -0
- package/dist/core/compaction/compaction-types.d.ts.map +1 -1
- package/dist/core/compaction/compaction-types.js.map +1 -1
- package/dist/core/compaction/index.d.ts +1 -0
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +1 -0
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/compaction/whole-context-stats.d.ts +21 -0
- package/dist/core/compaction/whole-context-stats.d.ts.map +1 -0
- package/dist/core/compaction/whole-context-stats.js +32 -0
- package/dist/core/compaction/whole-context-stats.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +11 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts +85 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +22 -18
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/session-manager-core.d.ts +2 -0
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +26 -3
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/index-extensions.d.ts +1 -1
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/main-session.d.ts.map +1 -1
- package/dist/main-session.js +5 -6
- package/dist/main-session.js.map +1 -1
- package/dist/modes/interactive/components/compaction-boundary-message.d.ts +2 -0
- package/dist/modes/interactive/components/compaction-boundary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-boundary-message.js +13 -3
- package/dist/modes/interactive/components/compaction-boundary-message.js.map +1 -1
- package/dist/modes/interactive/interactive-tui.d.ts +3 -6
- package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-tui.js +13 -5
- package/dist/modes/interactive/interactive-tui.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +14 -2
- package/dist/utils/clipboard.js.map +1 -1
- package/docs/compaction/reference.md +2 -0
- package/docs/compaction.md +3 -1
- package/docs/getting-started/installation.md +1 -1
- package/docs/keybindings.md +2 -0
- package/docs/models/reference.md +21 -0
- package/docs/workflows/operations.md +5 -1
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-tui.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-tui.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Component,\n\tisKeyRelease,\n\tProcessTerminal,\n\ttype Terminal,\n\ttype TUI,\n\tTuiAltScreen,\n\ttype TuiInputListener,\n\tTuiMainScreen,\n} from \"@earendil-works/pi-tui\";\nimport { stripOverlayActiveRowMarker } from \"../../core/extensions/ui-types.ts\";\nimport { isLifecycleTimingEnabled, markLifecycleTiming } from \"../../core/lifecycle-timings.ts\";\nimport { copyToClipboard } from \"../../utils/clipboard.ts\";\nimport { openBrowser } from \"../../utils/open-browser.ts\";\nimport { keyDisplayText } from \"./components/keybinding-hints.js\";\nimport { TRANSCRIPT_JUMP_TO_END_URL } from \"./components/transcript-follow-indicator.ts\";\nimport { theme } from \"./theme/theme.js\";\n\ninterface TuiOverlayEntry {\n\tcomponent: Component;\n\tpreFocus: Component | null;\n}\n\ninterface InternalUiActionOverlay extends Component {\n\thandlesInternalUiAction?: boolean;\n}\n\ntype TuiOverlayFocusRestore =\n\t| { status: \"inactive\" }\n\t| { status: \"eligible\"; overlay: TuiOverlayEntry }\n\t| {\n\t\t\tstatus: \"blocked\";\n\t\t\toverlay: TuiOverlayEntry;\n\t\t\tblockedBy: Component;\n\t\t\tresume: { status: \"restore-overlay\" } | { status: \"focus-target\"; target: Component | null };\n\t };\n\ninterface TuiOverlayInternals {\n\toverlayStack: TuiOverlayEntry[];\n\tisOverlayVisible(entry: TuiOverlayEntry): boolean;\n\tgetTopmostVisibleOverlay(): TuiOverlayEntry | undefined;\n\tsetFocusInternal(options: { component: Component | null; overlayFocusRestore: \"preserve\" }): void;\n\tgetVisibleOverlayFocusRestore(): TuiOverlayFocusRestore;\n\tclearOverlayFocusRestore(): void;\n\trequestImmediateRender(): void;\n}\n/** pi-tui 0.84.2 keeps this canonical mouse predicate private (tui-alt-screen.d.ts:114). */\ninterface TuiAltScreenMouseInternals {\n\tisMouseSequence(data: string): boolean;\n}\n\n/** pi-tui 0.84.2 keeps its overlay-deferral predicate private (tui-alt-screen.d.ts:84). */\ninterface TuiAltScreenViewportDeferral {\n\tshouldDeferViewportInputToOverlay?(): boolean;\n}\n\ninterface TuiAltScreenScrollToEndIndicatorInternals {\n\thandleScrollToEndIndicatorMouseEvent(event: unknown): boolean;\n}\n\ninterface TuiAltScreenSelectionInternals {\n\tselectionAnchor?: unknown;\n\tselectionFocus?: unknown;\n\tselectionInitialRange?: unknown;\n\tselectionPressActive: boolean;\n\tselectionDragged: boolean;\n\tlastClick?: unknown;\n}\n\nexport type InteractiveTui = TuiMainScreen | TuiAltScreen;\n\nexport function isOverlayMounted(tui: TUI, component: Component): boolean {\n\tconst internals = tui as unknown as Partial<TuiOverlayInternals>;\n\treturn (\n\t\tArray.isArray(internals.overlayStack) && internals.overlayStack.some((entry) => entry.component === component)\n\t);\n}\nexport function getFocusedOverlay(tui: InteractiveTui): Component | undefined {\n\tconst focused = tui.getFocusedComponent();\n\tif (!focused) return undefined;\n\tconst internals = tui as unknown as Partial<TuiOverlayInternals>;\n\tif (!Array.isArray(internals.overlayStack) || typeof internals.isOverlayVisible !== \"function\") return undefined;\n\tconst entry = internals.overlayStack.find((candidate) => candidate.component === focused);\n\treturn entry && internals.isOverlayVisible(entry) ? focused : undefined;\n}\n\nexport function handleFocusedOverlayInternalUiAction(tui: InteractiveTui, url: string): InternalUiActionResult {\n\tconst overlay = getFocusedOverlay(tui);\n\tif (!overlay || (overlay as InternalUiActionOverlay).handlesInternalUiAction !== true) return undefined;\n\tconst handleInput = overlay.handleInput as\n\t\t| ((data: string) => boolean | undefined | Promise<boolean | undefined>)\n\t\t| undefined;\n\treturn handleInput?.call(overlay, url);\n}\n\nexport type InternalUiActionResult = boolean | undefined | Promise<boolean | undefined>;\n\nexport interface InteractiveTuiOptions {\n\tshowHardwareCursor: boolean;\n\tlogDirectory: string;\n\tterminal?: Terminal;\n\tcopyOnSelect?: boolean;\n\tonRightClickPaste?: () => void;\n\tonOverlayInternalUiAction?: (url: string) => InternalUiActionResult;\n\tonInternalUiAction?: (url: string) => InternalUiActionResult;\n\t/**\n\t * Return false to let a focused overlay receive viewport input first.\n\t * Mouse input is deferred only while the focused component belongs to an\n\t * overlay; non-overlay focus keeps pi-tui's transcript selection path.\n\t */\n\tshouldHandleViewportInput?: (\n\t\tdata: string,\n\t\tisMouseInput: boolean,\n\t\tfocusedIsOverlay: boolean,\n\t\t_focusedIsViewportSearch: boolean,\n\t) => boolean;\n\t/** Handle an unconsumed overlay input before replaying it to the viewport. */\n\tonOverlayUnhandledInput?: (data: string) => boolean;\n\t/**\n\t * Copy selected text to the system clipboard; resolve false when the host\n\t * clipboard never received it. Defaults to Atomic's `copyToClipboard` with\n\t * its platform fallbacks, so pi-tui flashes \"Copy failed\" on a terminal\n\t * whose clipboard stayed untouched (upstream #8110) instead of the old\n\t * unconditional \"Copied!\". Injectable so hosts and tests observe the write.\n\t */\n\tcopySelection?: (text: string) => Promise<boolean>;\n}\n\n/** The default selection-copy route: Atomic's host clipboard write. */\nasync function copySelectionToHostClipboard(text: string): Promise<boolean> {\n\ttry {\n\t\tawait copyToClipboard(text);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport interface UrlActivationHandlers {\n\tonOverlayInternalUiAction?: (url: string) => InternalUiActionResult;\n\tonInternalUiAction?: (url: string) => InternalUiActionResult;\n\topenUrl: (url: string) => void;\n}\n\nfunction fallbackInternalUiAction(url: string, handlers: UrlActivationHandlers): void {\n\thandlers.onInternalUiAction?.(url);\n}\n\nfunction routeInternalUiAction(url: string, handlers: UrlActivationHandlers): void {\n\tlet result: InternalUiActionResult;\n\ttry {\n\t\tresult = handlers.onOverlayInternalUiAction?.(url);\n\t} catch {\n\t\tfallbackInternalUiAction(url, handlers);\n\t\treturn;\n\t}\n\tif (result instanceof Promise) {\n\t\tvoid result.then(\n\t\t\t(handled) => {\n\t\t\t\tif (handled !== true) fallbackInternalUiAction(url, handlers);\n\t\t\t},\n\t\t\t() => fallbackInternalUiAction(url, handlers),\n\t\t);\n\t\treturn;\n\t}\n\tif (result !== true) fallbackInternalUiAction(url, handlers);\n}\n\n/** Route OSC 8 activation without allowing unknown internal URLs to escape to a browser. */\nexport function handleUrlActivation(url: string, handlers: UrlActivationHandlers): void {\n\tconst internalUiScheme = \"atomic-ui:\";\n\tif (url.slice(0, internalUiScheme.length).toLowerCase() === internalUiScheme) {\n\t\tconst schemeEnd = url.indexOf(\":\");\n\t\tconst normalizedInternalUrl = `${url.slice(0, schemeEnd).toLowerCase()}${url.slice(schemeEnd)}`;\n\t\t// Forward the normalized URL: overlay-side matching is exact, so a\n\t\t// mixed-case scheme must not reach an overlay as an unrecognized string.\n\t\tif (normalizedInternalUrl === TRANSCRIPT_JUMP_TO_END_URL) routeInternalUiAction(normalizedInternalUrl, handlers);\n\t\treturn;\n\t}\n\n\thandlers.openUrl(url);\n}\n\nconst viewportInputListeners = new WeakSet<AtomicTuiAltScreen>();\n\ntype ViewportInputGate = (\n\tdata: string,\n\tisMouseInput: boolean,\n\tfocusedIsOverlay: boolean,\n\t_focusedIsViewportSearch: boolean,\n) => boolean;\n\nconst viewportInputGates = new WeakMap<AtomicTuiAltScreen, ViewportInputGate>();\nconst overlayUnhandledInputHandlers = new WeakMap<AtomicTuiAltScreen, (data: string) => boolean>();\n/** Instances currently replaying overlay-declined input into pi-tui's viewport listener. */\nconst viewportInputReplays = new WeakSet<AtomicTuiAltScreen>();\n/** Selections begun over Atomic overlays must never trigger or survive into main-chat clipboard actions. */\nconst overlayOwnedSelections = new WeakSet<AtomicTuiAltScreen>();\ninterface ViewportInputSubscription {\n\tviewportUnsubscribe: () => void;\n\trouteListener: TuiInputListener;\n\trouteUnsubscribe: () => void;\n}\n\nconst viewportInputSubscriptions = new WeakMap<AtomicTuiAltScreen, ViewportInputSubscription>();\n\ninterface ParsedMouseSequence {\n\treadonly data: string;\n\treadonly button: number;\n\treadonly x: number;\n\treadonly y: number;\n\treadonly isRelease: boolean;\n}\n\nconst SGR_MOUSE_SEQUENCE = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])/;\nconst LEFT_MOUSE_MODIFIER_MASK = 4 | 8 | 16;\n\nfunction parseMouseSequences(data: string): ParsedMouseSequence[] | undefined {\n\tif (data.length === 0) return undefined;\n\tconst sequences: ParsedMouseSequence[] = [];\n\tlet offset = 0;\n\twhile (offset < data.length) {\n\t\tconst remaining = data.slice(offset);\n\t\tconst sgr = SGR_MOUSE_SEQUENCE.exec(remaining);\n\t\tif (sgr) {\n\t\t\tconst sequence = sgr[0]!;\n\t\t\tsequences.push({\n\t\t\t\tdata: sequence,\n\t\t\t\tbutton: Number.parseInt(sgr[1]!, 10),\n\t\t\t\tx: Number.parseInt(sgr[2]!, 10) - 1,\n\t\t\t\ty: Number.parseInt(sgr[3]!, 10) - 1,\n\t\t\t\tisRelease: sgr[4] === \"m\",\n\t\t\t});\n\t\t\toffset += sequence.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (remaining.startsWith(\"\\x1b[M\") && remaining.length >= 6) {\n\t\t\tconst sequence = remaining.slice(0, 6);\n\t\t\tsequences.push({\n\t\t\t\tdata: sequence,\n\t\t\t\tbutton: sequence.charCodeAt(3) - 32,\n\t\t\t\tx: sequence.charCodeAt(4) - 33,\n\t\t\t\ty: sequence.charCodeAt(5) - 33,\n\t\t\t\tisRelease: false,\n\t\t\t});\n\t\t\toffset += 6;\n\t\t\tcontinue;\n\t\t}\n\t\treturn undefined;\n\t}\n\treturn sequences;\n}\n\n/** Whether every report in a mouse chunk is a vertical wheel event. */\nexport function isMouseWheelInput(data: string): boolean {\n\tconst sequences = parseMouseSequences(data);\n\treturn (\n\t\tsequences !== undefined &&\n\t\tsequences.length > 0 &&\n\t\tsequences.every(({ button }) => {\n\t\t\tconst direction = button & 3;\n\t\t\treturn (button & 64) !== 0 && (direction === 0 || direction === 1);\n\t\t})\n\t);\n}\n\nfunction isLeftMouseButton(sequence: ParsedMouseSequence): boolean {\n\tconst { button } = sequence;\n\tif ((button & 64) !== 0) return false;\n\tconst held = button & 3;\n\t// A release carries no button identity on the terminals upstream #7963\n\t// describes: they report the generic SGR code 3 rather than 0. pi-tui 0.84.2\n\t// ends a selection on `release && (button & 3) === 3`\n\t// (`dist/tui-alt-screen.js:796`), so a release Atomic drops here leaves the\n\t// press it already forwarded open — the selection never closes and the OSC 8\n\t// link under the press never activates. Shift, Meta/Option, and Ctrl are\n\t// application-bypass gestures on press and motion, but a release can retain\n\t// those bits and still has to close a selection.\n\tif (sequence.isRelease) return held === 0 || held === 3;\n\treturn held === 0 && (button & LEFT_MOUSE_MODIFIER_MASK) === 0;\n}\n\n/** Whether a mouse chunk contains a left-button selection gesture. */\nfunction isLeftMouseSequence(data: string): boolean {\n\treturn parseMouseSequences(data)?.some((sequence) => isLeftMouseButton(sequence)) ?? false;\n}\n\n/**\n * Replay a chunk one report at a time because pi-tui parses one report per\n * call. Only a chunk whose every byte is a mouse report is split; anything else\n * is replayed verbatim.\n *\n * **Probe, pi 0.84.2 (upstream `2a95ef70`, `06ed8716`):** neither the\n * lone-ESC timeout scope nor the split-`Alt+Enter` reassembly is affected by\n * this replay. Both land in `StdinBuffer`/`ProcessTerminal`\n * (`dist/stdin-buffer.js:process`, `dist/terminal.js:48`), which assemble\n * complete sequences before any listener runs; Atomic builds pi-tui's own\n * `ProcessTerminal` in `createFullscreenTui`/`createInteractiveTui` below and\n * overrides neither the buffer nor its escape timeout. A reassembled `\\x1b` or\n * `\\x1b\\r` reaches this function as one chunk, fails `parseMouseSequences`, and\n * is handed on unsplit — so a viewport action bound to `escape` or `alt+enter`\n * still matches after a decline.\n * Outcome: no breakage, no fix needed — covered by the replay probes in\n * `test/pi-0.84.2-overlay-viewport-deferral.test.ts`.\n */\nfunction replayMouseInput(viewportListener: TuiInputListener, data: string): void {\n\tconst sequences = parseMouseSequences(data);\n\tif (!sequences) {\n\t\tviewportListener(data);\n\t\treturn;\n\t}\n\tfor (const sequence of sequences) viewportListener(sequence.data);\n}\n\n/**\n * The first `addInputListener` call is load-bearing: pi-tui 0.84.2 registers\n * its viewport listener from `TuiAltScreen`'s constructor\n * (`dist/tui-alt-screen.js:85`). Keep the viewport wrapper first so mouse,\n * selection, and focus cleanup retain pi-tui's ordering. Put the focused-input\n * route last so application listeners still receive deferred viewport keys.\n */\nclass AtomicTuiAltScreen extends TuiAltScreen {\n\tconstructor(\n\t\tterminal: Terminal,\n\t\tshowHardwareCursor: boolean,\n\t\tlogDirectory: string,\n\t\toptions: ConstructorParameters<typeof TuiAltScreen>[3],\n\t\tviewportInputGate?: ViewportInputGate,\n\t\tonOverlayUnhandledInput?: (data: string) => boolean,\n\t) {\n\t\tsuper(terminal, showHardwareCursor, logDirectory, options);\n\t\tif (viewportInputGate) viewportInputGates.set(this, viewportInputGate);\n\t\tif (onOverlayUnhandledInput) overlayUnhandledInputHandlers.set(this, onOverlayUnhandledInput);\n\t\t// pi-tui 0.84.2 added `shouldDeferViewportInputToOverlay()`, which drops\n\t\t// viewport keys and wheel reports while an overlay holds focus (upstream\n\t\t// #7894). Atomic's gate offers that input to the focused overlay first and\n\t\t// replays only what the overlay declined (#2378 / PR #2381); pi-tui then\n\t\t// defers the replay a second time and the transcript freezes behind an\n\t\t// open dialog. Suppress the native answer for the replay alone. Input the\n\t\t// gate never routed through the overlay keeps pi-tui's routing and its\n\t\t// own deferral.\n\t\tconst deferral = this as unknown as TuiAltScreenViewportDeferral;\n\t\tconst deferToOverlay = deferral.shouldDeferViewportInputToOverlay?.bind(this);\n\t\tdeferral.shouldDeferViewportInputToOverlay = () => !viewportInputReplays.has(this) && deferToOverlay?.() === true;\n\n\t\t// pi-tui 0.85 owns the jump-to-end indicator, but its hit test runs before Atomic's\n\t\t// focused-overlay input gate. Let the gate offer that press to the overlay first.\n\t\tconst indicator = this as unknown as TuiAltScreenScrollToEndIndicatorInternals;\n\t\tconst handleScrollToEndIndicator = indicator.handleScrollToEndIndicatorMouseEvent.bind(this);\n\t\tindicator.handleScrollToEndIndicatorMouseEvent = (event) =>\n\t\t\tthis.isFocusedOverlay() ? false : handleScrollToEndIndicator(event);\n\t}\n\n\t/**\n\t * Last stop before pi-tui turns the composited screen into bytes, and where\n\t * it already removes its own `CURSOR_MARKER`. Every component tree that this\n\t * renderer paints converges here, so one strip covers the overlay, inline,\n\t * widget, and workflows stage-chat mounts at once — including hosts that\n\t * never call `ReservedBottomOverlay.takeActiveRow`. The mark is zero-width,\n\t * so removing it after cursor extraction cannot move a column.\n\t */\n\tprotected override applyLineResets(lines: string[]): string[] {\n\t\tif (overlayOwnedSelections.has(this) && !this.isFocusedOverlay()) this.clearOverlayOwnedSelection();\n\t\treturn stripOverlayActiveRowMarker(super.applyLineResets(lines));\n\t}\n\n\tprivate clearOverlayOwnedSelection(): void {\n\t\tconst selection = this as unknown as TuiAltScreenSelectionInternals;\n\t\tselection.selectionAnchor = undefined;\n\t\tselection.selectionFocus = undefined;\n\t\tselection.selectionInitialRange = undefined;\n\t\tselection.selectionPressActive = false;\n\t\tselection.selectionDragged = false;\n\t\tselection.lastClick = undefined;\n\t\toverlayOwnedSelections.delete(this);\n\t}\n\n\t/**\n\t * Keep pi-tui's private predicate as the fallback for its single-report\n\t * grammar. Injected terminals can deliver coalesced reports, so parse those\n\t * chunks locally before asking pi-tui about an unparsed value.\n\t */\n\tprivate isPiTuiMouseSequence(data: string): boolean {\n\t\tif (parseMouseSequences(data)) return true;\n\t\tconst predicate = (this as unknown as Partial<TuiAltScreenMouseInternals>).isMouseSequence;\n\t\treturn typeof predicate === \"function\" ? predicate.call(this, data) : false;\n\t}\n\n\tprivate isFocusedOverlay(): boolean {\n\t\tconst tui = this as unknown as TuiOverlayInternals;\n\t\treturn tui.overlayStack.some((entry) => entry.component === this.getFocusedComponent());\n\t}\n\n\toverride addInputListener(listener: TuiInputListener): () => void {\n\t\tif (!viewportInputListeners.has(this)) {\n\t\t\tviewportInputListeners.add(this);\n\t\t\tconst subscription: ViewportInputSubscription = {\n\t\t\t\tviewportUnsubscribe: () => {},\n\t\t\t\trouteListener: (data) => this.routeViewportInput(listener, data),\n\t\t\t\trouteUnsubscribe: () => {},\n\t\t\t};\n\t\t\tviewportInputSubscriptions.set(this, subscription);\n\t\t\tsubscription.viewportUnsubscribe = super.addInputListener((data) => {\n\t\t\t\tconst gate = viewportInputGates.get(this);\n\t\t\t\tconst isMouseInput = gate ? this.isPiTuiMouseSequence(data) : false;\n\t\t\t\tif (gate && !gate(data, isMouseInput, this.isFocusedOverlay(), false)) return undefined;\n\t\t\t\treturn listener(data);\n\t\t\t});\n\t\t\tsubscription.routeUnsubscribe = super.addInputListener(subscription.routeListener);\n\t\t\treturn () => {\n\t\t\t\tsubscription.viewportUnsubscribe();\n\t\t\t\tsubscription.routeUnsubscribe();\n\t\t\t\tviewportInputSubscriptions.delete(this);\n\t\t\t\tviewportInputListeners.delete(this);\n\t\t\t};\n\t\t}\n\n\t\tconst subscription = viewportInputSubscriptions.get(this);\n\t\tif (!subscription) return super.addInputListener(listener);\n\t\tsubscription.routeUnsubscribe();\n\t\tconst unsubscribe = super.addInputListener(listener);\n\t\tsubscription.routeUnsubscribe = super.addInputListener(subscription.routeListener);\n\t\treturn unsubscribe;\n\t}\n\n\tprivate repairOverlayFocus(): void {\n\t\tconst tui = this as unknown as TuiOverlayInternals;\n\t\tconst focused = this.getFocusedComponent();\n\t\tconst focusedOverlay = tui.overlayStack.find((entry) => entry.component === focused);\n\t\tif (focusedOverlay && !tui.isOverlayVisible(focusedOverlay)) {\n\t\t\tconst topVisible = tui.getTopmostVisibleOverlay();\n\t\t\tif (topVisible) {\n\t\t\t\tthis.setFocus(topVisible.component);\n\t\t\t} else {\n\t\t\t\ttui.setFocusInternal({ component: focusedOverlay.preFocus, overlayFocusRestore: \"preserve\" });\n\t\t\t}\n\t\t}\n\n\t\tconst focusIsOverlay = tui.overlayStack.some((entry) => entry.component === this.getFocusedComponent());\n\t\tif (focusIsOverlay) return;\n\n\t\tconst restoreState = tui.getVisibleOverlayFocusRestore();\n\t\tif (restoreState.status === \"eligible\") {\n\t\t\tthis.setFocus(restoreState.overlay.component);\n\t\t} else if (restoreState.status === \"blocked\" && restoreState.blockedBy !== this.getFocusedComponent()) {\n\t\t\tif (restoreState.resume.status === \"restore-overlay\") {\n\t\t\t\tthis.setFocus(restoreState.overlay.component);\n\t\t\t} else {\n\t\t\t\ttui.clearOverlayFocusRestore();\n\t\t\t\tthis.setFocus(restoreState.resume.target);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Keep pi-tui's selection state in sync while an overlay handles a left gesture. */\n\tprivate forwardSelectionMouseInput(viewportListener: TuiInputListener, data: string, focused: Component): void {\n\t\tif (this.getFocusedComponent() !== focused || !isLeftMouseSequence(data)) return;\n\t\tfor (const sequence of parseMouseSequences(data) ?? []) {\n\t\t\tif (isLeftMouseButton(sequence)) viewportListener(sequence.data);\n\t\t}\n\t\toverlayOwnedSelections.add(this);\n\t}\n\t/**\n\t * Replay input the focused overlay declined. pi-tui's native overlay\n\t * deferral is suppressed for the duration, because this chunk has already\n\t * been offered to the overlay it would defer to.\n\t */\n\tprivate replayViewportInput(viewportListener: TuiInputListener, data: string): void {\n\t\tviewportInputReplays.add(this);\n\t\ttry {\n\t\t\treplayMouseInput(viewportListener, data);\n\t\t} finally {\n\t\t\tviewportInputReplays.delete(this);\n\t\t}\n\t}\n\t/** Dispatch a declined chunk to the host action the gated route owns. */\n\tprivate handleOverlayUnhandledInput(data: string, focused: Component | null): boolean {\n\t\tif (this.getFocusedComponent() !== focused || !this.isFocusedOverlay()) return false;\n\t\treturn overlayUnhandledInputHandlers.get(this)?.(data) === true;\n\t}\n\n\t/**\n\t * Finish a chunk a focused overlay's asynchronous handler declined.\n\t *\n\t * Every settled result other than `true` is a decline. The component\n\t * contract is `boolean | undefined | Promise<boolean | undefined>`\n\t * (`ExtensionCustomComponent`), and both `docs/tui.md` and\n\t * `docs/extensions.md` document `false` *and* `undefined` as viewport\n\t * fallthrough, so a promise resolving `undefined` has to replay exactly like\n\t * one resolving `false` — matching only literal `false` consumed the key and\n\t * froze the transcript. A rejection is a decline for the same reason: the\n\t * overlay produced no answer.\n\t *\n\t * The focus guard stays: input that moved focus while the promise was\n\t * pending belongs to whatever holds focus now, not to the transcript.\n\t */\n\tprivate declineAsyncViewportInput(viewportListener: TuiInputListener, data: string, focused: Component): void {\n\t\tif (this.getFocusedComponent() !== focused) return;\n\t\tif (this.handleOverlayUnhandledInput(data, focused)) {\n\t\t\t(this as unknown as TuiOverlayInternals).requestImmediateRender();\n\t\t\treturn;\n\t\t}\n\t\tthis.replayViewportInput(viewportListener, data);\n\t}\n\n\tprivate routeViewportInput(viewportListener: TuiInputListener, data: string): ReturnType<TuiInputListener> {\n\t\tconst gate = viewportInputGates.get(this);\n\t\tconst isMouseInput = gate ? this.isPiTuiMouseSequence(data) : false;\n\t\tif (!gate || gate(data, isMouseInput, this.isFocusedOverlay(), false)) return undefined;\n\n\t\t// Returning `consume` below skips pi-tui's post-listener phase. Mirror its\n\t\t// overlay-focus repair before reading the focused component so a resize\n\t\t// cannot send a gated key to an invisible overlay.\n\t\tthis.repairOverlayFocus();\n\t\tconst focused = this.getFocusedComponent();\n\t\tconst tui = this as unknown as TuiOverlayInternals;\n\t\tif (focused?.handleInput && (!isKeyRelease(data) || focused.wantsKeyRelease === true)) {\n\t\t\tconst handleInput = focused.handleInput as (\n\t\t\t\tdata: string,\n\t\t\t) => boolean | undefined | Promise<boolean | undefined>;\n\t\t\tconst result = handleInput.call(focused, data);\n\t\t\tif (result instanceof Promise) {\n\t\t\t\tvoid result.then(\n\t\t\t\t\t(handled) => {\n\t\t\t\t\t\tif (handled === true) {\n\t\t\t\t\t\t\tthis.forwardSelectionMouseInput(viewportListener, data, focused);\n\t\t\t\t\t\t\ttui.requestImmediateRender();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.declineAsyncViewportInput(viewportListener, data, focused);\n\t\t\t\t\t},\n\t\t\t\t\t() => this.declineAsyncViewportInput(viewportListener, data, focused),\n\t\t\t\t);\n\t\t\t\treturn { consume: true };\n\t\t\t}\n\t\t\tif (result === true) {\n\t\t\t\tthis.forwardSelectionMouseInput(viewportListener, data, focused);\n\t\t\t\ttui.requestImmediateRender();\n\t\t\t\treturn { consume: true };\n\t\t\t}\n\t\t}\n\n\t\tif (this.handleOverlayUnhandledInput(data, focused)) {\n\t\t\ttui.requestImmediateRender();\n\t\t\treturn { consume: true };\n\t\t}\n\t\tthis.replayViewportInput(viewportListener, data);\n\t\treturn { consume: true };\n\t}\n}\n\n/**\n * CI detection follows the convention CI providers actually use: the variable\n * is SET AND NONEMPTY, with any value. GitHub Actions sets `CI=true`, but\n * other providers and users export arbitrary values (`CI=github-actions`,\n * `CI=circleci`); an allowlist of truthy spellings let those reach the\n * alternate screen and write escape sequences into CI logs (Greptile P1 on\n * PR #2308). Only explicit opt-outs (`0`, `false`, empty) read as not-CI.\n */\nfunction isCiEnvironment(value: string | undefined): boolean {\n\tif (value === undefined) return false;\n\tconst normalized = value.trim().toLowerCase();\n\treturn normalized !== \"\" && normalized !== \"0\" && normalized !== \"false\";\n}\n\nclass LifecycleTimingTerminal extends ProcessTerminal {\n\toverride write(data: string): void {\n\t\tmarkLifecycleTiming(\"first-terminal-write\");\n\t\tsuper.write(data);\n\t}\n}\n\nfunction createProcessTerminal(): ProcessTerminal {\n\treturn isLifecycleTimingEnabled() ? new LifecycleTimingTerminal() : new ProcessTerminal();\n}\n\nfunction shouldUseFullscreenTui(usesInjectedTerminal: boolean): boolean {\n\tif (process.env.TERM?.toLowerCase() === \"dumb\") return false;\n\tif (usesInjectedTerminal) return true;\n\treturn process.stdin.isTTY === true && process.stdout.isTTY === true && !isCiEnvironment(process.env.CI);\n}\n\n/**\n * Build Atomic's fullscreen renderer, `viewportInputGate` included, without\n * consulting the environment. `createInteractiveTui` calls this whenever\n * fullscreen applies; fixtures that assert fullscreen behavior call it\n * directly, because `shouldUseFullscreenTui` returns the main-screen fallback\n * under `TERM=dumb` even for an injected terminal and would otherwise hand\n * those tests a renderer with no layout and no gate.\n */\nexport function createFullscreenTui(options: InteractiveTuiOptions): TuiAltScreen {\n\treturn new AtomicTuiAltScreen(\n\t\toptions.terminal ?? createProcessTerminal(),\n\t\toptions.showHardwareCursor,\n\t\toptions.logDirectory,\n\t\t{\n\t\t\tscrollToEndIndicator: () => {\n\t\t\t\tconst shortcut = keyDisplayText(\"tui.altScreen.bottom\");\n\t\t\t\tconst label = ` ↓ Jump to latest message${shortcut ? ` · ${shortcut}` : \"\"} `;\n\t\t\t\treturn theme.bg(\"selectedBg\", theme.fg(\"text\", label));\n\t\t\t},\n\t\t\topenUrl: (url) =>\n\t\t\t\thandleUrlActivation(url, {\n\t\t\t\t\tonOverlayInternalUiAction: options.onOverlayInternalUiAction,\n\t\t\t\t\tonInternalUiAction: options.onInternalUiAction,\n\t\t\t\t\topenUrl: openBrowser,\n\t\t\t\t}),\n\t\t\tonRightClickPaste: options.onRightClickPaste,\n\t\t\tcopyOnSelect: options.copyOnSelect,\n\t\t\tcopySelection: options.copySelection ?? copySelectionToHostClipboard,\n\t\t},\n\t\toptions.shouldHandleViewportInput,\n\t\toptions.onOverlayUnhandledInput,\n\t);\n}\n\n/** Main-screen fallback renderer, carrying the same central mark strip as the fullscreen one. */\nclass AtomicTuiMainScreen extends TuiMainScreen {\n\tprotected override applyLineResets(lines: string[]): string[] {\n\t\treturn stripOverlayActiveRowMarker(super.applyLineResets(lines));\n\t}\n}\n\n/** Creates the fullscreen renderer for interactive TTY sessions. */\nexport function createInteractiveTui(options: InteractiveTuiOptions): InteractiveTui {\n\tconst usesInjectedTerminal = options.terminal !== undefined;\n\tconst terminal = options.terminal ?? createProcessTerminal();\n\tif (!shouldUseFullscreenTui(usesInjectedTerminal)) {\n\t\t// The normal CLI never reaches the interactive mode without a TTY. Keep a\n\t\t// main-screen renderer for internal harnesses and guarded fallback paths.\n\t\treturn new AtomicTuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);\n\t}\n\treturn createFullscreenTui({ ...options, terminal });\n}\n\n/** Keeps existing components pointed at the renderer selected at runtime. */\nexport function createInteractiveTuiReference(getTui: () => TUI): TUI {\n\treturn new Proxy({} as TUI, {\n\t\tget: (_target, property) => {\n\t\t\tconst tui = getTui();\n\t\t\tconst value = Reflect.get(tui, property, tui);\n\t\t\tif (typeof value !== \"function\") return value;\n\t\t\tlet methodTui = tui;\n\t\t\tlet method = value;\n\t\t\treturn (...args: unknown[]) => {\n\t\t\t\tconst currentTui = getTui();\n\t\t\t\tif (currentTui !== methodTui) {\n\t\t\t\t\tconst currentMethod = Reflect.get(currentTui, property, currentTui);\n\t\t\t\t\tif (typeof currentMethod !== \"function\") {\n\t\t\t\t\t\tthrow new TypeError(`TUI property ${String(property)} is not callable`);\n\t\t\t\t\t}\n\t\t\t\t\tmethodTui = currentTui;\n\t\t\t\t\tmethod = currentMethod;\n\t\t\t\t}\n\t\t\t\treturn Reflect.apply(method, methodTui, args);\n\t\t\t};\n\t\t},\n\t\tset: (_target, property, value) => {\n\t\t\tconst tui = getTui();\n\t\t\treturn Reflect.set(tui, property, value, tui);\n\t\t},\n\t\thas: (_target, property) => Reflect.has(getTui(), property),\n\t\tgetPrototypeOf: () => Reflect.getPrototypeOf(getTui()),\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactive-tui.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-tui.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Component,\n\tisKeyRelease,\n\tProcessTerminal,\n\ttype Terminal,\n\ttype TUI,\n\tTuiAltScreen,\n\ttype TuiInputListener,\n\tTuiMainScreen,\n} from \"@earendil-works/pi-tui\";\nimport { stripOverlayActiveRowMarker } from \"../../core/extensions/ui-types.ts\";\nimport { isLifecycleTimingEnabled, markLifecycleTiming } from \"../../core/lifecycle-timings.ts\";\nimport { copyToClipboard } from \"../../utils/clipboard.ts\";\nimport { openBrowser } from \"../../utils/open-browser.ts\";\nimport { keyDisplayText } from \"./components/keybinding-hints.js\";\nimport { TRANSCRIPT_JUMP_TO_END_URL } from \"./components/transcript-follow-indicator.ts\";\nimport { theme } from \"./theme/theme.js\";\n\ninterface TuiOverlayEntry {\n\tcomponent: Component;\n\tpreFocus: Component | null;\n}\n\ninterface InternalUiActionOverlay extends Component {\n\thandlesInternalUiAction?: boolean;\n}\n\ntype TuiOverlayFocusRestore =\n\t| { status: \"inactive\" }\n\t| { status: \"eligible\"; overlay: TuiOverlayEntry }\n\t| {\n\t\t\tstatus: \"blocked\";\n\t\t\toverlay: TuiOverlayEntry;\n\t\t\tblockedBy: Component;\n\t\t\tresume: { status: \"restore-overlay\" } | { status: \"focus-target\"; target: Component | null };\n\t };\n\ninterface TuiOverlayInternals {\n\toverlayStack: TuiOverlayEntry[];\n\tisOverlayVisible(entry: TuiOverlayEntry): boolean;\n\tgetTopmostVisibleOverlay(): TuiOverlayEntry | undefined;\n\tsetFocusInternal(options: { component: Component | null; overlayFocusRestore: \"preserve\" }): void;\n\tgetVisibleOverlayFocusRestore(): TuiOverlayFocusRestore;\n\tclearOverlayFocusRestore(): void;\n\trequestImmediateRender(): void;\n}\n/** pi-tui 0.84.2 keeps this canonical mouse predicate private (tui-alt-screen.d.ts:114). */\ninterface TuiAltScreenMouseInternals {\n\tisMouseSequence(data: string): boolean;\n}\n\n/** pi-tui 0.84.2 keeps its overlay-deferral predicate private (tui-alt-screen.d.ts:84). */\ninterface TuiAltScreenViewportDeferral {\n\tshouldDeferViewportInputToOverlay?(): boolean;\n}\n\ninterface TuiAltScreenScrollToEndIndicatorInternals {\n\thandleScrollToEndIndicatorMouseEvent(event: unknown): boolean;\n}\n\n/** pi-tui 0.85.1's private copy route only understands boolean callbacks. */\ninterface TuiAltScreenClipboardInternals {\n\tcopyTextToClipboard(text: string): Promise<boolean>;\n}\n\ninterface TuiAltScreenSelectionInternals {\n\tselectionAnchor?: unknown;\n\tselectionFocus?: unknown;\n\tselectionInitialRange?: unknown;\n\tselectionPressActive: boolean;\n\tselectionDragged: boolean;\n\tlastClick?: unknown;\n}\n\nexport type InteractiveTui = TuiMainScreen | TuiAltScreen;\n\nexport function isOverlayMounted(tui: TUI, component: Component): boolean {\n\tconst internals = tui as unknown as Partial<TuiOverlayInternals>;\n\treturn (\n\t\tArray.isArray(internals.overlayStack) && internals.overlayStack.some((entry) => entry.component === component)\n\t);\n}\nexport function getFocusedOverlay(tui: InteractiveTui): Component | undefined {\n\tconst focused = tui.getFocusedComponent();\n\tif (!focused) return undefined;\n\tconst internals = tui as unknown as Partial<TuiOverlayInternals>;\n\tif (!Array.isArray(internals.overlayStack) || typeof internals.isOverlayVisible !== \"function\") return undefined;\n\tconst entry = internals.overlayStack.find((candidate) => candidate.component === focused);\n\treturn entry && internals.isOverlayVisible(entry) ? focused : undefined;\n}\n\nexport function handleFocusedOverlayInternalUiAction(tui: InteractiveTui, url: string): InternalUiActionResult {\n\tconst overlay = getFocusedOverlay(tui);\n\tif (!overlay || (overlay as InternalUiActionOverlay).handlesInternalUiAction !== true) return undefined;\n\tconst handleInput = overlay.handleInput as\n\t\t| ((data: string) => boolean | undefined | Promise<boolean | undefined>)\n\t\t| undefined;\n\treturn handleInput?.call(overlay, url);\n}\n\nexport type InternalUiActionResult = boolean | undefined | Promise<boolean | undefined>;\n\nexport interface InteractiveTuiOptions {\n\tshowHardwareCursor: boolean;\n\tlogDirectory: string;\n\tterminal?: Terminal;\n\tcopyOnSelect?: boolean;\n\tonRightClickPaste?: () => void;\n\tonOverlayInternalUiAction?: (url: string) => InternalUiActionResult;\n\tonInternalUiAction?: (url: string) => InternalUiActionResult;\n\t/**\n\t * Return false to let a focused overlay receive viewport input first.\n\t * Mouse input is deferred only while the focused component belongs to an\n\t * overlay; non-overlay focus keeps pi-tui's transcript selection path.\n\t */\n\tshouldHandleViewportInput?: (\n\t\tdata: string,\n\t\tisMouseInput: boolean,\n\t\tfocusedIsOverlay: boolean,\n\t\t_focusedIsViewportSearch: boolean,\n\t) => boolean;\n\t/** Handle an unconsumed overlay input before replaying it to the viewport. */\n\tonOverlayUnhandledInput?: (data: string) => boolean;\n\t/**\n\t * Copy selected text; return true on success, false or a diagnostic on failure.\n\t * Defaults to Atomic's clipboard implementation and platform diagnostics.\n\t */\n\tcopySelection?: (text: string) => Promise<boolean | string>;\n}\n\n/** The default selection-copy route: Atomic's host clipboard write. */\nasync function copySelectionToHostClipboard(text: string): Promise<boolean | string> {\n\ttry {\n\t\tawait copyToClipboard(text);\n\t\treturn true;\n\t} catch (error) {\n\t\treturn error instanceof Error ? error.message : String(error);\n\t}\n}\n\nexport interface UrlActivationHandlers {\n\tonOverlayInternalUiAction?: (url: string) => InternalUiActionResult;\n\tonInternalUiAction?: (url: string) => InternalUiActionResult;\n\topenUrl: (url: string) => void;\n}\n\nfunction fallbackInternalUiAction(url: string, handlers: UrlActivationHandlers): void {\n\thandlers.onInternalUiAction?.(url);\n}\n\nfunction routeInternalUiAction(url: string, handlers: UrlActivationHandlers): void {\n\tlet result: InternalUiActionResult;\n\ttry {\n\t\tresult = handlers.onOverlayInternalUiAction?.(url);\n\t} catch {\n\t\tfallbackInternalUiAction(url, handlers);\n\t\treturn;\n\t}\n\tif (result instanceof Promise) {\n\t\tvoid result.then(\n\t\t\t(handled) => {\n\t\t\t\tif (handled !== true) fallbackInternalUiAction(url, handlers);\n\t\t\t},\n\t\t\t() => fallbackInternalUiAction(url, handlers),\n\t\t);\n\t\treturn;\n\t}\n\tif (result !== true) fallbackInternalUiAction(url, handlers);\n}\n\n/** Route OSC 8 activation without allowing unknown internal URLs to escape to a browser. */\nexport function handleUrlActivation(url: string, handlers: UrlActivationHandlers): void {\n\tconst internalUiScheme = \"atomic-ui:\";\n\tif (url.slice(0, internalUiScheme.length).toLowerCase() === internalUiScheme) {\n\t\tconst schemeEnd = url.indexOf(\":\");\n\t\tconst normalizedInternalUrl = `${url.slice(0, schemeEnd).toLowerCase()}${url.slice(schemeEnd)}`;\n\t\t// Forward the normalized URL: overlay-side matching is exact, so a\n\t\t// mixed-case scheme must not reach an overlay as an unrecognized string.\n\t\tif (normalizedInternalUrl === TRANSCRIPT_JUMP_TO_END_URL) routeInternalUiAction(normalizedInternalUrl, handlers);\n\t\treturn;\n\t}\n\n\thandlers.openUrl(url);\n}\n\nconst viewportInputListeners = new WeakSet<AtomicTuiAltScreen>();\n\ntype ViewportInputGate = (\n\tdata: string,\n\tisMouseInput: boolean,\n\tfocusedIsOverlay: boolean,\n\t_focusedIsViewportSearch: boolean,\n) => boolean;\n\nconst viewportInputGates = new WeakMap<AtomicTuiAltScreen, ViewportInputGate>();\nconst overlayUnhandledInputHandlers = new WeakMap<AtomicTuiAltScreen, (data: string) => boolean>();\n/** Instances currently replaying overlay-declined input into pi-tui's viewport listener. */\nconst viewportInputReplays = new WeakSet<AtomicTuiAltScreen>();\n/** Selections begun over Atomic overlays must never trigger or survive into main-chat clipboard actions. */\nconst overlayOwnedSelections = new WeakSet<AtomicTuiAltScreen>();\ninterface ViewportInputSubscription {\n\tviewportUnsubscribe: () => void;\n\trouteListener: TuiInputListener;\n\trouteUnsubscribe: () => void;\n}\n\nconst viewportInputSubscriptions = new WeakMap<AtomicTuiAltScreen, ViewportInputSubscription>();\n\ninterface ParsedMouseSequence {\n\treadonly data: string;\n\treadonly button: number;\n\treadonly x: number;\n\treadonly y: number;\n\treadonly isRelease: boolean;\n}\n\nconst SGR_MOUSE_SEQUENCE = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])/;\nconst LEFT_MOUSE_MODIFIER_MASK = 4 | 8 | 16;\n\nfunction parseMouseSequences(data: string): ParsedMouseSequence[] | undefined {\n\tif (data.length === 0) return undefined;\n\tconst sequences: ParsedMouseSequence[] = [];\n\tlet offset = 0;\n\twhile (offset < data.length) {\n\t\tconst remaining = data.slice(offset);\n\t\tconst sgr = SGR_MOUSE_SEQUENCE.exec(remaining);\n\t\tif (sgr) {\n\t\t\tconst sequence = sgr[0]!;\n\t\t\tsequences.push({\n\t\t\t\tdata: sequence,\n\t\t\t\tbutton: Number.parseInt(sgr[1]!, 10),\n\t\t\t\tx: Number.parseInt(sgr[2]!, 10) - 1,\n\t\t\t\ty: Number.parseInt(sgr[3]!, 10) - 1,\n\t\t\t\tisRelease: sgr[4] === \"m\",\n\t\t\t});\n\t\t\toffset += sequence.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (remaining.startsWith(\"\\x1b[M\") && remaining.length >= 6) {\n\t\t\tconst sequence = remaining.slice(0, 6);\n\t\t\tsequences.push({\n\t\t\t\tdata: sequence,\n\t\t\t\tbutton: sequence.charCodeAt(3) - 32,\n\t\t\t\tx: sequence.charCodeAt(4) - 33,\n\t\t\t\ty: sequence.charCodeAt(5) - 33,\n\t\t\t\tisRelease: false,\n\t\t\t});\n\t\t\toffset += 6;\n\t\t\tcontinue;\n\t\t}\n\t\treturn undefined;\n\t}\n\treturn sequences;\n}\n\n/** Whether every report in a mouse chunk is a vertical wheel event. */\nexport function isMouseWheelInput(data: string): boolean {\n\tconst sequences = parseMouseSequences(data);\n\treturn (\n\t\tsequences !== undefined &&\n\t\tsequences.length > 0 &&\n\t\tsequences.every(({ button }) => {\n\t\t\tconst direction = button & 3;\n\t\t\treturn (button & 64) !== 0 && (direction === 0 || direction === 1);\n\t\t})\n\t);\n}\n\nfunction isLeftMouseButton(sequence: ParsedMouseSequence): boolean {\n\tconst { button } = sequence;\n\tif ((button & 64) !== 0) return false;\n\tconst held = button & 3;\n\t// A release carries no button identity on the terminals upstream #7963\n\t// describes: they report the generic SGR code 3 rather than 0. pi-tui 0.84.2\n\t// ends a selection on `release && (button & 3) === 3`\n\t// (`dist/tui-alt-screen.js:796`), so a release Atomic drops here leaves the\n\t// press it already forwarded open — the selection never closes and the OSC 8\n\t// link under the press never activates. Shift, Meta/Option, and Ctrl are\n\t// application-bypass gestures on press and motion, but a release can retain\n\t// those bits and still has to close a selection.\n\tif (sequence.isRelease) return held === 0 || held === 3;\n\treturn held === 0 && (button & LEFT_MOUSE_MODIFIER_MASK) === 0;\n}\n\n/** Whether a mouse chunk contains a left-button selection gesture. */\nfunction isLeftMouseSequence(data: string): boolean {\n\treturn parseMouseSequences(data)?.some((sequence) => isLeftMouseButton(sequence)) ?? false;\n}\n\n/**\n * Replay a chunk one report at a time because pi-tui parses one report per\n * call. Only a chunk whose every byte is a mouse report is split; anything else\n * is replayed verbatim.\n *\n * **Probe, pi 0.84.2 (upstream `2a95ef70`, `06ed8716`):** neither the\n * lone-ESC timeout scope nor the split-`Alt+Enter` reassembly is affected by\n * this replay. Both land in `StdinBuffer`/`ProcessTerminal`\n * (`dist/stdin-buffer.js:process`, `dist/terminal.js:48`), which assemble\n * complete sequences before any listener runs; Atomic builds pi-tui's own\n * `ProcessTerminal` in `createFullscreenTui`/`createInteractiveTui` below and\n * overrides neither the buffer nor its escape timeout. A reassembled `\\x1b` or\n * `\\x1b\\r` reaches this function as one chunk, fails `parseMouseSequences`, and\n * is handed on unsplit — so a viewport action bound to `escape` or `alt+enter`\n * still matches after a decline.\n * Outcome: no breakage, no fix needed — covered by the replay probes in\n * `test/pi-0.84.2-overlay-viewport-deferral.test.ts`.\n */\nfunction replayMouseInput(viewportListener: TuiInputListener, data: string): void {\n\tconst sequences = parseMouseSequences(data);\n\tif (!sequences) {\n\t\tviewportListener(data);\n\t\treturn;\n\t}\n\tfor (const sequence of sequences) viewportListener(sequence.data);\n}\n\n/**\n * The first `addInputListener` call is load-bearing: pi-tui 0.84.2 registers\n * its viewport listener from `TuiAltScreen`'s constructor\n * (`dist/tui-alt-screen.js:85`). Keep the viewport wrapper first so mouse,\n * selection, and focus cleanup retain pi-tui's ordering. Put the focused-input\n * route last so application listeners still receive deferred viewport keys.\n */\nclass AtomicTuiAltScreen extends TuiAltScreen {\n\tconstructor(\n\t\tterminal: Terminal,\n\t\tshowHardwareCursor: boolean,\n\t\tlogDirectory: string,\n\t\toptions: ConstructorParameters<typeof TuiAltScreen>[3],\n\t\tviewportInputGate?: ViewportInputGate,\n\t\tonOverlayUnhandledInput?: (data: string) => boolean,\n\t\tcopySelection: NonNullable<InteractiveTuiOptions[\"copySelection\"]> = copySelectionToHostClipboard,\n\t) {\n\t\tsuper(terminal, showHardwareCursor, logDirectory, options);\n\t\tif (viewportInputGate) viewportInputGates.set(this, viewportInputGate);\n\t\tif (onOverlayUnhandledInput) overlayUnhandledInputHandlers.set(this, onOverlayUnhandledInput);\n\t\t// Adapt the private route rather than returning a truthy error string to\n\t\t// pi-tui 0.85.1. Both keyboard and mouse selection use this same door.\n\t\tconst clipboardRoute = this as unknown as TuiAltScreenClipboardInternals;\n\t\tclipboardRoute.copyTextToClipboard = async (text) => {\n\t\t\tconst result = await copySelection(text);\n\t\t\tconst copied = result === true;\n\t\t\tthis.flash(\n\t\t\t\tcopied ? \"Copied!\" : typeof result === \"string\" ? result : \"Copy failed\",\n\t\t\t\tcopied ? undefined : 5000,\n\t\t\t);\n\t\t\treturn copied;\n\t\t};\n\t\t// pi-tui 0.84.2 added `shouldDeferViewportInputToOverlay()`, which drops\n\t\t// viewport keys and wheel reports while an overlay holds focus (upstream\n\t\t// #7894). Atomic's gate offers that input to the focused overlay first and\n\t\t// replays only what the overlay declined (#2378 / PR #2381); pi-tui then\n\t\t// defers the replay a second time and the transcript freezes behind an\n\t\t// open dialog. Suppress the native answer for the replay alone. Input the\n\t\t// gate never routed through the overlay keeps pi-tui's routing and its\n\t\t// own deferral.\n\t\tconst deferral = this as unknown as TuiAltScreenViewportDeferral;\n\t\tconst deferToOverlay = deferral.shouldDeferViewportInputToOverlay?.bind(this);\n\t\tdeferral.shouldDeferViewportInputToOverlay = () => !viewportInputReplays.has(this) && deferToOverlay?.() === true;\n\n\t\t// pi-tui 0.85 owns the jump-to-end indicator, but its hit test runs before Atomic's\n\t\t// focused-overlay input gate. Let the gate offer that press to the overlay first.\n\t\tconst indicator = this as unknown as TuiAltScreenScrollToEndIndicatorInternals;\n\t\tconst handleScrollToEndIndicator = indicator.handleScrollToEndIndicatorMouseEvent.bind(this);\n\t\tindicator.handleScrollToEndIndicatorMouseEvent = (event) =>\n\t\t\tthis.isFocusedOverlay() ? false : handleScrollToEndIndicator(event);\n\t}\n\n\t/**\n\t * Last stop before pi-tui turns the composited screen into bytes, and where\n\t * it already removes its own `CURSOR_MARKER`. Every component tree that this\n\t * renderer paints converges here, so one strip covers the overlay, inline,\n\t * widget, and workflows stage-chat mounts at once — including hosts that\n\t * never call `ReservedBottomOverlay.takeActiveRow`. The mark is zero-width,\n\t * so removing it after cursor extraction cannot move a column.\n\t */\n\tprotected override applyLineResets(lines: string[]): string[] {\n\t\tif (overlayOwnedSelections.has(this) && !this.isFocusedOverlay()) this.clearOverlayOwnedSelection();\n\t\treturn stripOverlayActiveRowMarker(super.applyLineResets(lines));\n\t}\n\n\tprivate clearOverlayOwnedSelection(): void {\n\t\tconst selection = this as unknown as TuiAltScreenSelectionInternals;\n\t\tselection.selectionAnchor = undefined;\n\t\tselection.selectionFocus = undefined;\n\t\tselection.selectionInitialRange = undefined;\n\t\tselection.selectionPressActive = false;\n\t\tselection.selectionDragged = false;\n\t\tselection.lastClick = undefined;\n\t\toverlayOwnedSelections.delete(this);\n\t}\n\n\t/**\n\t * Keep pi-tui's private predicate as the fallback for its single-report\n\t * grammar. Injected terminals can deliver coalesced reports, so parse those\n\t * chunks locally before asking pi-tui about an unparsed value.\n\t */\n\tprivate isPiTuiMouseSequence(data: string): boolean {\n\t\tif (parseMouseSequences(data)) return true;\n\t\tconst predicate = (this as unknown as Partial<TuiAltScreenMouseInternals>).isMouseSequence;\n\t\treturn typeof predicate === \"function\" ? predicate.call(this, data) : false;\n\t}\n\n\tprivate isFocusedOverlay(): boolean {\n\t\tconst tui = this as unknown as TuiOverlayInternals;\n\t\treturn tui.overlayStack.some((entry) => entry.component === this.getFocusedComponent());\n\t}\n\n\toverride addInputListener(listener: TuiInputListener): () => void {\n\t\tif (!viewportInputListeners.has(this)) {\n\t\t\tviewportInputListeners.add(this);\n\t\t\tconst subscription: ViewportInputSubscription = {\n\t\t\t\tviewportUnsubscribe: () => {},\n\t\t\t\trouteListener: (data) => this.routeViewportInput(listener, data),\n\t\t\t\trouteUnsubscribe: () => {},\n\t\t\t};\n\t\t\tviewportInputSubscriptions.set(this, subscription);\n\t\t\tsubscription.viewportUnsubscribe = super.addInputListener((data) => {\n\t\t\t\tconst gate = viewportInputGates.get(this);\n\t\t\t\tconst isMouseInput = gate ? this.isPiTuiMouseSequence(data) : false;\n\t\t\t\tif (gate && !gate(data, isMouseInput, this.isFocusedOverlay(), false)) return undefined;\n\t\t\t\treturn listener(data);\n\t\t\t});\n\t\t\tsubscription.routeUnsubscribe = super.addInputListener(subscription.routeListener);\n\t\t\treturn () => {\n\t\t\t\tsubscription.viewportUnsubscribe();\n\t\t\t\tsubscription.routeUnsubscribe();\n\t\t\t\tviewportInputSubscriptions.delete(this);\n\t\t\t\tviewportInputListeners.delete(this);\n\t\t\t};\n\t\t}\n\n\t\tconst subscription = viewportInputSubscriptions.get(this);\n\t\tif (!subscription) return super.addInputListener(listener);\n\t\tsubscription.routeUnsubscribe();\n\t\tconst unsubscribe = super.addInputListener(listener);\n\t\tsubscription.routeUnsubscribe = super.addInputListener(subscription.routeListener);\n\t\treturn unsubscribe;\n\t}\n\n\tprivate repairOverlayFocus(): void {\n\t\tconst tui = this as unknown as TuiOverlayInternals;\n\t\tconst focused = this.getFocusedComponent();\n\t\tconst focusedOverlay = tui.overlayStack.find((entry) => entry.component === focused);\n\t\tif (focusedOverlay && !tui.isOverlayVisible(focusedOverlay)) {\n\t\t\tconst topVisible = tui.getTopmostVisibleOverlay();\n\t\t\tif (topVisible) {\n\t\t\t\tthis.setFocus(topVisible.component);\n\t\t\t} else {\n\t\t\t\ttui.setFocusInternal({ component: focusedOverlay.preFocus, overlayFocusRestore: \"preserve\" });\n\t\t\t}\n\t\t}\n\n\t\tconst focusIsOverlay = tui.overlayStack.some((entry) => entry.component === this.getFocusedComponent());\n\t\tif (focusIsOverlay) return;\n\n\t\tconst restoreState = tui.getVisibleOverlayFocusRestore();\n\t\tif (restoreState.status === \"eligible\") {\n\t\t\tthis.setFocus(restoreState.overlay.component);\n\t\t} else if (restoreState.status === \"blocked\" && restoreState.blockedBy !== this.getFocusedComponent()) {\n\t\t\tif (restoreState.resume.status === \"restore-overlay\") {\n\t\t\t\tthis.setFocus(restoreState.overlay.component);\n\t\t\t} else {\n\t\t\t\ttui.clearOverlayFocusRestore();\n\t\t\t\tthis.setFocus(restoreState.resume.target);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Keep pi-tui's selection state in sync while an overlay handles a left gesture. */\n\tprivate forwardSelectionMouseInput(viewportListener: TuiInputListener, data: string, focused: Component): void {\n\t\tif (this.getFocusedComponent() !== focused || !isLeftMouseSequence(data)) return;\n\t\tfor (const sequence of parseMouseSequences(data) ?? []) {\n\t\t\tif (isLeftMouseButton(sequence)) viewportListener(sequence.data);\n\t\t}\n\t\toverlayOwnedSelections.add(this);\n\t}\n\t/**\n\t * Replay input the focused overlay declined. pi-tui's native overlay\n\t * deferral is suppressed for the duration, because this chunk has already\n\t * been offered to the overlay it would defer to.\n\t */\n\tprivate replayViewportInput(viewportListener: TuiInputListener, data: string): void {\n\t\tviewportInputReplays.add(this);\n\t\ttry {\n\t\t\treplayMouseInput(viewportListener, data);\n\t\t} finally {\n\t\t\tviewportInputReplays.delete(this);\n\t\t}\n\t}\n\t/** Dispatch a declined chunk to the host action the gated route owns. */\n\tprivate handleOverlayUnhandledInput(data: string, focused: Component | null): boolean {\n\t\tif (this.getFocusedComponent() !== focused || !this.isFocusedOverlay()) return false;\n\t\treturn overlayUnhandledInputHandlers.get(this)?.(data) === true;\n\t}\n\n\t/**\n\t * Finish a chunk a focused overlay's asynchronous handler declined.\n\t *\n\t * Every settled result other than `true` is a decline. The component\n\t * contract is `boolean | undefined | Promise<boolean | undefined>`\n\t * (`ExtensionCustomComponent`), and both `docs/tui.md` and\n\t * `docs/extensions.md` document `false` *and* `undefined` as viewport\n\t * fallthrough, so a promise resolving `undefined` has to replay exactly like\n\t * one resolving `false` — matching only literal `false` consumed the key and\n\t * froze the transcript. A rejection is a decline for the same reason: the\n\t * overlay produced no answer.\n\t *\n\t * The focus guard stays: input that moved focus while the promise was\n\t * pending belongs to whatever holds focus now, not to the transcript.\n\t */\n\tprivate declineAsyncViewportInput(viewportListener: TuiInputListener, data: string, focused: Component): void {\n\t\tif (this.getFocusedComponent() !== focused) return;\n\t\tif (this.handleOverlayUnhandledInput(data, focused)) {\n\t\t\t(this as unknown as TuiOverlayInternals).requestImmediateRender();\n\t\t\treturn;\n\t\t}\n\t\tthis.replayViewportInput(viewportListener, data);\n\t}\n\n\tprivate routeViewportInput(viewportListener: TuiInputListener, data: string): ReturnType<TuiInputListener> {\n\t\tconst gate = viewportInputGates.get(this);\n\t\tconst isMouseInput = gate ? this.isPiTuiMouseSequence(data) : false;\n\t\tif (!gate || gate(data, isMouseInput, this.isFocusedOverlay(), false)) return undefined;\n\n\t\t// Returning `consume` below skips pi-tui's post-listener phase. Mirror its\n\t\t// overlay-focus repair before reading the focused component so a resize\n\t\t// cannot send a gated key to an invisible overlay.\n\t\tthis.repairOverlayFocus();\n\t\tconst focused = this.getFocusedComponent();\n\t\tconst tui = this as unknown as TuiOverlayInternals;\n\t\tif (focused?.handleInput && (!isKeyRelease(data) || focused.wantsKeyRelease === true)) {\n\t\t\tconst handleInput = focused.handleInput as (\n\t\t\t\tdata: string,\n\t\t\t) => boolean | undefined | Promise<boolean | undefined>;\n\t\t\tconst result = handleInput.call(focused, data);\n\t\t\tif (result instanceof Promise) {\n\t\t\t\tvoid result.then(\n\t\t\t\t\t(handled) => {\n\t\t\t\t\t\tif (handled === true) {\n\t\t\t\t\t\t\tthis.forwardSelectionMouseInput(viewportListener, data, focused);\n\t\t\t\t\t\t\ttui.requestImmediateRender();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.declineAsyncViewportInput(viewportListener, data, focused);\n\t\t\t\t\t},\n\t\t\t\t\t() => this.declineAsyncViewportInput(viewportListener, data, focused),\n\t\t\t\t);\n\t\t\t\treturn { consume: true };\n\t\t\t}\n\t\t\tif (result === true) {\n\t\t\t\tthis.forwardSelectionMouseInput(viewportListener, data, focused);\n\t\t\t\ttui.requestImmediateRender();\n\t\t\t\treturn { consume: true };\n\t\t\t}\n\t\t}\n\n\t\tif (this.handleOverlayUnhandledInput(data, focused)) {\n\t\t\ttui.requestImmediateRender();\n\t\t\treturn { consume: true };\n\t\t}\n\t\tthis.replayViewportInput(viewportListener, data);\n\t\treturn { consume: true };\n\t}\n}\n\n/**\n * CI detection follows the convention CI providers actually use: the variable\n * is SET AND NONEMPTY, with any value. GitHub Actions sets `CI=true`, but\n * other providers and users export arbitrary values (`CI=github-actions`,\n * `CI=circleci`); an allowlist of truthy spellings let those reach the\n * alternate screen and write escape sequences into CI logs (Greptile P1 on\n * PR #2308). Only explicit opt-outs (`0`, `false`, empty) read as not-CI.\n */\nfunction isCiEnvironment(value: string | undefined): boolean {\n\tif (value === undefined) return false;\n\tconst normalized = value.trim().toLowerCase();\n\treturn normalized !== \"\" && normalized !== \"0\" && normalized !== \"false\";\n}\n\nclass LifecycleTimingTerminal extends ProcessTerminal {\n\toverride write(data: string): void {\n\t\tmarkLifecycleTiming(\"first-terminal-write\");\n\t\tsuper.write(data);\n\t}\n}\n\nfunction createProcessTerminal(): ProcessTerminal {\n\treturn isLifecycleTimingEnabled() ? new LifecycleTimingTerminal() : new ProcessTerminal();\n}\n\nfunction shouldUseFullscreenTui(usesInjectedTerminal: boolean): boolean {\n\tif (process.env.TERM?.toLowerCase() === \"dumb\") return false;\n\tif (usesInjectedTerminal) return true;\n\treturn process.stdin.isTTY === true && process.stdout.isTTY === true && !isCiEnvironment(process.env.CI);\n}\n\n/**\n * Build Atomic's fullscreen renderer, `viewportInputGate` included, without\n * consulting the environment. `createInteractiveTui` calls this whenever\n * fullscreen applies; fixtures that assert fullscreen behavior call it\n * directly, because `shouldUseFullscreenTui` returns the main-screen fallback\n * under `TERM=dumb` even for an injected terminal and would otherwise hand\n * those tests a renderer with no layout and no gate.\n */\nexport function createFullscreenTui(options: InteractiveTuiOptions): TuiAltScreen {\n\treturn new AtomicTuiAltScreen(\n\t\toptions.terminal ?? createProcessTerminal(),\n\t\toptions.showHardwareCursor,\n\t\toptions.logDirectory,\n\t\t{\n\t\t\tscrollToEndIndicator: () => {\n\t\t\t\tconst shortcut = keyDisplayText(\"tui.altScreen.bottom\");\n\t\t\t\tconst label = ` ↓ Jump to latest message${shortcut ? ` · ${shortcut}` : \"\"} `;\n\t\t\t\treturn theme.bg(\"selectedBg\", theme.fg(\"text\", label));\n\t\t\t},\n\t\t\topenUrl: (url) =>\n\t\t\t\thandleUrlActivation(url, {\n\t\t\t\t\tonOverlayInternalUiAction: options.onOverlayInternalUiAction,\n\t\t\t\t\tonInternalUiAction: options.onInternalUiAction,\n\t\t\t\t\topenUrl: openBrowser,\n\t\t\t\t}),\n\t\t\tonRightClickPaste: options.onRightClickPaste,\n\t\t\tcopyOnSelect: options.copyOnSelect,\n\t\t},\n\t\toptions.shouldHandleViewportInput,\n\t\toptions.onOverlayUnhandledInput,\n\t\toptions.copySelection,\n\t);\n}\n\n/** Main-screen fallback renderer, carrying the same central mark strip as the fullscreen one. */\nclass AtomicTuiMainScreen extends TuiMainScreen {\n\tprotected override applyLineResets(lines: string[]): string[] {\n\t\treturn stripOverlayActiveRowMarker(super.applyLineResets(lines));\n\t}\n}\n\n/** Creates the fullscreen renderer for interactive TTY sessions. */\nexport function createInteractiveTui(options: InteractiveTuiOptions): InteractiveTui {\n\tconst usesInjectedTerminal = options.terminal !== undefined;\n\tconst terminal = options.terminal ?? createProcessTerminal();\n\tif (!shouldUseFullscreenTui(usesInjectedTerminal)) {\n\t\t// The normal CLI never reaches the interactive mode without a TTY. Keep a\n\t\t// main-screen renderer for internal harnesses and guarded fallback paths.\n\t\treturn new AtomicTuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);\n\t}\n\treturn createFullscreenTui({ ...options, terminal });\n}\n\n/** Keeps existing components pointed at the renderer selected at runtime. */\nexport function createInteractiveTuiReference(getTui: () => TUI): TUI {\n\treturn new Proxy({} as TUI, {\n\t\tget: (_target, property) => {\n\t\t\tconst tui = getTui();\n\t\t\tconst value = Reflect.get(tui, property, tui);\n\t\t\tif (typeof value !== \"function\") return value;\n\t\t\tlet methodTui = tui;\n\t\t\tlet method = value;\n\t\t\treturn (...args: unknown[]) => {\n\t\t\t\tconst currentTui = getTui();\n\t\t\t\tif (currentTui !== methodTui) {\n\t\t\t\t\tconst currentMethod = Reflect.get(currentTui, property, currentTui);\n\t\t\t\t\tif (typeof currentMethod !== \"function\") {\n\t\t\t\t\t\tthrow new TypeError(`TUI property ${String(property)} is not callable`);\n\t\t\t\t\t}\n\t\t\t\t\tmethodTui = currentTui;\n\t\t\t\t\tmethod = currentMethod;\n\t\t\t\t}\n\t\t\t\treturn Reflect.apply(method, methodTui, args);\n\t\t\t};\n\t\t},\n\t\tset: (_target, property, value) => {\n\t\t\tconst tui = getTui();\n\t\t\treturn Reflect.set(tui, property, value, tui);\n\t\t},\n\t\thas: (_target, property) => Reflect.has(getTui(), property),\n\t\tgetPrototypeOf: () => Reflect.getPrototypeOf(getTui()),\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clipboard.d.ts","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"AAoCA,wBAAsB,iBAAiB,CACtC,MAAM,GAAE;IAAE,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAgB,GACvD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"clipboard.d.ts","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"AAoCA,wBAAsB,iBAAiB,CACtC,MAAM,GAAE;IAAE,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAgB,GACvD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2HjE"}
|
package/dist/utils/clipboard.js
CHANGED
|
@@ -138,12 +138,24 @@ export async function copyToClipboard(text) {
|
|
|
138
138
|
// Fall through to OSC 52 fallback.
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
if (remote
|
|
141
|
+
if (remote) {
|
|
142
142
|
const osc52Copied = emitOsc52(text);
|
|
143
143
|
copied = copied || osc52Copied;
|
|
144
144
|
}
|
|
145
145
|
if (!copied) {
|
|
146
|
-
|
|
146
|
+
if (p === "linux") {
|
|
147
|
+
if (process.env.TERMUX_VERSION) {
|
|
148
|
+
throw new Error("Clipboard unavailable: install the Termux:API app and `termux-api` package");
|
|
149
|
+
}
|
|
150
|
+
if (process.env.WAYLAND_DISPLAY) {
|
|
151
|
+
throw new Error("Clipboard unavailable: install `wl-clipboard` (`wl-copy`) or check Wayland access");
|
|
152
|
+
}
|
|
153
|
+
if (process.env.DISPLAY) {
|
|
154
|
+
throw new Error("Clipboard unavailable: install `xclip` or `xsel`, or check X11 access");
|
|
155
|
+
}
|
|
156
|
+
throw new Error("Clipboard unavailable: no Wayland or X11 display detected");
|
|
157
|
+
}
|
|
158
|
+
throw new Error("Clipboard unavailable");
|
|
147
159
|
}
|
|
148
160
|
}
|
|
149
161
|
//# sourceMappingURL=clipboard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync, spawn } from \"child_process\";\nimport { platform } from \"os\";\nimport { createChildProcessEnvironment } from \"./child-process.ts\";\nimport { isWaylandSession } from \"./clipboard-image.ts\";\nimport { clipboard } from \"./clipboard-native.ts\";\n\ntype NativeClipboardExecOptions = {\n\tinput: string;\n\ttimeout: number;\n\tstdio: [\"pipe\", \"ignore\", \"ignore\"];\n\tenv: NodeJS.ProcessEnv;\n};\n\nfunction copyToX11Clipboard(options: NativeClipboardExecOptions): void {\n\ttry {\n\t\texecSync(\"xclip -selection clipboard\", options);\n\t} catch {\n\t\texecSync(\"xsel --clipboard --input\", options);\n\t}\n}\n\nconst MAX_OSC52_ENCODED_LENGTH = 100_000;\n\nfunction isRemoteSession(env: NodeJS.ProcessEnv = process.env): boolean {\n\treturn Boolean(env.SSH_CONNECTION || env.SSH_CLIENT || env.MOSH_CONNECTION);\n}\n\nfunction emitOsc52(text: string): boolean {\n\tconst encoded = Buffer.from(text).toString(\"base64\");\n\tif (encoded.length > MAX_OSC52_ENCODED_LENGTH) {\n\t\treturn false;\n\t}\n\tprocess.stdout.write(`\\x1b]52;c;${encoded}\\x07`);\n\treturn true;\n}\n\nexport async function readClipboardText(\n\tsource: { getText(): Promise<string> } | null = clipboard,\n): Promise<string | null> {\n\ttry {\n\t\tif (!source) return null;\n\t\treturn await source.getText();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function copyToClipboard(text: string): Promise<void> {\n\tlet copied = false;\n\n\tconst p = platform();\n\n\t// Prefer direct clipboard writes. Emitting OSC 52 first can make terminals\n\t// write the same native clipboard concurrently with the addon, and very large\n\t// OSC 52 payloads can desynchronize terminal rendering.\n\t//\n\t// On Linux, skip the native addon. The underlying `clipboard-rs` crate is\n\t// X11-only and does not retain selection ownership after `set_text`\n\t// resolves, so on Wayland-only compositors (Hyprland, Niri, ...) and even\n\t// some X11 sessions the call resolves successfully without populating the\n\t// clipboard. The platform tools below (wl-copy, xclip, xsel) properly\n\t// daemonize and keep ownership.\n\ttry {\n\t\tif (clipboard && p !== \"linux\") {\n\t\t\tawait clipboard.setText(text);\n\t\t\tcopied = true;\n\t\t}\n\t} catch {\n\t\t// Fall through to platform-specific clipboard tools.\n\t}\n\n\tconst remote = isRemoteSession();\n\tif (copied && !remote) {\n\t\treturn;\n\t}\n\n\tconst options: NativeClipboardExecOptions = {\n\t\tinput: text,\n\t\ttimeout: 5000,\n\t\tstdio: [\"pipe\", \"ignore\", \"ignore\"],\n\t\tenv: createChildProcessEnvironment(),\n\t};\n\n\tif (!copied) {\n\t\ttry {\n\t\t\tif (p === \"darwin\") {\n\t\t\t\texecSync(\"pbcopy\", options);\n\t\t\t\tcopied = true;\n\t\t\t} else if (p === \"win32\") {\n\t\t\t\texecSync(\"clip\", options);\n\t\t\t\tcopied = true;\n\t\t\t} else {\n\t\t\t\t// Linux. Try Termux, Wayland, or X11 clipboard tools.\n\t\t\t\tif (process.env.TERMUX_VERSION) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\texecSync(\"termux-clipboard-set\", options);\n\t\t\t\t\t\tcopied = true;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Fall back to Wayland or X11 tools.\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!copied) {\n\t\t\t\t\tconst hasWaylandDisplay = Boolean(process.env.WAYLAND_DISPLAY);\n\t\t\t\t\tconst hasX11Display = Boolean(process.env.DISPLAY);\n\t\t\t\t\tconst isWayland = isWaylandSession();\n\t\t\t\t\tif (isWayland && hasWaylandDisplay) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Verify wl-copy exists (spawn errors are async and won't be caught)\n\t\t\t\t\t\t\texecSync(\"which wl-copy\", { stdio: \"ignore\", env: createChildProcessEnvironment() });\n\t\t\t\t\t\t\t// wl-copy with execSync hangs due to fork behavior; use spawn instead.\n\t\t\t\t\t\t\t// Await its terminal event so failures can fall through to X11 or OSC 52.\n\t\t\t\t\t\t\tconst exitCode = await new Promise<number>((resolve) => {\n\t\t\t\t\t\t\t\tconst proc = spawn(\"wl-copy\", [], {\n\t\t\t\t\t\t\t\t\tstdio: [\"pipe\", \"ignore\", \"ignore\"],\n\t\t\t\t\t\t\t\t\tenv: createChildProcessEnvironment(),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\t\tconst finish = (code: number) => {\n\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\tresolve(code);\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tproc.once(\"error\", () => finish(1));\n\t\t\t\t\t\t\t\tproc.once(\"close\", (code) => finish(code ?? 1));\n\t\t\t\t\t\t\t\tproc.stdin.on(\"error\", () => {});\n\t\t\t\t\t\t\t\tproc.stdin.end(text);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (exitCode === 0) copied = true;\n\t\t\t\t\t\t\telse if (hasX11Display) {\n\t\t\t\t\t\t\t\tcopyToX11Clipboard(options);\n\t\t\t\t\t\t\t\tcopied = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tif (hasX11Display) {\n\t\t\t\t\t\t\t\tcopyToX11Clipboard(options);\n\t\t\t\t\t\t\t\tcopied = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (hasX11Display) {\n\t\t\t\t\t\tcopyToX11Clipboard(options);\n\t\t\t\t\t\tcopied = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to OSC 52 fallback.\n\t\t}\n\t}\n\n\tif (remote || !copied) {\n\t\tconst osc52Copied = emitOsc52(text);\n\t\tcopied = copied || osc52Copied;\n\t}\n\n\tif (!copied) {\n\t\tthrow new Error(\"Failed to copy to clipboard\");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync, spawn } from \"child_process\";\nimport { platform } from \"os\";\nimport { createChildProcessEnvironment } from \"./child-process.ts\";\nimport { isWaylandSession } from \"./clipboard-image.ts\";\nimport { clipboard } from \"./clipboard-native.ts\";\n\ntype NativeClipboardExecOptions = {\n\tinput: string;\n\ttimeout: number;\n\tstdio: [\"pipe\", \"ignore\", \"ignore\"];\n\tenv: NodeJS.ProcessEnv;\n};\n\nfunction copyToX11Clipboard(options: NativeClipboardExecOptions): void {\n\ttry {\n\t\texecSync(\"xclip -selection clipboard\", options);\n\t} catch {\n\t\texecSync(\"xsel --clipboard --input\", options);\n\t}\n}\n\nconst MAX_OSC52_ENCODED_LENGTH = 100_000;\n\nfunction isRemoteSession(env: NodeJS.ProcessEnv = process.env): boolean {\n\treturn Boolean(env.SSH_CONNECTION || env.SSH_CLIENT || env.MOSH_CONNECTION);\n}\n\nfunction emitOsc52(text: string): boolean {\n\tconst encoded = Buffer.from(text).toString(\"base64\");\n\tif (encoded.length > MAX_OSC52_ENCODED_LENGTH) {\n\t\treturn false;\n\t}\n\tprocess.stdout.write(`\\x1b]52;c;${encoded}\\x07`);\n\treturn true;\n}\n\nexport async function readClipboardText(\n\tsource: { getText(): Promise<string> } | null = clipboard,\n): Promise<string | null> {\n\ttry {\n\t\tif (!source) return null;\n\t\treturn await source.getText();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function copyToClipboard(text: string): Promise<void> {\n\tlet copied = false;\n\n\tconst p = platform();\n\n\t// Prefer direct clipboard writes. Emitting OSC 52 first can make terminals\n\t// write the same native clipboard concurrently with the addon, and very large\n\t// OSC 52 payloads can desynchronize terminal rendering.\n\t//\n\t// On Linux, skip the native addon. The underlying `clipboard-rs` crate is\n\t// X11-only and does not retain selection ownership after `set_text`\n\t// resolves, so on Wayland-only compositors (Hyprland, Niri, ...) and even\n\t// some X11 sessions the call resolves successfully without populating the\n\t// clipboard. The platform tools below (wl-copy, xclip, xsel) properly\n\t// daemonize and keep ownership.\n\ttry {\n\t\tif (clipboard && p !== \"linux\") {\n\t\t\tawait clipboard.setText(text);\n\t\t\tcopied = true;\n\t\t}\n\t} catch {\n\t\t// Fall through to platform-specific clipboard tools.\n\t}\n\n\tconst remote = isRemoteSession();\n\tif (copied && !remote) {\n\t\treturn;\n\t}\n\n\tconst options: NativeClipboardExecOptions = {\n\t\tinput: text,\n\t\ttimeout: 5000,\n\t\tstdio: [\"pipe\", \"ignore\", \"ignore\"],\n\t\tenv: createChildProcessEnvironment(),\n\t};\n\n\tif (!copied) {\n\t\ttry {\n\t\t\tif (p === \"darwin\") {\n\t\t\t\texecSync(\"pbcopy\", options);\n\t\t\t\tcopied = true;\n\t\t\t} else if (p === \"win32\") {\n\t\t\t\texecSync(\"clip\", options);\n\t\t\t\tcopied = true;\n\t\t\t} else {\n\t\t\t\t// Linux. Try Termux, Wayland, or X11 clipboard tools.\n\t\t\t\tif (process.env.TERMUX_VERSION) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\texecSync(\"termux-clipboard-set\", options);\n\t\t\t\t\t\tcopied = true;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Fall back to Wayland or X11 tools.\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!copied) {\n\t\t\t\t\tconst hasWaylandDisplay = Boolean(process.env.WAYLAND_DISPLAY);\n\t\t\t\t\tconst hasX11Display = Boolean(process.env.DISPLAY);\n\t\t\t\t\tconst isWayland = isWaylandSession();\n\t\t\t\t\tif (isWayland && hasWaylandDisplay) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Verify wl-copy exists (spawn errors are async and won't be caught)\n\t\t\t\t\t\t\texecSync(\"which wl-copy\", { stdio: \"ignore\", env: createChildProcessEnvironment() });\n\t\t\t\t\t\t\t// wl-copy with execSync hangs due to fork behavior; use spawn instead.\n\t\t\t\t\t\t\t// Await its terminal event so failures can fall through to X11 or OSC 52.\n\t\t\t\t\t\t\tconst exitCode = await new Promise<number>((resolve) => {\n\t\t\t\t\t\t\t\tconst proc = spawn(\"wl-copy\", [], {\n\t\t\t\t\t\t\t\t\tstdio: [\"pipe\", \"ignore\", \"ignore\"],\n\t\t\t\t\t\t\t\t\tenv: createChildProcessEnvironment(),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\t\tconst finish = (code: number) => {\n\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\tresolve(code);\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tproc.once(\"error\", () => finish(1));\n\t\t\t\t\t\t\t\tproc.once(\"close\", (code) => finish(code ?? 1));\n\t\t\t\t\t\t\t\tproc.stdin.on(\"error\", () => {});\n\t\t\t\t\t\t\t\tproc.stdin.end(text);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (exitCode === 0) copied = true;\n\t\t\t\t\t\t\telse if (hasX11Display) {\n\t\t\t\t\t\t\t\tcopyToX11Clipboard(options);\n\t\t\t\t\t\t\t\tcopied = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tif (hasX11Display) {\n\t\t\t\t\t\t\t\tcopyToX11Clipboard(options);\n\t\t\t\t\t\t\t\tcopied = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (hasX11Display) {\n\t\t\t\t\t\tcopyToX11Clipboard(options);\n\t\t\t\t\t\tcopied = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to OSC 52 fallback.\n\t\t}\n\t}\n\n\tif (remote) {\n\t\tconst osc52Copied = emitOsc52(text);\n\t\tcopied = copied || osc52Copied;\n\t}\n\n\tif (!copied) {\n\t\tif (p === \"linux\") {\n\t\t\tif (process.env.TERMUX_VERSION) {\n\t\t\t\tthrow new Error(\"Clipboard unavailable: install the Termux:API app and `termux-api` package\");\n\t\t\t}\n\t\t\tif (process.env.WAYLAND_DISPLAY) {\n\t\t\t\tthrow new Error(\"Clipboard unavailable: install `wl-clipboard` (`wl-copy`) or check Wayland access\");\n\t\t\t}\n\t\t\tif (process.env.DISPLAY) {\n\t\t\t\tthrow new Error(\"Clipboard unavailable: install `xclip` or `xsel`, or check X11 access\");\n\t\t\t}\n\t\t\tthrow new Error(\"Clipboard unavailable: no Wayland or X11 display detected\");\n\t\t}\n\t\tthrow new Error(\"Clipboard unavailable\");\n\t}\n}\n"]}
|
|
@@ -81,6 +81,8 @@ A successful run appends the existing pi-style `type:"compaction"` entry shape:
|
|
|
81
81
|
}
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
The entry's `tokensBefore` is the provider-aware whole-context count used for budgeting and the Compacted from display. `details.stats.tokensBefore`, `tokensAfter`, and `percentReduction` are heuristic estimates of the compactable region plus the kept tail. Those stats can differ from the entry count, and `percentReduction` is negative when the reconstructed estimate is larger. The display count is not stored again under `details.tokensBefore`.
|
|
85
|
+
|
|
84
86
|
`details.rung` is one of `"planned"` (a model ranked the lines — the session model **or** a borrowed fallback, including silent partial recovery), `"extension"` (a `session_before_compact` override), or `"fresh"` (the compactable conversation was discarded and a new context window started). `details.plannerModel` is present **only** when a borrowed fallback model ranked the lines:
|
|
85
87
|
|
|
86
88
|
```json
|
package/docs/compaction.md
CHANGED
|
@@ -207,7 +207,9 @@ Diagnostic categories distinguish malformed output, valid output with no usable
|
|
|
207
207
|
|
|
208
208
|
Interactive main chat and attached workflow stage chat treat `compaction_end` as the authority for cancellation and failure UI. A failed or cancelled `/compact` stops its spinner, shows the event-provided status or diagnostic path without a duplicate stack trace, writes no boundary, and leaves the session usable for another `/compact` attempt or a normal follow-up turn.
|
|
209
209
|
|
|
210
|
-
Context thresholds and
|
|
210
|
+
Context thresholds and the Compacted from token count use API-aware normalized usage. OpenAI Responses, Codex Responses, and OpenAI Completions sum uncached input plus cache-read/cache-write partitions. Anthropic Messages alone applies the mirrored-cache guard needed by compatible endpoints that duplicate the same prompt tokens across `input` and cache fields.
|
|
211
|
+
|
|
212
|
+
Persisted `stats.tokensBefore`, `stats.tokensAfter`, and `percentReduction` are symmetric heuristic estimates of the compactable region plus the kept tail. They are separate from the provider-aware `tokensBefore` on the compaction entry, which is used only for budgeting and display. If the reconstructed text estimates larger than the original region, `percentReduction` is negative.
|
|
211
213
|
|
|
212
214
|
## Persistence and resume
|
|
213
215
|
|
|
@@ -97,7 +97,7 @@ The shell installer detects Alpine and selects `atomic-linux-x64-musl.tar.gz` or
|
|
|
97
97
|
|
|
98
98
|
Two features work differently on musl:
|
|
99
99
|
|
|
100
|
-
- **Clipboard:** the musl archives omit a clipboard native binding because `@mariozechner/clipboard` 0.3.9 publishes metadata-only musl stubs without a `.node` payload
|
|
100
|
+
- **Clipboard:** the musl archives omit a clipboard native binding because `@mariozechner/clipboard` 0.3.9 publishes metadata-only musl stubs without a `.node` payload. Atomic uses Linux clipboard commands locally and permits OSC 52 only in SSH or Mosh sessions. Install `wl-clipboard` on Wayland, `xclip` or `xsel` on X11, or the Termux:API app and `termux-api` package on Termux. A failed local write reports the unavailable backend instead of claiming success through OSC 52.
|
|
101
101
|
- **Durable workflows:** the archives omit the glibc-linked `@embedded-postgres/*` binary packages and instead carry a checksum-pinned Alpine/musl PostgreSQL 18.6 runtime, so durable workflows provision offline without external Postgres or Docker. If no durable backend can be provisioned at all, Atomic still uses a loud non-durable in-memory fallback.
|
|
102
102
|
|
|
103
103
|
Then start Atomic in the project directory you want it to work on:
|
package/docs/keybindings.md
CHANGED
|
@@ -99,6 +99,8 @@ The dedicated history actions always change history entries, regardless of the c
|
|
|
99
99
|
| `tui.select.confirm` | `enter` | Confirm selection |
|
|
100
100
|
| `tui.select.cancel` | `escape`, `ctrl+c` | Cancel selection |
|
|
101
101
|
|
|
102
|
+
Local copy operations require a working native clipboard or platform command. On Linux, install `wl-clipboard` for Wayland, `xclip` or `xsel` for X11, or the Termux:API app and `termux-api` package for Termux. Fullscreen selection shows a backend-specific failure message for five seconds. Atomic sends OSC 52 only in SSH or Mosh sessions, where the terminal must support clipboard forwarding; it no longer treats OSC 52 as proof of a successful local copy.
|
|
103
|
+
|
|
102
104
|
### TUI Fullscreen Viewport
|
|
103
105
|
|
|
104
106
|
Interactive sessions always use this fullscreen viewport for the primary transcript scroll region. Mouse-wheel input scrolls the region under the pointer, falling back to the transcript over the fixed editor/status/footer dock. While the main transcript is scrolled up, a clickable "Jump to latest message" label on its bottom row shows the `tui.altScreen.bottom` shortcut; clicking it returns that transcript to its live end. An attached workflow stage chat keeps its own "Jump to latest message" OSC 8 link with the same shortcut, which returns the stage chat to its live end. Clicking other OSC 8 hyperlinks opens them in the default handler. Dragging with the primary mouse button selects text and, by default, copies it to the clipboard. Set `fullscreenCopyOnSelect` to `false` to highlight text without copying. See [Terminal setup](/terminal-setup) for terminal-specific mouse and trackpad behavior.
|
package/docs/models/reference.md
CHANGED
|
@@ -410,6 +410,7 @@ By default, Atomic sends per-tool `eager_input_streaming: true`. If a proxy or A
|
|
|
410
410
|
| `enforcesPreservedThinkingBinding` | Whether the model rejects a thinking block replayed behind a changed conversation prefix. Default: `false`. When `true`, Atomic sends the `thinking-binding-controls-2026-08-01` beta header and `prefix_mismatch_behavior: "drop_block"`. |
|
|
411
411
|
| `supportsMidConvoEffort` | Whether the exact Claude model transport supports per-turn effort system messages. Atomic persists native effort levels and sends `drop_block` when enabled. Default: `false`. |
|
|
412
412
|
| `supportsForcedToolChoice` | Whether the model accepts forced tool use (`tool_choice` `any` or a named tool). Default: `true`. When `false`, Atomic rejects a forced choice with an error rather than sending a request the model refuses. `auto` and `none` are never altered. |
|
|
413
|
+
| `allowedFallbackModels` | Ordered server-side fallback targets, at most three, each with nonempty `provider` and `model` strings and complete `cost` metadata. Costs require `input`, `output`, `cacheRead`, and `cacheWrite`; optional tiers require the same rates plus `inputTokensAbove`. Set `[]` to disable inherited fallbacks. |
|
|
413
414
|
|
|
414
415
|
`supportsMidConvoEffort` and `enforcesPreservedThinkingBinding` compose rather than replace one another. The former is restricted to exact provider/model transports that accept effort-only system messages and adds the two per-turn-effort betas. It also enables `drop_block`, because historical effort changes can invalidate a signed prefix. The latter remains a separate Atomic compatibility flag for transports that enforce preserved-thinking prefixes but do not accept effort-only messages. Do not enable `supportsMidConvoEffort` for an API that merely imitates the Messages shape.
|
|
415
416
|
|
|
@@ -417,6 +418,26 @@ By default, Atomic sends per-tool `eager_input_streaming: true`. If a proxy or A
|
|
|
417
418
|
|
|
418
419
|
On the completions adapter, `supportsTemperature: false` also strips `temperature`, `top_p`, and `top_k` out of `samplingParams`. That merge is documented as last-wins so its keys override the named request fields, which means it would otherwise reopen exactly the parameters the model rejects. The strip runs after the merge, so it also covers a model-level `samplingParams` default, and it removes only those three keys — every other custom key you pass still overrides as before.
|
|
419
420
|
|
|
421
|
+
### Server-side fallback configuration
|
|
422
|
+
|
|
423
|
+
Set `compat.allowedFallbackModels` at provider level, on a custom model, or in `modelOverrides`. A supplied array replaces inherited targets rather than appending to them. For example, disable built-in fallbacks for one model in `models.json`:
|
|
424
|
+
|
|
425
|
+
```json
|
|
426
|
+
{
|
|
427
|
+
"providers": {
|
|
428
|
+
"anthropic": {
|
|
429
|
+
"modelOverrides": {
|
|
430
|
+
"claude-fable-5-1": {
|
|
431
|
+
"compat": { "allowedFallbackModels": [] }
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
To enable a target, use an entry such as `{ "provider": "anthropic", "model": "claude-opus-5", "cost": { "input": 5, "output": 25, "cacheRead": 0.5, "cacheWrite": 6.25 } }`. Verify the provider's current rates and supported fallback targets before configuring them. Atomic sends the model names in array order and uses matching provider/model cost metadata to account for the serving model.
|
|
440
|
+
|
|
420
441
|
### Forced tool use on Claude Fable 5.1
|
|
421
442
|
|
|
422
443
|
Claude Fable 5.1 rejects forced tool use — `tool_choice: {"type": "any"}` and `{"type": "tool", ...}` — on every request with a 400, whichever platform serves it. Anthropic's guidance is to use `tool_choice: {"type": "auto"}` with strict tool use or structured outputs instead.
|
|
@@ -645,7 +645,11 @@ Set `ATOMIC_POSTGRES_RUNTIME_DIR` to a complete extracted runtime containing `bi
|
|
|
645
645
|
|
|
646
646
|
Packaged payloads include the complete library/share trees, executable modes, scriptless library-link metadata, licenses, and `runtime-provenance.json`. Release packaging rejects missing files, checksum failures, and mismatched CPU/libc/target payloads before shipping. Keep the whole extracted installation when moving an archive; copying only the `atomic` executable is insufficient. `ATOMIC_POSTGRES_RUNTIME_DIR` continues to accept complete legacy runtime directories without provenance, and an incomplete override falls through to installed candidates. A packaging failure does not require deleting or reinitializing your existing v18 cluster.
|
|
647
647
|
|
|
648
|
-
|
|
648
|
+
If installation reports **incomplete PostgreSQL runtime**, or macOS reports a missing library such as `libzstd.1.dylib`, download a repaired release and reinstall the complete archive. A rejected upgrade leaves your previous installation selected. Do not copy libraries from another version or delete your PostgreSQL data directory: this is an installation problem, not database corruption. An already-running server does not prove that the new installation is usable.
|
|
649
|
+
|
|
650
|
+
To check a standalone runtime directly, set `runtime` to `node_modules/@bastani/atomic-natives/postgres-runtime` inside the extracted installation, then run `"$runtime/bin/postgres" --version` and `"$runtime/bin/pg_ctl" --version`. On Windows, run the corresponding `.exe` files in PowerShell. Both must succeed. The installer also verifies the extracted file inventory, library aliases and macOS/Linux dependencies required for PostgreSQL startup and workflow database operation before selecting the installation. npm installations retain automatic first-use library-link setup; if symlink creation is unavailable, Atomic copies the required libraries instead. An invalid link manifest, conflicting alias or failed copy is reported rather than silently ignored.
|
|
651
|
+
|
|
652
|
+
Optional PostgreSQL OAuth and procedural-language modules may have upstream dependency gaps. Atomic does not bundle supplemental libcurl or Perl/Python/Tcl runtimes for those modules. They are not needed for normal workflow database operation; use a separately managed PostgreSQL server if you require them.
|
|
649
653
|
|
|
650
654
|
Pending-stage Intercom cleanup checks durable ownership only for runs with messages that need settlement. Repeated failures with the same message produce one warning per extension instance. Interactive hosts receive a display-only notification, never a console stack trace, even if notification delivery fails; headless hosts retain a console diagnostic. Pending messages are not discarded when cleanup fails.
|
|
651
655
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.20-alpha.
|
|
3
|
+
"version": "0.9.20-alpha.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bastani/atomic",
|
|
9
|
-
"version": "0.9.20-alpha.
|
|
9
|
+
"version": "0.9.20-alpha.3",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@bastani/atomic-natives": "0.9.20-alpha.
|
|
13
|
-
"@bastani/pi-ai": "0.9.20-alpha.
|
|
12
|
+
"@bastani/atomic-natives": "0.9.20-alpha.3",
|
|
13
|
+
"@bastani/pi-ai": "0.9.20-alpha.3",
|
|
14
14
|
"@dbos-inc/dbos-sdk": "4.25.14",
|
|
15
15
|
"@earendil-works/pi-agent-core": "0.85.1",
|
|
16
16
|
"@earendil-works/pi-client": "0.85.1",
|
|
@@ -518,18 +518,18 @@
|
|
|
518
518
|
}
|
|
519
519
|
},
|
|
520
520
|
"node_modules/@bastani/atomic-natives": {
|
|
521
|
-
"version": "0.9.20-alpha.
|
|
522
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.20-alpha.
|
|
521
|
+
"version": "0.9.20-alpha.3",
|
|
522
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.20-alpha.3.tgz",
|
|
523
523
|
"license": "MIT",
|
|
524
524
|
"optionalDependencies": {
|
|
525
|
-
"@bastani/atomic-natives-darwin-arm64": "0.9.20-alpha.
|
|
526
|
-
"@bastani/atomic-natives-darwin-x64": "0.9.20-alpha.
|
|
527
|
-
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.20-alpha.
|
|
528
|
-
"@bastani/atomic-natives-linux-arm64-musl": "0.9.20-alpha.
|
|
529
|
-
"@bastani/atomic-natives-linux-x64-gnu": "0.9.20-alpha.
|
|
530
|
-
"@bastani/atomic-natives-linux-x64-musl": "0.9.20-alpha.
|
|
531
|
-
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.20-alpha.
|
|
532
|
-
"@bastani/atomic-natives-win32-x64-msvc": "0.9.20-alpha.
|
|
525
|
+
"@bastani/atomic-natives-darwin-arm64": "0.9.20-alpha.3",
|
|
526
|
+
"@bastani/atomic-natives-darwin-x64": "0.9.20-alpha.3",
|
|
527
|
+
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.20-alpha.3",
|
|
528
|
+
"@bastani/atomic-natives-linux-arm64-musl": "0.9.20-alpha.3",
|
|
529
|
+
"@bastani/atomic-natives-linux-x64-gnu": "0.9.20-alpha.3",
|
|
530
|
+
"@bastani/atomic-natives-linux-x64-musl": "0.9.20-alpha.3",
|
|
531
|
+
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.20-alpha.3",
|
|
532
|
+
"@bastani/atomic-natives-win32-x64-msvc": "0.9.20-alpha.3"
|
|
533
533
|
},
|
|
534
534
|
"engines": {
|
|
535
535
|
"bun": ">=1.4.2",
|
|
@@ -537,8 +537,8 @@
|
|
|
537
537
|
}
|
|
538
538
|
},
|
|
539
539
|
"node_modules/@bastani/atomic-natives-darwin-arm64": {
|
|
540
|
-
"version": "0.9.20-alpha.
|
|
541
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.20-alpha.
|
|
540
|
+
"version": "0.9.20-alpha.3",
|
|
541
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.20-alpha.3.tgz",
|
|
542
542
|
"license": "MIT",
|
|
543
543
|
"os": [
|
|
544
544
|
"darwin"
|
|
@@ -549,8 +549,8 @@
|
|
|
549
549
|
"optional": true
|
|
550
550
|
},
|
|
551
551
|
"node_modules/@bastani/atomic-natives-darwin-x64": {
|
|
552
|
-
"version": "0.9.20-alpha.
|
|
553
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.20-alpha.
|
|
552
|
+
"version": "0.9.20-alpha.3",
|
|
553
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.20-alpha.3.tgz",
|
|
554
554
|
"license": "MIT",
|
|
555
555
|
"os": [
|
|
556
556
|
"darwin"
|
|
@@ -561,8 +561,8 @@
|
|
|
561
561
|
"optional": true
|
|
562
562
|
},
|
|
563
563
|
"node_modules/@bastani/atomic-natives-linux-arm64-gnu": {
|
|
564
|
-
"version": "0.9.20-alpha.
|
|
565
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.20-alpha.
|
|
564
|
+
"version": "0.9.20-alpha.3",
|
|
565
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.20-alpha.3.tgz",
|
|
566
566
|
"license": "MIT",
|
|
567
567
|
"os": [
|
|
568
568
|
"linux"
|
|
@@ -576,8 +576,8 @@
|
|
|
576
576
|
"optional": true
|
|
577
577
|
},
|
|
578
578
|
"node_modules/@bastani/atomic-natives-linux-arm64-musl": {
|
|
579
|
-
"version": "0.9.20-alpha.
|
|
580
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-musl/-/atomic-natives-linux-arm64-musl-0.9.20-alpha.
|
|
579
|
+
"version": "0.9.20-alpha.3",
|
|
580
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-musl/-/atomic-natives-linux-arm64-musl-0.9.20-alpha.3.tgz",
|
|
581
581
|
"license": "MIT",
|
|
582
582
|
"os": [
|
|
583
583
|
"linux"
|
|
@@ -591,8 +591,8 @@
|
|
|
591
591
|
"optional": true
|
|
592
592
|
},
|
|
593
593
|
"node_modules/@bastani/atomic-natives-linux-x64-gnu": {
|
|
594
|
-
"version": "0.9.20-alpha.
|
|
595
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.20-alpha.
|
|
594
|
+
"version": "0.9.20-alpha.3",
|
|
595
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.20-alpha.3.tgz",
|
|
596
596
|
"license": "MIT",
|
|
597
597
|
"os": [
|
|
598
598
|
"linux"
|
|
@@ -606,8 +606,8 @@
|
|
|
606
606
|
"optional": true
|
|
607
607
|
},
|
|
608
608
|
"node_modules/@bastani/atomic-natives-linux-x64-musl": {
|
|
609
|
-
"version": "0.9.20-alpha.
|
|
610
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-musl/-/atomic-natives-linux-x64-musl-0.9.20-alpha.
|
|
609
|
+
"version": "0.9.20-alpha.3",
|
|
610
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-musl/-/atomic-natives-linux-x64-musl-0.9.20-alpha.3.tgz",
|
|
611
611
|
"license": "MIT",
|
|
612
612
|
"os": [
|
|
613
613
|
"linux"
|
|
@@ -621,8 +621,8 @@
|
|
|
621
621
|
"optional": true
|
|
622
622
|
},
|
|
623
623
|
"node_modules/@bastani/atomic-natives-win32-arm64-msvc": {
|
|
624
|
-
"version": "0.9.20-alpha.
|
|
625
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.20-alpha.
|
|
624
|
+
"version": "0.9.20-alpha.3",
|
|
625
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.20-alpha.3.tgz",
|
|
626
626
|
"license": "MIT",
|
|
627
627
|
"os": [
|
|
628
628
|
"win32"
|
|
@@ -633,8 +633,8 @@
|
|
|
633
633
|
"optional": true
|
|
634
634
|
},
|
|
635
635
|
"node_modules/@bastani/atomic-natives-win32-x64-msvc": {
|
|
636
|
-
"version": "0.9.20-alpha.
|
|
637
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.20-alpha.
|
|
636
|
+
"version": "0.9.20-alpha.3",
|
|
637
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.20-alpha.3.tgz",
|
|
638
638
|
"license": "MIT",
|
|
639
639
|
"os": [
|
|
640
640
|
"win32"
|
|
@@ -645,8 +645,8 @@
|
|
|
645
645
|
"optional": true
|
|
646
646
|
},
|
|
647
647
|
"node_modules/@bastani/pi-ai": {
|
|
648
|
-
"version": "0.9.20-alpha.
|
|
649
|
-
"resolved": "https://registry.npmjs.org/@bastani/pi-ai/-/pi-ai-0.9.20-alpha.
|
|
648
|
+
"version": "0.9.20-alpha.3",
|
|
649
|
+
"resolved": "https://registry.npmjs.org/@bastani/pi-ai/-/pi-ai-0.9.20-alpha.3.tgz",
|
|
650
650
|
"license": "MIT",
|
|
651
651
|
"dependencies": {
|
|
652
652
|
"@anthropic-ai/sdk": "0.124.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.20-alpha.
|
|
3
|
+
"version": "0.9.20-alpha.3",
|
|
4
4
|
"description": "Atomic coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"atomicConfig": {
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"prepublishOnly": "bun run clean && bun run build && bun run shrinkwrap"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
-
"@bastani/atomic-natives": "0.9.20-alpha.
|
|
83
|
-
"@bastani/pi-ai": "0.9.20-alpha.
|
|
82
|
+
"@bastani/atomic-natives": "0.9.20-alpha.3",
|
|
83
|
+
"@bastani/pi-ai": "0.9.20-alpha.3",
|
|
84
84
|
"@dbos-inc/dbos-sdk": "4.25.14",
|
|
85
85
|
"@earendil-works/pi-agent-core": "0.85.1",
|
|
86
86
|
"@earendil-works/pi-client": "0.85.1",
|