@oh-my-pi/pi-coding-agent 16.1.23 → 16.2.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 (254) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/cli.js +3817 -3735
  3. package/dist/types/advisor/__tests__/emission-guard.test.d.ts +1 -0
  4. package/dist/types/advisor/emission-guard.d.ts +73 -0
  5. package/dist/types/advisor/index.d.ts +1 -0
  6. package/dist/types/advisor/runtime.d.ts +7 -0
  7. package/dist/types/advisor/watchdog.d.ts +2 -0
  8. package/dist/types/cli/flag-tables.d.ts +1 -0
  9. package/dist/types/cli/gallery-fixtures/search.d.ts +1 -1
  10. package/dist/types/collab/display-name.d.ts +3 -0
  11. package/dist/types/collab/host.d.ts +0 -2
  12. package/dist/types/commands/worktree.d.ts +0 -3
  13. package/dist/types/config/inline-tool-descriptors-mode.d.ts +13 -0
  14. package/dist/types/config/model-discovery.d.ts +6 -1
  15. package/dist/types/config/model-registry.d.ts +6 -2
  16. package/dist/types/config/model-resolver.d.ts +12 -0
  17. package/dist/types/config/models-config-schema.d.ts +29 -2
  18. package/dist/types/config/models-config.d.ts +22 -1
  19. package/dist/types/config/settings-schema.d.ts +91 -21
  20. package/dist/types/config/settings.d.ts +2 -0
  21. package/dist/types/dap/config.d.ts +1 -1
  22. package/dist/types/edit/hashline/filesystem.d.ts +4 -2
  23. package/dist/types/edit/renderer.d.ts +4 -0
  24. package/dist/types/extensibility/extensions/types.d.ts +17 -17
  25. package/dist/types/extensibility/hooks/types.d.ts +10 -10
  26. package/dist/types/extensibility/plugins/marketplace/types.d.ts +1 -0
  27. package/dist/types/internal-urls/__tests__/ssh-protocol.test.d.ts +1 -0
  28. package/dist/types/internal-urls/index.d.ts +1 -0
  29. package/dist/types/internal-urls/registry-helpers.d.ts +2 -0
  30. package/dist/types/internal-urls/router.d.ts +1 -1
  31. package/dist/types/internal-urls/ssh-protocol.d.ts +10 -0
  32. package/dist/types/internal-urls/types.d.ts +19 -2
  33. package/dist/types/irc/bus.d.ts +6 -0
  34. package/dist/types/modes/components/__tests__/move-overlay.test.d.ts +1 -0
  35. package/dist/types/modes/components/custom-editor.d.ts +7 -0
  36. package/dist/types/modes/components/move-overlay.d.ts +23 -0
  37. package/dist/types/modes/components/plugin-selector.d.ts +2 -1
  38. package/dist/types/modes/components/queue-mode-selector.d.ts +2 -1
  39. package/dist/types/modes/components/select-list-mouse-routing.d.ts +2 -0
  40. package/dist/types/modes/components/settings-defs.d.ts +4 -1
  41. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  42. package/dist/types/modes/components/show-images-selector.d.ts +2 -1
  43. package/dist/types/modes/components/status-line/component.d.ts +2 -0
  44. package/dist/types/modes/components/status-line/types.d.ts +2 -0
  45. package/dist/types/modes/components/theme-selector.d.ts +2 -1
  46. package/dist/types/modes/components/thinking-selector.d.ts +2 -1
  47. package/dist/types/modes/controllers/command-controller.d.ts +10 -1
  48. package/dist/types/modes/controllers/streaming-reveal.d.ts +6 -0
  49. package/dist/types/modes/interactive-mode.d.ts +10 -1
  50. package/dist/types/modes/internal-url-autocomplete.d.ts +1 -1
  51. package/dist/types/modes/running-subagent-badge.d.ts +6 -0
  52. package/dist/types/modes/theme/theme.d.ts +1 -1
  53. package/dist/types/modes/types.d.ts +9 -1
  54. package/dist/types/sdk.d.ts +2 -2
  55. package/dist/types/session/agent-session.d.ts +2 -1
  56. package/dist/types/session/session-manager.d.ts +13 -0
  57. package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
  58. package/dist/types/ssh/__tests__/connection-manager-args.test.d.ts +1 -0
  59. package/dist/types/ssh/__tests__/file-transfer-posix-guard.test.d.ts +1 -0
  60. package/dist/types/ssh/connection-manager.d.ts +2 -0
  61. package/dist/types/ssh/file-transfer.d.ts +79 -0
  62. package/dist/types/ssh/utils.d.ts +6 -0
  63. package/dist/types/system-prompt.d.ts +3 -0
  64. package/dist/types/task/executor.d.ts +16 -0
  65. package/dist/types/tiny/text.d.ts +1 -1
  66. package/dist/types/tools/builtin-names.d.ts +5 -1
  67. package/dist/types/tools/{find.d.ts → glob.d.ts} +15 -15
  68. package/dist/types/tools/{search.d.ts → grep.d.ts} +14 -14
  69. package/dist/types/tools/index.d.ts +3 -3
  70. package/dist/types/tools/path-utils.d.ts +29 -0
  71. package/dist/types/tools/read.d.ts +2 -2
  72. package/dist/types/tools/render-utils.d.ts +8 -0
  73. package/dist/types/tools/renderers.d.ts +11 -0
  74. package/dist/types/tools/ssh.d.ts +2 -0
  75. package/dist/types/tools/todo.d.ts +0 -16
  76. package/dist/types/tools/write.d.ts +2 -2
  77. package/dist/types/utils/active-repo-context.d.ts +8 -0
  78. package/dist/types/utils/image-resize.d.ts +1 -0
  79. package/dist/types/utils/markit-cache.d.ts +23 -0
  80. package/dist/types/utils/markit.d.ts +5 -1
  81. package/dist/types/utils/prompt-path.d.ts +1 -0
  82. package/dist/types/web/search/providers/duckduckgo.d.ts +14 -0
  83. package/dist/types/web/search/providers/firecrawl.d.ts +28 -0
  84. package/dist/types/web/search/providers/tinyfish.d.ts +29 -0
  85. package/dist/types/web/search/providers/xai.d.ts +13 -0
  86. package/dist/types/web/search/types.d.ts +18 -2
  87. package/package.json +30 -15
  88. package/scripts/build-binary.ts +9 -9
  89. package/scripts/bundle-dist.ts +2 -2
  90. package/src/advisor/__tests__/advisor.test.ts +40 -4
  91. package/src/advisor/__tests__/emission-guard.test.ts +147 -0
  92. package/src/advisor/advise-tool.ts +1 -1
  93. package/src/advisor/emission-guard.ts +172 -0
  94. package/src/advisor/index.ts +1 -0
  95. package/src/advisor/runtime.ts +11 -0
  96. package/src/advisor/watchdog.ts +12 -1
  97. package/src/cli/args.ts +5 -2
  98. package/src/cli/auth-broker-cli.ts +17 -0
  99. package/src/cli/config-cli.ts +4 -0
  100. package/src/cli/flag-tables.ts +7 -4
  101. package/src/cli/gallery-cli.ts +14 -2
  102. package/src/cli/gallery-fixtures/edit.ts +60 -0
  103. package/src/cli/gallery-fixtures/fs.ts +17 -17
  104. package/src/cli/gallery-fixtures/search.ts +4 -4
  105. package/src/cli/usage-cli.ts +20 -1
  106. package/src/cli/web-search-cli.ts +1 -1
  107. package/src/collab/display-name.ts +13 -0
  108. package/src/collab/guest.ts +5 -1
  109. package/src/collab/host.ts +2 -13
  110. package/src/commands/worktree.ts +6 -0
  111. package/src/config/inline-tool-descriptors-mode.ts +27 -0
  112. package/src/config/model-discovery.ts +77 -8
  113. package/src/config/model-registry.ts +89 -11
  114. package/src/config/model-resolver.ts +39 -1
  115. package/src/config/models-config-schema.ts +41 -5
  116. package/src/config/models-config.ts +4 -1
  117. package/src/config/settings-schema.ts +85 -27
  118. package/src/config/settings.ts +172 -1
  119. package/src/cursor.ts +1 -1
  120. package/src/dap/config.ts +152 -8
  121. package/src/dap/session.ts +1 -1
  122. package/src/discovery/helpers.ts +3 -1
  123. package/src/edit/hashline/diff.ts +14 -3
  124. package/src/edit/hashline/execute.ts +42 -6
  125. package/src/edit/hashline/filesystem.ts +38 -2
  126. package/src/edit/index.ts +1 -0
  127. package/src/edit/modes/patch.ts +11 -1
  128. package/src/edit/renderer.ts +140 -13
  129. package/src/eval/__tests__/agent-bridge.test.ts +101 -0
  130. package/src/eval/agent-bridge.ts +26 -3
  131. package/src/eval/js/tool-bridge.ts +2 -2
  132. package/src/export/html/index.ts +1 -1
  133. package/src/export/html/template.js +3 -1
  134. package/src/export/html/tool-views.generated.js +20 -20
  135. package/src/extensibility/extensions/types.ts +22 -22
  136. package/src/extensibility/hooks/types.ts +11 -11
  137. package/src/extensibility/plugins/legacy-pi-bundled-keys.ts +8 -3
  138. package/src/extensibility/plugins/legacy-pi-bundled-registry.ts +25 -10
  139. package/src/extensibility/plugins/marketplace/manager.ts +22 -0
  140. package/src/extensibility/plugins/marketplace/types.ts +1 -0
  141. package/src/internal-urls/__tests__/ssh-protocol.test.ts +331 -0
  142. package/src/internal-urls/docs-index.generated.txt +2 -2
  143. package/src/internal-urls/docs-index.ts +2 -3
  144. package/src/internal-urls/index.ts +1 -0
  145. package/src/internal-urls/registry-helpers.ts +19 -4
  146. package/src/internal-urls/router.ts +5 -3
  147. package/src/internal-urls/ssh-protocol.ts +367 -0
  148. package/src/internal-urls/types.ts +19 -2
  149. package/src/irc/bus.ts +11 -3
  150. package/src/mcp/tool-bridge.ts +32 -2
  151. package/src/memories/index.ts +1 -1
  152. package/src/modes/acp/acp-event-mapper.ts +2 -2
  153. package/src/modes/components/__tests__/move-overlay.test.ts +166 -0
  154. package/src/modes/components/agent-hub.ts +3 -0
  155. package/src/modes/components/agent-transcript-viewer.ts +9 -7
  156. package/src/modes/components/custom-editor.ts +90 -5
  157. package/src/modes/components/move-overlay.ts +282 -0
  158. package/src/modes/components/plan-review-overlay.ts +35 -35
  159. package/src/modes/components/plugin-selector.ts +6 -1
  160. package/src/modes/components/queue-mode-selector.ts +6 -1
  161. package/src/modes/components/select-list-mouse-routing.ts +35 -0
  162. package/src/modes/components/session-selector.ts +11 -10
  163. package/src/modes/components/settings-defs.ts +14 -1
  164. package/src/modes/components/settings-selector.ts +196 -29
  165. package/src/modes/components/show-images-selector.ts +6 -1
  166. package/src/modes/components/status-line/component.ts +108 -28
  167. package/src/modes/components/status-line/segments.ts +5 -1
  168. package/src/modes/components/status-line/types.ts +2 -0
  169. package/src/modes/components/theme-selector.ts +6 -1
  170. package/src/modes/components/thinking-selector.ts +6 -1
  171. package/src/modes/components/tool-execution.ts +25 -9
  172. package/src/modes/components/tree-selector.ts +5 -5
  173. package/src/modes/controllers/command-controller.ts +140 -47
  174. package/src/modes/controllers/event-controller.ts +59 -3
  175. package/src/modes/controllers/input-controller.ts +68 -2
  176. package/src/modes/controllers/selector-controller.ts +5 -2
  177. package/src/modes/controllers/streaming-reveal.ts +17 -0
  178. package/src/modes/controllers/tool-args-reveal.ts +1 -1
  179. package/src/modes/interactive-mode.ts +116 -50
  180. package/src/modes/internal-url-autocomplete.ts +17 -2
  181. package/src/modes/prompt-action-autocomplete.ts +3 -1
  182. package/src/modes/running-subagent-badge.ts +13 -0
  183. package/src/modes/setup-wizard/scenes/glyph.ts +2 -13
  184. package/src/modes/setup-wizard/scenes/providers.ts +2 -1
  185. package/src/modes/setup-wizard/scenes/theme.ts +6 -12
  186. package/src/modes/setup-wizard/scenes/web-search.ts +8 -13
  187. package/src/modes/setup-wizard/wizard-overlay.ts +6 -5
  188. package/src/modes/theme/theme.ts +9 -1
  189. package/src/modes/types.ts +9 -1
  190. package/src/modes/utils/interactive-context-helpers.ts +1 -1
  191. package/src/priority.json +15 -0
  192. package/src/prompts/advisor/active-repo-watchdog.md +6 -0
  193. package/src/prompts/advisor/system.md +21 -7
  194. package/src/prompts/agents/designer.md +1 -1
  195. package/src/prompts/agents/explore.md +1 -1
  196. package/src/prompts/agents/librarian.md +2 -2
  197. package/src/prompts/agents/plan.md +2 -2
  198. package/src/prompts/agents/reviewer.md +1 -1
  199. package/src/prompts/agents/task.md +2 -2
  200. package/src/prompts/system/active-repo-context.md +4 -0
  201. package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
  202. package/src/prompts/system/plan-mode-active.md +3 -3
  203. package/src/prompts/system/project-prompt.md +2 -2
  204. package/src/prompts/system/system-prompt.md +6 -6
  205. package/src/prompts/tools/bash.md +2 -2
  206. package/src/prompts/tools/checkpoint.md +1 -1
  207. package/src/prompts/tools/{find.md → glob.md} +1 -1
  208. package/src/prompts/tools/{search.md → grep.md} +3 -3
  209. package/src/prompts/tools/read.md +4 -2
  210. package/src/sdk.ts +55 -25
  211. package/src/session/agent-session.ts +508 -132
  212. package/src/session/session-history-format.ts +2 -2
  213. package/src/session/session-manager.ts +46 -0
  214. package/src/slash-commands/builtin-registry.ts +138 -20
  215. package/src/slash-commands/helpers/usage-report.ts +23 -2
  216. package/src/ssh/__tests__/connection-manager-args.test.ts +69 -0
  217. package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +68 -0
  218. package/src/ssh/connection-manager.ts +12 -15
  219. package/src/ssh/file-transfer.ts +209 -0
  220. package/src/ssh/utils.ts +24 -0
  221. package/src/system-prompt.ts +56 -28
  222. package/src/task/executor.ts +96 -36
  223. package/src/task/index.ts +3 -3
  224. package/src/task/render.ts +14 -13
  225. package/src/task/worktree.ts +38 -1
  226. package/src/tiny/text.ts +49 -4
  227. package/src/tiny/worker.ts +3 -3
  228. package/src/tools/bash.ts +2 -2
  229. package/src/tools/builtin-names.ts +26 -2
  230. package/src/tools/{find.ts → glob.ts} +48 -42
  231. package/src/tools/{search.ts → grep.ts} +311 -129
  232. package/src/tools/index.ts +13 -14
  233. package/src/tools/irc.ts +6 -2
  234. package/src/tools/path-utils.ts +64 -1
  235. package/src/tools/read.ts +35 -6
  236. package/src/tools/render-utils.ts +14 -0
  237. package/src/tools/renderers.ts +15 -4
  238. package/src/tools/ssh.ts +17 -2
  239. package/src/tools/todo.ts +4 -26
  240. package/src/tools/write.ts +25 -9
  241. package/src/utils/active-repo-context.ts +143 -0
  242. package/src/utils/image-resize.ts +88 -7
  243. package/src/utils/lang-from-path.ts +3 -3
  244. package/src/utils/markit-cache.ts +166 -0
  245. package/src/utils/markit.ts +86 -18
  246. package/src/utils/prompt-path.ts +3 -0
  247. package/src/utils/title-generator.ts +1 -1
  248. package/src/web/search/provider.ts +54 -34
  249. package/src/web/search/providers/duckduckgo.ts +140 -0
  250. package/src/web/search/providers/firecrawl.ts +144 -0
  251. package/src/web/search/providers/tinyfish.ts +159 -0
  252. package/src/web/search/providers/xai.ts +292 -0
  253. package/src/web/search/providers/zai.ts +142 -56
  254. package/src/web/search/types.ts +6 -2
