@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
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Transcript renderers for `cfg://` settings reads and writes.
3
+ *
4
+ * Reads show the YAML-ish settings listing the model received, highlighted as
5
+ * YAML. Writes show the `previous → value` change, its scope (session or
6
+ * saved), and whether the user approved it.
7
+ */
8
+ import type { Component } from "../tui.js";
9
+ import { type Theme } from "../theme/theme.js";
10
+ import type { RenderResultOptions } from "./renderer.js";
11
+ import { type CardToolResult } from "./result-card.js";
12
+ /** Summary of a `cfg://` read, attached to read tool details. */
13
+ export interface CfgReadDetails {
14
+ /** Dotted setting path or namespace that was read; empty for the whole tree. */
15
+ path: string;
16
+ /** Settings in the listing. */
17
+ count: number;
18
+ /** Listed settings whose effective value differs from the schema default. */
19
+ modified: number;
20
+ }
21
+ /** How a `cfg://` write ended. */
22
+ export type CfgWriteOutcome = "applied" | "declined" | "unchanged";
23
+ /** A `cfg://` write, attached to write tool details. Values are display-formatted (credentials redacted). */
24
+ export interface CfgWriteDetails {
25
+ path: string;
26
+ /** Persisted to config.yml rather than scoped to the session. */
27
+ save: boolean;
28
+ previous: string;
29
+ value: string;
30
+ outcome: CfgWriteOutcome;
31
+ /** Effective value after saving when a higher-precedence layer still shadows the saved one. */
32
+ effective?: string;
33
+ }
34
+ /** Render `read cfg://…`: pending header, or the highlighted listing with counts. */
35
+ export declare function renderCfgRead(url: string, result: CardToolResult | undefined, details: CfgReadDetails | undefined, options: RenderResultOptions, theme: Theme): Component;
36
+ /** Render `write cfg://…[/save]`: the proposed value while pending, then the approved/declined change. */
37
+ export declare function renderCfgWrite(url: string, content: string | undefined, result: CardToolResult | undefined, details: CfgWriteDetails | undefined, options: RenderResultOptions, theme: Theme): Component;
@@ -0,0 +1,16 @@
1
+ /** Canonical prefix for settings URLs. */
2
+ export declare const CFG_URL_PREFIX = "cfg://";
3
+ /** Trailing write segment that persists a `cfg://` change instead of scoping it to the session. */
4
+ export declare const CFG_SAVE_SEGMENT = "save";
5
+ /** Setting addressed by a `cfg://` URL. */
6
+ export interface CfgTarget {
7
+ /** Setting path segments; empty for the root. `/` and `.` both separate segments. */
8
+ segments: string[];
9
+ /** Whether the URL ends in the `/save` suffix, which is removed from {@link segments}. */
10
+ save: boolean;
11
+ }
12
+ /**
13
+ * Parse a `cfg://` URL (`cfg://advisor/enabled`, `cfg://advisor.enabled/save`).
14
+ * Returns `null` for other schemes; query and fragment are ignored.
15
+ */
16
+ export declare function parseCfgUrl(input: string): CfgTarget | null;
@@ -0,0 +1,46 @@
1
+ /** Launch-broker daemon types shared by services, `proc://`, and `omp ps`. */
2
+ /** Stable lifecycle states exposed by the launch broker. */
3
+ export type DaemonState = "starting" | "running" | "ready" | "restarting" | "stopping" | "exited" | "failed";
4
+ /** Restart behavior applied after an unexpected daemon exit. */
5
+ export type DaemonRestartPolicy = "no" | "on-failure" | "always";
6
+ /** Readiness conditions; every configured condition must pass. */
7
+ export interface DaemonReadySpec {
8
+ log?: string;
9
+ port?: number;
10
+ host?: string;
11
+ timeoutMs: number;
12
+ }
13
+ /** Immutable launch specification retained for restart and inspection. */
14
+ export interface DaemonSpec {
15
+ name: string;
16
+ application: string;
17
+ args: string[];
18
+ env: Record<string, string>;
19
+ cwd: string;
20
+ pty: boolean;
21
+ ready?: DaemonReadySpec;
22
+ restart: DaemonRestartPolicy;
23
+ persist: boolean;
24
+ detached: boolean;
25
+ }
26
+ /** Serializable daemon state visible to every client in one broker scope. */
27
+ export interface DaemonSnapshot {
28
+ name: string;
29
+ id: string;
30
+ state: DaemonState;
31
+ pid?: number;
32
+ createdAt: number;
33
+ startedAt: number;
34
+ readyAt?: number;
35
+ exitedAt?: number;
36
+ exitCode?: number;
37
+ exitReason?: string;
38
+ restartCount: number;
39
+ outputBytes: number;
40
+ owner?: string;
41
+ readyMatch?: string;
42
+ /** Readiness conditions still unmet while `state` is `starting`; absent once ready or without a ready spec. */
43
+ readyPending?: ("log" | "port")[];
44
+ persist: boolean;
45
+ detached: boolean;
46
+ }
@@ -11,7 +11,7 @@ export interface FindRange {
11
11
  }
