@oh-my-pi/pi-tui 18.2.10 → 18.3.0

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 (69) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/THIRD-PARTY-NOTICES.txt +1 -1
  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/overlays/annotation-overlay.d.ts +30 -0
  7. package/dist/types/overlays/annotation-types.d.ts +84 -0
  8. package/dist/types/overlays/copy-selector.d.ts +30 -2
  9. package/dist/types/overlays/copy-targets.d.ts +2 -0
  10. package/dist/types/overlays/model-hub.d.ts +2 -2
  11. package/dist/types/overlays/oauth-selector.d.ts +3 -6
  12. package/dist/types/overlays/usage-dashboard.d.ts +2 -0
  13. package/dist/types/prompt/image-source.d.ts +9 -8
  14. package/dist/types/render/render-utils.d.ts +2 -0
  15. package/dist/types/status-line/context-usage.d.ts +3 -1
  16. package/dist/types/theme/mermaid-cache.d.ts +4 -6
  17. package/dist/types/tools/bash.d.ts +7 -0
  18. package/dist/types/tools/daemon.d.ts +46 -0
  19. package/dist/types/tools/irc.d.ts +30 -0
  20. package/dist/types/tools/line-ranges.d.ts +1 -1
  21. package/dist/types/tools/proc-render.d.ts +34 -0
  22. package/dist/types/tools/read.d.ts +4 -1
  23. package/dist/types/tools/task.d.ts +4 -0
  24. package/dist/types/tools/wait.d.ts +131 -0
  25. package/dist/types/tools/write.d.ts +4 -0
  26. package/dist/types/tools/xd-url.d.ts +8 -0
  27. package/dist/types/windows-altgr.d.ts +54 -0
  28. package/package.json +13 -10
  29. package/src/apps/debug/protocol-probe.ts +1 -1
  30. package/src/apps/ps-data.ts +1 -1
  31. package/src/apps/ps-top.ts +1 -1
  32. package/src/chat/chat-transcript-builder.ts +4 -4
  33. package/src/chat/tool-execution.ts +8 -8
  34. package/src/chat/transcript-render-helpers.ts +3 -3
  35. package/src/components/markdown.ts +1 -1
  36. package/src/desktop-notify.ts +1 -1
  37. package/src/overlays/annotation-overlay.ts +1145 -0
  38. package/src/overlays/annotation-types.ts +78 -0
  39. package/src/overlays/copy-selector.ts +45 -19
  40. package/src/overlays/copy-targets.ts +3 -3
  41. package/src/overlays/model-hub.ts +5 -4
  42. package/src/overlays/oauth-selector.ts +8 -12
  43. package/src/overlays/plan-review-overlay.ts +213 -40
  44. package/src/overlays/settings-defs.ts +1 -0
  45. package/src/overlays/usage-dashboard.ts +120 -25
  46. package/src/prompt/image-source.ts +9 -8
  47. package/src/prompt/welcome.ts +4 -1
  48. package/src/render/render-utils.ts +1 -1
  49. package/src/setup/scenes/sign-in.ts +1 -1
  50. package/src/status-line/component.ts +15 -4
  51. package/src/status-line/context-usage.ts +15 -3
  52. package/src/status-line/segments.ts +3 -3
  53. package/src/terminal-capabilities.ts +16 -7
  54. package/src/terminal.ts +8 -1
  55. package/src/theme/mermaid-cache.ts +83 -25
  56. package/src/tools/bash.ts +14 -1
  57. package/src/tools/daemon.ts +51 -0
  58. package/src/tools/index.ts +2 -2
  59. package/src/tools/irc.ts +33 -0
  60. package/src/tools/line-ranges.ts +13 -3
  61. package/src/tools/proc-render.ts +294 -0
  62. package/src/tools/read.ts +22 -1
  63. package/src/tools/task.ts +18 -0
  64. package/src/tools/wait.ts +595 -0
  65. package/src/tools/write.ts +76 -0
  66. package/src/tools/xd-url.ts +9 -0
  67. package/src/windows-altgr.ts +227 -0
  68. package/dist/types/tools/hub.d.ts +0 -342
  69. package/src/tools/hub.ts +0 -1492
@@ -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,8 @@
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";
4
6
  import type { FileDiagnosticsResult } from "./lsp.js";
5
7
  import type { OutputMeta } from "./output-meta.js";
6
8
  import type { RenderResultOptions, ToolActivityContext, ToolActivitySummary } from "./renderer.js";
@@ -16,6 +18,8 @@ export interface WriteToolDetails {
16
18
  resolvedPath?: string;
17
19
  /** Set when the write dispatched an `xd://` tool device; drives renderer delegation. */
18
20
  xdev?: XdevRenderDispatch;
21
+ message?: CoordinationDetails;
22
+ proc?: ProcWriteDetails;
19
23
  }
