@oh-my-pi/pi-coding-agent 16.4.6 → 16.5.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 (141) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/dist/cli.js +3312 -3254
  3. package/dist/types/cli/args.d.ts +5 -0
  4. package/dist/types/cli/gallery-fixtures/shell.d.ts +1 -1
  5. package/dist/types/commands/launch.d.ts +15 -0
  6. package/dist/types/config/model-resolver.d.ts +4 -3
  7. package/dist/types/config/model-roles.d.ts +8 -0
  8. package/dist/types/config/settings-schema.d.ts +46 -14
  9. package/dist/types/extensibility/extensions/types.d.ts +1 -1
  10. package/dist/types/launch/broker.d.ts +2 -0
  11. package/dist/types/launch/client.d.ts +22 -0
  12. package/dist/types/launch/paths.d.ts +4 -0
  13. package/dist/types/launch/presence.d.ts +8 -0
  14. package/dist/types/launch/protocol.d.ts +170 -0
  15. package/dist/types/launch/terminal-output.d.ts +7 -0
  16. package/dist/types/modes/components/agent-hub.d.ts +1 -1
  17. package/dist/types/modes/components/index.d.ts +1 -0
  18. package/dist/types/modes/components/model-browser.d.ts +28 -3
  19. package/dist/types/modes/components/model-hub.d.ts +0 -10
  20. package/dist/types/modes/components/model-picker.d.ts +44 -0
  21. package/dist/types/modes/components/plan-review-overlay.d.ts +2 -0
  22. package/dist/types/modes/components/status-line/types.d.ts +3 -0
  23. package/dist/types/modes/components/welcome.d.ts +4 -0
  24. package/dist/types/modes/print-mode.d.ts +14 -8
  25. package/dist/types/modes/print-mode.test.d.ts +1 -0
  26. package/dist/types/modes/theme/theme.d.ts +2 -1
  27. package/dist/types/sdk.d.ts +5 -1
  28. package/dist/types/session/agent-session.d.ts +42 -0
  29. package/dist/types/session/session-context.d.ts +9 -0
  30. package/dist/types/session/session-entries.d.ts +6 -0
  31. package/dist/types/thinking.d.ts +2 -2
  32. package/dist/types/tiny/models.d.ts +1 -1
  33. package/dist/types/tools/browser/launch.d.ts +1 -0
  34. package/dist/types/tools/browser/run-cancellation.d.ts +28 -2
  35. package/dist/types/tools/browser/tab-protocol.d.ts +6 -0
  36. package/dist/types/tools/browser/tab-worker.d.ts +6 -0
  37. package/dist/types/tools/builtin-names.d.ts +1 -1
  38. package/dist/types/tools/index.d.ts +1 -0
  39. package/dist/types/tools/launch.d.ts +121 -0
  40. package/dist/types/tools/render-utils.d.ts +2 -0
  41. package/dist/types/tools/terminal-output.d.ts +5 -0
  42. package/dist/types/vibe/runtime.d.ts +2 -2
  43. package/dist/types/web/search/types.d.ts +0 -8
  44. package/package.json +20 -20
  45. package/src/cli/args.ts +11 -0
  46. package/src/cli/flag-tables.ts +9 -0
  47. package/src/cli/gallery-fixtures/shell.ts +82 -1
  48. package/src/cli.ts +10 -0
  49. package/src/commands/launch.ts +17 -0
  50. package/src/config/model-resolver.ts +110 -31
  51. package/src/config/model-roles.ts +14 -0
  52. package/src/config/settings-schema.ts +71 -7
  53. package/src/edit/renderer.ts +13 -10
  54. package/src/eval/__tests__/agent-bridge.test.ts +2 -2
  55. package/src/eval/__tests__/completion-bridge.test.ts +1 -1
  56. package/src/eval/completion-bridge.ts +4 -4
  57. package/src/eval/js/shared/rewrite-imports.ts +31 -13
  58. package/src/export/ttsr.ts +0 -3
  59. package/src/extensibility/extensions/model-api.ts +1 -1
  60. package/src/extensibility/extensions/types.ts +1 -1
  61. package/src/internal-urls/docs-index.ts +4 -4
  62. package/src/launch/broker.ts +1017 -0
  63. package/src/launch/client.ts +344 -0
  64. package/src/launch/paths.ts +17 -0
  65. package/src/launch/presence.ts +82 -0
  66. package/src/launch/protocol.ts +386 -0
  67. package/src/launch/terminal-output.ts +46 -0
  68. package/src/main.ts +50 -1
  69. package/src/modes/acp/acp-agent.ts +8 -1
  70. package/src/modes/components/agent-hub.ts +101 -31
  71. package/src/modes/components/compaction-summary-message.ts +8 -2
  72. package/src/modes/components/index.ts +1 -0
  73. package/src/modes/components/model-browser.ts +152 -49
  74. package/src/modes/components/model-hub.ts +55 -142
  75. package/src/modes/components/model-picker.ts +233 -0
  76. package/src/modes/components/plan-review-overlay.ts +7 -0
  77. package/src/modes/components/snapcompact-shape-preview-doc.md +7 -11
  78. package/src/modes/components/status-line/component.test.ts +41 -2
  79. package/src/modes/components/status-line/component.ts +4 -0
  80. package/src/modes/components/status-line/segments.ts +6 -0
  81. package/src/modes/components/status-line/types.ts +3 -0
  82. package/src/modes/components/tips.txt +2 -1
  83. package/src/modes/components/welcome.ts +13 -14
  84. package/src/modes/controllers/command-controller.ts +9 -1
  85. package/src/modes/controllers/event-controller.ts +31 -32
  86. package/src/modes/controllers/selector-controller.ts +96 -22
  87. package/src/modes/controllers/tan-command-controller.ts +40 -1
  88. package/src/modes/interactive-mode.ts +20 -3
  89. package/src/modes/print-mode.test.ts +71 -0
  90. package/src/modes/print-mode.ts +51 -2
  91. package/src/modes/theme/theme.ts +9 -0
  92. package/src/modes/utils/ui-helpers.ts +25 -4
  93. package/src/prompts/agents/designer.md +1 -1
  94. package/src/prompts/agents/librarian.md +1 -1
  95. package/src/prompts/agents/reviewer.md +1 -1
  96. package/src/prompts/agents/scout.md +1 -1
  97. package/src/prompts/system/plan-yolo-handoff.md +5 -0
  98. package/src/prompts/system/prewalk-checklist.md +7 -0
  99. package/src/prompts/system/prewalk-continue.md +1 -0
  100. package/src/prompts/system/prewalk-plan.md +13 -0
  101. package/src/prompts/system/system-prompt.md +9 -7
  102. package/src/prompts/system/tan-context-switch.md +17 -0
  103. package/src/prompts/tools/bash.md +6 -4
  104. package/src/prompts/tools/browser.md +4 -4
  105. package/src/prompts/tools/launch.md +25 -0
  106. package/src/sdk.ts +8 -2
  107. package/src/session/agent-session.ts +550 -87
  108. package/src/session/session-context.test.ts +10 -5
  109. package/src/session/session-context.ts +25 -8
  110. package/src/session/session-entries.ts +6 -0
  111. package/src/slash-commands/builtin-registry.ts +25 -0
  112. package/src/task/agents.ts +2 -2
  113. package/src/thinking.ts +10 -3
  114. package/src/tiny/models.ts +7 -7
  115. package/src/tools/bash-interactive.ts +5 -8
  116. package/src/tools/bash.ts +38 -24
  117. package/src/tools/browser/cmux/cmux-tab.ts +17 -2
  118. package/src/tools/browser/launch.ts +8 -4
  119. package/src/tools/browser/run-cancellation.ts +66 -6
  120. package/src/tools/browser/tab-protocol.ts +6 -0
  121. package/src/tools/browser/tab-supervisor.ts +17 -1
  122. package/src/tools/browser/tab-worker.ts +140 -21
  123. package/src/tools/builtin-names.ts +1 -0
  124. package/src/tools/eval-render.ts +16 -14
  125. package/src/tools/index.ts +5 -0
  126. package/src/tools/inspect-image.ts +2 -2
  127. package/src/tools/launch.ts +643 -0
  128. package/src/tools/render-utils.ts +3 -0
  129. package/src/tools/renderers.ts +2 -0
  130. package/src/tools/terminal-output.ts +141 -0
  131. package/src/tts/speech-enhancer.ts +2 -2
  132. package/src/utils/image-vision-fallback.ts +3 -3
  133. package/src/vibe/runtime.ts +2 -2
  134. package/src/web/search/provider.ts +0 -10
  135. package/src/web/search/providers/perplexity.ts +18 -2
  136. package/src/web/search/providers/public.ts +2 -4
  137. package/src/web/search/types.ts +0 -10
  138. package/dist/types/web/search/providers/bing.d.ts +0 -14
  139. package/dist/types/web/search/providers/yahoo.d.ts +0 -14
  140. package/src/web/search/providers/bing.ts +0 -197
  141. package/src/web/search/providers/yahoo.ts +0 -179