@@ -86,6 +86,7 @@ import planModeApprovedPrompt from "../prompts/system/plan-mode-approved.md" wit
86
86
  import planModeCompactInstructionsPrompt from "../prompts/system/plan-mode-compact-instructions.md" with {
87
87
  type: "text",
88
88
  };
89
+ import type { AgentRegistry } from "../registry/agent-registry";
89
90
  import type { AgentSession, AgentSessionEvent, ResolvedRoleModel } from "../session/agent-session";
90
91
  import type { CompactMode } from "../session/compact-modes";
91
92
  import { HistoryStorage } from "../session/history-storage";
@@ -104,9 +105,10 @@ import { normalizeLocalScheme } from "../tools/path-utils";
104
105
  import { replaceTabs, TRUNCATE_LENGTHS, truncateToWidth } from "../tools/render-utils";
105
106
  import { setAutoQaConsentHandler } from "../tools/report-tool-issue";
106
107
  import { type ResolveToolDetails, runResolveInvocation } from "../tools/resolve";
107
- import { formatPhaseDisplayName, selectStickyTodoWindow, todoMatchesAnyDescription } from "../tools/todo";
108
+ import { formatPhaseDisplayName, todoMatchesAnyDescription } from "../tools/todo";
108
109
  import { ToolError } from "../tools/tool-errors";
