@oh-my-pi/pi-tui 18.14.0 → 18.14.2
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 +36 -0
- package/README.md +6 -0
- package/dist/types/charts/table-data.d.ts +4 -2
- package/dist/types/chat/figure-markdown.d.ts +2 -0
- package/dist/types/chat/svg-figure.d.ts +5 -0
- package/dist/types/chat/table-chart.d.ts +2 -0
- package/dist/types/chat/transcript-render-helpers.d.ts +3 -3
- package/dist/types/components/image.d.ts +6 -0
- package/dist/types/native/describe.d.ts +4 -2
- package/dist/types/native/overlay.d.ts +42 -2
- package/dist/types/native/state.d.ts +4 -0
- package/dist/types/overlays/btw-history-panel.d.ts +2 -0
- package/dist/types/prompt/composer.d.ts +13 -5
- package/dist/types/render/render-utils.d.ts +2 -0
- package/dist/types/theme/theme.d.ts +1 -1
- package/dist/types/theme/tui-adapters.d.ts +2 -0
- package/dist/types/thinking.d.ts +8 -6
- package/dist/types/tools/ast-grep.d.ts +2 -0
- package/dist/types/tools/eval.d.ts +2 -0
- package/dist/types/tools/find.d.ts +1 -1
- package/dist/types/tools/grouped-file-output.d.ts +24 -11
- package/dist/types/tools/read.d.ts +4 -4
- package/dist/types/tools/task.d.ts +2 -2
- package/package.json +9 -9
- package/src/apps/git/git-tui.ts +10 -17
- package/src/apps/git/sidebar.ts +21 -35
- package/src/apps/ps-top.ts +4 -12
- package/src/charts/chart-plan.ts +0 -29
- package/src/charts/table-data.ts +55 -6
- package/src/chat/figure-markdown.ts +6 -4
- package/src/chat/svg-figure.ts +55 -16
- package/src/chat/table-chart.ts +19 -2
- package/src/chat/transcript-render-helpers.ts +18 -16
- package/src/components/image.ts +13 -0
- package/src/native/backend.ts +7 -3
- package/src/native/describe.ts +9 -4
- package/src/native/overlay.ts +124 -16
- package/src/native/state.ts +25 -5
- package/src/overlays/btw-history-panel.ts +8 -0
- package/src/overlays/extensions/extension-dashboard.ts +7 -8
- package/src/overlays/jobs-panel.ts +38 -4
- package/src/overlays/login-dialog.ts +8 -26
- package/src/overlays/tree-selector.ts +81 -27
- package/src/overlays/usage-dashboard.ts +2 -4
- package/src/prompt/composer.ts +17 -5
- package/src/render/render-utils.ts +2 -0
- package/src/theme/theme-class.ts +12 -3
- package/src/theme/theme.ts +1 -0
- package/src/theme/tui-adapters.ts +8 -3
- package/src/thinking.ts +17 -11
- package/src/tools/ast-grep.ts +10 -2
- package/src/tools/eval.ts +2 -0
- package/src/tools/find.ts +7 -2
- package/src/tools/grep.ts +8 -2
- package/src/tools/grouped-file-output.ts +172 -47
- package/src/tools/lsp.ts +158 -8
- package/src/tools/read.ts +6 -5
- package/src/tools/task.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.14.2] - 2026-10-31
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `assertModelSupportsEffortCeiling()`, which throws when a model has no supported thinking effort at or below a `task.maxEffort` ceiling ([#12229](https://github.com/can1357/oh-my-pi/pull/12229) by [@Xytronix](https://github.com/Xytronix))
|
|
10
|
+
- Added `iconButton()`, `quietButton()` and `segmentedTabs()` to `native/overlay`, and `disabled`, `busy` and `icon` options to `actionButton()`
|
|
11
|
+
- Added `nativeTail` to `Composer.setRuntimeChildren` options: containers whose children continue the native surface's `main` after the transcript instead of riding in the dock
|
|
12
|
+
- Added `isHighlightLanguage` and `createCodeFrameStyler` for renderers that highlight source lines in their file's language ([#17550](https://github.com/can1357/oh-my-pi/pull/17550) by [@JustasMasiulis](https://github.com/JustasMasiulis))
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Grep and read results with gaps between line runs now render in Tern as one code block that scrolls sideways as a whole, with `…` gap rows aligned in the line-number gutter
|
|
17
|
+
- Tern builds that draw the `button` kind get omp's buttons as real buttons (pointer cursor, accessible pressed/disabled state, a disabled button's tooltip says why) and segmented controls as `tabs` `variant: "segmented"`; older Tern builds keep the role-styled rows
|
|
18
|
+
- Source lines in Grep, AST Grep and Find results and LSP symbol names are syntax-highlighted in their file's language instead of drawn in one color; consecutive lines highlight together, so multi-line strings and comments keep their colors ([#17550](https://github.com/can1357/oh-my-pi/pull/17550) by [@JustasMasiulis](https://github.com/JustasMasiulis))
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Fixed table charts plotting a ratio column against the timings it divides (`ratio` 0.997 beside `C++ (ms)` drew as "719× less"): `analyzeTable` reads a column equal to the quotient of two others as restating them, written bare or as `×`
|
|
23
|
+
- Fixed IRC coordination cards remaining visible when Hide Tool Activity is enabled, including incoming messages, automatic replies, relays, and workpool messages in live and replayed transcripts ([#17498](https://github.com/can1357/oh-my-pi/pull/17498) by [@dannyboy-ai](https://github.com/dannyboy-ai)).
|
|
24
|
+
- Fixed text after a nested color losing the outer color, such as the rest of the `/mcp` and `/ssh` hints after the highlighted command (`Run /mcp list to see all configured servers.`) falling back to the default text color instead of staying muted ([#17521](https://github.com/can1357/oh-my-pi/pull/17521) by [@JustasMasiulis](https://github.com/JustasMasiulis))
|
|
25
|
+
- Fixed LSP definition, type definition and implementation results showing the raw `Found 1 definition(s):` text; the response now counts them (`1 definition`) and shows each location over its source lines, its own line marked like a grep match ([#17549](https://github.com/can1357/oh-my-pi/pull/17549) by [@JustasMasiulis](https://github.com/JustasMasiulis))
|
|
26
|
+
- Fixed an LSP definition, type definition or implementation location whose path starts with whitespace being dropped, with its source lines shown under the previous location
|
|
27
|
+
- Fixed session tree user and assistant turns looking identical in themes whose `accent` and `success` colors match or nearly match (`dark-terminal`, `dark-poimandres`, `light-poimandres`): user rows are now bold, the `assistant:` label switches to the path color, and custom and advisor messages are muted ([#17520](https://github.com/can1357/oh-my-pi/pull/17520) by [@wolfiesch](https://github.com/wolfiesch))
|
|
28
|
+
|
|
29
|
+
## [18.14.1] - 2026-10-31
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- Added a `maxRows` callback to `FigureMarkdown`, `SvgFigure` and `TableChartFigure` so surfaces shorter than the screen can fit their figures; zero hides a figure without delaying transcript completion ([#15661](https://github.com/can1357/oh-my-pi/issues/15661), [#15853](https://github.com/can1357/oh-my-pi/pull/15853) by [@KunoLu](https://github.com/KunoLu))
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- Fixed IME composition text in the BTW history `Follow up:` input appearing at the left edge instead of at the caret when the hardware cursor is enabled ([#17427](https://github.com/can1357/oh-my-pi/issues/17427))
|
|
38
|
+
- Fixed session tree rows overlapping when messages, tool arguments, or labels contain carriage returns or Unicode line/paragraph separators (`U+2028`, `U+2029`), while keeping multiline formatting in the selected entry preview ([#17430](https://github.com/can1357/oh-my-pi/pull/17430) by [@lincicomb](https://github.com/lincicomb)).
|
|
39
|
+
- Fixed the Background jobs sheet dropping a finished job and its output while you were reading it; the selected job now stays until you select another ([#17506](https://github.com/can1357/oh-my-pi/pull/17506) by [@H4vC](https://github.com/H4vC))
|
|
40
|
+
|
|
5
41
|
## [18.14.0] - 2026-10-29
|
|
6
42
|
|
|
7
43
|
### Breaking Changes
|
package/README.md
CHANGED
|
@@ -521,6 +521,12 @@ SIXEL images encode off the JavaScript thread: the first render reserves the ima
|
|
|
521
521
|
|
|
522
522
|
Supported formats: PNG, JPEG, GIF, WebP. Dimensions are parsed from the image headers automatically.
|
|
523
523
|
|
|
524
|
+
### Figures
|
|
525
|
+
|
|
526
|
+
`FigureMarkdown`, `SvgFigure`, and `TableChartFigure` size their images to a share of the terminal viewport. A surface shorter than the screen (an overlay, a pane) passes `maxRows: () => rows`, read on every render: the rows each figure may fill, a table chart's separator included. Zero hides a figure and keeps it from holding up transcript completion. Callers reserve room for prose and chrome themselves.
|
|
527
|
+
|
|
528
|
+
Lowering the ceiling refits the drawn image at once and redraws it at the new size; a SIXEL reserves its rows while each re-encode runs off the JavaScript thread, as for a width change. Changing the ceiling of rows already committed to native scrollback forces a resync, so leave committed figures alone.
|
|
529
|
+
|
|
524
530
|
## Autocomplete
|
|
525
531
|
|
|
526
532
|
### CombinedAutocompleteProvider
|
|
@@ -101,8 +101,10 @@ export interface TableColumn {
|
|
|
101
101
|
/**
|
|
102
102
|
* Index of the measure column this one restates, read from the values: a
|
|
103
103
|
* proportional copy (`pass` 33/38 beside `pass%` 87%, `Samples` beside `% of
|
|
104
|
-
* Total`, `Leverage vs $200` beside the cost)
|
|
105
|
-
* (`Offset` summing `Verts`)
|
|
104
|
+
* Total`, `Leverage vs $200` beside the cost), a running total of it
|
|
105
|
+
* (`Offset` summing `Verts`), or its ratio to another column of its unit
|
|
106
|
+
* (`ratio` 0.997 for `Python (ms)` ÷ `C++ (ms)`, `Speedup` 4.1×: the
|
|
107
|
+
* numerator's index). Such a column is never a measure of its own.
|
|
106
108
|
*/
|
|
107
109
|
readonly restates?: number;
|
|
108
110
|
}
|
|
@@ -8,6 +8,8 @@ export interface FigureMarkdownOptions {
|
|
|
8
8
|
charts: boolean;
|
|
9
9
|
/** Shared inline-image budget for the figures. */
|
|
10
10
|
budget?: ImageBudget;
|
|
11
|
+
/** Rows each figure may fill, read on every render; callers reserve prose, chrome and separators themselves. Unset or `undefined` takes a share of the terminal viewport. */
|
|
12
|
+
maxRows?: () => number | undefined;
|
|
11
13
|
/** A figure's rows changed outside a text update (raster landed, fell back to code). */
|
|
12
14
|
onChange: () => void;
|
|
13
15
|
}
|
|
@@ -16,6 +16,11 @@ export interface SvgFigureOptions {
|
|
|
16
16
|
markdown?: (text: string) => Markdown;
|
|
17
17
|
/** Shared inline-image budget; superseded rasters are released from it. */
|
|
18
18
|
budget?: ImageBudget;
|
|
19
|
+
/**
|
|
20
|
+
* Rows the figure may fill, fallback code included, read on every render;
|
|
21
|
+
* zero hides it. Unset or `undefined` takes a share of the terminal viewport.
|
|
22
|
+
*/
|
|
23
|
+
maxRows?: () => number | undefined;
|
|
19
24
|
/** The figure's rows changed outside a text update: a raster landed or rendering fell back to code. */
|
|
20
25
|
onChange: () => void;
|
|
21
26
|
}
|
|
@@ -64,6 +64,8 @@ export declare function chartFence(svg: string): string;
|
|
|
64
64
|
export interface TableChartFigureOptions {
|
|
65
65
|
/** Shared inline-image budget. */
|
|
66
66
|
budget?: ImageBudget;
|
|
67
|
+
/** Rows the chart may fill, its separator included, read on every render; under two hides it. Unset or `undefined` takes a share of the terminal viewport. */
|
|
68
|
+
maxRows?: () => number | undefined;
|
|
67
69
|
/** The chart's rows changed outside a text update: its pick or raster landed. */
|
|
68
70
|
onChange: () => void;
|
|
69
71
|
}
|
|
@@ -28,9 +28,9 @@ export declare function buildAsyncResultBlock(message: CustomOrHookMessage): Too
|
|
|
28
28
|
*/
|
|
29
29
|
export declare function buildLaunchCompletionBlock(message: CustomOrHookMessage): ToolActivityContainer;
|
|
30
30
|
/**
|
|
31
|
-
* Render
|
|
32
|
-
* `irc:relay`) as a
|
|
33
|
-
* expanded-state getter for the cached card.
|
|
31
|
+
* Render an IRC coordination custom message (`irc:incoming` / `irc:autoreply` /
|
|
32
|
+
* `irc:relay` / `irc:workpool`) as a tool-activity card. `getExpanded` supplies
|
|
33
|
+
* the live expanded-state getter for the cached card.
|
|
34
34
|
*/
|
|
35
35
|
export declare function buildIrcMessageCard(message: CustomOrHookMessage, getExpanded: () => boolean): Component;
|
|
36
36
|
/**
|
|
@@ -205,6 +205,12 @@ export declare class Image implements Component {
|
|
|
205
205
|
/** Return source metadata without exposing the encoded image buffer. */
|
|
206
206
|
debugState(): Record<string, unknown>;
|
|
207
207
|
invalidate(): void;
|
|
208
|
+
/**
|
|
209
|
+
* Refit to a new row ceiling; a SIXEL reserves its rows until the off-thread
|
|
210
|
+
* encode lands. A demoted fallback keeps the height already drawn only
|
|
211
|
+
* within the new ceiling: the owner chose to shrink the block.
|
|
212
|
+
*/
|
|
213
|
+
setMaxHeightCells(maxHeightCells: number): void;
|
|
208
214
|
releaseRenderCaches(): void;
|
|
209
215
|
/**
|
|
210
216
|
* A native `image` backed by a content-addressed blob; the terminal fits
|
|
@@ -56,7 +56,9 @@ export declare function list(items: readonly NativeChild[], p?: TspProps<"list">
|
|
|
56
56
|
/** Terminal-clocked elapsed counter: `age` ms already elapsed; `stopped` freezes it there. */
|
|
57
57
|
export declare function elapsed(age: number, stopped?: boolean): NativeNode;
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
59
|
+
* The key names of one key id (`"ctrl+o"` → `["ctrl", "o"]`), as `kbd` and
|
|
60
|
+
* `button` `keys` take them. A literal `+` key survives (`"+"`, `"ctrl++"`).
|
|
61
61
|
*/
|
|
62
|
+
export declare function keyNames(key: string): string[];
|
|
63
|
+
/** Keycap for one key id ({@link keyNames}); the terminal draws platform glyphs. */
|
|
62
64
|
export declare function kbd(key: string, nodeKey?: string): NativeNode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Overlay chrome for `describe()`: root cards, key-hint footers,
|
|
3
|
-
* lists and annotation callouts.
|
|
2
|
+
* Overlay chrome for `describe()`: root cards, key-hint footers, buttons and
|
|
3
|
+
* segmented controls, selectable lists and annotation callouts.
|
|
4
4
|
*
|
|
5
5
|
* The overlay frame itself (glass, ring, placement) is the terminal's: the
|
|
6
6
|
* engine wraps every overlay-stack component in an `overlay` node. An overlay
|
|
@@ -53,11 +53,23 @@ export interface ActionButtonOptions {
|
|
|
53
53
|
readonly title?: string;
|
|
54
54
|
/** Target of an `open` action (URL or `file://` path). */
|
|
55
55
|
readonly href?: string;
|
|
56
|
+
/** Why the action can't run now: the button dims and a click sends nothing. */
|
|
57
|
+
readonly disabled?: string;
|
|
58
|
+
/** The button's work is running: a spinner leads the label. */
|
|
59
|
+
readonly busy?: boolean;
|
|
60
|
+
/** Icon beside the label (before it on a `button` node, after it on a row). */
|
|
61
|
+
readonly icon?: string;
|
|
56
62
|
}
|
|
57
63
|
/**
|
|
58
64
|
* A native button (role `omp.btn`): a label plus an optional keycap. A click
|
|
59
65
|
* sends `act` back as an `action` event (or runs a terminal-local `open`/`copy`),
|
|
60
66
|
* which the component routes to the same code path as the key.
|
|
67
|
+
*
|
|
68
|
+
* A terminal that draws the `button` kind ({@link nativeButtons}) gets one
|
|
69
|
+
* (tone `accent` → variant `primary`, `error` → `danger`, `disabled` with its
|
|
70
|
+
* reason as the tooltip); older ones get the row their stylesheets draw by
|
|
71
|
+
* role. Both keep the role and tone the omp sheets' context rules key on; a
|
|
72
|
+
* disabled button's tone is `muted`.
|
|
61
73
|
*/
|
|
62
74
|
export declare function actionButton(label: string, act: string, options?: ActionButtonOptions): NativeNode;
|
|
63
75
|
/**
|
|
@@ -65,6 +77,34 @@ export declare function actionButton(label: string, act: string, options?: Actio
|
|
|
65
77
|
* `act` (default `close`), which the component routes to its Esc path.
|
|
66
78
|
*/
|
|
67
79
|
export declare function escCloseButton(act?: string, key?: string): NativeNode;
|
|
80
|
+
/** Options of an {@link iconButton}. */
|
|
81
|
+
export interface IconButtonOptions {
|
|
82
|
+
/** Sibling identity key; unkeyed buttons take their position. */
|
|
83
|
+
readonly key?: string;
|
|
84
|
+
/** Accessible name; defaults to the title. */
|
|
85
|
+
readonly aria?: string;
|
|
86
|
+
/** A toggle that is on (role `omp.app.ibtn.set`). */
|
|
87
|
+
readonly on?: boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A quiet icon-only button (role `omp.app.ibtn`, the kit's icon button) for an
|
|
91
|
+
* app head or toolbar: a `button` node where the terminal draws one
|
|
92
|
+
* ({@link nativeButtons}), else an `icon` with a click action.
|
|
93
|
+
*/
|
|
94
|
+
export declare function iconButton(name: string, act: string, title: string, options?: IconButtonOptions): NativeNode;
|
|
95
|
+
/**
|
|
96
|
+
* A quiet text button (role `omp.app.qbtn`, the kit's quiet button) for a
|
|
97
|
+
* section head or toolbar, keyed by its action: a small quiet `button` where
|
|
98
|
+
* the terminal draws one ({@link nativeButtons}), else a row.
|
|
99
|
+
*/
|
|
100
|
+
export declare function quietButton(label: string, act: string, title: string): NativeNode;
|
|
101
|
+
/**
|
|
102
|
+
* A segmented control: `tabs` drawn as a well with a raised thumb on the
|
|
103
|
+
* active tab. A terminal that draws the `button` kind ({@link nativeButtons})
|
|
104
|
+
* draws `variant: "segmented"` too; older ones restyle the tabs by role
|
|
105
|
+
* (`omp.app.seg`) or parent.
|
|
106
|
+
*/
|
|
107
|
+
export declare function segmentedTabs(p: TspProps<"tabs">, key: string): NativeNode;
|
|
68
108
|
/** A row of {@link actionButton}s (role `omp.actions`); `null` entries become the spacer that end-aligns what follows. */
|
|
69
109
|
export declare function actionBar(buttons: readonly (NativeNode | null)[], key?: string): NativeNode;
|
|
70
110
|
/** Spans of an annotation callout: a dim `label:` then the note. */
|
|
@@ -2,5 +2,9 @@
|
|
|
2
2
|
export declare function isNativeRendering(): boolean;
|
|
3
3
|
/** Called by the native backend on surface open and close. */
|
|
4
4
|
export declare function setNativeRendering(on: boolean): void;
|
|
5
|
+
/** Whether omp's buttons go out as `button` nodes (see {@link setNativeButtons}). */
|
|
6
|
+
export declare function nativeButtons(): boolean;
|
|
7
|
+
/** Called by the native backend when it adopts a `hello` reply and when it stops. */
|
|
8
|
+
export declare function setNativeButtons(on: boolean): void;
|
|
5
9
|
/** Call `listener` whenever native rendering starts or stops; returns the unsubscribe. */
|
|
6
10
|
export declare function onNativeRenderingChange(listener: (on: boolean) => void): () => void;
|
|
@@ -33,6 +33,8 @@ export declare class BtwHistoryPanel implements Component, Focusable {
|
|
|
33
33
|
constructor(options: BtwHistoryPanelOptions);
|
|
34
34
|
get focused(): boolean;
|
|
35
35
|
set focused(value: boolean);
|
|
36
|
+
/** Keep the follow-up input's cursor mode aligned so the hardware cursor (and IME preedit) lands on its caret. */
|
|
37
|
+
setUseTerminalCursor(useTerminalCursor: boolean): void;
|
|
36
38
|
update(records: readonly BtwHistoryRecord[]): void;
|
|
37
39
|
/** Visual confirmation that `c` copied this record's answer to the clipboard. */
|
|
38
40
|
markCopied(recordId: string, text: string): void;
|
|
@@ -2,7 +2,7 @@ import type { StatusLineComponent } from "../status-line/component.js";
|
|
|
2
2
|
import type { StatusLineSession } from "../status-line/host.js";
|
|
3
3
|
import { type StatusLineStartupData } from "../status-line/startup.js";
|
|
4
4
|
import { type Terminal } from "../terminal.js";
|
|
5
|
-
import { type Component, type ResizeScrollbackMode, type TerminalFramePlan, type TerminalFrameProvider, TUI, type TUIOptions, type ViewportSize } from "../tui.js";
|
|
5
|
+
import { type Component, Container, type ResizeScrollbackMode, type TerminalFramePlan, type TerminalFrameProvider, TUI, type TUIOptions, type ViewportSize } from "../tui.js";
|
|
6
6
|
import type { NativeSurface, NativeSurfaceProvider } from "../native/node.js";
|
|
7
7
|
import { CustomEditor } from "./custom-editor.js";
|
|
8
8
|
import type { WordCompletionMethod } from "./word-completion.js";
|
|
@@ -61,6 +61,13 @@ export interface RuntimeChildrenOptions {
|
|
|
61
61
|
* to the roots below the transcript in render order.
|
|
62
62
|
*/
|
|
63
63
|
readonly nativeDock?: readonly Component[];
|
|
64
|
+
/**
|
|
65
|
+
* Below-transcript containers whose children continue `main` on a TSP
|
|
66
|
+
* terminal, one block each after the transcript's, instead of riding in the
|
|
67
|
+
* dock: output on its way into the transcript (shell runs deferred until the
|
|
68
|
+
* next prompt) reads as its tail, and keeps its block when it moves in.
|
|
69
|
+
*/
|
|
70
|
+
readonly nativeTail?: readonly Container[];
|
|
64
71
|
/**
|
|
65
72
|
* Below-transcript roots the user opens and closes (the editor surface that
|
|
66
73
|
* drafts and dialogs swap into, docked reports). Their rows never become
|
|
@@ -141,10 +148,11 @@ export declare class Composer implements TerminalFrameProvider, NativeSurfacePro
|
|
|
141
148
|
/**
|
|
142
149
|
* Describe the whole surface for a TSP terminal. `main` is the flowing
|
|
143
150
|
* document: the header (welcome, extras) and every transcript block as its
|
|
144
|
-
* own component child
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
151
|
+
* own component child, then the children of the
|
|
152
|
+
* {@link RuntimeChildrenOptions.nativeTail} roots. `dock` is the live chrome
|
|
153
|
+
* below the transcript in render order: pending messages, HUDs, the working
|
|
154
|
+
* row, the editor and the status line. There is no history/viewport split:
|
|
155
|
+
* retirement, resize replay and hover bands are ANSI concerns.
|
|
148
156
|
*/
|
|
149
157
|
describeSurface(): NativeSurface;
|
|
150
158
|
/**
|
|
@@ -49,6 +49,8 @@ export declare const PREVIEW_LIMITS: {
|
|
|
49
49
|
readonly EXPANDED_LINES: 12;
|
|
50
50
|
/** Items (files, results) shown in collapsed view */
|
|
51
51
|
readonly COLLAPSED_ITEMS: 8;
|
|
52
|
+
/** Definition, type-definition and implementation locations shown in collapsed view */
|
|
53
|
+
readonly LOCATIONS_COLLAPSED: 2;
|
|
52
54
|
/** Output preview lines in collapsed view */
|
|
53
55
|
readonly OUTPUT_COLLAPSED: 3;
|
|
54
56
|
/** Output preview lines in expanded view */
|
|
@@ -6,7 +6,7 @@ export { getAvailableThemes, getAvailableThemesWithPaths, getThemeByName, type T
|
|
|
6
6
|
export { isValidThemeColor, type ThemeBg, type ThemeColor } from "./schema.js";
|
|
7
7
|
export { getAvailableSymbolPresets, isValidSymbolPreset, type SpinnerType, type SymbolKey, type SymbolPreset, } from "./symbols.js";
|
|
8
8
|
export { Theme } from "./theme-class.js";
|
|
9
|
-
export { createHighlightStream, getEditorTheme, getMarkdownTheme, getMarkdownThemeWithLinkTargets, getSelectListTheme, getSettingsListTheme, getSymbolTheme, highlightCode, setMarkdownMermaidRendering, warmHighlighter, } from "./tui-adapters.js";
|
|
9
|
+
export { createHighlightStream, getEditorTheme, getMarkdownTheme, getMarkdownThemeWithLinkTargets, getSelectListTheme, getSettingsListTheme, getSymbolTheme, highlightCode, isHighlightLanguage, setMarkdownMermaidRendering, warmHighlighter, } from "./tui-adapters.js";
|
|
10
10
|
/**
|
|
11
11
|
* Subscribe to native fallback appearance changes independently of theme changes.
|
|
12
12
|
* Consumers must re-check the effective background: COLORFGBG can override it.
|
|
@@ -6,6 +6,8 @@ import type { SettingsListTheme } from "../components/settings-list.js";
|
|
|
6
6
|
import type { SymbolTheme } from "../symbols.js";
|
|
7
7
|
import type { SlashCommandIconName } from "./symbols.js";
|
|
8
8
|
import type { Theme } from "./theme-class.js";
|
|
9
|
+
/** Whether {@link highlightCode} colors `lang`; text in any other language comes back unstyled. */
|
|
10
|
+
export declare function isHighlightLanguage(lang: string | undefined): lang is string;
|
|
9
11
|
/**
|
|
10
12
|
* Highlight code with syntax coloring based on file extension or language.
|
|
11
13
|
* Returns array of highlighted lines.
|
package/dist/types/thinking.d.ts
CHANGED
|
@@ -137,12 +137,12 @@ export type TaskEffort = (typeof TASK_EFFORTS)[number];
|
|
|
137
137
|
export declare function resolveTaskEffortLevel(model: Model | undefined, effort: TaskEffort, maxEffort?: Effort): Effort | undefined;
|
|
138
138
|
/**
|
|
139
139
|
* Clamps a concrete thinking selector to a per-session effort ceiling (e.g. a
|
|
140
|
-
* task spawn's `task.maxEffort
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
140
|
+
* task spawn's `task.maxEffort`). Unset/`inherit`/`off` retain their existing
|
|
141
|
+
* meaning, as do levels already at or below the ceiling. Levels above it snap
|
|
142
|
+
* to the highest model-supported effort at or below the ceiling. A model whose
|
|
143
|
+
* floor exceeds the ceiling has nothing valid to snap to; the requested level
|
|
144
|
+
* is returned unchanged and the caller must reject or skip such models (see
|
|
145
|
+
* {@link modelSupportsEffortCeiling}).
|
|
146
146
|
*/
|
|
147
147
|
export declare function clampThinkingLevelToCeiling(model: Model | undefined, level: Effort | undefined, ceiling: Effort | undefined): Effort | undefined;
|
|
148
148
|
export declare function clampThinkingLevelToCeiling(model: Model | undefined, level: ThinkingLevel | undefined, ceiling: Effort | undefined): ThinkingLevel | undefined;
|
|
@@ -153,6 +153,8 @@ export declare function clampThinkingLevelToCeiling(model: Model | undefined, le
|
|
|
153
153
|
* skip models whose floor would force the session above the ceiling.
|
|
154
154
|
*/
|
|
155
155
|
export declare function modelSupportsEffortCeiling(model: Model, ceiling: Effort): boolean;
|
|
156
|
+
/** Throws when `model` has no supported effort at or below `task.maxEffort`, so a capped spawn fails instead of running at its floor. */
|
|
157
|
+
export declare function assertModelSupportsEffortCeiling(model: Model, maxEffort: Effort): void;
|
|
156
158
|
/**
|
|
157
159
|
* The provisional concrete level shown while `auto` is configured but before a
|
|
158
160
|
* turn has been classified, and the fallback when classification fails. Prefers
|
|
@@ -34,6 +34,8 @@ interface AstGrepRenderArgs {
|
|
|
34
34
|
/** Legacy pre-`path` argument name; kept so historical transcripts still render a scope. */
|
|
35
35
|
paths?: string[];
|
|
36
36
|
skip?: number;
|
|
37
|
+
/** Language the search parsed the files as; highlighting follows it over the file extension. */
|
|
38
|
+
lang?: string;
|
|
37
39
|
}
|
|
38
40
|
/** Render AST grep calls and results. */
|
|
39
41
|
export declare const astGrepToolRenderer: {
|
|
@@ -71,6 +71,8 @@ export interface EvalToolDetails {
|
|
|
71
71
|
statusEvents?: EvalStatusEvent[];
|
|
72
72
|
/** Evictable events dropped from the front of `statusEvents` (see {@link recordStatusEvent}). */
|
|
73
73
|
statusEventsElided?: number;
|
|
74
|
+
/** Text the cell's tool calls sent to `out://`, oldest first; transcripts draw each as a reply after the call. */
|
|
75
|
+
replies?: string[];
|
|
74
76
|
isError?: boolean;
|
|
75
77
|
meta?: OutputMeta;
|
|
76
78
|
/** First backend that produced cells. Kept for transcript compatibility. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Theme } from "../theme/theme.js";
|
|
2
2
|
import type { Component } from "../tui.js";
|
|
3
3
|
import type { OutputMeta } from "./output-meta.js";
|
|
4
4
|
import type { NativeToolView, RenderResultContextOptions, RenderResultOptions } from "./renderer.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NativeNode } from "../native/node.js";
|
|
2
|
+
import { type Theme, type ThemeColor } from "../theme/theme.js";
|
|
2
3
|
/**
|
|
3
4
|
* One file's contribution to a grouped file output. The header itself is generated
|
|
4
5
|
* by `formatGroupedFiles` (one `#` per nesting level); use `headerSuffix` to tack
|
|
@@ -85,6 +86,15 @@ export declare function classifyGroupedLines(lines: readonly string[], headerBas
|
|
|
85
86
|
* indices lets callers slice parallel arrays (raw lines, styled lines, contexts).
|
|
86
87
|
*/
|
|
87
88
|
export declare function groupLineIndicesByBlank(rawLines: readonly string[]): number[][];
|
|
89
|
+
/**
|
|
90
|
+
* Styled code-frame rows of grouped search output, highlighted in each owning
|
|
91
|
+
* file's language (`lang` overrides it when the highlighter knows it). A run of
|
|
92
|
+
* consecutive line numbers in one file highlights together on its first
|
|
93
|
+
* request; a gap row, a jump in line numbers or another file starts a new run.
|
|
94
|
+
* Rows without a numbered code frame (headers, gap rows, notes) return
|
|
95
|
+
* undefined, for the caller to style.
|
|
96
|
+
*/
|
|
97
|
+
export declare function createCodeFrameStyler(lines: readonly string[], contexts: readonly GroupedLineContext[], color: ThemeColor, theme: Theme, lang?: string): (index: number) => string | undefined;
|
|
88
98
|
/** One event of {@link walkGroupedOutput}: a directory header, a file header, or a non-blank body line. */
|
|
89
99
|
export type GroupedOutputEvent = {
|
|
90
100
|
readonly kind: "dir";
|
|
@@ -102,31 +112,34 @@ export type GroupedOutputEvent = {
|
|
|
102
112
|
* joined with the name) and dropping blank separator lines.
|
|
103
113
|
*/
|
|
104
114
|
export declare function walkGroupedOutput(lines: readonly string[]): Generator<GroupedOutputEvent>;
|
|
105
|
-
/** One source line for {@link numberedCode}: its number (`null` for an elision marker), text and match mark. */
|
|
115
|
+
/** One source line for {@link numberedCode}: its number (`null` for an elision marker, which adds no line), text and match mark. */
|
|
106
116
|
export interface NumberedLine {
|
|
107
117
|
n: number | null;
|
|
108
118
|
text: string;
|
|
109
119
|
mark?: boolean;
|
|
110
120
|
}
|
|
111
121
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
122
|
+
* One numbered `code` block for possibly non-contiguous source lines (match
|
|
123
|
+
* lines `mark`ed by their line number): `start` when the numbers run on
|
|
124
|
+
* consecutively, else `nums` (each line's number), from whose jumps Tern draws
|
|
125
|
+
* the `…` gap rows in the gutter. Elision markers (`n: null`) add no line; the
|
|
126
|
+
* numbers jump around them. `path` is the file the lines come from: Tern picks
|
|
127
|
+
* their grammar from it and draws no header (the row or head above names the
|
|
128
|
+
* file). `wrap` soft-wraps long lines instead of scrolling the block sideways.
|
|
129
|
+
* `undefined` when no line is numbered.
|
|
118
130
|
*/
|
|
119
131
|
export declare function numberedCode(lines: readonly NumberedLine[], opts?: {
|
|
120
132
|
path?: string;
|
|
121
133
|
wrap?: boolean;
|
|
122
|
-
}): NativeNode
|
|
134
|
+
}): NativeNode | undefined;
|
|
123
135
|
/**
|
|
124
136
|
* Describe grouped search output (grep / ast-grep / ast-edit display content)
|
|
125
137
|
* by file (§7.3 grep): per file a 22px path row (dim dir, strong name, the
|
|
126
138
|
* header's suffix or the match count as a chip), then its lines as
|
|
127
|
-
* {@link numberedCode} with match lines marked
|
|
128
|
-
* runs. Unnumbered body lines stay plain
|
|
129
|
-
* first files (the caller says how many
|
|
139
|
+
* one {@link numberedCode} block with match lines marked (gaps between
|
|
140
|
+
* non-adjacent runs drawn in its gutter). Unnumbered body lines stay plain
|
|
141
|
+
* `code`. `maxFiles` keeps only the first files (the caller says how many
|
|
142
|
+
* were left out). `file` owns the lines
|
|
130
143
|
* before any header: a single-file search prints none, yet its lines get the
|
|
131
144
|
* same file row as a directory search's.
|
|
132
145
|
*/
|
|
@@ -139,11 +139,11 @@ export declare function readSourceFsPath(details: unknown): string | undefined;
|
|
|
139
139
|
*/
|
|
140
140
|
export declare function readResultIsMarkdown(details: ReadToolDetails | undefined, args: ReadRenderArgs | undefined): boolean;
|
|
141
141
|
/**
|
|
142
|
-
* Read content as numbered, wrapped `code` (no path header: the head
|
|
143
|
-
* the file), matching the ANSI preview's hanging wrap. Numbers come from
|
|
142
|
+
* Read content as one numbered, wrapped `code` block (no path header: the head
|
|
143
|
+
* names the file), matching the ANSI preview's hanging wrap. Numbers come from
|
|
144
144
|
* `lineNumbers` (`displayContent`'s per-line numbers, `null` for an elided
|
|
145
|
-
* block
|
|
146
|
-
* up from `start`.
|
|
145
|
+
* block, which Tern shows as a `…` gap row where the numbers jump) when they
|
|
146
|
+
* cover every line, else count up from `start`.
|
|
147
147
|
*/
|
|
148
148
|
export declare function readContentCode(content: string, start: number, numbers: readonly (number | null)[] | undefined, path: string | undefined): NativeNode[];
|
|
149
149
|
/** Render file, image, and URL reads in the transcript. */
|
|
@@ -104,7 +104,7 @@ export interface TaskItem {
|
|
|
104
104
|
agent?: string;
|
|
105
105
|
/** Historical source session selected by the bundled consult agent. */
|
|
106
106
|
sourceSession?: string;
|
|
107
|
-
/**
|
|
107
|
+
/** Bundled seance: override for the source session's saved model. Any other agent: one exact per-call model, gated by `task.perCallModel`. */
|
|
108
108
|
model?: string | string[];
|
|
109
109
|
/** Inline instructions; exactly one of task or taskFile is required. */
|
|
110
110
|
task?: string;
|
|
@@ -135,7 +135,7 @@ export interface TaskParams {
|
|
|
135
135
|
agent?: string;
|
|
136
136
|
/** Historical source session selected by the bundled consult agent. */
|
|
137
137
|
sourceSession?: string;
|
|
138
|
-
/**
|
|
138
|
+
/** See {@link TaskItem.model}. */
|
|
139
139
|
model?: string | string[];
|
|
140
140
|
/** The work (flat form). */
|
|
141
141
|
task?: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-tui",
|
|
4
|
-
"version": "18.14.
|
|
4
|
+
"version": "18.14.2",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": {
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"gen:glyphs": "bun scripts/gen-glyphs.ts"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@oh-my-pi/omptype": "18.14.
|
|
45
|
-
"@oh-my-pi/pi-agent-core": "18.14.
|
|
46
|
-
"@oh-my-pi/pi-ai": "18.14.
|
|
47
|
-
"@oh-my-pi/pi-catalog": "18.14.
|
|
48
|
-
"@oh-my-pi/pi-natives": "18.14.
|
|
49
|
-
"@oh-my-pi/pi-utils": "18.14.
|
|
50
|
-
"@oh-my-pi/pi-wire": "18.14.
|
|
51
|
-
"@oh-my-pi/snapcompact": "18.14.
|
|
44
|
+
"@oh-my-pi/omptype": "18.14.2",
|
|
45
|
+
"@oh-my-pi/pi-agent-core": "18.14.2",
|
|
46
|
+
"@oh-my-pi/pi-ai": "18.14.2",
|
|
47
|
+
"@oh-my-pi/pi-catalog": "18.14.2",
|
|
48
|
+
"@oh-my-pi/pi-natives": "18.14.2",
|
|
49
|
+
"@oh-my-pi/pi-utils": "18.14.2",
|
|
50
|
+
"@oh-my-pi/pi-wire": "18.14.2",
|
|
51
|
+
"@oh-my-pi/snapcompact": "18.14.2"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"kitty-vt-wasm": "^0.2.0"
|
package/src/apps/git/git-tui.ts
CHANGED
|
@@ -37,7 +37,7 @@ import { routeSgrMouseInput } from "../../mouse";
|
|
|
37
37
|
import { col, compact, keyed, node, row, span, stableKey, text } from "../../native/describe";
|
|
38
38
|
import { Memo } from "../../native/memo";
|
|
39
39
|
import type { DescribeContext, NativeNode, NativeUiEvent } from "../../native/node";
|
|
40
|
-
import { actionButton } from "../../native/overlay";
|
|
40
|
+
import { actionButton, iconButton, segmentedTabs } from "../../native/overlay";
|
|
41
41
|
import { type Component, type OverlayHandle, TUI } from "../../tui";
|
|
42
42
|
import { truncateToWidth, visibleWidth } from "../../utils";
|
|
43
43
|
import { theme, warmHighlighter } from "../../theme/theme";
|
|
@@ -1039,35 +1039,28 @@ class GitTuiComponent implements Component {
|
|
|
1039
1039
|
} else {
|
|
1040
1040
|
left.push(text([span(this.#model.branch ?? "detached", "muted")], { role: "omp.app.git.path" }));
|
|
1041
1041
|
}
|
|
1042
|
-
const
|
|
1043
|
-
|
|
1044
|
-
"icon",
|
|
1045
|
-
{ name, title, aria: title, role: on ? "omp.app.ibtn.set" : "omp.app.ibtn", actions: { click: act } },
|
|
1046
|
-
undefined,
|
|
1047
|
-
act,
|
|
1048
|
-
);
|
|
1042
|
+
const tool = (name: string, act: string, title: string, on?: boolean): NativeNode =>
|
|
1043
|
+
iconButton(name, act, title, { key: act, on });
|
|
1049
1044
|
const right: NativeNode[] = [
|
|
1050
1045
|
row(
|
|
1051
1046
|
[
|
|
1052
|
-
|
|
1053
|
-
|
|
1047
|
+
tool("chev-up", "prev-hunk", `Previous change (${formatTooltipKey("alt+up")})`),
|
|
1048
|
+
tool("chev", "next-hunk", `Next change (${formatTooltipKey("alt+down")})`),
|
|
1054
1049
|
],
|
|
1055
1050
|
{ gap: "none", align: "center" },
|
|
1056
1051
|
),
|
|
1057
|
-
|
|
1058
|
-
"tabs",
|
|
1052
|
+
segmentedTabs(
|
|
1059
1053
|
{
|
|
1060
1054
|
items: VIEW_TABS.map(tab => ({ id: tab.id, label: tab.label })),
|
|
1061
1055
|
active: this.#pane.mode,
|
|
1062
1056
|
role: "omp.app.seg",
|
|
1063
1057
|
},
|
|
1064
|
-
undefined,
|
|
1065
1058
|
"views",
|
|
1066
1059
|
),
|
|
1067
1060
|
];
|
|
1068
1061
|
if (!narrow) {
|
|
1069
1062
|
right.push(
|
|
1070
|
-
|
|
1063
|
+
tool(
|
|
1071
1064
|
"type",
|
|
1072
1065
|
"whitespace",
|
|
1073
1066
|
this.#whitespace === "off"
|
|
@@ -1077,7 +1070,7 @@ class GitTuiComponent implements Component {
|
|
|
1077
1070
|
: `Ignoring formatting and imports; show all (${formatTooltipKey("b")})`,
|
|
1078
1071
|
this.#whitespace !== "off",
|
|
1079
1072
|
),
|
|
1080
|
-
|
|
1073
|
+
tool("corner-down-right", "wrap", `Wrap lines (${formatTooltipKey("w")})`, this.#pane.wrap),
|
|
1081
1074
|
);
|
|
1082
1075
|
}
|
|
1083
1076
|
if (file?.area === "unstaged" || file?.area === "staged") {
|
|
@@ -1089,8 +1082,8 @@ class GitTuiComponent implements Component {
|
|
|
1089
1082
|
);
|
|
1090
1083
|
}
|
|
1091
1084
|
right.push(
|
|
1092
|
-
|
|
1093
|
-
|
|
1085
|
+
tool("keyboard", "help", `Keyboard shortcuts (${formatTooltipKey("?")})`),
|
|
1086
|
+
tool("x", "close", `Close (${formatTooltipKey("q")})`),
|
|
1094
1087
|
);
|
|
1095
1088
|
return keyed(
|
|
1096
1089
|
row(
|