@@ -11,6 +11,11 @@ export interface Args {
11
11
  smol?: string;
12
12
  slow?: string;
13
13
  plan?: string;
14
+ prewalk?: boolean;
15
+ noPrewalk?: boolean;
16
+ prewalkInto?: string;
17
+ planYolo?: boolean;
18
+ planYoloInto?: string;
14
19
  maxTime?: number;
15
20
  apiKey?: string;
16
21
  systemPrompt?: string;
@@ -1,3 +1,3 @@
1
- /** Gallery fixtures for the shell tools (bash, eval). */
1
+ /** Gallery fixtures for the shell tools (bash, eval, launch). */
2
2
  import type { GalleryFixture } from "./types.js";
3
3
  export declare const shellFixtures: Record<string, GalleryFixture>;
@@ -25,6 +25,21 @@ export default class Index extends Command {
25
25
  plan: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
26
26
  description: string;
27
27
  };
28
+ prewalk: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
29
+ description: string;
30
+ };
31
+ "no-prewalk": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
32
+ description: string;
33
+ };
34
+ "prewalk-into": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
35
+ description: string;
36
+ };
37
+ "plan-yolo": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
38
+ description: string;
39
+ };
40
+ "plan-yolo-into": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
41
+ description: string;
42
+ };
28
43
  provider: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
29
44
  description: string;
30
45
  };
@@ -95,7 +95,7 @@ export declare function parseModelPattern(pattern: string, availableModels: Mode
95
95
  allowInvalidThinkingSelectorFallback?: boolean;
96
96
  }): ParsedModelResult;