109
110
  import { vocalizer } from "../tts/vocalizer";
111
+ import { renderTreeList } from "../tui/tree-list";
110
112
  import type { EventBus } from "../utils/event-bus";
111
113
  import { getEditorCommand, openInEditor } from "../utils/external-editor";
112
114
  import { getSessionAccentAnsi, getSessionAccentHex } from "../utils/session-color";
@@ -154,6 +156,7 @@ import {
154
156
  parseLoopLimitArgs,
155
157
  } from "./loop-limit";
156
158
  import { OAuthManualInputManager } from "./oauth-manual-input";
159
+ import { countRunningSubagentBadgeAgents, getRunningSubagentBadgeRegistry } from "./running-subagent-badge";
157
160
  import type { ObservableSession } from "./session-observer-registry";
158
161
  import { SessionObserverRegistry } from "./session-observer-registry";
159
162
  import { runProviderSetupWizard } from "./setup-wizard/lazy";
@@ -309,13 +312,15 @@ export interface InteractiveModeOptions {
309
312
  }
310
313
 
311
314
  /**
312
- * Hosts the working loader and transient status rows. While anything is
313
- * mounted, every row is live: report a seam at 0 so the engine never commits
314
- * a still-animating loader to native scrollback (stale `Working…` rows would
315
- * otherwise pile up above the live one). The transcript's own seam, when
316
- * present, sits higher and wins (topmost-seam merge in TUI.render).
315
+ * Anchored live-region container for the HUD/status rows between the transcript
316
+ * and the editor (working loader, todo + subagent HUDs, transient notification
317
+ * panels). While it has content every row is live: it reports a seam at 0 so the
318
+ * engine never commits these anchored, rebuilt-in-place rows to native
319
+ * scrollback otherwise stale duplicates pile up above the live copy on short
320
+ * terminals once the loader sits below a tall HUD. The transcript's own seam,
321
+ * when present, sits higher and wins (topmost-seam merge in TUI.render).
317
322
  */