12
12
  /** A file whose verified passages cleared the threshold; `ranges` are merged positive spans, strongest first. */
13
13
  export interface FindHit {
14
- /** Display path relative to {@link FindToolDetails.cwd}, or an `omp://` doc URL for docs scopes. */
14
+ /** Display path relative to {@link FindToolDetails.cwd}, or an internal URL under URL scopes. */
15
15
  rel: string;
16
16
  /** Filename judgment, when the name batch answered. */
17
17
  nameScore?: number;
@@ -55,7 +55,7 @@ export interface FindToolDetails {
55
55
  elapsedMs: number;
56
56
  /** Session cwd; hit paths are relative to it. */
57
57
  cwd: string;
58
- /** Display form of the searched directory when narrower than cwd. */
58
+ /** Display form of the searched directory or file when narrower than cwd. */
59
59
  scopePath?: string;
60
60
  meta?: OutputMeta;
61
61
  }
@@ -0,0 +1,30 @@
1
+ /** Peer-message types and roster constants shared by messaging, `wait`, and child prompts. */
2
+ /** Maximum live peer rows embedded in child prompts. */
3
+ export declare const DEFAULT_PEER_ROSTER_LIMIT = 32;
4
+ /** Serializable peer message retained in coordination result snapshots. */
5
+ export interface IrcMessage {
6
+ id: string;
7
+ /** Sender agent id. */
8
+ from: string;
9
+ /** Recipient agent id (resolved; "all" is expanded by the tool, not stored). */
10
+ to: string;
11
+ body: string;
12
+ ts: number;
13
+ /** Message id being answered. */
14
+ replyTo?: string;
15
+ /**
16
+ * Automated wake-turn relay of a woken subagent's stop output (task executor
17
+ * `relayWakeTurnOutput`). Relays are answers, never wake sources: the
18
+ * recipient's own wake-turn relay must skip them or two idle peers
19
+ * ping-pong forever.
20
+ */
21
+ wakeRelay?: boolean;
22
+ }
23
+ /** Delivery outcome for one peer recipient. */
24
+ export interface IrcDeliveryReceipt {
25
+ to: string;
26
+ outcome: "injected" | "woken" | "revived" | "failed";
27
+ error?: string;
28
+ }
29
+ /** Status ordering for peer rosters in child prompts. */
30
+ export declare const LIST_STATUS_ORDER: Record<string, number>;
@@ -11,7 +11,7 @@ export declare const LINE_RANGE_CHUNK_SOURCE: string;
11
11
  /** Parse a single `N`, `N-M`, `N-`, `N+K`, or `..`-aliased (`N..M`, `N..`) chunk. Throws via {@link ToolError} on invalid bounds. */
12
12
  export declare function parseLineRangeChunk(sel: string): LineRange | null;
13
13
  /**
14
- * Parse a comma-separated list of line ranges (e.g. `5-16,960-973`). Returns
14
+ * Parse a comma-separated list of line ranges (e.g. `5-16,960-973` or `19,59`). Returns
15
15
  * the ranges in ascending order with overlapping/adjacent ranges merged so
16
16
  * downstream consumers can stream the file in a single forward pass per range.
17
17
  */
@@ -96,6 +96,8 @@ export interface OutputMeta {
96
96
  /** Capture failure of this output itself; aggregate reports keep source failures on their entries. */
97
97
  artifactError?: OutputArtifactError;
98
98
  source?: SourceMeta;
99
+ /** The output is a bounded page of session artifact storage its `source` re-reads with line selectors; spill-to-artifact skips it. */
100
+ pagedSource?: true;
99
101
  diagnostics?: DiagnosticMeta;
100
102
  limits?: LimitsMeta;
101
103
  }
@@ -0,0 +1,27 @@
1
+ import type { Component } from "../tui.js";
2
+ import type { Theme } from "../theme/theme.js";
3
+ import type { RenderResultOptions } from "./renderer.js";
4
+ import type { AgentActivitySnapshot, CoordinationDetails, JobSnapshot } from "./wait.js";
5
+ import type { DaemonSnapshot } from "./daemon.js";
6
+ import { type CardToolResult as ToolResult } from "./result-card.js";
7
+ export interface ProcReadDetails {
8
+ jobs?: JobSnapshot[];
9
+ agents?: AgentActivitySnapshot[];
10
+ daemons?: DaemonSnapshot[];
11
+ job?: JobSnapshot;
12
+ daemon?: DaemonSnapshot;
13
+ log?: string;
14
+ terminalRows?: string[];
15
+ }
16
+ export type ProcWriteDetails = CoordinationDetails | {
17
+ action: "stop" | "stdin" | "mode";
18
+ daemon: DaemonSnapshot;
19
+ input?: string;
20
+ mode?: string;
21
+ };
22
+ /** Process operation selected by a write URL, independent of its content. */
23
+ export type ProcWriteAction = "stdin" | "mode" | "kill";
24
+ export declare function renderAgentWrite(to: string, body: string, result: ToolResult | undefined, details: CoordinationDetails | undefined, options: RenderResultOptions, theme: Theme): Component;
25
+ /** Render live and completed process writes with the URL-selected operation. */
26
+ export declare function renderProcWrite(id: string, action: ProcWriteAction, content: string | undefined, result: ToolResult | undefined, details: ProcWriteDetails | undefined, options: RenderResultOptions, theme: Theme): Component;
27
+ export declare function renderProcRead(id: string, result: ToolResult | undefined, details: ProcReadDetails | undefined, options: RenderResultOptions, theme: Theme): Component;
@@ -1,14 +1,19 @@
1
1
  import type { SummaryResult } from "@oh-my-pi/pi-natives";
2
2
  import type { Component } from "../tui.js";
3
- import type { RenderResultOptions } from "./renderer.js";
3
+ import type { RenderResultOptions, ToolActivityContext, ToolActivitySummary } from "./renderer.js";
4
4
  import type { Theme } from "../theme/theme.js";
5
5
  import type { OutputMeta } from "./output-meta.js";
6
6
  import type { TruncationResult } from "./streaming-output.js";
7
+ import { type ProcReadDetails } from "./proc-render.js";
8
+ import { type CfgReadDetails } from "./cfg-render.js";
9
+ import { type InternalUrlSchemeSpec } from "./url-scheme-host.js";
7
10
  /** Read result metadata retains truncation statistics, not a second copy of the body. */
8
11
  export type ReadTruncationStats = Omit<TruncationResult, "content">;
9
12
  /** Display metadata for file and URL reads. */
10
13
  export interface ReadToolDetails {
11
14
  kind?: "file" | "url";
15
+ proc?: ProcReadDetails;
16
+ cfg?: CfgReadDetails;
12
17
  /** Filesystem hyperlink target resolved by the executing tool. */
13
18
  displayTarget?: string;
14
19
  truncation?: ReadTruncationStats;
@@ -69,12 +74,16 @@ export declare function splitPathAndSel(rawPath: string): {
69
74
  * This function iteratively peels selector-shaped chunks (well-formed plus
70
75
  * common malformed shapes like `:-N-M`) so the rest of the read tool can pass a
71
76
  * clean URL to the protocol handler and surface selector errors via parseSel
72
- * instead of as misleading "host invalid" errors from the handler. Schemes
73
- * whose resource URIs may legitimately contain colons (`mcp://`) are skipped.
77
+ * instead of as misleading "host invalid" errors from the handler.
78
+ *
79
+ * Only schemes whose spec declares `lines` selectors peel; server-defined URIs
80
+ * (`opaque`), selector-free schemes, and unregistered schemes pass through
81
+ * verbatim. `specOf` defaults to the installed scheme host, so nothing peels
82
+ * before a host is installed.
74
83
  *
75
84
  * Falls back to the input unchanged when nothing matches.
76
85
  */
77
- export declare function splitInternalUrlSel(rawPath: string): {
86
+ export declare function splitInternalUrlSel(rawPath: string, specOf?: (scheme: string) => InternalUrlSchemeSpec | undefined): {
78
87
  path: string;
79
88
  sel?: string;
80
89
  };
@@ -89,6 +98,10 @@ export interface ReadRenderArgs {
89
98
  limit?: number;
90
99
  raw?: boolean;
91
100
  }
101
+ /** Local file a pending read/write input points at, before the tool resolves it:
102
+ * expands `~` and drops archive-member / SQLite-row selectors so the link opens
103
+ * the containing file. */
104
+ export declare function pendingFileLinkPath(inputPath: string): string;
92
105
  /** Absolute fs path the read result actually resolved to, used as the OSC 8 link
93
106
  * target when the structured `resolvedPath` isn't set (the common plain-file and
94
107
  * image reads only record the path in `meta.source`). URL/internal sources are
@@ -96,6 +109,7 @@ export interface ReadRenderArgs {
96
109
  export declare function readSourceFsPath(details: ReadToolDetails | undefined): string | undefined;
97
110
  /** Render file, image, and URL reads in the transcript. */
98
111
  export declare const readToolRenderer: {
112
+ activitySummary(args: unknown, _context: ToolActivityContext): ToolActivitySummary;
99
113
  renderCall(args: ReadRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component;
100
114
  renderResult(result: {
101
115
  content: Array<{
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Line-based status cards shared by the internal-URL renderers (`proc://`,
3
+ * `agent://`, `cfg://`): a header plus sanitized, width-truncated body lines.
4
+ */
5
+ import type { Component } from "../tui.js";
6
+ import type { RenderResultOptions } from "./renderer.js";
7
+ /** Tool result fields the card renderers read. */
8
+ export interface CardToolResult {
9
+ content: Array<{
10
+ type: string;
11
+ text?: string;
12
+ }>;
13
+ isError?: boolean;
14
+ }
15
+ /** First text block of a tool result, or `""`. */
16
+ export declare function firstText(result: CardToolResult): string;
17
+ /** Sanitize one display line: tabs become spaces, carriage returns are dropped. */
18
+ export declare function safe(value: string): string;
19
+ /** Padded card whose lines are sanitized and truncated, re-rendered when the expanded state flips. */
20
+ export declare function card(lines: (width: number, expanded: boolean) => string[], options: RenderResultOptions): Component;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Scheme facts supplied by the internal URL host. pi-tui cannot import the
3
+ * coding-agent router, so the router installs this bridge when it loads;
4
+ * selector peeling and transcript renderers consult it instead of hardcoding
5
+ * scheme names.
6
+ */
7
+ /** Renderer-relevant subset of a registered scheme's declared spec. */
8
+ export interface InternalUrlSchemeSpec {
9
+ /** `lines`: a trailing `:<selector>` chain is a read selector; `none`/`opaque`: never peel. */
10
+ readonly selectors: "lines" | "none" | "opaque";
11
+ /** A trailing `:N` with no path after the authority is a port, not a selector (ssh://host:2222). */
12
+ readonly portAuthority?: boolean;
13
+ /** Read cards collapse into the compact read group like plain files instead of expanding. */
14
+ readonly compactTranscript?: boolean;
15
+ }
16
+ /** Scheme registry capabilities installed by the internal URL host. */
17
+ export interface InternalUrlSchemeHost {
18
+ /** Declared spec of a registered scheme (case-insensitive); undefined when unregistered. */
19
+ spec(scheme: string): InternalUrlSchemeSpec | undefined;
20
+ }
21
+ /** Install the scheme registry. Until one is installed, no URL counts as an internal scheme. */
22
+ export declare function setInternalUrlSchemeHost(host: InternalUrlSchemeHost): void;
23
+ /** Declared spec of `scheme`; undefined when it is unregistered or no host is installed. */
24
+ export declare function internalUrlSchemeSpec(scheme: string): InternalUrlSchemeSpec | undefined;
25
+ /** Split a hierarchical `scheme://rest` URL into its lowercased scheme and the text after `://`. */
26
+ export declare function splitUrlScheme(input: string): {
27
+ scheme: string;
28
+ rest: string;
29
+ } | undefined;
@@ -0,0 +1,131 @@
1
+ import type { Component } from "../tui.js";
2
+ import type { Theme } from "../theme/theme.js";
3
+ import { type OutputMeta } from "./output-meta.js";
4
+ import { type ConfiguredThinkingLevel } from "../render/render-utils.js";
5
+ import type { StructuredSubagentOutput } from "./task.js";
6
+ import type { RenderResultOptions, ToolActivitySummary } from "./renderer.js";
7
+ import type { IrcDeliveryReceipt, IrcMessage } from "./irc.js";
8
+ /** Whether a wait snapshot contains only running jobs and no cancellations. */
9
+ export declare function isWaitingPollDetails(details: unknown): boolean;
10
+ /** Coordination details retained by wait and background job operations. */
11
+ export type CoordinationOp = "send" | "wait" | "jobs" | "cancel";
12
+ /** Background-job row surfaced by `wait`/`cancel`/`jobs` results. */
13
+ export interface JobSnapshot {
14
+ id: string;
15
+ type: "bash" | "task" | "eval";
16
+ status: "running" | "completed" | "failed" | "cancelled";
17
+ label: string;
18
+ durationMs: number;
19
+ /** Process exit status when the job reports one. */
20
+ exitCode?: number;
21
+ /** Effective task model selector, including an explicit reasoning suffix when configured. */
22
+ resolvedModel?: string;
23
+ /** Provider/id including routing, with no added thinking suffix. */
24
+ resolvedModelIdentity?: string;
25
+ /** Explicit thinking metadata, independent of the model identity. */
26
+ resolvedThinkingLevel?: ConfiguredThinkingLevel;
27
+ /** True when the task progress reports an attached live advisor. */
28
+ advisor?: boolean;
29
+ resultText?: string;
30
+ errorText?: string;
31
+ /** Source-output metadata retained for per-job warnings and persisted row rendering. */
32
+ meta?: OutputMeta;
33
+ /** Capture error in historical snapshots; new snapshots store source metadata in `meta`. */
34
+ artifactError?: OutputMeta["artifactError"];
35
+ structured?: StructuredSubagentOutput;
36
+ /**
37
+ * `agent://<id>` handle backing this job's artifacts — the job-row's
38
+ * registry `agentId` when the manager disambiguated a requested job id
39
+ * on collision, else the job id itself. See {@link AsyncJob.agentId}.
40
+ */
41
+ agentUrlId?: string;
42
+ }
43
+ /** Outcome of cancelling one background job. */
44
+ export type CancelStatus = "cancelled" | "not_found" | "already_completed";
45
+ /** Cancellation outcome and its model-facing explanation. */
46
+ export interface CancelOutcome {
47
+ id: string;
48
+ status: CancelStatus;
49
+ message: string;
50
+ }
51
+ /**
52
+ * A live subagent from the AgentRegistry that has no backing job in the
53
+ * AsyncJobManager — e.g. an idle agent woken (or a parked agent revived) via
54
+ * a peer message, or a spawn owned by another agent. Surfaced by background
55
+ * snapshots so the displayed picture matches the UI's running-agent
56
+ * count.
57
+ */
58
+ export interface AgentActivitySnapshot {
59
+ id: string;
60
+ parentId?: string;
61
+ /** Latest activity gist recorded by the registry (display-only). */
62
+ activity?: string;
63
+ /** Time since the agent was registered. */
64
+ ageMs: number;
65
+ /**
66
+ * Whether an attached session corroborates the `running` claim. False marks
67
+ * a ref that says `running` with no turn in flight — either a spawn still
68
+ * wiring up or a stale registration that an explicit cancellation clears (#8634).
69
+ */
70
+ live: boolean;
71
+ /**
72
+ * Acceptance time of the agent's final result, when the registry recorded
73
+ * one. With `live: false` this is an accepted run the parent may cancel
74
+ * instead of waiting on (#11079).
75
+ */
76
+ acceptedAt?: number;
77
+ }
78
+ /** Details shared by messaging receipts and job/wait results. */
79
+ export interface CoordinationDetails {
80
+ meta?: OutputMeta;
81
+ op: CoordinationOp;
82
+ from?: string;
83
+ to?: string;
84
+ receipts?: IrcDeliveryReceipt[];
85
+ /** Message consumed by `wait`. */
86
+ waited?: IrcMessage | null;
87
+ jobs?: JobSnapshot[];
88
+ cancelled?: {
89
+ id: string;
90
+ status: CancelStatus;
91
+ }[];
92
+ /** Running subagents not represented by a job row in this result. */
93
+ agents?: AgentActivitySnapshot[];
94
+ /** `wait` was cut short by steering, a peer message, or a completion notice that injects next. */
95
+ interrupted?: boolean;
96
+ }
97
+ /** Pending wait frame. */
98
+ declare function waitRenderCall(_args: object, _options: RenderResultOptions, uiTheme: Theme): Component;
99
+ /**
100
+ * Display-only transcript card for live IRC traffic: `irc:incoming` DMs
101
+ * delivered to this session, `irc:autoreply` side-channel replies sent on
102
+ * this session's behalf, and `irc:relay` observations of agent↔agent
103
+ * traffic. Shares the tool renderer's glyph + quote-border conventions so
104
+ * cards and peer-message output look identical in the transcript.
105
+ */
106
+ export declare function createIrcMessageCard(card: {
107
+ kind: "incoming" | "autoreply" | "relay" | "workpool";
108
+ from?: string;
109
+ to?: string;
110
+ body?: string;
111
+ replyTo?: string;
112
+ timestamp?: number;
113
+ pool?: string;
114
+ mode?: string;
115
+ }, getExpanded: () => boolean, uiTheme: Theme): Component;
116
+ /** Render either a received message or a background-job snapshot. */
117
+ export declare const waitToolRenderer: {
118
+ inline: true;
119
+ mergeCallAndResult: true;
120
+ activitySummary(): ToolActivitySummary;
121
+ renderCall: typeof waitRenderCall;
122
+ renderResult(result: {
123
+ content: Array<{
124
+ type: string;
125
+ text?: string;
126
+ }>;
127
+ details?: CoordinationDetails;
128
+ isError?: boolean;
129
+ }, options: RenderResultOptions, uiTheme: Theme): Component;
130
+ };
131
+ export {};
@@ -1,6 +1,9 @@
1
1
  import type { HighlightStream } from "@oh-my-pi/pi-natives";
2
2
  import type { Component } from "../tui.js";
3
3
  import { type Theme } from "../theme/theme.js";
4
+ import type { CoordinationDetails } from "./wait.js";
5
+ import { type ProcWriteDetails } from "./proc-render.js";
6
+ import { type CfgWriteDetails } from "./cfg-render.js";
4
7
  import type { FileDiagnosticsResult } from "./lsp.js";
5
8
  import type { OutputMeta } from "./output-meta.js";
6
9
  import type { RenderResultOptions, ToolActivityContext, ToolActivitySummary } from "./renderer.js";
@@ -16,6 +19,9 @@ export interface WriteToolDetails {
16
19
  resolvedPath?: string;
17
20
  /** Set when the write dispatched an `xd://` tool device; drives renderer delegation. */
18
21
  xdev?: XdevRenderDispatch;
22
+ message?: CoordinationDetails;
23
+ proc?: ProcWriteDetails;
24
+ cfg?: CfgWriteDetails;
19
25
  }
20
26
  interface WriteRenderArgs {
21
27
  path?: unknown;
@@ -9,5 +9,13 @@ export declare function stripXdUrlPrefix(name: string): string;
9
9
  export declare function parseXdUrl(input: string): {
10
10
  name: string | null;
11
11
  } | null;
12
+ /**
13
+ * Parse a read-only `xd://<tool>/<topic>` documentation URL.
14
+ * Returns `null` for anything else, including bare device URLs.
15
+ */
16
+ export declare function parseXdTopicUrl(input: string): {
17
+ name: string;
18
+ topic: string;
19
+ } | null;
12
20
  /** Whether a streaming path prefix could still become an `xd://` URL. */
13
21
  export declare function couldBecomeXdUrl(partialPath: string): boolean;
@@ -9,10 +9,18 @@ export interface XdevMountedRenderer {
9
9
  renderResult?(...args: Parameters<ToolRenderer["renderResult"]>): unknown;
10
10
  mergeCallAndResult?: boolean;
11
11
  }
12
- /** Mounted tool presentation state supplied by the host's canonical tool map. */
12
+ /** Tool presentation state supplied by the host's canonical tool map. */
13
13
  export interface XdevMountedState {
14
14
  readonly mountedNames: ReadonlySet<string>;
15
15
  readonly tools: ReadonlyMap<string, XdevMountedRenderer>;
16
+ /**
17
+ * Canonical renderer for a device name, supplied by the host with the same
18
+ * predicate as dispatch (`resolveXdevTool`: mounted devices plus active
19
+ * top-level tools, which the `write` transport also accepts). The TUI keeps
20
+ * no predicate copy of its own — a second copy is what dropped a top-level
21
+ * dispatch to the generic card.
22
+ */
23
+ readonly resolve?: (name: string) => XdevMountedRenderer | undefined;
16
24
  }
17
25
  /** Result metadata consumed by delegated device rendering. */
18
26
  export interface XdevRenderDispatch {
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Recover AltGr text that Windows console hosts drop under the kitty keyboard protocol.
3
+ *
4
+ * The kitty encoder shipped in Windows Terminal / OpenConsole before
5
+ * microsoft/terminal#20052 reports AltGr+key as Alt (or Ctrl+Alt) plus the
6
+ * layout's *unmodified* base key, without the produced text: Hungarian
7
+ * AltGr+F arrives as `CSI 102;3u` instead of `[`. The byte stream is then
8
+ * indistinguishable from a real Alt+F shortcut, so the character is lost and
9
+ * the chord fires `alt+f` bindings instead.
10
+ *
11
+ * Recovery reads two pieces of local state the bytes lack:
12
+ * - whether Right Alt (AltGr) is physically held, via `GetAsyncKeyState`;
13
+ * - what the active keyboard layout's AltGr layer produces for the base key,
14
+ * via `ToUnicodeEx`.
15
+ *
16
+ * Layouts without an AltGr layer (US, UK, ...) resolve to an empty table once and
17
+ * short-circuit every later event. The per-layout table is built once and cached;
18
+ * it is rebuilt only when the foreground window reports a different layout handle.
19
+ *
20
+ * Known limitation: AltGr keys that produce a dead key on the active layout have no
21
+ * table entry (`ToUnicodeEx` reports them as pending composition, not text), so those
22
+ * chords keep reaching Alt bindings.
23
+ */
24
+ import { type Pointer } from "bun:ffi";
25
+ /** Keyboard layout handle (`HKL`) as `bun:ffi` surfaces pointer-sized values. */
26
+ export type KeyboardLayoutHandle = Pointer | bigint;
27
+ /**
28
+ * AltGr layer of an explicit layout handle (`HKL`), keyed `"<baseCodepoint>:<shift 0|1>"`.
29
+ * Test seam: lets a harness inspect a loaded layout without making it the active one.
30
+ */
31
+ export declare function readAltGrLayer(hkl: KeyboardLayoutHandle): ReadonlyMap<string, string>;
32
+ /** Local keyboard state the translator reads; injectable so tests need no live desktop. */
33
+ export interface AltGrHost {
34
+ /** AltGr layer of the layout that produced the keystroke, keyed like {@link readAltGrLayer}. */
35
+ activeLayer(): ReadonlyMap<string, string>;
36
+ /** Whether Right Alt (AltGr) is held, or was within the last {@link RIGHT_ALT_LATCH_MS}. */
37
+ isRightAltDown(): boolean;
38
+ }
39
+ /**
40
+ * How long an observed Right Alt press keeps counting as held. Key state is sampled
41
+ * at processing time, and one stdin read can carry several queued AltGr repeats that
42
+ * are dispatched synchronously after the key is released; the latch keeps that tail
43
+ * typing text. Far shorter than any release-then-Left-Alt chord a person can press.
44
+ */
45
+ export declare const RIGHT_ALT_LATCH_MS = 30;
46
+ /** Wrap a raw Right Alt probe so a press stays observed for {@link RIGHT_ALT_LATCH_MS}. */
47
+ export declare function createRightAltLatch(isDownNow: () => boolean, now: () => number): () => boolean;
48
+ /**
49
+ * Translate a kitty CSI-u Alt/Ctrl+Alt chord into the text AltGr produced, or
50
+ * `undefined` when the sequence is not an AltGr keystroke on the active layout.
51
+ *
52
+ * Only call this on native Windows ConPTY hosts with the kitty protocol active.
53
+ */
54
+ export declare function translateWindowsAltGrSequence(data: string, host?: AltGrHost): string | undefined;
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-tui",
4
- "version": "18.2.11",
4
+ "version": "18.3.1",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://omp.sh",
7
- "author": "Stencil Labs, Inc.",
7
+ "author": {
8
+ "name": "Stencil Labs, Inc.",
9
+ "url": "https://stencil.so"
10
+ },
8
11
  "contributors": [
9
12
  "Mario Zechner"
10
13
  ],
@@ -37,14 +40,14 @@
37
40
  "fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
38
41
  },
39
42
  "dependencies": {
40
- "@oh-my-pi/omptype": "18.2.11",
41
- "@oh-my-pi/pi-agent-core": "18.2.11",
42
- "@oh-my-pi/pi-ai": "18.2.11",
43
- "@oh-my-pi/pi-catalog": "18.2.11",
44
- "@oh-my-pi/pi-natives": "18.2.11",
45
- "@oh-my-pi/pi-utils": "18.2.11",
46
- "@oh-my-pi/pi-wire": "18.2.11",
47
- "@oh-my-pi/snapcompact": "18.2.11"
43
+ "@oh-my-pi/omptype": "18.3.1",
44
+ "@oh-my-pi/pi-agent-core": "18.3.1",
45
+ "@oh-my-pi/pi-ai": "18.3.1",
46
+ "@oh-my-pi/pi-catalog": "18.3.1",
47
+ "@oh-my-pi/pi-natives": "18.3.1",
48
+ "@oh-my-pi/pi-utils": "18.3.1",
49
+ "@oh-my-pi/pi-wire": "18.3.1",
50
+ "@oh-my-pi/snapcompact": "18.3.1"
48
51
  },
49
52
  "devDependencies": {
50
53
  "kitty-vt-wasm": "^0.2.0"
@@ -217,7 +217,7 @@ export class ProtocolProbeComponent extends Container {
217
217
  new Text(
218
218
  [
219
219
  `${theme.fg("muted", "Hyperlinks (OSC 8)")} — ${yesNo(hyperlinksOn)}`,
220
- ` \x1b]8;;https://github.com/can1357/oh-my-pi\x07oh-my-pi repo\x1b]8;;\x07`,
220
+ ` \x1b]8;;https://github.com/can1357/oh-my-pi\x07omp repo\x1b]8;;\x07`,
221
221
  ].join("\n"),
222
222
  1,
223
223
  0,
@@ -1,7 +1,7 @@
1
1
  import * as path from "node:path";
2
2
  import { formatDuration } from "@oh-my-pi/pi-utils";
3
3
  import chalk from "@oh-my-pi/pi-utils/chalk";
4
- import type { DaemonSnapshot, DaemonSpec, DaemonState } from "../tools/hub";
4
+ import type { DaemonSnapshot, DaemonSpec, DaemonState } from "../tools/daemon";
5
5
 
6
6
  /** One broker scope: a project runtime dir or a machine-global service dir. */
7
7
  export interface PsScope {
@@ -15,7 +15,7 @@ import { type Component, TUI } from "../tui";
15
15
  import { truncateToWidth } from "../utils";
16
16
  import { formatDuration } from "@oh-my-pi/pi-utils";
17
17
  import chalk from "@oh-my-pi/pi-utils/chalk";
18
- import type { DaemonSnapshot, DaemonSpec } from "../tools/hub";
18
+ import type { DaemonSnapshot, DaemonSpec } from "../tools/daemon";
19
19
  import {
20
20
  collapseCommand,
21
21
  daemonLabel,