@oh-my-pi/pi-tui 18.2.11 → 18.3.1

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.
Files changed (101) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/THIRD-PARTY-NOTICES.txt +3 -3
  3. package/dist/types/apps/ps-data.d.ts +1 -1
  4. package/dist/types/apps/ps-top.d.ts +1 -1
  5. package/dist/types/chat/chat-transcript-builder.d.ts +1 -1
  6. package/dist/types/chat/read-tool-group.d.ts +3 -3
  7. package/dist/types/chat/user-message.d.ts +4 -1
  8. package/dist/types/components/editor.d.ts +0 -2
  9. package/dist/types/components/input.d.ts +16 -0
  10. package/dist/types/overlays/annotation-overlay.d.ts +30 -0
  11. package/dist/types/overlays/annotation-types.d.ts +84 -0
  12. package/dist/types/overlays/btw-history-panel.d.ts +4 -1
  13. package/dist/types/overlays/copy-selector.d.ts +30 -2
  14. package/dist/types/overlays/copy-targets.d.ts +2 -0
  15. package/dist/types/overlays/model-hub.d.ts +2 -2
  16. package/dist/types/overlays/oauth-selector.d.ts +3 -6
  17. package/dist/types/overlays/settings-defs.d.ts +5 -0
  18. package/dist/types/overlays/usage-dashboard.d.ts +2 -0
  19. package/dist/types/prompt/composer.d.ts +12 -1
  20. package/dist/types/prompt/custom-editor.d.ts +5 -26
  21. package/dist/types/prompt/image-source.d.ts +9 -8
  22. package/dist/types/space-hold.d.ts +45 -0
  23. package/dist/types/status-line/context-usage.d.ts +3 -1
  24. package/dist/types/status-line/host.d.ts +2 -0
  25. package/dist/types/theme/mermaid-cache.d.ts +4 -6
  26. package/dist/types/tools/bash.d.ts +7 -0
  27. package/dist/types/tools/cfg-render.d.ts +37 -0
  28. package/dist/types/tools/cfg-url.d.ts +16 -0
  29. package/dist/types/tools/daemon.d.ts +46 -0
  30. package/dist/types/tools/find.d.ts +2 -2
  31. package/dist/types/tools/irc.d.ts +30 -0
  32. package/dist/types/tools/line-ranges.d.ts +1 -1
  33. package/dist/types/tools/output-meta.d.ts +2 -0
  34. package/dist/types/tools/proc-render.d.ts +27 -0
  35. package/dist/types/tools/read.d.ts +18 -4
  36. package/dist/types/tools/result-card.d.ts +20 -0
  37. package/dist/types/tools/url-scheme-host.d.ts +29 -0
  38. package/dist/types/tools/wait.d.ts +131 -0
  39. package/dist/types/tools/write.d.ts +6 -0
  40. package/dist/types/tools/xd-url.d.ts +8 -0
  41. package/dist/types/tools/xdev.d.ts +9 -1
  42. package/dist/types/windows-altgr.d.ts +54 -0
  43. package/package.json +13 -10
  44. package/src/apps/debug/protocol-probe.ts +1 -1
  45. package/src/apps/ps-data.ts +1 -1
  46. package/src/apps/ps-top.ts +1 -1
  47. package/src/chat/chat-transcript-builder.ts +9 -5
  48. package/src/chat/read-tool-group.ts +8 -9
  49. package/src/chat/tool-execution.ts +15 -13
  50. package/src/chat/transcript-render-helpers.ts +3 -3
  51. package/src/chat/user-message.ts +16 -6
  52. package/src/components/editor.ts +2 -4
  53. package/src/components/input.ts +103 -30
  54. package/src/components/markdown.ts +19 -7
  55. package/src/desktop-notify.ts +1 -1
  56. package/src/overlays/annotation-overlay.ts +1144 -0
  57. package/src/overlays/annotation-types.ts +78 -0
  58. package/src/overlays/btw-history-panel.ts +4 -0
  59. package/src/overlays/copy-selector.ts +45 -19
  60. package/src/overlays/copy-targets.ts +3 -3
  61. package/src/overlays/model-hub.ts +5 -4
  62. package/src/overlays/oauth-selector.ts +8 -12
  63. package/src/overlays/plan-review-overlay.ts +213 -40
  64. package/src/overlays/settings-defs.ts +6 -0
  65. package/src/overlays/settings-selector.ts +4 -3
  66. package/src/overlays/usage-dashboard.ts +22 -1
  67. package/src/prompt/composer.ts +83 -56
  68. package/src/prompt/custom-editor.ts +15 -137
  69. package/src/prompt/image-source.ts +9 -8
  70. package/src/prompt/tips.txt +1 -0
  71. package/src/setup/scenes/sign-in.ts +1 -1
  72. package/src/space-hold.ts +143 -0
  73. package/src/status-line/component.ts +6 -0
  74. package/src/status-line/context-usage.ts +15 -3
  75. package/src/status-line/host.ts +2 -0
  76. package/src/status-line/segments.ts +4 -0
  77. package/src/terminal-capabilities.ts +2 -2
  78. package/src/terminal.ts +8 -1
  79. package/src/theme/mermaid-cache.ts +83 -25
  80. package/src/tools/bash.ts +14 -1
  81. package/src/tools/cfg-render.ts +117 -0
  82. package/src/tools/cfg-url.ts +30 -0
  83. package/src/tools/daemon.ts +51 -0
  84. package/src/tools/find.ts +7 -6
  85. package/src/tools/index.ts +2 -2
  86. package/src/tools/irc.ts +33 -0
  87. package/src/tools/line-ranges.ts +13 -3
  88. package/src/tools/output-meta.ts +2 -0
  89. package/src/tools/proc-render.ts +270 -0
  90. package/src/tools/read.ts +118 -56
  91. package/src/tools/result-card.ts +36 -0
  92. package/src/tools/url-scheme-host.ts +42 -0
  93. package/src/tools/wait.ts +595 -0
  94. package/src/tools/write.ts +120 -1
  95. package/src/tools/xd-url.ts +9 -0
  96. package/src/tools/xdev.ts +9 -1
  97. package/src/windows-altgr.ts +227 -0
  98. package/dist/types/chat/read-target.d.ts +0 -4
  99. package/dist/types/tools/hub.d.ts +0 -342
  100. package/src/chat/read-target.ts +0 -7
  101. package/src/tools/hub.ts +0 -1492