318
- class StatusContainer extends Container implements NativeScrollbackLiveRegion {
323
+ class AnchoredLiveContainer extends Container implements NativeScrollbackLiveRegion {
319
324
  getNativeScrollbackLiveRegionStart(): number | undefined {
320
325
  return this.children.length > 0 ? 0 : undefined;
321
326
  }
@@ -408,6 +413,15 @@ export class InteractiveMode implements InteractiveModeContext {
408
413
  #modelCycleClearTimer: NodeJS.Timeout | undefined;
409
414
  todoPhases: TodoPhase[] = [];
410
415
  hideThinkingBlock = false;
416
+ /**
417
+ * Effective thinking-block visibility: hidden when the user's setting is on
418
+ * OR the session thinking level is "off". Some providers (MiniMax, GLM,
419
+ * DeepSeek) return thinking blocks even with reasoning disabled; this
420
+ * respects the user's intent when they set thinking to "off" (#626).
421
+ */
422
+ get effectiveHideThinkingBlock(): boolean {
423
+ return this.hideThinkingBlock || (this.viewSession?.thinkingLevel ?? ThinkingLevel.Off) === ThinkingLevel.Off;
424
+ }
411
425
  proseOnlyThinking = true;
412
426
  compactionQueuedMessages: CompactionQueuedMessage[] = [];
413
427
  pendingTools = new Map<string, ToolExecutionHandle>();
@@ -541,6 +555,8 @@ export class InteractiveMode implements InteractiveModeContext {
541
555
  #observerRegistry: SessionObserverRegistry;
542
556
  #eventBus?: EventBus;
543
557
  #eventBusUnsubscribers: Array<() => void> = [];
558
+ #agentRegistryUnsubscribe?: () => void;
559
+ #agentRegistrySubscriptionTarget?: AgentRegistry;
544
560
  #mcpStatusOrder: string[] = [];
545
561
  #mcpPendingServers = new Set<string>();
546
562
  #mcpConnectedServers = new Set<string>();
@@ -598,13 +614,13 @@ export class InteractiveMode implements InteractiveModeContext {
598
614
  setTerminalTextSizing(settings.get("tui.textSizing") && TERMINAL.textSizing);
599
615
  this.chatContainer = new TranscriptContainer();
600
616
  this.pendingMessagesContainer = new Container();
601
- this.statusContainer = new StatusContainer();
602
- this.todoContainer = new Container();
603
- this.subagentContainer = new Container();
604
- this.btwContainer = new Container();
605
- this.omfgContainer = new Container();
606
- this.errorBannerContainer = new Container();
607
- this.modelCycleContainer = new Container();
617
+ this.statusContainer = new AnchoredLiveContainer();
618
+ this.todoContainer = new AnchoredLiveContainer();
619
+ this.subagentContainer = new AnchoredLiveContainer();
620
+ this.btwContainer = new AnchoredLiveContainer();
621
+ this.omfgContainer = new AnchoredLiveContainer();
622
+ this.errorBannerContainer = new AnchoredLiveContainer();
623
+ this.modelCycleContainer = new AnchoredLiveContainer();
608
624
  this.editor = new CustomEditor(getEditorTheme());
609
625
  this.editor.setUseTerminalCursor(this.ui.getShowHardwareCursor());
610
626
  this.editor.setAutocompleteMaxVisible(settings.get("autocompleteMaxVisible"));
@@ -818,13 +834,16 @@ export class InteractiveMode implements InteractiveModeContext {
818
834
 
819
835
  this.ui.addChild(this.chatContainer);
820
836
  this.ui.addChild(this.pendingMessagesContainer);
821
- this.ui.addChild(this.statusContainer);
822
837
  this.ui.addChild(this.todoContainer);
823
838
  this.ui.addChild(this.subagentContainer);
824
839
  this.ui.addChild(this.btwContainer);
825
840
  this.ui.addChild(this.omfgContainer);
826
841
  this.ui.addChild(this.errorBannerContainer);
827
842
  this.ui.addChild(this.modelCycleContainer);
843
+ // Working loader / transient status sits below the sticky todo + subagent
844
+ // HUDs, just above the editor's hook-widget top margin — so it reads next to
845
+ // the prompt while keeping the one-line gap above the editor.
846
+ this.ui.addChild(this.statusContainer);
828
847
  this.ui.addChild(this.statusLine); // Only renders hook statuses (main status in editor border)
829
848
  this.ui.addChild(this.hookWidgetContainerAbove);
830
849
  this.ui.addChild(this.editorContainer);
@@ -839,8 +858,14 @@ export class InteractiveMode implements InteractiveModeContext {
839
858
  this.#observerRegistry.subscribeToEventBus(this.#eventBus);
840
859
  }
841
860
  this.#observerRegistry.setMainSession(this.sessionManager.getSessionFile() ?? undefined);
861
+ this.statusLine.setSubagentHubHint(
862
+ this.keybindings.getDisplayString("app.agents.hub") ||
863
+ this.keybindings.getDisplayString("app.session.observe") ||
864
+ undefined,
865
+ );
866
+ this.syncRunningSubagentBadge();
842
867
  this.#observerRegistry.onChange(() => {
843
- this.statusLine.setSubagentCount(this.#observerRegistry.getActiveSubagentCount());
868
+ this.syncRunningSubagentBadge();
844
869
  // Auto-checkmark todos whose matching subagent just succeeded, then
845
870
  // re-render so the running override (the static "live" glyph when a
846
871
  // subagent is doing the work for a still-pending todo) updates as
@@ -1435,6 +1460,22 @@ export class InteractiveMode implements InteractiveModeContext {
1435
1460
  this.ui.requestRender();
1436
1461
  }
1437
1462
 
1463
+ /** Refresh the running-subagents status badge from the active local or collab registry. */
1464
+ syncRunningSubagentBadge(): void {
1465
+ const registry = getRunningSubagentBadgeRegistry(this.collabGuest);
1466
+ if (this.#agentRegistrySubscriptionTarget !== registry) {
1467
+ this.#agentRegistryUnsubscribe?.();
1468
+ this.#agentRegistrySubscriptionTarget = registry;
1469
+ this.#agentRegistryUnsubscribe = registry.onChange(() => {
1470
+ this.syncRunningSubagentBadge();
1471
+ this.ui.requestRender();
1472
+ });
1473
+ }
1474
+ const count = countRunningSubagentBadgeAgents(registry);
1475
+ this.statusLine.setSubagentCount(count);
1476
+ this.updateEditorTopBorder();
1477
+ }
1478
+
1438
1479
  updateEditorTopBorder(): void {
1439
1480
  const availableWidth = this.editor.getTopBorderAvailableWidth(this.ui.terminal.columns);
1440
1481
  const topBorder = this.statusLine.getTopBorder(availableWidth);
@@ -1486,9 +1527,7 @@ export class InteractiveMode implements InteractiveModeContext {
1486
1527
  case "abandoned":
1487
1528
  return theme.fg("error", `${prefix}${checkbox.unchecked} ${chalk.strikethrough(todo.content)}`) + marker;
1488
1529
  default:
1489
- if (matched) {
1490
- return theme.fg("accent", `${prefix}${checkbox.unchecked} ${todo.content}`) + marker;
1491
- }
1530
+ if (matched) return theme.fg("accent", `${prefix}${checkbox.unchecked} ${todo.content}`) + marker;
1492
1531
  return theme.fg("dim", `${prefix}${checkbox.unchecked} ${todo.content}`) + marker;
1493
1532
  }
1494
1533
  }
@@ -1629,44 +1668,66 @@ export class InteractiveMode implements InteractiveModeContext {
1629
1668
  this.todoContainer.clear();
1630
1669
  const phases = this.todoPhases.filter(phase => phase.tasks.length > 0);
1631
1670
  if (phases.length === 0) return;
1632
- const indent = " ";
1633
- const hook = theme.tree.hook;
1634
- const lines = ["", indent + theme.bold(theme.fg("accent", "Todos"))];
1671
+ const expanded = this.todoExpanded;
1672
+ const multiPhase = phases.length > 1;
1673
+ const activeIdx = phases.indexOf(this.#getActivePhase(phases) ?? phases[0]);
1674
+ // Fixed budgets keep the HUD bounded regardless of plan size / progress.
1675
+ const subsequentStageCap = 4; // stages shown after the active one (header count implies the rest)
1676
+ const activeTaskCap = 5; // open tasks previewed for the active stage
1635
1677
 
1636
1678
  const activeDescs = this.#getActiveSubagentDescriptions();
1637
- // A pending todo "lights up" (accent + running glyph) when an in-flight
1638
- // subagent is doing its work, matched by normalized content overlap.
1679
+ // A pending todo "lights up" (accent) when an in-flight subagent is doing
1680
+ // its work, matched by normalized content overlap.
1639
1681
  const isMatched = (todo: TodoItem): boolean =>
1640
1682
  activeDescs.length > 0 && todoMatchesAnyDescription(todo.content, activeDescs);
1641
1683
 
1642
- if (!this.todoExpanded) {
1643
- const activeIdx = phases.indexOf(this.#getActivePhase(phases) ?? phases[0]);
1644
- const activePhase = phases[activeIdx];
1645
- if (!activePhase) return;
1646
- const { visible, hiddenOpenCount } = selectStickyTodoWindow(activePhase.tasks, 5);
1647
-
1648
- lines.push(
1649
- `${indent}${theme.fg("accent", `${hook} ${formatPhaseDisplayName(activePhase.name, activeIdx + 1)}`)}`,
1684
+ // Task subtree for a phase. Collapsed previews the first open tasks — the
1685
+ // stage's `done/total` makes the hidden count obvious, so there is no
1686
+ // "… more" row; expanded lists every task.
1687
+ const renderTasks = (phase: TodoPhase): string[] => {
1688
+ const open = phase.tasks.filter(t => t.status === "pending" || t.status === "in_progress");
1689
+ const base = expanded ? phase.tasks : open.length > 0 ? open : phase.tasks;
1690
+ const items = expanded ? base : base.slice(0, activeTaskCap);
1691
+ return renderTreeList(
1692
+ { items, expanded: true, renderItem: todo => this.#formatTodoLine(todo, "", isMatched(todo)) },
1693
+ theme,
1650
1694
  );
1651
- visible.forEach((todo, index) => {
1652
- const prefix = `${indent}${index === 0 ? hook : " "} `;
1653
- lines.push(this.#formatTodoLine(todo, prefix, isMatched(todo)));
1654
- });
1655
- if (hiddenOpenCount > 0) {
1656
- lines.push(theme.fg("muted", `${indent} ${hook} +${hiddenOpenCount} more`));
1695
+ };
1696
+
1697
+ // One phase node. The active stage is highlighted with normal-brightness task
1698
+ // progress; other stages render their whole row (name + progress) in the
1699
+ // brighter muted gray. The root header carries overall stage progression.
1700
+ const renderPhase = (phase: TodoPhase, oneBased: number, isActive: boolean): string | string[] => {
1701
+ const label = multiPhase ? formatPhaseDisplayName(phase.name, oneBased) : phase.name;
1702
+ const done = phase.tasks.filter(t => t.status === "completed").length;
1703
+ const progress = ` · ${done}/${phase.tasks.length}`;
1704
+ if (!isActive) {
1705
+ const header = theme.fg("muted", label) + theme.fg("dim", progress);
1706
+ return expanded ? [header, ...renderTasks(phase)] : header;
1657
1707
  }
1658
- this.todoContainer.addChild(new Text(lines.join("\n"), 1, 0));
1659
- return;
1660
- }
1708
+ const header = theme.bold(theme.fg("accent", label)) + theme.fg("dim", progress);
1709
+ return [header, ...renderTasks(phase)];
1710
+ };
1661
1711
 
1662
- phases.forEach((phase, phaseIndex) => {
1663
- lines.push(`${indent}${theme.fg("accent", `${hook} ${formatPhaseDisplayName(phase.name, phaseIndex + 1)}`)}`);
1664
- phase.tasks.forEach((todo, index) => {
1665
- const prefix = `${indent}${index === 0 ? hook : " "} `;
1666
- lines.push(this.#formatTodoLine(todo, prefix, isMatched(todo)));
1667
- });
1668
- });
1712
+ // Collapsed: active stage + a bounded number of following stages (the
1713
+ // header's "n/total" count implies any not shown). Expanded: every stage
1714
+ // from the top. Roman numerals stay tied to the real phase index.
1715
+ const baseIdx = expanded ? 0 : activeIdx;
1716
+ const phaseSlice = expanded ? phases.slice(baseIdx) : phases.slice(baseIdx, baseIdx + 1 + subsequentStageCap);
1717
+ const phaseTreeLines = renderTreeList(
1718
+ {
1719
+ items: phaseSlice,
1720
+ expanded: true,
1721
+ renderItem: (phase, ctx) => renderPhase(phase, baseIdx + ctx.index + 1, baseIdx + ctx.index === activeIdx),
1722
+ },
1723
+ theme,
1724
+ );
1669
1725
 
1726
+ // Header carries overall stage progression, e.g. "Todos · 1/8".
1727
+ const root =
1728
+ theme.bold(theme.fg("accent", "Todos")) +
1729
+ (multiPhase ? theme.fg("dim", ` · ${activeIdx + 1}/${phases.length}`) : "");
1730
+ const lines = ["", root, ...phaseTreeLines.map(line => ` ${line}`)];
1670
1731
  this.todoContainer.addChild(new Text(lines.join("\n"), 1, 0));
1671
1732
  }
1672
1733
 
@@ -3156,6 +3217,9 @@ export class InteractiveMode implements InteractiveModeContext {
3156
3217
  }
3157
3218
  this.#eventBusUnsubscribers = [];
3158
3219
  this.#observerRegistry.dispose();
3220
+ this.#agentRegistryUnsubscribe?.();
3221
+ this.#agentRegistryUnsubscribe = undefined;
3222
+ this.#agentRegistrySubscriptionTarget = undefined;
3159
3223
  this.#eventController.dispose();
3160
3224
  this.statusLine.dispose();
3161
3225
  if (this.#resizeHandler) {
@@ -3441,8 +3505,10 @@ export class InteractiveMode implements InteractiveModeContext {
3441
3505
  getSymbolTheme().spinnerFrames,
3442
3506
  );
3443
3507
  this.statusContainer.addChild(this.loadingAnimation);
3508
+ } else if (!this.statusContainer.children.includes(this.loadingAnimation)) {
3509
+ this.statusContainer.clear();
3510
+ this.statusContainer.addChild(this.loadingAnimation);
3444
3511
  }
3445
-
3446
3512
  this.applyPendingWorkingMessage();
3447
3513
  }
3448
3514
 
@@ -3626,7 +3692,7 @@ export class InteractiveMode implements InteractiveModeContext {
3626
3692
  return this.#commandController.handleForkCommand();
3627
3693
  }
3628
3694
 
3629
- handleMoveCommand(targetPath: string): Promise<void> {
3695
+ handleMoveCommand(targetPath?: string): Promise<void> {
3630
3696
  return this.#commandController.handleMoveCommand(targetPath);
3631
3697
  }
3632
3698
 
@@ -60,6 +60,16 @@ function fuzzyScore(query: string, target: string): number {
60
60
  return Math.max(1, 40 - gaps * 5);
61
61
  }
62
62
 
63
+ /** Decode a completion `value` for fuzzy matching (the inserted value may be
64
+ * percent-encoded, e.g. an ssh host `alice%40prod`); identity for plain values. */
65
+ function decodeUrlCompletionValue(value: string): string {
66
+ try {
67
+ return decodeURIComponent(value);
68
+ } catch {
69
+ return value;
70
+ }
71
+ }
72
+
63
73
  /**
64
74
  * Detect a completable internal-url token immediately before the cursor.
65
75
  * Returns `null` when the text is not a `scheme://` token whose scheme is
@@ -82,17 +92,22 @@ export function extractInternalUrlContext(textBeforeCursor: string): InternalUrl
82
92
  */
83
93
  export async function getInternalUrlSuggestions(
84
94
  textBeforeCursor: string,
95
+ cwd?: string,
85
96
  ): Promise<{ items: AutocompleteItem[]; prefix: string } | null> {
86
97
  const ctx = extractInternalUrlContext(textBeforeCursor);
87
98
  if (!ctx) return null;
88
99
 
89
- const candidates = await InternalUrlRouter.instance().complete(ctx.scheme, ctx.query);
100
+ const candidates = await InternalUrlRouter.instance().complete(
101
+ ctx.scheme,
102
+ ctx.query,
103
+ cwd === undefined ? undefined : { cwd },
104
+ );
90
105
  if (!candidates || candidates.length === 0) return null;
91
106
 
92
107
  const query = ctx.query.toLowerCase();
93
108
  const scored: Array<{ item: AutocompleteItem; score: number }> = [];
94
109
  for (const candidate of candidates) {
95
- const target = candidate.value.toLowerCase();
110
+ const target = decodeUrlCompletionValue(candidate.value).toLowerCase();
96
111
  if (!fuzzyMatch(query, target)) continue;
97
112
  scored.push({
98
113
  item: {
@@ -96,9 +96,11 @@ function getPromptActionPrefix(textBeforeCursor: string): string | null {
96
96
  export class PromptActionAutocompleteProvider implements AutocompleteProvider {
97
97
  #baseProvider: CombinedAutocompleteProvider;
98
98
  #actions: PromptActionDefinition[];
99
+ #basePath: string;
99
100
 
100
101
  constructor(commands: SlashCommand[], basePath: string, actions: PromptActionDefinition[]) {
101
102
  this.#baseProvider = new CombinedAutocompleteProvider(commands, basePath);
103
+ this.#basePath = basePath;
102
104
  this.#actions = actions;
103
105
  }
104
106
 
@@ -133,7 +135,7 @@ export class PromptActionAutocompleteProvider implements AutocompleteProvider {
133
135
  }
134
136
  }
135
137
 
136
- const urlSuggestions = await getInternalUrlSuggestions(textBeforeCursor);
138
+ const urlSuggestions = await getInternalUrlSuggestions(textBeforeCursor, this.#basePath);
137
139
  if (urlSuggestions) return urlSuggestions;
138
140
 
139
141
  if (!isSettingsInitialized() || settings.get("emojiAutocomplete")) {
@@ -0,0 +1,13 @@
1
+ import { AgentRegistry } from "../registry/agent-registry";
2
+
3
+ export interface RunningSubagentRegistrySource {
4
+ agentRegistry: AgentRegistry;
5
+ }
6
+
7
+ export function getRunningSubagentBadgeRegistry(collabGuest: RunningSubagentRegistrySource | undefined): AgentRegistry {
8
+ return collabGuest?.agentRegistry ?? AgentRegistry.global();
9
+ }
10
+
11
+ export function countRunningSubagentBadgeAgents(registry: AgentRegistry): number {
12
+ return registry.list().filter(ref => ref.kind === "sub" && ref.status === "running").length;
13
+ }
@@ -1,4 +1,4 @@
1
- import { type SelectItem, SelectList, type SgrMouseEvent } from "@oh-my-pi/pi-tui";
1
+ import { routeSelectListMouse, type SelectItem, SelectList, type SgrMouseEvent } from "@oh-my-pi/pi-tui";
2
2
  import { getSelectListTheme, type SymbolPreset, setSymbolPreset, theme } from "../../theme/theme";
3
3
  import type { SetupScene, SetupSceneController, SetupSceneHost } from "./types";
4
4
 
@@ -65,18 +65,7 @@ class GlyphSceneController implements SetupSceneController {
65
65
  /** Wheel moves the highlight (live preview); hover lights the row under the pointer; click confirms it. */
66
66
  routeMouse(event: SgrMouseEvent, line: number, _col: number): void {
67
67
  if (this.#committing) return;
68
- if (event.wheel !== null) {
69
- this.#selectList.handleWheel(event.wheel);
70
- return;
71
- }
72
- const index = this.#selectList.hitTest(line - this.#listRowStart);
73
- if (event.motion) {
74
- this.#selectList.setHoverIndex(index ?? null);
75
- return;
76
- }
77
- if (event.leftClick && index !== undefined) {
78
- this.#selectList.clickItem(index);
79
- }
68
+ routeSelectListMouse(this.#selectList, event, line - this.#listRowStart);
80
69
  }
81
70
 
82
71
  render(width: number): readonly string[] {
@@ -74,7 +74,8 @@ class ProvidersSceneController implements SetupSceneController {
74
74
  return;
75
75
  }
76
76
  if (event.motion) this.#tabBar.setHoverTab(null);
77
- const bodyLine = line - this.#tabRowCount - 1;
77
+ const spacerRowsAfterTabs = 1;
78
+ const bodyLine = line - this.#tabRowCount - spacerRowsAfterTabs;
78
79
  if (tab.routeMouse) {
79
80
  tab.routeMouse(event, bodyLine, col);
80
81
  return;
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  padding,
3
+ routeSelectListMouse,
3
4
  type SelectItem,
4
5
  SelectList,
5
6
  type SgrMouseEvent,
@@ -128,18 +129,11 @@ class ThemeSceneController implements SetupSceneController {
128
129
 
129
130
  /** Wheel moves the highlight (live preview); hover lights the row under the pointer; click confirms it. */
130
131
  routeMouse(event: SgrMouseEvent, line: number, _col: number): void {
131
- if (event.wheel !== null) {
132
- this.#selectList.handleWheel(event.wheel);
133
- return;
134
- }
135
- const index = this.#listRowStart >= 0 ? this.#selectList.hitTest(line - this.#listRowStart) : undefined;
136
- if (event.motion) {
137
- this.#selectList.setHoverIndex(index ?? null);
138
- return;
139
- }
140
- if (event.leftClick && index !== undefined) {
141
- this.#selectList.clickItem(index);
142
- }
132
+ // Mirror the pre-helper flow: wheel/motion are always processed, but a
133
+ // hidden list (#listRowStart < 0, e.g. while loading all themes) must
134
+ // never hit-test a row — route through a line that resolves to undefined.
135
+ const listLine = this.#listRowStart >= 0 ? line - this.#listRowStart : Number.NEGATIVE_INFINITY;
136
+ routeSelectListMouse(this.#selectList, event, listLine);
143
137
  }
144
138
 
145
139
  render(width: number): readonly string[] {
@@ -1,4 +1,10 @@
1
- import { type SelectItem, SelectList, type SgrMouseEvent, truncateToWidth } from "@oh-my-pi/pi-tui";
1
+ import {
2
+ routeSelectListMouse,
3
+ type SelectItem,
4
+ SelectList,
5
+ type SgrMouseEvent,
6
+ truncateToWidth,
7
+ } from "@oh-my-pi/pi-tui";
2
8
  import { SETTINGS_SCHEMA } from "../../../config/settings-schema";
3
9
  import { getSearchProvider, setPreferredSearchProvider } from "../../../web/search/provider";
4
10
  import { isSearchProviderPreference, type SearchProviderId } from "../../../web/search/types";
@@ -59,18 +65,7 @@ export class WebSearchTab implements SetupTab {
59
65
 
60
66
  /** Wheel moves the highlight; hover lights the row under the pointer; click confirms it. */
61
67
  routeMouse(event: SgrMouseEvent, line: number, _col: number): void {
62
- if (event.wheel !== null) {
63
- this.#list.handleWheel(event.wheel);
64
- return;
65
- }
66
- const index = this.#list.hitTest(line - this.#listRowStart);
67
- if (event.motion) {
68
- this.#list.setHoverIndex(index ?? null);
69
- return;
70
- }
71
- if (event.leftClick && index !== undefined) {
72
- this.#list.clickItem(index);
73
- }
68
+ routeSelectListMouse(this.#list, event, line - this.#listRowStart);
74
69
  }
75
70
 
76
71
  invalidate(): void {
@@ -3,7 +3,8 @@ import {
3
3
  matchesKey,
4
4
  type OverlayFocusOwner,
5
5
  padding,
6
- parseSgrMouse,
6
+ routeSgrMouseInput,
7
+ type SgrMouseEvent,
7
8
  truncateToWidth,
8
9
  visibleWidth,
9
10
  } from "@oh-my-pi/pi-tui";
@@ -104,7 +105,9 @@ export class SetupWizardComponent implements Component, OverlayFocusOwner {
104
105
  handleInput(data: string): void {
105
106
  if (this.#phase === "done") return;
106
107
  if (data.startsWith("\x1b[<")) {
107
- this.#handleMouse(data);
108
+ routeSgrMouseInput(data, event => {
109
+ this.#routeMouseEvent(event);
110
+ });
108
111
  return;
109
112
  }
110
113
  if (matchesKey(data, "ctrl+c")) {
@@ -146,9 +149,7 @@ export class SetupWizardComponent implements Component, OverlayFocusOwner {
146
149
  * advances the splash/outro like Enter. Raw reports never reach scene
147
150
  * keyboard input.
148
151
  */
149
- #handleMouse(data: string): void {
150
- const event = parseSgrMouse(data);
151
- if (!event) return;
152
+ #routeMouseEvent(event: SgrMouseEvent): void {
152
153
  if (this.#phase === "splash" || this.#phase === "outro") {
153
154
  if (!event.leftClick) return;
154
155
  if (this.#phase === "splash") this.#beginScene();
@@ -228,7 +228,9 @@ export type SymbolKey =
228
228
  | "tool.review"
229
229
  | "tool.inspectImage"
230
230
  | "tool.goal"
231
- | "tool.irc";
231
+ | "tool.irc"
232
+ | "tool.delete"
233
+ | "tool.move";
232
234
 
233
235
  type SymbolMap = Record<SymbolKey, string>;
234
236
 
@@ -430,6 +432,8 @@ const UNICODE_SYMBOLS: SymbolMap = {
430
432
  "tool.inspectImage": "🖼",
431
433
  "tool.goal": "◎",
432
434
  "tool.irc": "✉",
435
+ "tool.delete": "🗑",
436
+ "tool.move": "➜",
433
437
  };
434
438
 
435
439
  const NERD_SYMBOLS: SymbolMap = {
@@ -735,6 +739,8 @@ const NERD_SYMBOLS: SymbolMap = {
735
739
  "tool.inspectImage": "\uEAEA",
736
740
  "tool.goal": "\uEBF8",
737
741
  "tool.irc": "\uF086",
742
+ "tool.delete": "\uf12d",
743
+ "tool.move": "\uf061",
738
744
  };
739
745
 
740
746
  const ASCII_SYMBOLS: SymbolMap = {
@@ -933,6 +939,8 @@ const ASCII_SYMBOLS: SymbolMap = {
933
939
  "tool.inspectImage": "[i]",
934
940
  "tool.goal": "(o)",
935
941
  "tool.irc": "irc",
942
+ "tool.delete": "rm",
943
+ "tool.move": "mv",
936
944
  };
937
945
 
938
946
  const SYMBOL_PRESETS: Record<SymbolPreset, SymbolMap> = {
@@ -159,6 +159,12 @@ export interface InteractiveModeContext {
159
159
  loopLimit?: LoopLimitRuntime;
160
160
  planModePlanFilePath?: string;
161
161
  hideThinkingBlock: boolean;
162
+ /**
163
+ * Effective thinking-block visibility: true when hidden by user setting OR
164
+ * thinking level is "off". Read this in render paths instead of
165
+ * {@link hideThinkingBlock} so blocks are auto-hidden when thinking is off.
166
+ */
167
+ readonly effectiveHideThinkingBlock: boolean;
162
168
  proseOnlyThinking: boolean;
163
169
  compactionQueuedMessages: CompactionQueuedMessage[];
164
170
  pendingTools: Map<string, ToolExecutionHandle>;
@@ -288,6 +294,8 @@ export interface InteractiveModeContext {
288
294
  findLastAssistantMessage(): AssistantMessage | undefined;
289
295
  extractAssistantText(message: AssistantMessage): string;
290
296
  updateEditorTopBorder(): void;
297
+ /** Refresh the running-subagents status badge from the active local or collab registry. */
298
+ syncRunningSubagentBadge(): void;
291
299
  updateEditorBorderColor(): void;
292
300
  rebuildChatFromMessages(): void;
293
301
  setTodos(todos: TodoItem[] | TodoPhase[]): void;
@@ -320,7 +328,7 @@ export interface InteractiveModeContext {
320
328
  handleCompactCommand(customInstructions?: string, mode?: CompactMode): Promise<CompactionOutcome>;
321
329
  handleHandoffCommand(customInstructions?: string): Promise<void>;
322
330
  handleShakeCommand(mode: ShakeMode): Promise<void>;
323
- handleMoveCommand(targetPath: string): Promise<void>;
331
+ handleMoveCommand(targetPath?: string): Promise<void>;
324
332
  handleRenameCommand(title: string): Promise<void>;
325
333
  handleMemoryCommand(text: string): Promise<void>;
326
334
  handleSTTToggle(): Promise<void>;
@@ -18,7 +18,7 @@ export function createAssistantMessageComponent(
18
18
  ): AssistantMessageComponent {
19
19
  return new AssistantMessageComponent(
20
20
  message,
21
- ctx.hideThinkingBlock,
21
+ ctx.effectiveHideThinkingBlock,
22
22
  () => ctx.ui.requestRender(),
23
23
  ctx.viewSession.extensionRunner?.getAssistantThinkingRenderers(),
24
24
  ctx.ui.imageBudget,
package/src/priority.json CHANGED
@@ -3,6 +3,18 @@
3
3
  "cerebras/zai-glm-4.7",
4
4
  "cerebras/zai-glm-4.6",
5
5
  "cerebras/zai-glm",
6
+ "google-antigravity/gemini-3.1-flash-lite",
7
+ "google-gemini-cli/gemini-3.1-flash-lite",
8
+ "gemini-3.1-flash-lite",
9
+ "gemini-3-1-flash-lite",
10
+ "flash-lite",
11
+ "google-antigravity/gemini-3.5-flash",
12
+ "google-antigravity/gemini-3-flash",
13
+ "google-gemini-cli/gemini-3.5-flash",
14
+ "google-gemini-cli/gemini-3-flash",
15
+ "gemini-3.5-flash",
16
+ "gemini-3-5-flash",
17
+ "gemini-3-flash",
6
18
  "haiku-4-5",
7
19
  "haiku-4.5",
8
20
  "haiku",
@@ -10,6 +22,9 @@
10
22
  "mini"
11
23
  ],
12
24
  "slow": [
25
+ "openai-codex/gpt-5.5",
26
+ "openai-codex/gpt-5.4",
27
+ "openai-codex/gpt-5.3-codex",
13
28
  "gpt-5.5",
14
29
  "gpt-5.4",
15
30
  "gpt-5.3-codex",
@@ -0,0 +1,6 @@
1
+ Especially pay attention to:
2
+ <attention>
3
+ The session cwd is outside git, and exactly one direct child git repository was detected at `{{relativeRepoRoot}}`.
4
+
5
+ Paths under `{{relativeRepoRoot}}/` are the active project. Do not claim work is missing, destroyed, or absent at the parent cwd until you have checked under `{{relativeRepoRoot}}/`.
6
+ </attention>