@oh-my-pi/pi-coding-agent 16.4.8 → 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 (134) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/cli.js +3502 -3444
  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 +17 -2
  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/status-line/types.d.ts +3 -0
  22. package/dist/types/modes/print-mode.d.ts +14 -8
  23. package/dist/types/modes/print-mode.test.d.ts +1 -0
  24. package/dist/types/modes/theme/theme.d.ts +2 -1
  25. package/dist/types/sdk.d.ts +5 -1
  26. package/dist/types/session/agent-session.d.ts +42 -0
  27. package/dist/types/session/session-context.d.ts +9 -0
  28. package/dist/types/session/session-entries.d.ts +6 -0
  29. package/dist/types/thinking.d.ts +2 -2
  30. package/dist/types/tiny/models.d.ts +1 -1
  31. package/dist/types/tools/browser/launch.d.ts +1 -0
  32. package/dist/types/tools/browser/run-cancellation.d.ts +28 -2
  33. package/dist/types/tools/browser/tab-protocol.d.ts +6 -0
  34. package/dist/types/tools/browser/tab-worker.d.ts +6 -0
  35. package/dist/types/tools/builtin-names.d.ts +1 -1
  36. package/dist/types/tools/index.d.ts +1 -0
  37. package/dist/types/tools/launch.d.ts +121 -0
  38. package/dist/types/tools/render-utils.d.ts +2 -0
  39. package/dist/types/tools/terminal-output.d.ts +5 -0
  40. package/dist/types/vibe/runtime.d.ts +2 -2
  41. package/dist/types/web/search/types.d.ts +0 -8
  42. package/package.json +20 -20
  43. package/src/cli/args.ts +11 -0
  44. package/src/cli/flag-tables.ts +9 -0
  45. package/src/cli/gallery-fixtures/shell.ts +82 -1
  46. package/src/cli.ts +10 -0
  47. package/src/commands/launch.ts +17 -0
  48. package/src/config/model-resolver.ts +110 -31
  49. package/src/config/model-roles.ts +14 -0
  50. package/src/config/settings-schema.ts +71 -7
  51. package/src/edit/renderer.ts +13 -10
  52. package/src/eval/__tests__/agent-bridge.test.ts +2 -2
  53. package/src/eval/__tests__/completion-bridge.test.ts +1 -1
  54. package/src/eval/completion-bridge.ts +4 -4
  55. package/src/export/ttsr.ts +0 -3
  56. package/src/extensibility/extensions/model-api.ts +1 -1
  57. package/src/extensibility/extensions/types.ts +1 -1
  58. package/src/internal-urls/docs-index.ts +4 -4
  59. package/src/launch/broker.ts +1017 -0
  60. package/src/launch/client.ts +344 -0
  61. package/src/launch/paths.ts +17 -0
  62. package/src/launch/presence.ts +82 -0
  63. package/src/launch/protocol.ts +386 -0
  64. package/src/launch/terminal-output.ts +46 -0
  65. package/src/main.ts +50 -1
  66. package/src/modes/acp/acp-agent.ts +8 -1
  67. package/src/modes/components/agent-hub.ts +101 -31
  68. package/src/modes/components/compaction-summary-message.ts +8 -2
  69. package/src/modes/components/index.ts +1 -0
  70. package/src/modes/components/model-browser.ts +111 -21
  71. package/src/modes/components/model-hub.ts +23 -116
  72. package/src/modes/components/model-picker.ts +233 -0
  73. package/src/modes/components/snapcompact-shape-preview-doc.md +7 -11
  74. package/src/modes/components/status-line/component.test.ts +41 -2
  75. package/src/modes/components/status-line/component.ts +4 -0
  76. package/src/modes/components/status-line/segments.ts +6 -0
  77. package/src/modes/components/status-line/types.ts +3 -0
  78. package/src/modes/controllers/command-controller.ts +9 -1
  79. package/src/modes/controllers/event-controller.ts +31 -32
  80. package/src/modes/controllers/selector-controller.ts +96 -22
  81. package/src/modes/controllers/tan-command-controller.ts +40 -1
  82. package/src/modes/interactive-mode.ts +7 -3
  83. package/src/modes/print-mode.test.ts +71 -0
  84. package/src/modes/print-mode.ts +51 -2
  85. package/src/modes/theme/theme.ts +9 -0
  86. package/src/modes/utils/ui-helpers.ts +25 -4
  87. package/src/prompts/agents/designer.md +1 -1
  88. package/src/prompts/agents/librarian.md +1 -1
  89. package/src/prompts/agents/reviewer.md +1 -1
  90. package/src/prompts/agents/scout.md +1 -1
  91. package/src/prompts/system/plan-yolo-handoff.md +5 -0
  92. package/src/prompts/system/prewalk-checklist.md +7 -0
  93. package/src/prompts/system/prewalk-continue.md +1 -0
  94. package/src/prompts/system/prewalk-plan.md +13 -0
  95. package/src/prompts/system/system-prompt.md +9 -7
  96. package/src/prompts/system/tan-context-switch.md +17 -0
  97. package/src/prompts/tools/bash.md +6 -4
  98. package/src/prompts/tools/browser.md +4 -4
  99. package/src/prompts/tools/launch.md +25 -0
  100. package/src/sdk.ts +8 -2
  101. package/src/session/agent-session.ts +550 -87
  102. package/src/session/session-context.test.ts +10 -5
  103. package/src/session/session-context.ts +25 -8
  104. package/src/session/session-entries.ts +6 -0
  105. package/src/slash-commands/builtin-registry.ts +25 -0
  106. package/src/task/agents.ts +2 -2
  107. package/src/thinking.ts +10 -3
  108. package/src/tiny/models.ts +7 -7
  109. package/src/tools/bash-interactive.ts +5 -8
  110. package/src/tools/bash.ts +38 -24
  111. package/src/tools/browser/cmux/cmux-tab.ts +17 -2
  112. package/src/tools/browser/launch.ts +8 -4
  113. package/src/tools/browser/run-cancellation.ts +66 -6
  114. package/src/tools/browser/tab-protocol.ts +6 -0
  115. package/src/tools/browser/tab-supervisor.ts +17 -1
  116. package/src/tools/browser/tab-worker.ts +140 -21
  117. package/src/tools/builtin-names.ts +1 -0
  118. package/src/tools/eval-render.ts +16 -14
  119. package/src/tools/index.ts +5 -0
  120. package/src/tools/inspect-image.ts +2 -2
  121. package/src/tools/launch.ts +643 -0
  122. package/src/tools/render-utils.ts +3 -0
  123. package/src/tools/renderers.ts +2 -0
  124. package/src/tools/terminal-output.ts +141 -0
  125. package/src/tts/speech-enhancer.ts +2 -2
  126. package/src/utils/image-vision-fallback.ts +3 -3
  127. package/src/vibe/runtime.ts +2 -2
  128. package/src/web/search/provider.ts +0 -10
  129. package/src/web/search/providers/public.ts +2 -4
  130. package/src/web/search/types.ts +0 -10
  131. package/dist/types/web/search/providers/bing.d.ts +0 -14
  132. package/dist/types/web/search/providers/yahoo.d.ts +0 -14
  133. package/src/web/search/providers/bing.ts +0 -197
  134. package/src/web/search/providers/yahoo.ts +0 -179