package/CHANGELOG.md CHANGED
@@ -2,6 +2,50 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.3.1] - 2026-09-25
6
+
7
+ ### Breaking Changes
8
+
9
+ - Replaced the `CustomEditor` space-hold callbacks and `sttHoldEnabled` option with the `spaceHold.handler` API.
10
+ - Removed `Editor.cursorOverrideWidth`; widths for `cursorOverride` glyphs are now measured automatically.
11
+
12
+ ### Added
13
+
14
+ - Added push-to-talk dictation to `Input`, with live transcription and `cursorOverride` support.
15
+ - Added visual indicators for live-steered user messages and paginated content in read-tool results.
16
+ - Added transcript support for `cfg://` configuration read and write tool calls.
17
+ - Added an Anthropic slow-mode badge to the status-line model segment, showing the priority state, end time, and remaining request percentage when available.
18
+
19
+ ### Changed
20
+
21
+ - Updated the settings selector so clearing an input field fully unsets the corresponding setting.
22
+
23
+ ### Fixed
24
+
25
+ - Fixed dimmed blockquote styling after inline code spans.
26
+ - Fixed rendering of tool calls and results for top-level extension and MCP tools invoked through `xd://` links.
27
+ - Fixed file links in pending Read and Write cards so they open the correct local targets, including paths in the home directory, archives, and databases.
28
+
29
+ ## [18.3.0] - 2026-09-24
30
+
31
+ ### Added
32
+
33
+ - Added proc:// and agent:// URI support for interacting with processes and agents.
34
+ - Added support for xd:// documentation topic URLs.
35
+ - Added rendering for background job state and peer-to-peer messages from the wait tool.
36
+ - Added supervised bash service rendering with status, readiness, and output information.
37
+ - Added a fullscreen annotation overlay for diffs and text, including multi-line notes, editing, deletion, and undo ([#12601](https://github.com/can1357/oh-my-pi/pull/12601) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy)).
38
+ - Added Daybreak-enabled account listings to the usage dashboard.
39
+
40
+ ### Changed
41
+
42
+ - Mermaid flowcharts and state diagrams now automatically choose a layout that best fits the available terminal width and reflow when the terminal is resized.
43
+ - Plan Review annotations now support multi-line editing, deletion, and undo ([#12601](https://github.com/can1357/oh-my-pi/pull/12601) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy)).
44
+
45
+ ### Fixed
46
+
47
+ - Fixed AltGr characters, including `[`, `]`, `{`, and `}`, being dropped in Windows Terminal when using the kitty keyboard protocol on Hungarian and other international keyboard layouts ([#12984](https://github.com/can1357/oh-my-pi/pull/12984) by [@H4vC](https://github.com/H4vC)).
48
+
5
49
  ## [18.2.11] - 2026-09-23
6
50
 
7
51
  ### Added
@@ -78,8 +78,8 @@ below.
78
78
  uutils coreutils (https://github.com/uutils/coreutils), MIT
79
79
  --------------------------------------------------------------------------------
80
80
  Covers: base32, base64, basename, cat, cksum (shared checksum machinery),
81
- b2sum, md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, comm, cut,
82
- date, dirname, head, hostname, ln, ls, mkdir, mktemp, mv, nproc, paste,
81
+ b2sum, md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, comm, cp,
82
+ cut, date, dirname, head, hostname, ln, ls, mkdir, mktemp, mv, nproc, paste,
83
83
  printenv, readlink, realpath, rm, seq, sort, stat, tac, tail, tee, touch, tr,
84
84
  truncate, uname, uniq, wc, whoami, yes.
85
85
 
@@ -293,7 +293,7 @@ MIT License
293
293
  Copyright (c) 2026 Sander Land
294
294
  (measured tokenizer vocabulary data, reconstruction model, and reference
295
295
  implementation: https://github.com/sanderland/ctok)
296
- Copyright (c) 2026 Can Bölük and the Oh My Pi contributors
296
+ Copyright (c) 2026 Can Bölük and the omp contributors
297
297
  Copyright (c) 2026 Stencil Labs, Inc.
298
298
  (Rust implementation and the compact binary vocabulary encoding in
299
299
  crates/pi-natives/src/utok/claude)
@@ -1,4 +1,4 @@
1
- import type { DaemonSnapshot, DaemonSpec, DaemonState } from "../tools/hub.js";
1
+ import type { DaemonSnapshot, DaemonSpec, DaemonState } from "../tools/daemon.js";
2
2
  /** One broker scope: a project runtime dir or a machine-global service dir. */
3
3
  export interface PsScope {
4
4
  kind: "project" | "global";
@@ -1,5 +1,5 @@
1
1
  import { type Component, TUI } from "../tui.js";
2
- import type { DaemonSnapshot, DaemonSpec } from "../tools/hub.js";
2
+ import type { DaemonSnapshot, DaemonSpec } from "../tools/daemon.js";
3
3
  import { type PsScope, type PsScopeReport, type PsTarget } from "./ps-data.js";
4
4
  /** Options accepted by the interactive monitor: scope selection from the list flags. */
5
5
  export interface PsTopOptions extends PsTarget {
@@ -5,7 +5,7 @@
5
5
  * viewer ({@link AgentTranscriptViewer}) to render a parked subagent / advisor /
6
6
  * collab-guest transcript that has no live session.
7
7
  *
8
- * Unlike the old incremental hub sync, {@link ChatTranscriptBuilder.rebuild}
8
+ * Unlike incremental transcript sync, {@link ChatTranscriptBuilder.rebuild}
9
9
  * always discards prior components and rebuilds the whole transcript from the
10
10
  * supplied entries. Re-rendering a growing transcript is therefore O(n) in the
11
11
  * entry count, but it cannot duplicate or misorder rows the way incremental
@@ -7,9 +7,9 @@ export declare function readArgsHaveTarget(args: unknown): boolean;
7
7
  /**
8
8
  * Whether a read collapses into the compact {@link ReadToolGroupComponent}
9
9
  * rather than a full tool execution. Filesystem/external targets always
10
- * collapse; other internal URLs (`skill://`, `agent://`, …) render full so
11
- * their resolved content is visible. `xd://` device reads are the exception —
12
- * they list devices/docs and read better in the compact grouped view.
10
+ * collapse; registered internal-URL schemes render full so their resolved
11
+ * content is visible, unless their spec declares `compactTranscript`
12
+ * (device listings/docs read better in the compact grouped view).
13
13
  */
14
14
  export declare function readArgsCollapseIntoGroup(args: unknown): boolean;
15
15
  /**
@@ -6,6 +6,8 @@ export interface UserBubbleOptions {
6
6
  imageLinks?: readonly (string | undefined)[];
7
7
  /** Agent-attributed input: dim, flat prose. */
8
8
  synthetic?: boolean;
9
+ /** Delivered into the response that was streaming; marked `*` at the bubble's top-left. */
10
+ liveSteered?: boolean;
9
11
  /** SKILL.md path for a skill chip by name; `undefined` leaves the chip unlinked. */
10
12
  skillPath?: (name: string) => string | undefined;
11
13
  }
@@ -19,7 +21,8 @@ export interface UserBubbleOptions {
19
21
  export declare function userBubbleColor(options?: UserBubbleOptions, tokenRegex?: RegExp): (value: string) => string;
20
22
  /**
21
23
  * Component that renders a user message. Accepts an agent reaction badge
22
- * (see {@link ReactionTarget}) drawn right-aligned in the bubble's top padding row.
24
+ * (see {@link ReactionTarget}) drawn right-aligned in the bubble's top padding row;
25
+ * a live-steered message carries a `*` marker left-aligned in the same row.
23
26
  */
24
27
  export declare class UserMessageComponent extends Container implements ReactionTarget {
25
28
  #private;
@@ -69,8 +69,6 @@ export declare class Editor implements Component, Focusable {
69
69
  focused: boolean;
70
70
  /** When set, replaces the normal cursor glyph at end-of-text with this ANSI-styled string. */
71
71
  cursorOverride: string | undefined;
72
- /** Display width of the cursorOverride glyph (needed because override may contain ANSI escapes). */
73
- cursorOverrideWidth: number | undefined;
74
72
  /** Optional hook that decorates displayed user text after source-text layout.
75
73
  * Width-changing output is allowed on lines without the cursor; it is truncated
76
74
  * to the content width rather than reflowed. Cursor glyphs and inline hints are excluded. */
@@ -1,3 +1,4 @@
1
+ import { SpaceHoldGesture } from "../space-hold.js";
1
2
  import { type Component, type Focusable } from "../tui.js";
2
3
  /**
3
4
  * Input component - single-line text input with horizontal scrolling
@@ -10,6 +11,10 @@ export declare class Input implements Component, Focusable {
10
11
  mask: boolean;
11
12
  onSubmit?: (value: string) => void;
12
13
  onEscape?: () => void;
14
+ /** Space-bar push-to-talk; set its `handler` to enable it. */
15
+ readonly spaceHold: SpaceHoldGesture;
16
+ /** When set, replaces the cursor glyph at end-of-text with this ANSI-styled string. */
17
+ cursorOverride: string | undefined;
13
18
  /** Focusable interface - set by TUI when focus changes */
14
19
  focused: boolean;
15
20
  getValue(): string;
@@ -22,6 +27,17 @@ export declare class Input implements Component, Focusable {
22
27
  /** Apply terminal paste semantics to text from non-bracketed paste transports
23
28
  * (e.g. kitty's OSC 5522 enhanced clipboard read). Mirrors `Editor.pasteText`. */
24
29
  pasteText(text: string): void;
30
+ /** Programmatically trigger submission (e.g. for voice submit). */
31
+ submit(): void;
32
+ /** Delete up to `count` characters immediately before the cursor. */
33
+ deleteBeforeCursor(count: number): void;
34
+ /** Show or replace a volatile speech-to-text preview at the cursor, outside undo history.
35
+ * Finalize it with {@link commitVolatileText} or drop it with {@link clearVolatileText}. */
36
+ setVolatileText(text: string): void;
37
+ /** Remove the current volatile preview without committing it. */
38
+ clearVolatileText(): void;
39
+ /** Drop any volatile preview, then insert `text` as a single undoable edit. */
40
+ commitVolatileText(text: string): void;
25
41
  invalidate(): void;
26
42
  render(width: number): readonly string[];
27
43
  }
@@ -0,0 +1,30 @@
1
+ import { type Component, type TUI } from "../index.js";
2
+ import { type KeybindingsManager } from "../app-keybindings.js";
3
+ import { type Theme } from "../theme/theme.js";
4
+ import type { CodeReviewAnnotation, CodeReviewOverlayResult, ReviewDiffFile, TextReviewAnnotation, TextReviewOverlayResult, TextReviewSource } from "./annotation-types.js";
5
+ export declare const CONTINUE_CODE_REVIEW_ACTION = "Continue with LLM review";
6
+ export declare const PASTE_CODE_REVIEW_ACTION = "Paste annotations into prompt";
7
+ export interface AnnotationOverlayCallbacks {
8
+ onComplete(result: CodeReviewOverlayResult | TextReviewOverlayResult | undefined): void;
9
+ onWarning?(message: string): void;
10
+ /** Open the draft in the host's editor and invoke `commit` with its result. */
11
+ onAnnotationExternalEditor?(draft: string, commit: (text: string | null) => void): void | Promise<void>;
12
+ }
13
+ export interface CodeReviewOverlayCallbacks extends AnnotationOverlayCallbacks {
14
+ onComplete(result: CodeReviewOverlayResult | undefined): void;
15
+ }
16
+ export interface TextReviewOverlayCallbacks extends AnnotationOverlayCallbacks {
17
+ onComplete(result: TextReviewOverlayResult | undefined): void;
18
+ }
19
+ /** A fullscreen, annotated diff picker that only relies on public OMP APIs. */
20
+ export declare class AnnotationOverlay implements Component {
21
+ #private;
22
+ constructor(tui: TUI, theme: Theme, keybindings: KeybindingsManager, files: readonly ReviewDiffFile[], mode: string, callbacks: CodeReviewOverlayCallbacks);
23
+ constructor(tui: TUI, theme: Theme, keybindings: KeybindingsManager, source: TextReviewSource, callbacks: TextReviewOverlayCallbacks);
24
+ invalidate(): void;
25
+ dispose(): void;
26
+ getAnnotations(): CodeReviewAnnotation[];
27
+ getTextAnnotations(): TextReviewAnnotation[];
28
+ handleInput(data: string): void;
29
+ render(width: number): readonly string[];
30
+ }
@@ -0,0 +1,84 @@
1
+ export type ReviewSourceRowKind = "context" | "added" | "removed";
2
+ export interface ReviewSourceRow {
3
+ kind: ReviewSourceRowKind;
4
+ raw: string;
5
+ content: string;
6
+ oldLine?: number;
7
+ newLine?: number;
8
+ hunkHeader: string;
9
+ }
10
+ export type ReviewDiffRow = ReviewSourceRow | {
11
+ kind: "hunk";
12
+ raw: string;
13
+ hunkHeader: string;
14
+ } | {
15
+ kind: "no-newline";
16
+ raw: string;
17
+ hunkHeader: string;
18
+ };
19
+ export interface ReviewDiffFile {
20
+ path: string;
21
+ oldPath?: string;
22
+ newPath?: string;
23
+ occurrence: number;
24
+ rawDiff: string;
25
+ rows: ReviewDiffRow[];
26
+ linesAdded: number;
27
+ linesRemoved: number;
28
+ isBinary: boolean;
29
+ }
30
+ export interface CodeReviewAnnotationBase {
31
+ path: string;
32
+ oldPath?: string;
33
+ newPath?: string;
34
+ occurrence: number;
35
+ note: string;
36
+ }
37
+ export type CodeReviewAnnotation = (CodeReviewAnnotationBase & {
38
+ scope: "file";
39
+ }) | (CodeReviewAnnotationBase & {
40
+ scope: "line";
41
+ hunkHeader: string;
42
+ oldLine?: number;
43
+ newLine?: number;
44
+ rawLine: string;
45
+ });
46
+ export interface CodeReviewOverlayResult {
47
+ action: "review" | "paste";
48
+ annotations: CodeReviewAnnotation[];
49
+ }
50
+ export type TextReviewSourceProvenance = {
51
+ kind: "latest-assistant";
52
+ entryId: string;
53
+ } | {
54
+ kind: "session";
55
+ entryId: string;
56
+ } | {
57
+ kind: "file";
58
+ path: string;
59
+ } | {
60
+ kind: "prompt";
61
+ };
62
+ export interface TextReviewSource {
63
+ /** Identifies the source within this annotation run. */
64
+ id: string;
65
+ kind: "message" | "code" | "quote" | "command" | "file" | "prompt";
66
+ label: string;
67
+ text: string;
68
+ /** Identifies the active session entry that supplied this source, when applicable. */
69
+ provenance?: TextReviewSourceProvenance;
70
+ sessionId?: string;
71
+ }
72
+ export type TextReviewAnnotation = {
73
+ scope: "text";
74
+ note: string;
75
+ } | {
76
+ scope: "line";
77
+ line: number;
78
+ quote: string;
79
+ note: string;
80
+ };
81
+ export interface TextReviewOverlayResult {
82
+ action: "paste";
83
+ annotations: TextReviewAnnotation[];
84
+ }
@@ -1,5 +1,6 @@
1
- import { type Component, type Focusable } from "../index.js";
1
+ import { type Component, type Focusable, Input } from "../index.js";
2
2
  import { type BtwHistoryRecord } from "./btw-history.js";
3
+ import type { SpaceHoldHandler } from "../space-hold.js";
3
4
  interface BtwHistoryPanelOptions {
4
5
  records: readonly BtwHistoryRecord[];
5
6
  onClose: () => void;
@@ -7,6 +8,8 @@ interface BtwHistoryPanelOptions {
7
8
  onCancel: (record: BtwHistoryRecord) => void;
8
9
  canFollowUp?: (record: BtwHistoryRecord) => boolean;
9
10
  onFollowUp?: (record: BtwHistoryRecord, question: string, signal: AbortSignal) => Promise<boolean>;
11
+ /** Space-bar push-to-talk for a follow-up composer: dictates into `input` while Space is held. */
12
+ spaceHold?: (input: Input) => SpaceHoldHandler;
10
13
  requestRender: () => void;
11
14
  getHeight: () => number;
12
15
  }
@@ -29,12 +29,40 @@ export interface CopySelectorDeps {
29
29
  proseOnlyThinking?: () => boolean;
30
30
  linkTargets?: ReadonlyMap<string, string>;
31
31
  requestRender: () => void;
32
- /** The outlined content was chosen — copy it. `label` feeds the status line. */
33
- onPick: (content: string, label: string) => void;
32
+ /** Replaces the "Copy" header when the picker is reused for another purpose. */
33
+ title?: string;
34
+ /** Verb shown for the pick action in hints and block controls (default "copy"). */
35
+ actionLabel?: string;
36
+ /**
37
+ * The outlined content was chosen — copy it. `label` feeds the status line;
38
+ * `source` names the transcript entry (and inner block, when descended) it came from.
39
+ */
40
+ onPick: (content: string, label: string, source: CopyPickSource) => void;
34
41
  /** `o` on a link block — open `href` with the system opener. Absent: `o` is ignored. */
35
42
  onOpen?: (href: string, label: string) => void;
36
43
  onCancel: () => void;
37
44
  }
45
+ /** Where picked content came from in the transcript. */
46
+ export interface CopyPickSource {
47
+ entry: TranscriptEntry;
48
+ /** The inner block, when the pick happened in the descended block view. */
49
+ block?: CopyBlock;
50
+ }
51
+ /** One copyable inner block of a transcript turn. */
52
+ export interface CopyBlock {
53
+ /** Short kind label ("code · ts", "bash command", "read result", …). */
54
+ label: string;
55
+ /** Exact text placed on the clipboard. */
56
+ content: string;
57
+ /** Transcript entry that produced this block. */
58
+ entry: TranscriptEntry;
59
+ /** Markdown code/quote block, or a bash/eval tool-call command. */
60
+ kind?: "code" | "quote" | "command";
61
+ /** Highlight language for the block preview. */
62
+ language?: string;
63
+ /** Set for link blocks: the URL `o` opens. `content` is the same URL. */
64
+ href?: string;
65
+ }
38
66
  export declare class CopySelectorComponent implements Component {
39
67
  #private;
40
68
  private readonly deps;
@@ -61,3 +61,5 @@ export declare function extractLastLink(messages: readonly AgentMessage[]): Link
61
61
  export declare function commandFromToolCall(tc: ToolCall): LastCommand | undefined;
62
62
  /** Walk the transcript backwards for the most recent bash command or eval code. */
63
63
  export declare function extractLastCommand(messages: readonly AgentMessage[]): LastCommand | undefined;
64
+ /** Concatenated visible text of an assistant message, verbatim; undefined when blank. */
65
+ export declare function assistantText(msg: AgentMessage): string | undefined;
@@ -1,4 +1,4 @@
1
- import type { Model } from "@oh-my-pi/pi-ai";
1
+ import type { KeysApi, Model } from "@oh-my-pi/pi-ai";
2
2
  import type { Component, TUI } from "../tui.js";
3
3
  import type { ModelBrowserSource, ModelBrowserRegistry } from "./model-browser.js";
4
4
  import { type ConfiguredThinkingLevel } from "../thinking.js";
@@ -15,7 +15,7 @@ export interface ModelHubSource extends ModelBrowserSource {
15
15
  /** Catalog capabilities required by the model hub. */
16
16
  export interface ModelHubRegistry extends ModelBrowserRegistry {
17
17
  readonly authStorage: {
18
- hasAuth(provider: string): boolean;
18
+ readonly keys: Pick<KeysApi, "source">;
19
19
  };
20
20
  getDiscoverableProviders(): string[];
21
21
  getProviderDiscoveryState(provider: string): {
@@ -1,13 +1,10 @@
1
+ import type { CredentialsApi, KeysApi } from "@oh-my-pi/pi-ai";
1
2
  import { type SgrMouseEvent } from "../index.js";
2
3
  import { OverlayPanel } from "../chrome/overlay-box.js";
3
4
  /** Credential presence and provenance needed by the provider picker. */
4
5
  export interface OAuthSelectorAuthSource {
5
- has(providerId: string): boolean;
6
- hasAuth(providerId: string): boolean;
7
- getCredentialOrigin(providerId: string): {
8
- kind: "runtime" | "config" | "oauth" | "api_key" | "env" | "fallback";
9
- envVar?: string;
10
- } | undefined;
6
+ readonly credentials: Pick<CredentialsApi, "has">;
7
+ readonly keys: Pick<KeysApi, "source">;
11
8
  }
12
9
  /**
13
10
  * Component that renders an OAuth provider selector.
@@ -57,6 +57,11 @@ export interface SettingsHost {
57
57
  entries: readonly SettingsDisplayEntry[];
58
58
  get(path: string): unknown;
59
59
  set(path: string, value: unknown): void;
60
+ /**
61
+ * Removes the value from the global config: a project or other layer, or an environment
62
+ * variable, that configures the setting still applies; otherwise the default does.
63
+ */
64
+ unset(path: string): void;
60
65
  normalizeProviderLimits(value: unknown): Record<string, number>;
61
66
  validateProviderLimits(value: unknown): Record<string, number>;
62
67
  }
@@ -38,6 +38,8 @@ export interface ProviderCard {
38
38
  soonestExpiryMs?: number;
39
39
  unavailableReasons: string[];
40
40
  };
41
+ /** Labels of accounts with verified Daybreak access. */
42
+ daybreakAccounts?: string[];
41
43
  }
42
44
  /**
43
45
  * Collapse usage reports into one compact card per provider: limits grouped by
@@ -56,6 +56,17 @@ export interface ComposerOptions {
56
56
  readonly exit?: (code: number) => void;
57
57
  readonly now?: () => number;
58
58
  }
59
+ /** How {@link Composer.setRuntimeChildren} bills below-transcript roots against transcript retirement. */
60
+ export interface RuntimeChildrenOptions {
61
+ /**
62
+ * Below-transcript roots whose growth is momentary (inline dialogs, a tall
63
+ * multi-line editor). They are billed at their smallest height so expansion
64
+ * clips the live tail instead of retiring rows a later shrink could not
65
+ * reclaim (#11007). Every other root is billed at its current height, so
66
+ * settled rows it displaces retire to native scrollback.
67
+ */
68
+ readonly transient?: readonly Component[];
69
+ }
59
70
  /** Controls the first terminal paint for a composer that does not already own the terminal. */
60
71
  export interface ComposerStartOptions {
61
72
  readonly clearScrollback?: boolean;
@@ -149,7 +160,7 @@ export declare class Composer implements TerminalFrameProvider {
149
160
  */
150
161
  setStatusComponent(component: Component): void;
151
162
  /** Mount or replace session-aware root children while preserving the header and status hosts. */
152
- setRuntimeChildren(children: readonly Component[]): void;
163
+ setRuntimeChildren(children: readonly Component[], options?: RuntimeChildrenOptions): void;
153
164
  /** Play or replay the welcome intro against the stable header render target. */
154
165
  playWelcomeIntro(): void;
155
166
  /** Transfer terminal ownership to InteractiveMode without stopping the composer. */
@@ -1,27 +1,11 @@
1
1
  import type { ImageContent } from "@oh-my-pi/pi-ai";
2
2
  import { Editor, type EditorTextDecorationContext } from "../components/editor.js";
3
3
  import { type KeyId } from "../keys.js";
4
+ import { SpaceHoldGesture } from "../space-hold.js";
4
5
  import { TUI } from "../tui.js";
5
6
  import type { AppKeybinding } from "../app-keybindings.js";
6
7
  import { type SpellingFeatures } from "./macos-spelling.js";
7
8
  type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.display.reset" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.message.dequeue" | "app.retry" | "app.clipboard.pasteImage" | "app.clipboard.pasteTextRaw" | "app.clipboard.copyPrompt">;
8
- /** Max gap (ms) between two spaces for the later one to count as OS key auto-repeat rather than a
9
- * deliberate press. OS auto-repeat is fast; a deliberate tap (even a fast one) is slower. */
10
- export declare const SPACE_REPEAT_MAX_GAP_MS = 120;
11
- /** Two consecutive inter-space gaps are "mechanical" (machine-driven auto-repeat) when both are
12
- * within {@link SPACE_REPEAT_MAX_GAP_MS} and differ by no more than this — an absolute jitter floor
13
- * or, for slower repeat rates, {@link SPACE_REPEAT_JITTER_RATIO} of the smaller gap. OS key-repeat
14
- * is metronomic; a human smashing the bar is fast but irregular, so its deltas never stay this
15
- * steady. */
16
- export declare const SPACE_REPEAT_JITTER_MS = 18;
17
- export declare const SPACE_REPEAT_JITTER_RATIO = 0.35;
18
- /** Consecutive mechanical (fast + steady) deltas that confirm the space bar is held and start
19
- * recording. Needs a sustained metronomic cadence, so jittery smashing and deliberate taps never
20
- * reach it. */
21
- export declare const SPACE_HOLD_MECHANICAL_RUN = 2;
22
- /** Idle gap (ms) after the last repeated space that counts as the space bar being released, ending
23
- * the push-to-talk recording. Must comfortably exceed the OS key-repeat interval. */
24
- export declare const SPACE_HOLD_RELEASE_MS = 250;
25
9
  /**
26
10
  * Extract image-or-other file paths from plain (un-bracketed) clipboard text.
27
11
  * Mirrors {@link extractBracketedPastePaths} for terminals/handlers that
@@ -224,15 +208,10 @@ export declare class CustomEditor extends Editor {
224
208
  onCapsLock?: () => void;
225
209
  /** Called when left-arrow is pressed while the editor is empty (cursor necessarily at start). */
226
210
  onLeftAtStart?: () => void;
227
- /** Fired when a sustained space-bar hold is recognized — the push-to-talk STT start. The
228
- * optimistically-typed spaces have already been deleted by the time this runs. */
229
- onSpaceHoldStart?: () => void;
230
- /** Fired when the held space bar is released (detected as an idle gap with no further repeated
231
- * spaces) — the push-to-talk STT stop. */
232
- onSpaceHoldEnd?: () => void;
233
- /** Gate for the space-hold gesture. Returns false to keep the space bar inserting spaces
234
- * normally; wired to `stt.enabled` so disabling STT restores plain space behavior. */
235
- sttHoldEnabled?: () => boolean;
211
+ /** Space-bar push-to-talk; set its `handler` to enable it. It is a text-composition gesture, so it
212
+ * stays out of Vim's Normal/Visual modes (where the space bar is the `l` motion) and away from an
213
+ * open autocomplete menu. */
214
+ readonly spaceHold: SpaceHoldGesture;
236
215
  setActionKeys(action: ConfigurableEditorAction, keys: KeyId[]): void;
237
216
  /**
238
217
  * Register a custom key handler. Extensions use this for shortcuts.
@@ -1,16 +1,17 @@
1
1
  /**
2
- * Original filesystem source carried on image attachments that entered from a
3
- * file on disk: path-pasted/drag-and-dropped images and generated video
4
- * contact-sheet previews. Symbol metadata stays out of serialized/model-bound
5
- * image data while traveling with the draft object, until AgentSession creates
6
- * the hidden companion message that tells the model the path (and link
7
- * materialization prefers it over a blob copy).
2
+ * File source carried on image attachments backed by a file on disk:
3
+ * path-pasted/drag-and-dropped images, clipboard images the coding agent commits
4
+ * to the session's `local://` root, and generated video contact-sheet previews.
5
+ * Symbol metadata stays out of serialized/model-bound image data while traveling
6
+ * with the draft object, until AgentSession creates the hidden companion message
7
+ * that tells the model the path (and link materialization prefers it over a blob copy).
8
8
  */
9
9
  import type { ImageContent } from "@oh-my-pi/pi-ai";
10
10
  /** How an image attachment's backing file entered the session. */
11
11
  export type ImageAttachmentSourceKind = "image" | "video";
12
- /** Original local file backing an image attachment. */
12
+ /** Local file backing an image attachment. */
13
13
  export interface ImageAttachmentSource {
14
+ /** Absolute filesystem path, or a session-relative `local://` URL for images committed to the session. */
14
15
  readonly path: string;
15
16
  readonly kind: ImageAttachmentSourceKind;
16
17
  }
@@ -21,6 +22,6 @@ export type SourceTaggedImage = ImageContent & {
21
22
  };
22
23
  /** Create a model-ready image tagged with the local file it was loaded from. */
23
24
  export declare function tagImageAttachmentSource(image: ImageContent, path: string, kind: ImageAttachmentSourceKind): SourceTaggedImage;
24
- /** Return the original local source of an image attachment, or undefined for payloads with no source file (clipboard bitmaps). */
25
+ /** Return the local file backing an image attachment, or undefined for payloads with no file on disk. */
25
26
  export declare function imageAttachmentSource(image: ImageContent): ImageAttachmentSource | undefined;
26
27
  export {};
@@ -0,0 +1,45 @@
1
+ /** Max gap (ms) between two spaces for the later one to count as OS key auto-repeat rather than a
2
+ * deliberate press. OS auto-repeat is fast; a deliberate tap (even a fast one) is slower. */
3
+ export declare const SPACE_REPEAT_MAX_GAP_MS = 120;
4
+ /** Two consecutive inter-space gaps are "mechanical" (machine-driven auto-repeat) when both are
5
+ * within {@link SPACE_REPEAT_MAX_GAP_MS} and differ by no more than this — an absolute jitter floor
6
+ * or, for slower repeat rates, {@link SPACE_REPEAT_JITTER_RATIO} of the smaller gap. OS key-repeat
7
+ * is metronomic; a human smashing the bar is fast but irregular, so its deltas never stay this
8
+ * steady. */
9
+ export declare const SPACE_REPEAT_JITTER_MS = 18;
10
+ export declare const SPACE_REPEAT_JITTER_RATIO = 0.35;
11
+ /** Consecutive mechanical (fast + steady) deltas that confirm the space bar is held and start
12
+ * recording. Needs a sustained metronomic cadence, so jittery smashing and deliberate taps never
13
+ * reach it. */
14
+ export declare const SPACE_HOLD_MECHANICAL_RUN = 2;
15
+ /** Idle gap (ms) after the last repeated space that counts as the space bar being released, ending
16
+ * the push-to-talk recording. Must comfortably exceed the OS key-repeat interval. */
17
+ export declare const SPACE_HOLD_RELEASE_MS = 250;
18
+ /** What a recognized space-bar hold drives — the push-to-talk start and stop. */
19
+ export interface SpaceHoldHandler {
20
+ /** Gate for the gesture. Returns false to keep the space bar inserting spaces normally, so
21
+ * disabling push-to-talk restores plain space behavior. */
22
+ enabled(): boolean;
23
+ /** A sustained hold was recognized. The optimistically-typed spaces have already been deleted. */
24
+ onStart(): void;
25
+ /** The held space bar was released (an idle gap with no further repeated spaces, or any other key). */
26
+ onEnd(): void;
27
+ }
28
+ /** What the host must do with a keypress after {@link SpaceHoldGesture.process} has seen it:
29
+ * `"pass"` — handle it normally; `"type"` — insert the space now (it is tracked back out if the run
30
+ * turns into a hold); `"swallow"` — drop it, the gesture consumed it. */
31
+ export type SpaceHoldStep = "pass" | "type" | "swallow";
32
+ /** Space-hold push-to-talk state machine. A held space bar emits OS auto-repeat: a *steady* stream
33
+ * of spaces at a fixed fast interval. We watch the inter-space deltas and only recognize a hold once
34
+ * {@link SPACE_HOLD_MECHANICAL_RUN} consecutive deltas are "mechanical" — both auto-repeat-fast and
35
+ * near-identical (see {@link gapsAreMechanical}). Smashing the bar is fast but jittery and deliberate
36
+ * taps are too slow, so neither escalates and both keep typing real spaces; the few spaces typed
37
+ * before a real hold is recognized are tracked back out of the host input. */
38
+ export declare class SpaceHoldGesture {
39
+ #private;
40
+ /** Unset (the default) keeps the space bar typing spaces. */
41
+ handler: SpaceHoldHandler | undefined;
42
+ constructor(deleteTyped: (count: number) => void, allowed?: () => boolean);
43
+ /** Feed one keypress, `isSpace` when it is a plain space bar press. */
44
+ process(isSpace: boolean): SpaceHoldStep;
45
+ }
@@ -7,7 +7,7 @@ interface ContextSkill {
7
7
  readonly description?: string;
8
8
  readonly hide?: boolean;
9
9
  }
10
- type ContextTool = Pick<AiTool, "name" | "description" | "parameters">;
10
+ type ContextTool = Pick<AiTool, "name" | "description" | "parameters" | "examples">;
11
11
  /** Savings computed by the host's inline-image planner, not by the renderer. */
12
12
  export interface ContextSavingsEstimate {
13
13
  visionCapable: boolean;
@@ -100,6 +100,8 @@ export interface NonMessageTokenSource {
100
100
  };
101
101
  };
102
102
  readonly skills?: readonly ContextSkill[];
103
+ /** Provider-facing, session-frozen descriptions when available. */
104
+ readonly renderedSkills?: readonly ContextSkill[];
103
105
  }
104
106
  /** Shared empty system-prompt part list, avoiding an allocation per render. */
105
107
  export declare const EMPTY_STRING_PARTS: string[];
@@ -63,6 +63,8 @@ export interface StatusLineSession {
63
63
  } | undefined;
64
64
  autoResolvedThinkingLevel(): string | undefined;
65
65
  isFastModeActive(): boolean;
66
+ /** Anthropic subscription slow-mode label (`low priority until 14:30 · 62% left`) while active. */
67
+ getAnthropicSlowModeLabel?(): string | undefined;
66
68
  getPrewalkState?(): unknown;
67
69
  getAsyncJobSnapshot(): {
68
70
  running: readonly {
@@ -6,12 +6,10 @@ import type { MermaidRenderOptions } from "@oh-my-pi/pi-natives";
6
6
  */
7
7
  export interface MermaidResolveOptions extends MermaidRenderOptions {
8
8
  /**
9
- * Maximum display width (terminal columns) the diagram should occupy. A
10
- * layout that overflows this width is re-rendered in the perpendicular
11
- * orientation — a wide horizontal chain collapses to a tall vertical column
12
- * (which the terminal can scroll), and a wide vertical fan-out collapses to a
13
- * tall horizontal column. Omit to keep the source's own layout regardless of
14
- * width.
9
+ * Maximum display width (terminal columns) the diagram should occupy.
10
+ * Flowcharts are also rendered top-down and left-to-right. A resize picks
11
+ * the shortest variant that fits; if none fit, the narrowest, which the
12
+ * caller may still clip. Omit to keep the source's own layout.
15
13
  */
16
14
  maxWidth?: number;
17
15
  }
@@ -19,6 +19,13 @@ export interface BashToolDetails {
19
19
  timedOut?: boolean;
20
20
  /** Live ACP update only; completed results refer to released terminals. */
21
21
  terminalId?: string;
22
+ service?: {
23
+ name: string;
24
+ state: string;
25
+ ready: boolean;
26
+ timedOut: boolean;
27
+ pid?: number;
28
+ };
22
29
  async?: {
23
30
  state: "running" | "completed" | "failed";
24
31
  jobId: string;