97
97
  /**
98
- * Expand a role alias like "pi/smol" to the configured model string.
98
+ * Expand a role alias like "@smol" to the configured model string.
99
99
  */
100
100
  export declare function expandRoleAlias(value: string, settings?: Settings): string;
101
101
  export declare function resolveConfiguredModelPatterns(value: string | string[] | undefined, settings?: Settings): string[];
@@ -202,7 +202,7 @@ export declare function resolveAdvisorRoleSelection(settings: Settings, availabl
202
202
  * The algorithm tries to match the full pattern first, then progressively
203
203
  * strips colon-suffixes to find a match.
204
204
  */
205
- export declare function resolveModelScope(patterns: string[], modelRegistry: Pick<ModelRegistry, "getAvailable">, preferences?: ModelMatchPreferences): Promise<ScopedModel[]>;
205
+ export declare function resolveModelScope(patterns: string[], modelRegistry: Pick<ModelRegistry, "getAvailable">, preferences?: ModelMatchPreferences, settings?: Settings): Promise<ScopedModel[]>;
206
206
  /**
207
207
  * Resolve the set of models a session is allowed to use, given the active
208
208
  * settings. Starts from `modelRegistry.getAvailable()` (so disabled providers
@@ -232,7 +232,7 @@ export declare function resolveAllowedModels(modelRegistry: Pick<ModelRegistry,
232
232
  * a UI picker should treat an empty list as "hide the picker entry", matching how the SDK
233
233
  * surfaces the same misconfiguration during session initialization.
234
234
  */
235
- export declare function filterAvailableModelsByEnabledPatterns(available: Model<Api>[], patterns: readonly string[]): Model<Api>[];
235
+ export declare function filterAvailableModelsByEnabledPatterns(available: Model<Api>[], patterns: readonly string[], settings?: Settings): Model<Api>[];
236
236
  export interface ResolveCliModelResult {
237
237
  model: Model<Api> | undefined;
238
238
  selector?: string;
@@ -247,6 +247,7 @@ export declare function resolveCliModel(options: {
247
247
  cliProvider?: string;
248
248
  cliModel?: string;
249
249
  modelRegistry: CliModelRegistry;
250
+ settings?: Settings;
250
251
  preferences?: ModelMatchPreferences;
251
252
  }): ResolveCliModelResult;
252
253
  export interface InitialModelResult {
@@ -3,6 +3,14 @@
3
3
  */
4
4
  import { type ThemeColor } from "../modes/theme/theme.js";
5
5
  import type { Settings } from "./settings.js";
6
+ /** Canonical prefix for a configured model role selector. */
7
+ export declare const MODEL_ROLE_ALIAS_PREFIX = "@";
8
+ /** Legacy prefix accepted for backwards-compatible role selectors. */
9
+ export declare const LEGACY_MODEL_ROLE_ALIAS_PREFIX = "pi/";
10
+ /** Shorthand selector for the default model role. */
11
+ export declare const DEFAULT_MODEL_ROLE_ALIAS = "*";
12
+ /** Format a model role as its canonical selector. */
13
+ export declare function formatModelRoleAlias(role: string): string;
6
14
  export type ModelRole = "default" | "smol" | "slow" | "vision" | "plan" | "designer" | "commit" | "tiny" | "task" | "advisor";
7
15
  export interface ModelRoleInfo {
8
16
  tag?: string;
@@ -176,6 +176,16 @@ export declare const SETTINGS_SCHEMA: {
176
176
  readonly description: "Pair a second model (assigned to the 'advisor' role) that passively reviews each turn and injects notes.";
177
177
  };
178
178
  };
179
+ readonly "prewalk.enabled": {
180
+ readonly type: "boolean";
181
+ readonly default: false;
182
+ readonly ui: {
183
+ readonly tab: "model";
184
+ readonly group: "Prewalk";
185
+ readonly label: "Enable Prewalk";
186
+ readonly description: "Start on the active model, then switch to a fast/cheap model (default the 'smol' role) at the first edit/write after the plan nudge's todo list exists — the strong model plans, commits the todos, and starts the implementation before handing off. Overridable per session with --prewalk / --no-prewalk.";
187
+ };
188
+ };
179
189
  readonly "advisor.subagents": {
180
190
  readonly type: "boolean";
181
191
  readonly default: false;
@@ -806,6 +816,16 @@ export declare const SETTINGS_SCHEMA: {
806
816
  readonly description: "Remove the 1-character horizontal padding from the left and right of the terminal output";
807
817
  };
808
818
  };
819
+ readonly "tui.scrollbackRebuild": {
820
+ readonly type: "boolean";
821
+ readonly default: false;
822
+ readonly ui: {
823
+ readonly tab: "appearance";
824
+ readonly group: "Display";
825
+ readonly label: "Rewrite Scrollback";
826
+ readonly description: "Erase and replay terminal scrollback when a block's final form replaces its live preview. When off (default), stale preview copies remain in history and the final content is appended below.";
827
+ };
828
+ };
809
829
  readonly "display.shimmer": {
810
830
  readonly type: "enum";
811
831
  readonly values: readonly ["classic", "kitt", "disabled"];
@@ -860,6 +880,16 @@ export declare const SETTINGS_SCHEMA: {
860
880
  readonly description: "Show a divider above an assistant turn whose request lost (missed) the prompt cache";
861
881
  };
862
882
  };
883
+ readonly "display.collapseCompacted": {
884
+ readonly type: "boolean";
885
+ readonly default: true;
886
+ readonly ui: {
887
+ readonly tab: "appearance";
888
+ readonly group: "Display";
889
+ readonly label: "Collapse Compacted History";
890
+ readonly description: "Collapse pre-compaction history behind the summary divider on the live transcript; disable to keep the full transcript inline with dividers at each compaction point";
891
+ };
892
+ };
863
893
  readonly showHardwareCursor: {
864
894
  readonly type: "boolean";
865
895
  readonly default: true;
@@ -1241,7 +1271,7 @@ export declare const SETTINGS_SCHEMA: {
1241
1271
  readonly textVerbosity: {
1242
1272
  readonly type: "enum";
1243
1273
  readonly values: readonly ["low", "medium", "high"];
1244
- readonly default: "high";
1274
+ readonly default: "medium";
1245
1275
  readonly ui: {
1246
1276
  readonly tab: "model";
1247
1277
  readonly group: "Sampling";
@@ -1254,11 +1284,11 @@ export declare const SETTINGS_SCHEMA: {
1254
1284
  }, {
1255
1285
  readonly value: "medium";
1256
1286
  readonly label: "Medium";
1257
- readonly description: "Balance brevity and detail";
1287
+ readonly description: "Balance brevity and detail (default)";
1258
1288
  }, {
1259
1289
  readonly value: "high";
1260
1290
  readonly label: "High";
1261
- readonly description: "Prefer detailed responses (default)";
1291
+ readonly description: "Prefer detailed responses";
1262
1292
  }];
1263
1293
  };
1264
1294
  };
@@ -2690,7 +2720,7 @@ export declare const SETTINGS_SCHEMA: {
2690
2720
  readonly tab: "memory";
2691
2721
  readonly group: "Mnemopi";
2692
2722
  readonly label: "Mnemopi LLM Mode";
2693
- readonly description: "Use no LLM, the online tiny model (the TINY role from /models, else pi/smol), or a remote OpenAI-compatible endpoint";
2723
+ readonly description: "Use no LLM, the online tiny model (the TINY role from /models, else @smol), or a remote OpenAI-compatible endpoint";
2694
2724
  readonly condition: "mnemopiActive";
2695
2725
  readonly options: readonly [{
2696
2726
  readonly value: "none";
@@ -2699,7 +2729,7 @@ export declare const SETTINGS_SCHEMA: {
2699
2729
  }, {
2700
2730
  readonly value: "smol";
2701
2731
  readonly label: "Online (tiny)";
2702
- readonly description: "Use the online tiny model (the TINY role from /models, else pi/smol)";
2732
+ readonly description: "Use the online tiny model (the TINY role from /models, else @smol)";
2703
2733
  }, {
2704
2734
  readonly value: "remote";
2705
2735
  readonly label: "Remote";
@@ -3649,6 +3679,16 @@ export declare const SETTINGS_SCHEMA: {
3649
3679
  readonly description: "Enable the debug tool for DAP-based debugging";
3650
3680
  };
3651
3681
  };
3682
+ readonly "launch.enabled": {
3683
+ readonly type: "boolean";
3684
+ readonly default: true;
3685
+ readonly ui: {
3686
+ readonly tab: "tools";
3687
+ readonly group: "Available Tools";
3688
+ readonly label: "Launch";
3689
+ readonly description: "Enable the launch tool for supervising shared long-running project processes";
3690
+ };
3691
+ };
3652
3692
  readonly "speechgen.enabled": {
3653
3693
  readonly type: "boolean";
3654
3694
  readonly default: false;
@@ -4587,14 +4627,6 @@ export declare const SETTINGS_SCHEMA: {
4587
4627
  readonly value: "duckduckgo";
4588
4628
  readonly label: "DuckDuckGo";
4589
4629
  readonly description: "Credential-free best-effort fallback; may be bot-challenged on datacenter/shared-egress IPs";
4590
- }, {
4591
- readonly value: "bing";
4592
- readonly label: "Bing";
4593
- readonly description: "Credential-free HTML scrape of Bing results; may be bot-challenged";
4594
- }, {
4595
- readonly value: "yahoo";
4596
- readonly label: "Yahoo";
4597
- readonly description: "Credential-free HTML scrape of Yahoo (Bing-backed) results";
4598
4630
  }, {
4599
4631
  readonly value: "ecosia";
4600
4632
  readonly label: "Ecosia";
@@ -4833,7 +4865,7 @@ export declare const SETTINGS_SCHEMA: {
4833
4865
  readonly tab: "providers";
4834
4866
  readonly group: "Tiny Model";
4835
4867
  readonly label: "Tiny Model";
4836
- readonly description: "Session-title model: online (the TINY role from /models, else pi/smol) by default, or a local on-device model";
4868
+ readonly description: "Session-title model: online (the TINY role from /models, else @smol) by default, or a local on-device model";
4837
4869
  readonly options: ({
4838
4870
  value: "online";
4839
4871
  label: string;
@@ -257,7 +257,7 @@ export interface ExtensionModelQuery {
257
257
  /** The current session model, if one is set. */
258
258
  current(): Model | undefined;
259
259
  /**
260
- * Resolve a model string (`provider/id`, bare id) or role alias (`pi/slow`, a
260
+ * Resolve a model string (`provider/id`, bare id) or role alias (`@slow`, a
261
261
  * configured role) to a Model, using the same settings-backed aliases and match
262
262
  * preferences as core selection. Thinking/routing suffixes are accepted and resolved
263
263
  * to the base model (pass effort separately). Returns undefined when nothing matches.
@@ -0,0 +1,2 @@
1
+ /** Start the detached per-project daemon broker selected by the CLI worker host. */
2
+ export declare function startDaemonBrokerFromEnvironment(): Promise<void>;
@@ -0,0 +1,22 @@
1
+ import { type DaemonOperation, type DaemonRpcResult } from "./protocol.js";
2
+ /** Broker location and lifecycle overrides used by smoke tests and isolated consumers. */
3
+ export interface DaemonBrokerClientOptions {
4
+ /** Runtime directory override; defaults to the project-scoped config path. */
5
+ runtimeDir?: string;
6
+ /** Last-client shutdown grace override in milliseconds. */
7
+ idleGraceMs?: number;
8
+ }
9
+ /** Persistent per-process connection to one project's daemon broker. */
10
+ export interface DaemonBrokerClient {
11
+ readonly projectDir: string;
12
+ request(operation: DaemonOperation, signal?: AbortSignal): Promise<DaemonRpcResult>;
13
+ close(): void;
14
+ }
15
+ /** Create an independent socket connection to one project's shared daemon broker. */
16
+ export declare function createDaemonBrokerClient(projectDir: string, options?: DaemonBrokerClientOptions): Promise<DaemonBrokerClient>;
17
+ /** Get the process-shared daemon broker client for one canonical project directory. */
18
+ export declare function daemonClientForProject(projectDir: string): Promise<DaemonBrokerClient>;
19
+ /** Close every project broker connection held by this omp process. */
20
+ export declare function closeDaemonClients(): Promise<void>;
21
+ /** Exercise worker-host broker startup and authenticated RPC for distribution smoke tests. */
22
+ export declare function smokeTestDaemonBroker(): Promise<void>;
@@ -0,0 +1,4 @@
1
+ /** Resolve the private runtime directory shared by omp processes in one project directory. */
2
+ export declare function daemonRuntimeDir(projectDir: string, configRoot?: string): string;
3
+ /** Resolve the Unix socket or Windows named pipe used by one project broker. */
4
+ export declare function daemonBrokerEndpoint(projectDir: string, runtimeDir: string): string;
@@ -0,0 +1,8 @@
1
+ /** Handle keeping one omp process registered in a project daemon scope. */
2
+ export interface DaemonProjectPresence {
3
+ close(): Promise<void>;
4
+ }
5
+ /** Register this omp process so project daemons survive while it remains alive. */
6
+ export declare function registerDaemonProjectPresence(projectDir: string, runtimeOverride?: string): Promise<DaemonProjectPresence>;
7
+ /** Return whether a registered omp process in this runtime directory is still alive. */
8
+ export declare function hasLiveDaemonProjectPresence(runtimeDir: string): Promise<boolean>;
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Cross-process daemon broker protocol shared by the tool, client, and broker.
3
+ */
4
+ /** Hidden CLI selector used to re-enter the daemon broker worker. */
5
+ export declare const DAEMON_BROKER_WORKER_ARG = "__omp_worker_daemon_broker";
6
+ /** Fixed dimensions negotiated with every supervised PTY. */
7
+ export declare const DAEMON_PTY_COLUMNS = 120;
8
+ export declare const DAEMON_PTY_ROWS = 40;
9
+ /** Environment key carrying the broker's canonical project directory. */
10
+ export declare const DAEMON_PROJECT_DIR_ENV = "OMP_DAEMON_PROJECT_DIR";
11
+ /** Environment key carrying the broker's private runtime directory. */
12
+ export declare const DAEMON_RUNTIME_DIR_ENV = "OMP_DAEMON_RUNTIME_DIR";
13
+ /** Optional environment key overriding last-client shutdown grace. */
14
+ export declare const DAEMON_IDLE_GRACE_ENV = "OMP_DAEMON_IDLE_GRACE_MS";
15
+ /** Stable lifecycle states exposed by the launch tool. */
16
+ export type DaemonState = "starting" | "running" | "ready" | "restarting" | "stopping" | "exited" | "failed";
17
+ /** Restart behavior applied after an unexpected daemon exit. */
18
+ export type DaemonRestartPolicy = "no" | "on-failure" | "always";
19
+ /** Readiness conditions; every configured condition must pass. */
20
+ export interface DaemonReadySpec {
21
+ log?: string;
22
+ port?: number;
23
+ host?: string;
24
+ timeoutMs: number;
25
+ }
26
+ /** Immutable launch specification retained for restart and inspection. */
27
+ export interface DaemonSpec {
28
+ name: string;
29
+ application: string;
30
+ args: string[];
31
+ env: Record<string, string>;
32
+ cwd: string;
33
+ pty: boolean;
34
+ ready?: DaemonReadySpec;
35
+ restart: DaemonRestartPolicy;
36
+ persist: boolean;
37
+ detached: boolean;
38
+ }
39
+ /** Serializable daemon state visible to every client in one project directory. */
40
+ export interface DaemonSnapshot {
41
+ name: string;
42
+ id: string;
43
+ state: DaemonState;
44
+ pid?: number;
45
+ createdAt: number;
46
+ startedAt: number;
47
+ readyAt?: number;
48
+ exitedAt?: number;
49
+ exitCode?: number;
50
+ exitReason?: string;
51
+ restartCount: number;
52
+ outputBytes: number;
53
+ owner?: string;
54
+ readyMatch?: string;
55
+ /** Readiness conditions still unmet while `state` is `starting`; absent once ready or without a ready spec. */
56
+ readyPending?: ("log" | "port")[];
57
+ persist: boolean;
58
+ detached: boolean;
59
+ }
60
+ /** Signals accepted by daemon input operations. */
61
+ export type DaemonSignal = "SIGINT" | "SIGTERM" | "SIGHUP" | "SIGQUIT" | "SIGKILL";
62
+ /** Typed broker operation sent over the authenticated socket. */
63
+ export type DaemonOperation = {
64
+ op: "ping";
65
+ } | {
66
+ op: "start";
67
+ spec: DaemonSpec;
68
+ owner?: string;
69
+ } | {
70
+ op: "list";
71
+ } | {
72
+ op: "logs";
73
+ name: string;
74
+ lines: number;
75
+ head: boolean;
76
+ grep?: string;
77
+ follow: boolean;
78
+ cursor?: number;
79
+ timeoutMs: number;
80
+ } | {
81
+ op: "wait";
82
+ name: string;
83
+ for: "ready" | "exit";
84
+ pattern?: string;
85
+ timeoutMs: number;
86
+ } | {
87
+ op: "send";
88
+ name: string;
89
+ data?: string;
90
+ signal?: DaemonSignal;
91
+ } | {
92
+ op: "stop";
93
+ name: string;
94
+ timeoutMs: number;
95
+ } | {
96
+ op: "restart";
97
+ name: string;
98
+ } | {
99
+ op: "describe";
100
+ name: string;
101
+ } | {
102
+ op: "shutdown";
103
+ };
104
+ /** Typed broker result decoded before it reaches tool code. */
105
+ export type DaemonRpcResult = {
106
+ op: "ping";
107
+ projectDir: string;
108
+ } | {
109
+ op: "start";
110
+ daemon: DaemonSnapshot;
111
+ readyTimedOut: boolean;
112
+ } | {
113
+ op: "list";
114
+ daemons: DaemonSnapshot[];
115
+ } | {
116
+ op: "logs";
117
+ name: string;
118
+ text: string;
119
+ /** Raw PTY byte stream used only to reconstruct the terminal screen. */
120
+ terminalText?: string;
121
+ cursor: number;
122
+ timedOut: boolean;
123
+ state: DaemonState;
124
+ } | {
125
+ op: "wait";
126
+ daemon: DaemonSnapshot;
127
+ matched?: string;
128
+ timedOut: boolean;
129
+ } | {
130
+ op: "send";
131
+ daemon: DaemonSnapshot;
132
+ } | {
133
+ op: "stop";
134
+ daemon: DaemonSnapshot;
135
+ } | {
136
+ op: "restart";
137
+ daemon: DaemonSnapshot;
138
+ } | {
139
+ op: "describe";
140
+ daemon: DaemonSnapshot;
141
+ spec: DaemonSpec;
142
+ } | {
143
+ op: "shutdown";
144
+ };
145
+ /** Authenticated request envelope used by socket clients. */
146
+ export interface DaemonWireRequest {
147
+ id: string;
148
+ token: string;
149
+ operation: DaemonOperation;
150
+ }
151
+ /** Response envelope kept raw until matched with its pending operation. */
152
+ export type DaemonWireResponse = {
153
+ id: string;
154
+ ok: true;
155
+ result: unknown;
156
+ } | {
157
+ id: string;
158
+ ok: false;
159
+ error: string;
160
+ };
161
+ /** Decode and validate a daemon launch specification. */
162
+ export declare function parseDaemonSpec(value: unknown): DaemonSpec;
163
+ /** Decode and validate one daemon snapshot. */
164
+ export declare function parseDaemonSnapshot(value: unknown): DaemonSnapshot;
165
+ /** Decode a socket request before the broker acts on it. */
166
+ export declare function parseDaemonWireRequest(value: unknown): DaemonWireRequest;
167
+ /** Decode a socket response envelope before resolving a pending call. */
168
+ export declare function parseDaemonWireResponse(value: unknown): DaemonWireResponse;
169
+ /** Decode a broker result using its pending operation as the discriminator. */
170
+ export declare function parseDaemonRpcResult(operation: DaemonOperation, value: unknown): DaemonRpcResult;
@@ -0,0 +1,7 @@
1
+ /** Controls which virtual terminal rows a launch log exposes. */
2
+ export interface TerminalOutputOptions {
3
+ head: boolean;
4
+ maxRows: number;
5
+ }
6
+ /** Replays daemon bytes with the same xterm screen renderer used by PTY mode. */
7
+ export declare function renderTerminalOutput(output: string, options: TerminalOutputOptions): Promise<string[] | undefined>;
@@ -1,4 +1,4 @@
1
- import type { AgentTool } from "@oh-my-pi/pi-agent-core";
1
+ import { type AgentTool } from "@oh-my-pi/pi-agent-core";
2
2
  import { Container, type TUI } from "@oh-my-pi/pi-tui";
3
3
  import type { KeyId } from "../../config/keybindings.js";
4
4
  import type { MessageRenderer } from "../../extensibility/extensions/types.js";
@@ -18,6 +18,7 @@ export * from "./login-dialog.js";
18
18
  export * from "./logout-account-selector.js";
19
19
  export * from "./model-browser.js";
20
20
  export * from "./model-hub.js";
21
+ export * from "./model-picker.js";
21
22
  export * from "./oauth-selector.js";
22
23
  export * from "./queue-mode-selector.js";
23
24
  export * from "./read-tool-group.js";
@@ -3,12 +3,15 @@ import { type Component, type SgrMouseEvent } from "@oh-my-pi/pi-tui";
3
3
  import type { Settings } from "../../config/settings.js";
4
4
  import type { ModelPerfStats } from "../../session/agent-storage.js";
5
5
  import { type ConfiguredThinkingLevel } from "../../thinking.js";
6
- /** One selectable model row. `selector` is the canonical `provider/id` key. */
6
+ import { type ThemeColor } from "../theme/theme.js";
7
+ /** One selectable row. `selector` is a canonical model key or host-specific virtual key. */
7
8
  export interface ModelBrowserItem {
8
9
  provider: string;
9
10
  id: string;
10
11
  model: Model;
11
12
  selector: string;
13
+ /** Optional foreground color for the row label. */
14
+ labelColor?: ThemeColor;
12
15
  }
13
16
  /** Resolved role assignment as displayed by the browser and the hub. */
14
17
  export interface RoleAssignment {
@@ -19,6 +22,13 @@ export interface RoleAssignment {
19
22
  }
20
23
  /** Map of role id to its resolved assignment (absent roles are unresolved). */
21
24
  export type RoleAssignments = Record<string, RoleAssignment | undefined>;
25
+ /**
26
+ * Resolve every known role to its display assignment: configured role values
27
+ * resolve against `allModels`; unconfigured roles fall back to auto-selection
28
+ * over `autoCandidates` (skipped when empty). Shared by the /models hub and
29
+ * the alt+p session picker.
30
+ */
31
+ export declare function resolveRoleAssignments(settings: Settings, allModels: ReadonlyArray<Model>, autoCandidates: ReadonlyArray<Model>): RoleAssignments;
22
32
  /** Wrap raw models into browser items. */
23
33
  export declare function buildBrowserItems(models: ReadonlyArray<Model>): ModelBrowserItem[];
24
34
  /** Options for {@link sortModelItems}. */
@@ -54,7 +64,6 @@ export interface ModelBrowserOptions {
54
64
  disableOverContext?: boolean;
55
65
  /** Host-provided empty-state text (e.g. provider discovery status). */
56
66
  emptyText?: () => string | undefined;
57
- initialQuery?: string;
58
67
  }
59
68
  /**
60
69
  * The reusable browser component. Renders a fixed-height block
@@ -70,6 +79,8 @@ export declare class ModelBrowser implements Component {
70
79
  /** Cancel key with an empty query (a non-empty query is cleared first). */
71
80
  onCancel?: () => void;
72
81
  constructor(settings: Settings, options?: ModelBrowserOptions);
82
+ /** Mark `selector` as the session's active model (undefined clears the mark). */
83
+ setCurrentSelector(selector: string | undefined): void;
73
84
  /** Replace the scope's base items; the live query re-applies and selection is pinned by selector. */
74
85
  setItems(items: ModelBrowserItem[]): void;
75
86
  setRoles(roles: RoleAssignments): void;
@@ -78,6 +89,12 @@ export declare class ModelBrowser implements Component {
78
89
  setPerfStats(perf: ReadonlyMap<string, ModelPerfStats>): void;
79
90
  setMaxVisible(rows: number): void;
80
91
  setShowProvider(show: boolean): void;
92
+ /** Keep the source order after fuzzy filtering instead of applying model-specific ranking. */
93
+ setPreserveQueryOrder(preserve: boolean): void;
94
+ /** Allow hosts to toggle context-window eligibility between browser modes. */
95
+ setDisableOverContext(disable: boolean): void;
96
+ /** Focused: accent cursor + selected-row background band. Unfocused: dim cursor, no band. */
97
+ setFocused(focused: boolean): void;
81
98
  /** Total rendered height for the current `maxVisible` (host layout budgeting). */
82
99
  get renderedRows(): number;
83
100
  get query(): string;
@@ -86,7 +103,13 @@ export declare class ModelBrowser implements Component {
86
103
  get visibleCount(): number;
87
104
  /** Move selection to `selector`; false when it is not in the current view. */
88
105
  selectSelector(selector: string): boolean;
89
- moveSelection(delta: number): void;
106
+ /**
107
+ * Move the selection by `delta` rows, skipping disabled rows. Single steps
108
+ * wrap at the ends; `wrap: false` (page/home/end jumps) clamps instead.
109
+ */
110
+ moveSelection(delta: number, options?: {
111
+ wrap?: boolean;
112
+ }): void;
90
113
  handleInput(data: string): void;
91
114
  /** Cancel-key ladder: clear a non-empty query first, then bubble to the host. */
92
115
  handleCancel(): void;
@@ -95,6 +118,8 @@ export declare class ModelBrowser implements Component {
95
118
  * row (the search row).
96
119
  */
97
120
  routeMouse(event: SgrMouseEvent, line: number): void;
121
+ /** Drop the hover band. Hosts call this when the pointer leaves the browser pane. */
122
+ clearHover(): void;
98
123
  render(width: number): string[];
99
124
  invalidate(): void;
100
125
  }
@@ -3,8 +3,6 @@ import { type Component, type TUI } from "@oh-my-pi/pi-tui";
3
3
  import type { ModelRegistry } from "../../config/model-registry.js";
4
4
  import type { Settings } from "../../config/settings.js";
5
5
  import { type ConfiguredThinkingLevel } from "../../thinking.js";
6
- /** `roles` is the full /models hub; `pick` is a one-shot session/embedded picker. */
7
- export type ModelHubMode = "roles" | "pick";
8
6
  /** A `--models` scope entry (mirrors the session's scoped model list). */
9
7
  export interface ScopedModelItem {
10
8
  model: Model;
@@ -17,8 +15,6 @@ export interface ModelHubCallbacks {
17
15
  onUnassign: (role: string) => void;
18
16
  /** Persist a `retry.fallbackChains` entry — keyed by a role, `provider/model-id`, or `provider/*`; an empty chain clears the key. */
19
17
  onFallbackChainChange?: (role: string, chain: string[]) => void;
20
- /** Pick-mode activation: session-only switch or embedded pick. */
21
- onPick?: (model: Model, selector: string) => void;
22
18
  /** Locked provider activation: forward to the /login flow. */
23
19
  onLoginRequest?: (providerId: string) => void;
24
20
  /** Persist a new quick-switch cycle order (the ctrl+p role cycle). */
@@ -26,14 +22,8 @@ export interface ModelHubCallbacks {
26
22
  onCancel: () => void;
27
23
  }
28
24
  export interface ModelHubOptions {
29
- mode?: ModelHubMode;
30
- /** Session token count; in pick mode, models with smaller context windows are disabled. */
31
- currentContextTokens?: number;
32
25
  /** Preselect this provider's sidebar entry (e.g. when reopening after /login). */
33
26
  initialProviderId?: string;
34
- /** Status-row hint shown in pick mode. */
35
- pickerHint?: string;
36
- initialQuery?: string;
37
27
  }
38
28
  /** Test hook: forget which providers were auto-refreshed this process. */
39
29
  export declare function resetProviderAutoRefreshGuard(): void;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Compact session-model picker (alt+p / `/switch`): a bottom-anchored
3
+ * floating overlay hosting just a {@link ModelBrowser} — no provider sidebar.
4
+ * Model entries switch the current session only; a search beginning with `@`
5
+ * exposes the configured ctrl+p quick roles.
6
+ */
7
+ import type { Model } from "@oh-my-pi/pi-ai";
8
+ import type { Component, TUI } from "@oh-my-pi/pi-tui";
9
+ import type { ModelRegistry } from "../../config/model-registry.js";
10
+ import type { Settings } from "../../config/settings.js";
11
+ import type { ResolvedRoleModel } from "../../session/agent-session.js";
12
+ import type { ScopedModelItem } from "./model-hub.js";
13
+ export interface ModelPickerCallbacks {
14
+ /** A model was chosen for a session-only switch. `selector` is `provider/id`. */
15
+ onPick: (model: Model, selector: string) => void;
16
+ /** A configured ctrl+p quick role was chosen. */
17
+ onPickRole?: (entry: ResolvedRoleModel) => void;
18
+ /** The picker was dismissed. */
19
+ onCancel: () => void;
20
+ }
21
+ export interface ModelPickerOptions {
22
+ /** Session token count; models with smaller context windows are disabled. */
23
+ currentContextTokens?: number;
24
+ /** `provider/id` of the session's active model; highlighted and preselected. */
25
+ currentSelector?: string;
26
+ /** Resolved role models in the same order used by the ctrl+p quick-role cycle. */
27
+ quickRoles?: ReadonlyArray<ResolvedRoleModel>;
28
+ /** Complete ctrl+p order, including unavailable roles, to preserve segment colors. */
29
+ quickRoleOrder?: ReadonlyArray<string>;
30
+ /** Active quick role, highlighted when the search begins with `@`. */
31
+ currentQuickRole?: string;
32
+ }
33
+ /**
34
+ * The alt+p picker component. Hosted as a non-fullscreen bottom-anchored
35
+ * overlay (`ui.showOverlay(..., { anchor: "bottom-center" })`); keyboard-only,
36
+ * since mouse tracking is reserved for fullscreen overlays.
37
+ */
38
+ export declare class ModelPickerComponent implements Component {
39
+ #private;
40
+ constructor(tui: TUI, settings: Settings, registry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, callbacks: ModelPickerCallbacks, options?: ModelPickerOptions);
41
+ invalidate(): void;
42
+ handleInput(data: string): void;
43
+ render(width: number): string[];
44
+ }
@@ -23,6 +23,8 @@ export interface PlanReviewOverlayCallbacks {
23
23
  onPick: (label: string) => void;
24
24
  /** Invoked on Esc / cancel. */
25
25
  onCancel: () => void;
26
+ /** Invoked with the current full plan text when the copy hotkey is pressed. */
27
+ onCopyPlan?: (content: string) => void | Promise<void>;
26
28
  /** Invoked when the external-editor key is pressed (overlay stays open). */
27
29
  onExternalEditor?: () => void;
28
30
  /** Invoked when the external-editor key edits the active annotation draft. */
@@ -60,6 +60,9 @@ export interface SegmentContext {
60
60
  enabled: boolean;
61
61
  paused: boolean;
62
62
  } | null;
63
+ prewalk: {
64
+ enabled: boolean;
65
+ } | null;
63
66
  loopMode: {
64
67
  enabled: boolean;
65
68
  } | null;