@@ -6,7 +6,7 @@ export type SymbolPreset = "unicode" | "nerd" | "ascii";
6
6
  /**
7
7
  * All available symbol keys organized by category.
8
8
  */
9
- export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "status.done" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.loop" | "icon.folder" | "icon.worktree" | "icon.search" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.ghost" | "icon.agents" | "icon.job" | "icon.cache" | "icon.cacheMiss" | "icon.input" | "icon.output" | "icon.throughput" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "icon.camera" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "thinking.max" | "thinking.autoPending" | "checkbox.checked" | "checkbox.unchecked" | "radio.selected" | "radio.unselected" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "md.colorSwatch" | "advisor.rail" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.julia" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.files" | "tab.shell" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers" | "tool.write" | "tool.edit" | "tool.bash" | "tool.ssh" | "tool.lsp" | "tool.gh" | "tool.webSearch" | "tool.exa" | "tool.browser" | "tool.eval" | "tool.debug" | "tool.mcp" | "tool.job" | "tool.task" | "tool.todo" | "tool.memory" | "tool.ask" | "tool.resolve" | "tool.review" | "tool.inspectImage" | "tool.goal" | "tool.irc" | "tool.delete" | "tool.move";
9
+ export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "status.done" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.prewalk" | "icon.goal" | "icon.pause" | "icon.loop" | "icon.folder" | "icon.worktree" | "icon.search" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.ghost" | "icon.agents" | "icon.job" | "icon.cache" | "icon.cacheMiss" | "icon.input" | "icon.output" | "icon.throughput" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "icon.camera" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "thinking.max" | "thinking.autoPending" | "checkbox.checked" | "checkbox.unchecked" | "radio.selected" | "radio.unselected" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "md.colorSwatch" | "advisor.rail" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.julia" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.files" | "tab.shell" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers" | "tool.write" | "tool.edit" | "tool.bash" | "tool.ssh" | "tool.lsp" | "tool.gh" | "tool.webSearch" | "tool.exa" | "tool.browser" | "tool.eval" | "tool.debug" | "tool.mcp" | "tool.job" | "tool.launch" | "tool.task" | "tool.todo" | "tool.memory" | "tool.ask" | "tool.resolve" | "tool.review" | "tool.inspectImage" | "tool.goal" | "tool.irc" | "tool.delete" | "tool.move";
10
10
  export type SpinnerType = "status" | "activity";