20
24
  interface WriteRenderArgs {
21
25
  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;
@@ -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.10",
4
+ "version": "18.3.0",
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.10",
41
- "@oh-my-pi/pi-agent-core": "18.2.10",
42
- "@oh-my-pi/pi-ai": "18.2.10",
43
- "@oh-my-pi/pi-catalog": "18.2.10",
44
- "@oh-my-pi/pi-natives": "18.2.10",
45
- "@oh-my-pi/pi-utils": "18.2.10",
46
- "@oh-my-pi/pi-wire": "18.2.10",
47
- "@oh-my-pi/snapcompact": "18.2.10"
43
+ "@oh-my-pi/omptype": "18.3.0",
44
+ "@oh-my-pi/pi-agent-core": "18.3.0",
45
+ "@oh-my-pi/pi-ai": "18.3.0",
46
+ "@oh-my-pi/pi-catalog": "18.3.0",
47
+ "@oh-my-pi/pi-natives": "18.3.0",
48
+ "@oh-my-pi/pi-utils": "18.3.0",
49
+ "@oh-my-pi/pi-wire": "18.3.0",
50
+ "@oh-my-pi/snapcompact": "18.3.0"
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,
@@ -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
@@ -184,12 +184,12 @@ export class ChatTranscriptBuilder {
184
184
  this.#expandables.push(component);
185
185
  }
186
186
 
187
- /** A `hub` wait showing all-running is displaced by the next `hub` call. */
187
+ /** A `wait` showing all-running is displaced by the next `wait` call. */
188
188
  #resolveWaitingPoll(nextToolName?: string): void {
189
189
  const previous = this.#waitingPoll;
190
190
  if (!previous) return;
191
191
  this.#waitingPoll = null;
192
- if (nextToolName === "hub" && previous.isDisplaceableBlock() && this.container.canRemoveBlock(previous)) {
192
+ if (nextToolName === "wait" && previous.isDisplaceableBlock() && this.container.canRemoveBlock(previous)) {
193
193
  this.container.removeChild(previous);
194
194
  }
195
195
  previous.seal();
@@ -517,7 +517,7 @@ export class ChatTranscriptBuilder {
517
517
  if (!pending) return;
518
518
  pending.updateResult(message, false, message.toolCallId);
519
519
  this.#pendingTools.delete(message.toolCallId);
520
- if (message.toolName === "hub" && pending instanceof ToolExecutionComponent && pending.isDisplaceableBlock()) {
520
+ if (message.toolName === "wait" && pending instanceof ToolExecutionComponent && pending.isDisplaceableBlock()) {
521
521
  this.#waitingPoll = pending;
522
522
  } else if (
523
523
  message.toolName === "todo" &&
@@ -22,7 +22,7 @@ import { type EditMode, type PerFileDiffPreview, renderStreamingFallback } from
22
22
  import { EVAL_DEFAULT_PREVIEW_LINES } from "../tools/eval";
23
23
  import { taskCardAgentIds } from "../tools/task";
24
24
  import { TODO_STRIKE_TOTAL_FRAMES, type TodoToolDetails } from "../tools/todo";
25
- import { isWaitingPollDetails } from "../tools/hub";
25
+ import { isWaitingPollDetails } from "../tools/wait";
26
26
  import { formatStatusIcon, replaceTabs, resolveImageOptions } from "../render/render-utils";
27
27
  import type { XdevMountedState } from "../tools/xdev";
28
28
  import { isFramedBlockComponent, markFramedBlockComponent, renderStatusLine, WidthAwareText } from "../render/index";
@@ -35,7 +35,7 @@ import { type AnimationFrame, trimBlankEdges } from "../chrome/transcript-contai
35
35
  export function toolRenderName(wireName: string, tool: AgentTool | undefined): string {
36
36
  return tool?.name ?? wireName;
37
37
  }
38
- type DisplaceableToolName = "hub" | "todo";
38
+ type DisplaceableToolName = "wait" | "todo";
39
39
 
40
40
  function isTodoToolDetails(details: unknown): details is TodoToolDetails {
41
41
  return (
@@ -67,7 +67,7 @@ function displaceableToolName(
67
67
  isPartial: boolean,
68
68
  ): DisplaceableToolName | undefined {
69
69
  if (result.isError === true) return undefined;
70
- if (toolName === "hub" && isWaitingPollDetails(result.details)) return "hub";
70
+ if (toolName === "wait" && isWaitingPollDetails(result.details)) return "wait";
71
71
  if (toolName === "todo" && !isPartial && isTodoToolDetails(result.details)) return "todo";
72
72
  return undefined;
73
73
  }
@@ -311,7 +311,7 @@ export class ToolExecutionComponent extends Container {
311
311
  // late result can update its streaming preview.
312
312
  #sealed = false;
313
313
  // Tool result snapshots that may be superseded by a later same-tool call
314
- // while still in the mutable viewport. `hub` uses this for repeated all-running polls; `todo` uses
314
+ // while still in the mutable viewport. `wait` uses this for repeated all-running polls; `todo` uses
315
315
  // it for per-turn state snapshots so only the latest list remains visible.
316
316
  #displaceableByToolName: DisplaceableToolName | undefined;
317
317
  // Execution start on the presentation clock (performance.now domain, the
@@ -605,7 +605,7 @@ export class ToolExecutionComponent extends Container {
605
605
  this.#toolName !== "todo" &&
606
606
  !isBackgroundAsyncRunning &&
607
607
  (pendingCallConsumesSpinner || partialResultConsumesSpinner);
608
- const needsSpinner = isStreamingArgs || isLivePartialTool || this.#displaceableByToolName === "hub";
608
+ const needsSpinner = isStreamingArgs || isLivePartialTool || this.#displaceableByToolName === "wait";
609
609
  if (needsSpinner && !this.#spinnerActive) {
610
610
  const frameCount = theme.spinnerFrames.length;
611
611
  const frame = sharedSpinnerFrame(frameCount);
@@ -845,8 +845,8 @@ export class ToolExecutionComponent extends Container {
845
845
  if (this.#allocation < 3) {
846
846
  // A squeezed allocation degrades only blocks that genuinely overflow it.
847
847
  // The allocator measures blocks by trimmed height and never squeezes one
848
- // below that, so inline tools whose real content is 1-2 rows (hub
849
- // receipts, one-line results) keep that content instead of an equally
848
+ // below that, so inline tools whose real content is 1-2 rows (wait
849
+ // results, one-line receipts) keep that content instead of an equally
850
850
  // tall but contentless frame.
851
851
  const trimmed = trimBlankEdges(lines);
852
852
  if (trimmed.length > this.#allocation) return this.#renderCompact(width);
@@ -891,7 +891,7 @@ export class ToolExecutionComponent extends Container {
891
891
  });
892
892
  if (summary !== undefined) {
893
893
  if (summary.detail) return summary;
894
- // A detail-less custom summary (e.g. hub before its streamed args
894
+ // A detail-less custom summary (e.g. wait before its result
895
895
  // parse) must not fold to a bare `╭─ Label` frame under viewport
896
896
  // pressure — keep the generic liveness hint for in-flight calls.
897
897
  return this.#isRunning() ? { ...summary, detail: "running" } : summary;
@@ -7,10 +7,10 @@
7
7
  import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
8
8
  import { type Component } from "../tui";
9
9
  import { formatBytes, formatDuration } from "@oh-my-pi/pi-utils";
10
- import type { JobSnapshot } from "../tools/hub";
11
- import type { DaemonSnapshot } from "../tools/hub";
10
+ import type { JobSnapshot } from "../tools/wait";
11
+ import type { DaemonSnapshot } from "../tools/daemon";
12
12
  import { type CustomMessage, type FileMentionMessage, resolveAbortLabel, shouldRenderAbortReason } from "./messages";
13
- import { createIrcMessageCard } from "../tools/hub";
13
+ import { createIrcMessageCard } from "../tools/wait";
14
14
  import { formatArtifactErrorNotice, type OutputMeta } from "../tools/output-meta";
15
15
  import { replaceTabs, TRUNCATE_LENGTHS, truncateToWidth } from "../render/render-utils";
16
16
  import { canonicalizeMessage } from "./thinking-display";
@@ -2955,7 +2955,7 @@ export class Markdown implements Component {
2955
2955
  // resolver. The art is preformatted, so clip each row to the content
2956
2956
  // width: the later wrap pass would otherwise fragment the box-drawing
2957
2957
  // canvas. truncateToWidth is ANSI- and wide-char-aware, and the
2958
- // resolver already re-fits over-wide horizontal graphs top-down.
2958
+ // resolver picks the shortest orientation that fits this width.
2959
2959
  if (token.lang === "mermaid" && this.#theme.resolveMermaidAscii) {
2960
2960
  const ascii = this.#theme.resolveMermaidAscii(token.text, width);
2961
2961
  if (ascii) {
@@ -26,7 +26,7 @@ import { $which } from "@oh-my-pi/pi-utils";
26
26
  import type { TerminalId, TerminalNotification } from "./terminal-capabilities";
27
27
 
28
28
  /** Application name surfaced as the notification source. */
29
- const APP_NAME = "Oh My Pi";
29
+ const APP_NAME = "omp";
30
30
 
31
31
  /** Resolved notifier binary used to fan a notification out to D-Bus. */
32
32
  export type DesktopNotifierKind = "notify-send" | "gdbus";