11
11
  export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "thinkingText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "thinkingMax" | "bashMode" | "pythonMode" | "statusLineSep" | "statusLineModel" | "statusLinePath" | "statusLineGitClean" | "statusLineGitDirty" | "statusLineContext" | "statusLineSpend" | "statusLineStaged" | "statusLineDirty" | "statusLineUntracked" | "statusLineOutput" | "statusLineCost" | "statusLineSubagents";
12
12
  /** Check if a string is a valid ThemeColor value */
@@ -160,6 +160,7 @@ export declare class Theme {
160
160
  get icon(): {
161
161
  model: string;
162
162
  plan: string;
163
+ prewalk: string;
163
164
  goal: string;
164
165
  pause: string;
165
166
  loop: string;
@@ -17,7 +17,7 @@ import { type LocalProtocolOptions } from "./internal-urls/index.js";
17
17
  import { MCPManager, type MCPToolsLoadResult } from "./mcp/index.js";
18
18
  import type { MnemopiSessionState } from "./mnemopi/state.js";
19
19
  import { AgentRegistry } from "./registry/agent-registry.js";
20
- import { AgentSession } from "./session/agent-session.js";
20
+ import { AgentSession, type PlanYolo, type Prewalk } from "./session/agent-session.js";
21
21
  import type { AuthStorage } from "./session/auth-storage.js";
22
22
  import { SessionManager } from "./session/session-manager.js";
23
23
  import { type BuildSystemPromptResult } from "./system-prompt.js";
@@ -52,6 +52,10 @@ export interface CreateAgentSessionOptions {
52
52
  model: Model;
53
53
  thinkingLevel?: ThinkingLevel;
54
54
  }>;
55
+ /** Prewalk from the starting model to a fast/cheap target at the first edit/write once the todo list exists. */
56
+ prewalk?: Prewalk;
57
+ /** Force read-only plan mode at start, auto-approve on the model's first resolve call, then switch to execute. */
58
+ planYolo?: PlanYolo;
55
59
  /** Provider-facing system prompt override. Replaces the fully rendered default blocks. */
56
60
  systemPrompt?: string | string[] | ((defaultPrompt: string[]) => string | string[]);
57
61
  /** Already-loaded custom prompt text rendered through the bundled custom system prompt template. */
@@ -151,6 +151,33 @@ export interface AsyncJobSnapshot {
151
151
  delivery: AsyncJobDeliveryState;
152
152
  }
153
153
  export type { ShakeMode, ShakeResult };
154
+ /**
155
+ * Prewalk: switches an active session one-way from its starting model to
156
+ * a fast/cheap `target` at the first completed turn that runs an edit/write
157
+ * tool once the todo list exists. A hidden plan nudge asks the starting
158
+ * model to write a plan, initialize its todo list from it, and start; the
159
+ * todo call opens the trigger gate (it never fires the switch itself), so
160
+ * the starting model always begins the implementation. A hidden
161
+ * checklist nudge asks the target model to verify its work before
162
+ * finishing. Both are always on — this is the one mechanism that won out
163
+ * over turn-count and ungated variants in testing.
164
+ */
165
+ export interface Prewalk {
166
+ target: Model;
167
+ thinkingLevel?: ConfiguredThinkingLevel;
168
+ }
169
+ /**
170
+ * PlanYolo: forces the session into read-only plan mode at start, then
171
+ * auto-approves the plan the instant the model calls `resolve({ action:
172
+ * "apply" })` for it — no interactive review — and switches to a fast/cheap
173
+ * `target` model to implement it. The headless counterpart to interactive
174
+ * plan mode's "Approve and execute", for print/non-interactive runs where
175
+ * there is no one to click Approve.
176
+ */
177
+ export interface PlanYolo {
178
+ target: Model;
179
+ thinkingLevel?: ConfiguredThinkingLevel;
180
+ }
154
181
  export interface AgentSessionConfig {
155
182
  agent: Agent;
156
183
  sessionManager: SessionManager;
@@ -164,6 +191,11 @@ export interface AgentSessionConfig {
164
191
  }>;
165
192
  /** Initial session thinking selector. */
166
193
  thinkingLevel?: ConfiguredThinkingLevel;
194
+ /** Prewalk from the starting model to a fast/cheap target at the first edit/write once the todo list exists. */
195
+ prewalk?: Prewalk;
196
+ /** Force read-only plan mode at start, auto-approve on the model's first
197
+ * `resolve` call, then switch to the target to implement. */
198
+ planYolo?: PlanYolo;
167
199
  /** Initial per-family service tiers (OpenAI / Anthropic / Google) for the live session. */
168
200
  serviceTierByFamily?: ServiceTierByFamily;
169
201
  /** Prompt templates for expansion */
@@ -489,6 +521,14 @@ export declare class AgentSession {
489
521
  fileSnapshotStore?: InMemorySnapshotStore;
490
522
  readonly configWarnings: string[];
491
523
  readonly rawSseDebugBuffer: RawSseDebugBuffer;
524
+ /**
525
+ * Arm prewalk outside the normal startup path (the `/prewalk` slash
526
+ * command): sets the target and immediately steers the plan nudge rather
527
+ * than waiting for the next turn boundary, since an explicit manual
528
+ * invocation means "start this now." A no-op with a notice if a prewalk
529
+ * is already armed and waiting.
530
+ */
531
+ armPrewalk(target: Model, thinkingLevel?: ConfiguredThinkingLevel): void;
492
532
  constructor(config: AgentSessionConfig);
493
533
  /** Model registry for API key resolution and model discovery */
494
534
  get modelRegistry(): ModelRegistry;
@@ -736,6 +776,8 @@ export declare class AgentSession {
736
776
  }>;
737
777
  /** Prompt templates */
738
778
  getPlanModeState(): PlanModeState | undefined;
779
+ /** Prewalk state, if armed and active */
780
+ getPrewalkState(): Prewalk | undefined;
739
781
  setPlanModeState(state: PlanModeState | undefined): void;
740
782
  getGoalModeState(): GoalModeState | undefined;
741
783
  setGoalModeState(state: GoalModeState | undefined): void;
@@ -50,4 +50,13 @@ export interface BuildSessionContextOptions {
50
50
  */
51
51
  keepDanglingToolCalls?: boolean;
52
52
  }
53
+ /**
54
+ * Display-only marker set on transcript assistant messages whose dangling
55
+ * `toolCall` blocks were stripped (no paired result on the resolved path —
56
+ * failed/retried turns, results on sibling branches). The TUI renders a
57
+ * placeholder row from it so the turn's activity never silently vanishes.
58
+ */
59
+ export interface StrippedToolCallsMarker {
60
+ strippedToolCalls?: number;
61
+ }
53
62
  export declare function buildSessionContext(entries: SessionEntry[], leafId?: string | null, byId?: Map<string, SessionEntry>, options?: BuildSessionContextOptions): SessionContext;
@@ -77,6 +77,12 @@ export interface CompactionEntry<T = unknown> extends SessionEntryBase {
77
77
  preserveData?: Record<string, unknown>;
78
78
  /** True if generated by an extension, undefined/false if pi-generated (backward compatible) */
79
79
  fromExtension?: boolean;
80
+ /**
81
+ * Dead-end warning from the post-pass progress guard: the pass completed
82
+ * but freed too little for maintenance to continue. Rendered on the
83
+ * compaction divider.
84
+ */
85
+ warning?: string;
80
86
  }
81
87
  export interface BranchSummaryEntry<T = unknown> extends SessionEntryBase {
82
88
  type: "branch_summary";
@@ -9,11 +9,11 @@ export interface ThinkingLevelMetadata {
9
9
  description: string;
10
10
  }
11
11
  /**
12
- * Parses a provider-facing effort value.
12
+ * Parses a provider-facing effort value. Accepts unambiguous abbreviations.
13
13
  */
14
14
  export declare function parseEffort(value: string | null | undefined): Effort | undefined;
15
15
  /**
16
- * Parses an agent-local thinking selector.
16
+ * Parses an agent-local thinking selector. Accepts unambiguous abbreviations.
17
17
  */
18
18
  export declare function parseThinkingLevel(value: string | null | undefined): ThinkingLevel | undefined;
19
19
  /**
@@ -1,4 +1,4 @@
1
- /** Default session-title model: the online pi/smol path (no local download / on-device inference). */
1
+ /** Default session-title model: the online @smol path (no local download / on-device inference). */
2
2
  export declare const ONLINE_TINY_TITLE_MODEL_KEY = "online";
3
3
  /** Local model the `tiny-models` CLI downloads when none is named. Not the session-title default — that is {@link ONLINE_TINY_TITLE_MODEL_KEY}. */
4
4
  export declare const DEFAULT_TINY_TITLE_LOCAL_MODEL_KEY = "lfm2-700m";
@@ -13,6 +13,7 @@ export declare const DEFAULT_VIEWPORT: {
13
13
  export declare const BROWSER_PROTOCOL_TIMEOUT_MS = 60000;
14
14
  export declare function loadPuppeteer(): Promise<typeof Puppeteer>;
15
15
  export declare function loadPuppeteerInWorker(safeDir: string): Promise<typeof Puppeteer>;
16
+ export declare function ensureChromiumExecutable(): Promise<string | undefined>;
16
17
  export interface LaunchHeadlessOptions {
17
18
  headless: boolean;
18
19
  viewport?: {
@@ -9,7 +9,33 @@
9
9
  * that do await it still receive the rejection.
10
10
  */
11
11
  export declare function markHandled<T>(promise: Promise<T>): Promise<T>;
12
- /** Sleeps inside evaluated browser code while honoring the owning run's cancellation signal. */
13
- export declare function waitForBrowserRun(ms: number, signal: AbortSignal): Promise<void>;
12
+ /** Headroom subtracted from the cell budget so an in-run deadline fires before the opaque whole-cell timeout. */
13
+ export declare const CELL_BUDGET_SLACK_MS = 1000;
14
+ /** Default poll deadline for `wait(predicate)` before clamping to the cell budget. */
15
+ export declare const DEFAULT_PREDICATE_TIMEOUT_MS = 30000;
16
+ /** Options for the predicate form of the run-scoped `wait()` helper. */
17
+ export interface WaitPredicateOptions {
18
+ /** Max time to poll before failing, in ms (default 30s, clamped to the cell budget). */
19
+ timeout?: number;
20
+ /** Poll interval in ms (default 100, floor 10). */
21
+ interval?: number;
22
+ }
23
+ /**
24
+ * Effective `wait(predicate)` deadline for a given cell budget. Always strictly below
25
+ * the cell budget so the named `wait(predicate) timed out` error wins the race against
26
+ * the opaque whole-cell "Browser code execution timed out". `0`/`Infinity` ("disable")
27
+ * map to the largest bounded deadline; negative/NaN garbage falls back to the default.
28
+ */
29
+ export declare function resolvePredicateTimeout(cellTimeoutMs: number, explicit?: number): number;
30
+ /**
31
+ * Run-scoped `wait()` helper for evaluated browser code, honoring the owning run's
32
+ * cancellation signal.
33
+ *
34
+ * - `wait(ms)` sleeps for `ms` milliseconds.
35
+ * - `wait(fn, { timeout?, interval? })` polls `fn` (sync or async) until it returns a
36
+ * truthy value and resolves with that value; throws a named `ToolError` on timeout
37
+ * instead of stalling into the whole-cell deadline. Predicate errors propagate.
38
+ */
39
+ export declare function waitForBrowserRun(msOrPredicate: number | (() => unknown), signal: AbortSignal, opts?: WaitPredicateOptions): Promise<unknown>;
14
40
  /** Binds a long-lived browser facade to one evaluated run's abort signal. */
15
41
  export declare function bindBrowserRunFacade<T extends object>(target: T, signal: AbortSignal): T;
@@ -59,6 +59,12 @@ export type WorkerInitPayload = {
59
59
  safeDir: string;
60
60
  targetId: string;
61
61
  dialogs?: "accept" | "dismiss";
62
+ /**
63
+ * Post-timeout recycle: before adopting the page, dismiss any open JS dialog and
64
+ * stop a pending navigation so a blocked target cannot stall worker init (which
65
+ * previously force-killed the tab). Never set for first-time Electron attach.
66
+ */
67
+ recover?: boolean;
62
68
  };
63
69
  export type ToolReply = {
64
70
  ok: true;
@@ -1,6 +1,12 @@
1
1
  import type { HTMLElement } from "linkedom";
2
2
  import type { ElementHandle, ImageFormat } from "puppeteer-core";
3
3
  import type { Transport } from "./tab-protocol.js";
4
+ declare module "puppeteer-core" {
5
+ interface Frame {
6
+ /** Puppeteer's main JavaScript realm, retained by our pinned runtime patch. */
7
+ mainRealm(): Realm;
8
+ }
9
+ }
4
10
  declare global {
5
11
  interface Element extends HTMLElement {
6
12
  }
@@ -1,4 +1,4 @@
1
- export declare const BUILTIN_TOOL_NAMES: readonly ["read", "bash", "edit", "ast_grep", "ast_edit", "ask", "debug", "eval", "ssh", "github", "glob", "grep", "lsp", "inspect_image", "browser", "checkpoint", "rewind", "task", "job", "irc", "todo", "web_search", "search_tool_bm25", "write", "memory_edit", "retain", "recall", "reflect", "learn", "manage_skill"];
1
+ export declare const BUILTIN_TOOL_NAMES: readonly ["read", "bash", "launch", "edit", "ast_grep", "ast_edit", "ask", "debug", "eval", "ssh", "github", "glob", "grep", "lsp", "inspect_image", "browser", "checkpoint", "rewind", "task", "job", "irc", "todo", "web_search", "search_tool_bm25", "write", "memory_edit", "retain", "recall", "reflect", "learn", "manage_skill"];
2
2
  export type BuiltinToolName = (typeof BUILTIN_TOOL_NAMES)[number];
3
3
  /** Return the canonical tool name for current and legacy built-in tool IDs. */
4
4
  export declare function normalizeToolName(name: string): string;
@@ -48,6 +48,7 @@ export * from "./image-gen.js";
48
48
  export * from "./inspect-image.js";
49
49
  export * from "./irc.js";
50
50
  export * from "./job.js";
51
+ export * from "./launch.js";
51
52
  export * from "./learn.js";
52
53
  export * from "./manage-skill.js";
53
54
  export * from "./memory-edit.js";
@@ -0,0 +1,121 @@
1
+ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback, ToolApprovalDecision } from "@oh-my-pi/pi-agent-core";
2
+ import type { ToolExample } from "@oh-my-pi/pi-ai";
3
+ import type { Component } from "@oh-my-pi/pi-tui";
4
+ import type { RenderResultOptions } from "../extensibility/custom-tools/types.js";
5
+ import type { DaemonSnapshot, DaemonSpec, DaemonState } from "../launch/protocol.js";
6
+ import type { Theme } from "../modes/theme/theme.js";
7
+ import type { ToolSession } from "./index.js";
8
+ declare const launchSchema: import("arktype/internal/variants/object.ts").ObjectType<{
9
+ op: "describe" | "list" | "logs" | "restart" | "send" | "start" | "stop" | "wait";
10
+ name?: string | undefined;
11
+ application?: string | undefined;
12
+ args?: string[] | undefined;
13
+ env?: {
14
+ [x: string]: string;
15
+ } | undefined;
16
+ cwd?: string | undefined;
17
+ pty?: boolean | undefined;
18
+ ready?: {
19
+ log?: string | undefined;
20
+ port?: number | undefined;
21
+ host?: string | undefined;
22
+ timeout?: number | undefined;
23
+ } | undefined;
24
+ restart?: "always" | "no" | "on-failure" | undefined;
25
+ persist?: boolean | undefined;
26
+ detached?: boolean | undefined;
27
+ lines?: number | undefined;
28
+ head?: boolean | undefined;
29
+ grep?: string | undefined;
30
+ follow?: boolean | undefined;
31
+ cursor?: number | undefined;
32
+ for?: "exit" | "ready" | undefined;
33
+ pattern?: string | undefined;
34
+ text?: string | undefined;
35
+ enter?: boolean | undefined;
36
+ keys?: string[] | undefined;
37
+ signal?: "SIGHUP" | "SIGINT" | "SIGKILL" | "SIGQUIT" | "SIGTERM" | undefined;
38
+ timeout?: number | undefined;
39
+ }, {}>;
40
+ type LaunchParams = typeof launchSchema.infer;
41
+ /** Structured launch state retained for compact TUI rendering. */
42
+ export interface LaunchToolDetails {
43
+ op: LaunchParams["op"];
44
+ daemon?: DaemonSnapshot;
45
+ daemons?: DaemonSnapshot[];
46
+ cursor?: number;
47
+ timedOut?: boolean;
48
+ /** logs: daemon lifecycle state at read time. */
49
+ state?: DaemonState;
50
+ /** logs: virtual terminal rows for display; model-facing content remains sanitized text. */
51
+ terminalRows?: string[];
52
+ /** wait: output line that satisfied the pattern. */
53
+ matched?: string;
54
+ /** describe: immutable launch spec backing the command/cwd detail lines. */
55
+ spec?: DaemonSpec;
56
+ }
57
+ declare function approvalFor(params: unknown): ToolApprovalDecision;
58
+ /** Project-scoped launch tool for supervising processes in every coding-agent session. */
59
+ export declare class LaunchTool implements AgentTool<typeof launchSchema, LaunchToolDetails, Theme> {
60
+ private readonly session;
61
+ readonly name = "launch";
62
+ readonly label = "Launch";
63
+ readonly loadMode = "essential";
64
+ readonly summary = "Launch and control shared long-running project processes";
65
+ readonly description: string;
66
+ readonly parameters: import("arktype/internal/variants/object.ts").ObjectType<{
67
+ op: "describe" | "list" | "logs" | "restart" | "send" | "start" | "stop" | "wait";
68
+ name?: string | undefined;
69
+ application?: string | undefined;
70
+ args?: string[] | undefined;
71
+ env?: {
72
+ [x: string]: string;
73
+ } | undefined;
74
+ cwd?: string | undefined;
75
+ pty?: boolean | undefined;
76
+ ready?: {
77
+ log?: string | undefined;
78
+ port?: number | undefined;
79
+ host?: string | undefined;
80
+ timeout?: number | undefined;
81
+ } | undefined;
82
+ restart?: "always" | "no" | "on-failure" | undefined;
83
+ persist?: boolean | undefined;
84
+ detached?: boolean | undefined;
85
+ lines?: number | undefined;
86
+ head?: boolean | undefined;
87
+ grep?: string | undefined;
88
+ follow?: boolean | undefined;
89
+ cursor?: number | undefined;
90
+ for?: "exit" | "ready" | undefined;
91
+ pattern?: string | undefined;
92
+ text?: string | undefined;
93
+ enter?: boolean | undefined;
94
+ keys?: string[] | undefined;
95
+ signal?: "SIGHUP" | "SIGINT" | "SIGKILL" | "SIGQUIT" | "SIGTERM" | undefined;
96
+ timeout?: number | undefined;
97
+ }, {}>;
98
+ readonly strict = true;
99
+ readonly examples: readonly ToolExample<LaunchParams>[];
100
+ readonly approval: typeof approvalFor;
101
+ constructor(session: ToolSession);
102
+ execute(_toolCallId: string, params: LaunchParams, signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<LaunchToolDetails, typeof launchSchema>, _context?: AgentToolContext): Promise<AgentToolResult<LaunchToolDetails>>;
103
+ }
104
+ /** Args shape visible to the renderer, possibly mid-stream (every field optional). */
105
+ type LaunchRenderArgs = Partial<LaunchParams>;
106
+ /** TUI renderer: one status header per op, meta from structured details, capped body lines. */
107
+ export declare const launchToolRenderer: {
108
+ inline: boolean;
109
+ mergeCallAndResult: boolean;
110
+ animatedPendingPreview: boolean;
111
+ renderCall(args: LaunchRenderArgs, options: RenderResultOptions, theme: Theme): Component;
112
+ renderResult(result: {
113
+ content: Array<{
114
+ type: string;
115
+ text?: string;
116
+ }>;
117
+ details?: LaunchToolDetails;
118
+ isError?: boolean;
119
+ }, options: RenderResultOptions, theme: Theme, args?: LaunchRenderArgs): Component;
120
+ };
121
+ export {};
@@ -33,6 +33,8 @@ export declare const PREVIEW_LIMITS: {
33
33
  /** Max diff lines shown when collapsed (edit tool) */
34
34
  readonly DIFF_COLLAPSED_LINES: 40;
35
35
  };
36
+ /** Default number of terminal output rows shown before expansion. */
37
+ export declare const DEFAULT_TERMINAL_PREVIEW_LINES = 10;
36
38
  /** Truncation lengths for different content types */
37
39
  export declare const TRUNCATE_LENGTHS: {
38
40
  /** Short titles, labels */
@@ -0,0 +1,5 @@
1
+ import type { Terminal as XtermTerminal } from "@xterm/headless";
2
+ /** Applies the active tool-output color while preserving safe styles from a virtual terminal row. */
3
+ export declare function styleTerminalRow(row: string, baseForeground: string): string;
4
+ /** Reads terminal screen rows as sanitized text plus only the styles the TUI may replay. */
5
+ export declare function readTerminalRows(terminal: XtermTerminal, startRow: number, rowCount: number): string[];
@@ -4,8 +4,8 @@ import type { ToolSession } from "../tools/index.js";
4
4
  export type VibeCli = "fast" | "good";
5
5
  /**
6
6
  * CLI flavor → bundled agent type. This IS the model-tier mapping: `sonic`
7
- * carries `model: "pi/smol"` (the configured fast/low-latency role) and `task`
8
- * carries `model: "pi/task"` (inherits the session's strong model).
7
+ * carries `model: "@smol"` (the configured fast/low-latency role) and `task`
8
+ * carries `model: "@task"` (inherits the session's strong model).
9
9
  * Resolution goes through {@link resolveAgentModelPatterns} exactly like a
10
10
  * `task` spawn, so `task.agentModelOverrides` and model-role settings apply.
11
11
  */
@@ -83,14 +83,6 @@ export declare const SEARCH_PROVIDER_OPTIONS: readonly [{
83
83
  readonly value: "duckduckgo";
84
84
  readonly label: "DuckDuckGo";
85
85
  readonly description: "Credential-free best-effort fallback; may be bot-challenged on datacenter/shared-egress IPs";
86
- }, {
87
- readonly value: "bing";
88
- readonly label: "Bing";
89
- readonly description: "Credential-free HTML scrape of Bing results; may be bot-challenged";
90
- }, {
91
- readonly value: "yahoo";
92
- readonly label: "Yahoo";
93
- readonly description: "Credential-free HTML scrape of Yahoo (Bing-backed) results";
94
86
  }, {
95
87
  readonly value: "ecosia";
96
88
  readonly label: "Ecosia";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-coding-agent",
4
- "version": "16.4.8",
4
+ "version": "16.5.0",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -49,39 +49,39 @@
49
49
  "bench:guard": "bun scripts/bench-guard.ts"
50
50
  },
51
51
  "dependencies": {
52
- "@agentclientprotocol/sdk": "0.25.0",
52
+ "@agentclientprotocol/sdk": "1.2.1",
53
53
  "@babel/parser": "^7.29.7",
54
54
  "@mozilla/readability": "^0.6.0",
55
- "@oh-my-pi/hashline": "16.4.8",
56
- "@oh-my-pi/omp-stats": "16.4.8",
57
- "@oh-my-pi/pi-agent-core": "16.4.8",
58
- "@oh-my-pi/pi-ai": "16.4.8",
59
- "@oh-my-pi/pi-catalog": "16.4.8",
60
- "@oh-my-pi/pi-mnemopi": "16.4.8",
61
- "@oh-my-pi/pi-natives": "16.4.8",
62
- "@oh-my-pi/pi-tui": "16.4.8",
63
- "@oh-my-pi/pi-utils": "16.4.8",
64
- "@oh-my-pi/pi-wire": "16.4.8",
65
- "@oh-my-pi/snapcompact": "16.4.8",
55
+ "@oh-my-pi/hashline": "16.5.0",
56
+ "@oh-my-pi/omp-stats": "16.5.0",
57
+ "@oh-my-pi/pi-agent-core": "16.5.0",
58
+ "@oh-my-pi/pi-ai": "16.5.0",
59
+ "@oh-my-pi/pi-catalog": "16.5.0",
60
+ "@oh-my-pi/pi-mnemopi": "16.5.0",
61
+ "@oh-my-pi/pi-natives": "16.5.0",
62
+ "@oh-my-pi/pi-tui": "16.5.0",
63
+ "@oh-my-pi/pi-utils": "16.5.0",
64
+ "@oh-my-pi/pi-wire": "16.5.0",
65
+ "@oh-my-pi/snapcompact": "16.5.0",
66
66
  "@opentelemetry/api": "^1.9.1",
67
67
  "@opentelemetry/context-async-hooks": "^2.7.1",
68
- "@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
68
+ "@opentelemetry/exporter-trace-otlp-proto": "^0.220.0",
69
69
  "@opentelemetry/resources": "^2.7.1",
70
70
  "@opentelemetry/sdk-trace-base": "^2.7.1",
71
71
  "@opentelemetry/sdk-trace-node": "^2.7.1",
72
- "@puppeteer/browsers": "^3.0.4",
72
+ "@puppeteer/browsers": "^3.0.6",
73
73
  "@types/turndown": "5.0.6",
74
74
  "@xterm/headless": "^6.0.0",
75
- "arktype": "2.2.2",
75
+ "arktype": "2.2.3",
76
76
  "chalk": "^5.6.2",
77
77
  "diff": "^9.0.0",
78
- "fast-xml-parser": "^5.9.0",
78
+ "fast-xml-parser": "^5.9.3",
79
79
  "handlebars": "^4.7.9",
80
80
  "header-generator": "^2.1.82",
81
- "linkedom": "^0.18.12",
82
- "lru-cache": "11.5.1",
81
+ "linkedom": "^0.18.13",
82
+ "lru-cache": "11.5.2",
83
83
  "mammoth": "^1.12.0",
84
- "mupdf": "^1.27.0",
84
+ "mupdf": "^1.28.0",
85
85
  "puppeteer-core": "25.3.0",
86
86
  "turndown": "7.2.4",
87
87
  "turndown-plugin-gfm": "1.0.2",
package/src/cli/args.ts CHANGED
@@ -27,6 +27,11 @@ export interface Args {
27
27
  smol?: string;
28
28
  slow?: string;
29
29
  plan?: string;
30
+ prewalk?: boolean;
31
+ noPrewalk?: boolean;
32
+ prewalkInto?: string;
33
+ planYolo?: boolean;
34
+ planYoloInto?: string;
30
35
  maxTime?: number;
31
36
  apiKey?: string;
32
37
  systemPrompt?: string;
@@ -231,6 +236,12 @@ export function parseArgs(inputArgs: string[], extensionFlags?: Map<string, { ty
231
236
  result.hideThinking = true;
232
237
  } else if (arg === "--advisor") {
233
238
  result.advisor = true;
239
+ } else if (arg === "--prewalk") {
240
+ result.prewalk = true;
241
+ } else if (arg === "--no-prewalk") {
242
+ result.noPrewalk = true;
243
+ } else if (arg === "--plan-yolo") {
244
+ result.planYolo = true;
234
245
  } else if (arg === "--print" || arg === "-p") {
235
246
  result.print = true;
236
247
  } else if (arg === "--print-thoughts") {
@@ -121,6 +121,12 @@ export const STRING_SETTERS: Record<string, StringSetter> = {
121
121
  "--plan": (result, value) => {
122
122
  result.plan = value;
123
123
  },
124
+ "--prewalk-into": (result, value) => {
125
+ result.prewalkInto = value;
126
+ },
127
+ "--plan-yolo-into": (result, value) => {
128
+ result.planYoloInto = value;
129
+ },
124
130
  "--max-time": (result, value, deps) => {
125
131
  const seconds = Number(value);
126
132
  if (Number.isFinite(seconds) && seconds > 0) {
@@ -275,6 +281,9 @@ export const VALUELESS_FLAGS: ReadonlySet<string> = new Set([
275
281
  "--no-pty",
276
282
  "--hide-thinking",
277
283
  "--advisor",
284
+ "--prewalk",
285
+ "--no-prewalk",
286
+ "--plan-yolo",
278
287
  "--print",
279
288
  "--print-thoughts",
280
289
  "--no-extensions",