@oh-my-pi/pi-coding-agent 15.12.4 → 15.13.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 (291) hide show
  1. package/CHANGELOG.md +304 -6
  2. package/dist/cli.js +1015 -881
  3. package/dist/types/async/job-manager.d.ts +15 -0
  4. package/dist/types/autolearn/controller.d.ts +25 -0
  5. package/dist/types/autolearn/managed-skills.d.ts +45 -0
  6. package/dist/types/autoresearch/state.d.ts +1 -1
  7. package/dist/types/autoresearch/types.d.ts +1 -1
  8. package/dist/types/cli/args.d.ts +19 -1
  9. package/dist/types/cli/session-picker.d.ts +1 -1
  10. package/dist/types/cli/setup-cli.d.ts +1 -1
  11. package/dist/types/cli/setup-model-picker.d.ts +14 -0
  12. package/dist/types/collab/protocol.d.ts +1 -1
  13. package/dist/types/commands/say.d.ts +24 -0
  14. package/dist/types/config/keybindings.d.ts +3 -3
  15. package/dist/types/config/model-registry.d.ts +10 -0
  16. package/dist/types/config/models-config-schema.d.ts +12 -0
  17. package/dist/types/config/models-config.d.ts +8 -2
  18. package/dist/types/config/settings-schema.d.ts +261 -58
  19. package/dist/types/export/html/index.d.ts +2 -1
  20. package/dist/types/extensibility/extensions/model-api.d.ts +17 -0
  21. package/dist/types/extensibility/extensions/runner.d.ts +3 -1
  22. package/dist/types/extensibility/extensions/types.d.ts +47 -1
  23. package/dist/types/extensibility/hooks/index.d.ts +2 -1
  24. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +9 -0
  25. package/dist/types/extensibility/plugins/loader.d.ts +11 -0
  26. package/dist/types/extensibility/shared-events.d.ts +1 -1
  27. package/dist/types/extensibility/skills.d.ts +10 -0
  28. package/dist/types/goals/guided-setup.d.ts +18 -0
  29. package/dist/types/goals/state.d.ts +1 -1
  30. package/dist/types/hindsight/transcript.d.ts +1 -1
  31. package/dist/types/index.d.ts +5 -0
  32. package/dist/types/internal-urls/local-protocol.d.ts +4 -2
  33. package/dist/types/main.d.ts +4 -3
  34. package/dist/types/mcp/startup-events.d.ts +11 -0
  35. package/dist/types/memories/index.d.ts +7 -0
  36. package/dist/types/memory-backend/local-backend.d.ts +4 -3
  37. package/dist/types/mnemopi/config.d.ts +4 -4
  38. package/dist/types/modes/components/agent-hub.d.ts +6 -0
  39. package/dist/types/modes/components/assistant-message.d.ts +1 -2
  40. package/dist/types/modes/components/compaction-summary-message.d.ts +15 -1
  41. package/dist/types/modes/components/custom-editor.d.ts +39 -1
  42. package/dist/types/modes/components/custom-editor.test.d.ts +1 -0
  43. package/dist/types/modes/components/session-selector.d.ts +1 -1
  44. package/dist/types/modes/components/tool-execution.d.ts +26 -16
  45. package/dist/types/modes/components/transcript-container.d.ts +23 -2
  46. package/dist/types/modes/components/tree-selector.d.ts +1 -1
  47. package/dist/types/modes/components/usage-row.d.ts +3 -0
  48. package/dist/types/modes/controllers/command-controller.d.ts +2 -2
  49. package/dist/types/modes/controllers/input-controller.d.ts +14 -0
  50. package/dist/types/modes/controllers/selector-controller.d.ts +3 -1
  51. package/dist/types/modes/gradient-highlight.d.ts +9 -4
  52. package/dist/types/modes/image-references.d.ts +6 -0
  53. package/dist/types/modes/interactive-mode.d.ts +27 -3
  54. package/dist/types/modes/magic-keywords.d.ts +13 -1
  55. package/dist/types/modes/rpc/rpc-mode.d.ts +35 -1
  56. package/dist/types/modes/rpc/rpc-types.d.ts +9 -1
  57. package/dist/types/modes/runtime-init.d.ts +4 -0
  58. package/dist/types/modes/theme/theme.d.ts +13 -2
  59. package/dist/types/modes/types.d.ts +8 -2
  60. package/dist/types/modes/utils/ui-helpers.d.ts +1 -1
  61. package/dist/types/registry/agent-registry.d.ts +17 -0
  62. package/dist/types/secrets/obfuscator.d.ts +1 -1
  63. package/dist/types/session/agent-session.d.ts +14 -2
  64. package/dist/types/session/indexed-session-storage.d.ts +3 -4
  65. package/dist/types/session/session-context.d.ts +39 -0
  66. package/dist/types/session/session-entries.d.ts +159 -0
  67. package/dist/types/session/session-listing.d.ts +69 -0
  68. package/dist/types/session/session-loader.d.ts +16 -0
  69. package/dist/types/session/session-manager.d.ts +82 -474
  70. package/dist/types/session/session-migrations.d.ts +12 -0
  71. package/dist/types/session/session-paths.d.ts +25 -0
  72. package/dist/types/session/session-persistence.d.ts +8 -0
  73. package/dist/types/session/session-storage.d.ts +11 -12
  74. package/dist/types/session/snapcompact-inline.d.ts +12 -1
  75. package/dist/types/session/snapcompact-savings-journal.d.ts +46 -0
  76. package/dist/types/session/tool-choice-queue.d.ts +6 -6
  77. package/dist/types/stt/asr-client.d.ts +90 -0
  78. package/dist/types/stt/asr-protocol.d.ts +97 -0
  79. package/dist/types/stt/asr-worker.d.ts +2 -0
  80. package/dist/types/stt/downloader.d.ts +38 -0
  81. package/dist/types/stt/endpointer.d.ts +59 -0
  82. package/dist/types/stt/index.d.ts +5 -1
  83. package/dist/types/stt/models.d.ts +120 -0
  84. package/dist/types/stt/recorder.d.ts +17 -0
  85. package/dist/types/stt/stt-controller.d.ts +6 -0
  86. package/dist/types/stt/transcriber.d.ts +5 -7
  87. package/dist/types/stt/wav.d.ts +29 -0
  88. package/dist/types/system-prompt.d.ts +4 -0
  89. package/dist/types/task/executor.d.ts +2 -0
  90. package/dist/types/task/index.d.ts +9 -1
  91. package/dist/types/task/types.d.ts +36 -0
  92. package/dist/types/tools/bash.d.ts +2 -2
  93. package/dist/types/tools/eval-render.d.ts +1 -1
  94. package/dist/types/tools/index.d.ts +11 -1
  95. package/dist/types/tools/irc.d.ts +1 -0
  96. package/dist/types/tools/learn.d.ts +51 -0
  97. package/dist/types/tools/manage-skill.d.ts +40 -0
  98. package/dist/types/tools/plan-mode-guard.d.ts +10 -0
  99. package/dist/types/tools/renderers.d.ts +7 -11
  100. package/dist/types/tools/ssh.d.ts +1 -1
  101. package/dist/types/tools/todo.d.ts +1 -1
  102. package/dist/types/tools/tts.d.ts +25 -0
  103. package/dist/types/tools/write.d.ts +1 -1
  104. package/dist/types/tts/downloader.d.ts +20 -0
  105. package/dist/types/tts/index.d.ts +8 -0
  106. package/dist/types/tts/models.d.ts +82 -0
  107. package/dist/types/tts/player.d.ts +32 -0
  108. package/dist/types/tts/runtime.d.ts +6 -0
  109. package/dist/types/tts/streaming-player.d.ts +41 -0
  110. package/dist/types/tts/tts-client.d.ts +93 -0
  111. package/dist/types/tts/tts-protocol.d.ts +95 -0
  112. package/dist/types/tts/tts-worker.d.ts +2 -0
  113. package/dist/types/tts/vocalizer.d.ts +41 -0
  114. package/dist/types/tts/wav.d.ts +8 -0
  115. package/dist/types/utils/tool-choice.d.ts +8 -0
  116. package/dist/types/utils/tools-manager.d.ts +2 -1
  117. package/dist/types/utils/tools-manager.test.d.ts +1 -0
  118. package/dist/types/web/scrapers/github.d.ts +1 -1
  119. package/package.json +15 -14
  120. package/src/async/job-manager.ts +49 -0
  121. package/src/autolearn/controller.ts +139 -0
  122. package/src/autolearn/managed-skills.ts +257 -0
  123. package/src/autoresearch/state.ts +1 -1
  124. package/src/autoresearch/types.ts +1 -1
  125. package/src/cli/args.ts +56 -2
  126. package/src/cli/session-picker.ts +2 -1
  127. package/src/cli/setup-cli.ts +148 -47
  128. package/src/cli/setup-model-picker.ts +43 -0
  129. package/src/cli-commands.ts +1 -0
  130. package/src/cli.ts +45 -13
  131. package/src/collab/host.ts +1 -1
  132. package/src/collab/protocol.ts +1 -1
  133. package/src/commands/say.ts +102 -0
  134. package/src/commands/setup.ts +1 -1
  135. package/src/commit/agentic/tools/analyze-file.ts +3 -0
  136. package/src/config/keybindings.ts +2 -2
  137. package/src/config/model-discovery.ts +11 -5
  138. package/src/config/model-registry.ts +64 -9
  139. package/src/config/models-config-schema.ts +4 -1
  140. package/src/config/models-config.ts +2 -1
  141. package/src/config/settings-schema.ts +248 -32
  142. package/src/config/settings.ts +10 -0
  143. package/src/discovery/builtin.ts +23 -1
  144. package/src/discovery/claude-plugins.ts +44 -5
  145. package/src/discovery/helpers.ts +41 -1
  146. package/src/eval/__tests__/budget-bridge.test.ts +1 -1
  147. package/src/eval/js/shared/prelude.txt +69 -17
  148. package/src/export/html/index.ts +3 -6
  149. package/src/extensibility/extensions/model-api.ts +41 -0
  150. package/src/extensibility/extensions/runner.ts +4 -0
  151. package/src/extensibility/extensions/types.ts +52 -1
  152. package/src/extensibility/extensions/wrapper.ts +41 -5
  153. package/src/extensibility/hooks/index.ts +2 -1
  154. package/src/extensibility/plugins/legacy-pi-compat.ts +43 -13
  155. package/src/extensibility/plugins/loader.ts +30 -19
  156. package/src/extensibility/plugins/manager.ts +221 -90
  157. package/src/extensibility/shared-events.ts +1 -1
  158. package/src/extensibility/skills.ts +96 -15
  159. package/src/goals/guided-setup.ts +133 -0
  160. package/src/goals/state.ts +1 -1
  161. package/src/hindsight/transcript.ts +1 -1
  162. package/src/index.ts +5 -0
  163. package/src/internal-urls/docs-index.generated.ts +10 -10
  164. package/src/internal-urls/history-protocol.ts +1 -1
  165. package/src/internal-urls/local-protocol.ts +29 -7
  166. package/src/main.ts +27 -7
  167. package/src/mcp/startup-events.ts +21 -0
  168. package/src/mcp/transports/stdio.ts +2 -1
  169. package/src/memories/index.ts +146 -11
  170. package/src/memory-backend/local-backend.ts +11 -5
  171. package/src/mnemopi/backend.ts +1 -0
  172. package/src/mnemopi/config.ts +26 -10
  173. package/src/modes/acp/acp-agent.ts +3 -5
  174. package/src/modes/components/agent-hub.ts +49 -4
  175. package/src/modes/components/assistant-message.ts +4 -37
  176. package/src/modes/components/compaction-summary-message.ts +125 -26
  177. package/src/modes/components/custom-editor.test.ts +96 -0
  178. package/src/modes/components/custom-editor.ts +164 -8
  179. package/src/modes/components/session-selector.ts +1 -1
  180. package/src/modes/components/settings-defs.ts +7 -0
  181. package/src/modes/components/tool-execution.ts +82 -43
  182. package/src/modes/components/transcript-container.ts +70 -1
  183. package/src/modes/components/tree-selector.ts +1 -1
  184. package/src/modes/components/usage-row.ts +18 -0
  185. package/src/modes/components/user-message.ts +4 -2
  186. package/src/modes/controllers/command-controller.ts +14 -4
  187. package/src/modes/controllers/event-controller.ts +78 -11
  188. package/src/modes/controllers/extension-ui-controller.ts +6 -0
  189. package/src/modes/controllers/input-controller.ts +258 -27
  190. package/src/modes/controllers/selector-controller.ts +12 -2
  191. package/src/modes/gradient-highlight.ts +21 -9
  192. package/src/modes/image-references.ts +20 -0
  193. package/src/modes/interactive-mode.ts +286 -40
  194. package/src/modes/magic-keywords.ts +27 -5
  195. package/src/modes/rpc/rpc-mode.ts +146 -14
  196. package/src/modes/rpc/rpc-subagents.ts +2 -2
  197. package/src/modes/rpc/rpc-types.ts +8 -2
  198. package/src/modes/runtime-init.ts +28 -3
  199. package/src/modes/theme/theme.ts +98 -50
  200. package/src/modes/types.ts +6 -2
  201. package/src/modes/utils/hotkeys-markdown.ts +1 -1
  202. package/src/modes/utils/ui-helpers.ts +34 -6
  203. package/src/priority.json +5 -1
  204. package/src/prompts/agents/task.md +1 -0
  205. package/src/prompts/goals/guided-goal-interview.md +8 -0
  206. package/src/prompts/goals/guided-goal-system.md +12 -0
  207. package/src/prompts/memories/read-path.md +6 -0
  208. package/src/prompts/system/autolearn-guidance-learn.md +1 -0
  209. package/src/prompts/system/autolearn-guidance.md +7 -0
  210. package/src/prompts/system/autolearn-nudge.md +3 -0
  211. package/src/prompts/system/eager-task.md +7 -0
  212. package/src/prompts/system/eager-todo.md +11 -6
  213. package/src/prompts/system/subagent-system-prompt.md +4 -0
  214. package/src/prompts/system/system-prompt.md +10 -5
  215. package/src/prompts/system/title-marker-instruction.md +1 -0
  216. package/src/prompts/system/title-system-marker.md +16 -0
  217. package/src/prompts/tools/job.md +1 -0
  218. package/src/prompts/tools/learn.md +7 -0
  219. package/src/prompts/tools/manage-skill.md +9 -0
  220. package/src/prompts/tools/task.md +3 -0
  221. package/src/registry/agent-registry.ts +30 -0
  222. package/src/sdk.ts +88 -24
  223. package/src/secrets/obfuscator.ts +1 -1
  224. package/src/session/agent-session.ts +209 -87
  225. package/src/session/history-storage.ts +2 -2
  226. package/src/session/indexed-session-storage.ts +7 -17
  227. package/src/session/session-context.ts +352 -0
  228. package/src/session/session-entries.ts +194 -0
  229. package/src/session/session-listing.ts +588 -0
  230. package/src/session/session-loader.ts +106 -0
  231. package/src/session/session-manager.ts +933 -3145
  232. package/src/session/session-migrations.ts +78 -0
  233. package/src/session/session-paths.ts +193 -0
  234. package/src/session/session-persistence.ts +131 -0
  235. package/src/session/session-storage.ts +91 -50
  236. package/src/session/snapcompact-inline.ts +21 -1
  237. package/src/session/snapcompact-savings-journal.ts +113 -0
  238. package/src/session/tool-choice-queue.ts +23 -11
  239. package/src/slash-commands/builtin-registry.ts +25 -3
  240. package/src/stt/asr-client.ts +520 -0
  241. package/src/stt/asr-protocol.ts +65 -0
  242. package/src/stt/asr-worker.ts +790 -0
  243. package/src/stt/downloader.ts +107 -47
  244. package/src/stt/endpointer.ts +259 -0
  245. package/src/stt/index.ts +5 -1
  246. package/src/stt/models.ts +150 -0
  247. package/src/stt/recorder.ts +247 -60
  248. package/src/stt/stt-controller.ts +201 -22
  249. package/src/stt/transcriber.ts +37 -68
  250. package/src/stt/wav.ts +173 -0
  251. package/src/system-prompt.ts +8 -0
  252. package/src/task/agents.ts +1 -2
  253. package/src/task/executor.ts +49 -15
  254. package/src/task/index.ts +60 -6
  255. package/src/task/render.ts +83 -8
  256. package/src/task/types.ts +53 -0
  257. package/src/tools/ask.ts +8 -0
  258. package/src/tools/bash.ts +4 -3
  259. package/src/tools/eval-render.ts +4 -3
  260. package/src/tools/index.ts +40 -4
  261. package/src/tools/irc.ts +10 -2
  262. package/src/tools/job.ts +14 -2
  263. package/src/tools/learn.ts +144 -0
  264. package/src/tools/manage-skill.ts +104 -0
  265. package/src/tools/plan-mode-guard.ts +53 -19
  266. package/src/tools/renderers.ts +7 -11
  267. package/src/tools/ssh.ts +4 -3
  268. package/src/tools/todo.ts +1 -1
  269. package/src/tools/tts.ts +203 -92
  270. package/src/tools/write.ts +18 -2
  271. package/src/tts/downloader.ts +64 -0
  272. package/src/tts/index.ts +8 -0
  273. package/src/tts/models.ts +137 -0
  274. package/src/tts/player.ts +137 -0
  275. package/src/tts/runtime.ts +21 -0
  276. package/src/tts/streaming-player.ts +266 -0
  277. package/src/tts/tts-client.ts +647 -0
  278. package/src/tts/tts-protocol.ts +60 -0
  279. package/src/tts/tts-worker.ts +497 -0
  280. package/src/tts/vocalizer.ts +162 -0
  281. package/src/tts/wav.ts +58 -0
  282. package/src/utils/title-generator.ts +48 -5
  283. package/src/utils/tool-choice.ts +16 -0
  284. package/src/utils/tools-manager.test.ts +25 -0
  285. package/src/utils/tools-manager.ts +19 -1
  286. package/src/web/scrapers/github.ts +96 -0
  287. package/src/web/search/index.ts +13 -0
  288. package/src/web/search/providers/searxng.ts +13 -1
  289. package/dist/types/stt/setup.d.ts +0 -18
  290. package/src/stt/setup.ts +0 -52
  291. package/src/stt/transcribe.py +0 -70
@@ -0,0 +1,18 @@
1
+ import type { AgentSession } from "../session/agent-session";
2
+ export interface GuidedGoalMessage {
3
+ role: "user" | "assistant";
4
+ content: string;
5
+ }
6
+ export type GuidedGoalTurnResult = {
7
+ kind: "question";
8
+ question: string;
9
+ objective?: string;
10
+ } | {
11
+ kind: "ready";
12
+ objective: string;
13
+ };
14
+ export interface GuidedGoalTurnOptions {
15
+ messages: readonly GuidedGoalMessage[];
16
+ signal?: AbortSignal;
17
+ }
18
+ export declare function runGuidedGoalTurn(session: AgentSession, options: GuidedGoalTurnOptions): Promise<GuidedGoalTurnResult>;
@@ -1,4 +1,4 @@
1
- import type { UsageStatistics } from "../session/session-manager";
1
+ import type { UsageStatistics } from "../session/session-entries";
2
2
  export type GoalStatus = "active" | "paused" | "budget-limited" | "complete" | "dropped";
3
3
  export interface Goal {
4
4
  id: string;
@@ -6,7 +6,7 @@
6
6
  * messages, and anything else that isn't a primary conversation turn. Each
7
7
  * surviving message's `TextContent` parts are joined with newlines.
8
8
  */
9
- import type { SessionEntry } from "../session/session-manager";
9
+ import type { SessionEntry } from "../session/session-entries";
10
10
  import type { HindsightMessage } from "./content";
11
11
  export interface ReadonlySessionManagerLike {
12
12
  getEntries(): SessionEntry[];
@@ -25,8 +25,13 @@ export * from "./session/auth-storage";
25
25
  export * from "./session/indexed-session-storage";
26
26
  export * from "./session/messages";
27
27
  export * from "./session/redis-session-storage";
28
+ export * from "./session/session-context";
28
29
  export * from "./session/session-dump-format";
30
+ export * from "./session/session-entries";
31
+ export * from "./session/session-listing";
32
+ export * from "./session/session-loader";
29
33
  export * from "./session/session-manager";
34
+ export * from "./session/session-migrations";
30
35
  export * from "./session/session-storage";
31
36
  export * from "./session/sql-session-storage";
32
37
  export * from "./task/executor";
@@ -3,8 +3,10 @@ export interface LocalProtocolOptions {
3
3
  getArtifactsDir?: () => string | null;
4
4
  getSessionId?: () => string | null;
5
5
  }
6
- export declare function resolveLocalRoot(options: LocalProtocolOptions): string;
7
- export declare function resolveLocalUrlToPath(input: string | InternalUrl, options: LocalProtocolOptions): string;
6
+ /** Resolve the session-scoped local:// root, shortening long Windows artifact paths before writes hit MAX_PATH. */
7
+ export declare function resolveLocalRoot(options: LocalProtocolOptions, platform?: NodeJS.Platform): string;
8
+ /** Resolve a local:// URL to an on-disk path under the active session's local root. */
9
+ export declare function resolveLocalUrlToPath(input: string | InternalUrl, options: LocalProtocolOptions, platform?: NodeJS.Platform): string;
8
10
  /**
9
11
  * On-disk roots the eval helpers (`read`/`write`/`append`) substitute for
10
12
  * internal-URL schemes so e.g. `write("local://x.md")` lands where a later
@@ -1,4 +1,4 @@
1
- import type { Args } from "./cli/args";
1
+ import { type Args } from "./cli/args";
2
2
  import { ModelRegistry } from "./config/model-registry";
3
3
  import { type ScopedModel } from "./config/model-resolver";
4
4
  import { Settings } from "./config/settings";
@@ -7,14 +7,15 @@ import type { SubmittedUserInput } from "./modes/types";
7
7
  import { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession, discoverAuthStorage } from "./sdk";
8
8
  import type { AgentSession } from "./session/agent-session";
9
9
  import type { AuthStorage } from "./session/auth-storage";
10
- import { type SessionInfo, SessionManager } from "./session/session-manager";
10
+ import { type SessionInfo } from "./session/session-listing";
11
+ import { SessionManager } from "./session/session-manager";
11
12
  type RunAcpMode = (createSession: AcpSessionFactory) => Promise<never>;
12
13
  export interface InteractiveModeNotify {
13
14
  kind: "warn" | "error" | "info";
14
15
  message: string;
15
16
  }
16
17
  export declare function buildModelScopeNotification(scopedModelsForDisplay: readonly Pick<ScopedModel, "model" | "thinkingLevel" | "explicitThinkingLevel">[], startupQuiet: boolean): InteractiveModeNotify | null;
17
- export declare function submitInteractiveInput(mode: Pick<InteractiveMode, "markPendingSubmissionStarted" | "finishPendingSubmission" | "showError" | "checkShutdownRequested">, session: Pick<AgentSession, "prompt" | "promptCustomMessage">, input: SubmittedUserInput): Promise<void>;
18
+ export declare function submitInteractiveInput(mode: Pick<InteractiveMode, "markPendingSubmissionStarted" | "finishPendingSubmission" | "showError" | "checkShutdownRequested">, session: Pick<AgentSession, "prompt" | "promptCustomMessage" | "isStreaming">, input: SubmittedUserInput): Promise<void>;
18
19
  type AcpSessionFactory = (cwd: string) => Promise<AgentSession>;
19
20
  export interface AcpSessionFactoryOptions {
20
21
  baseOptions: CreateAgentSessionOptions;
@@ -0,0 +1,11 @@
1
+ export declare const MCP_CONNECTING_EVENT_CHANNEL = "mcp:connecting";
2
+ export type McpConnectingEvent = {
3
+ serverNames: string[];
4
+ };
5
+ export declare function formatMCPConnectingMessage(serverNames: string[]): string;
6
+ /**
7
+ * Runtime validator for the cross-module event payload. The event bus is
8
+ * untyped at runtime, so the subscriber verifies the shape before formatting
9
+ * rather than trusting a cast — a malformed emit is ignored instead of throwing.
10
+ */
11
+ export declare function isMcpConnectingEvent(data: unknown): data is McpConnectingEvent;
@@ -1,5 +1,6 @@
1
1
  import type { ModelRegistry } from "../config/model-registry";
2
2
  import type { Settings } from "../config/settings";
3
+ import type { MemoryBackendSaveInput, MemoryBackendSaveResult } from "../memory-backend/types";
3
4
  import type { AgentSession } from "../session/agent-session";
4
5
  /**
5
6
  * Start the background memory startup pipeline.
@@ -26,3 +27,9 @@ export declare function clearMemoryData(agentDir: string, cwd: string): Promise<
26
27
  */
27
28
  export declare function enqueueMemoryConsolidation(agentDir: string, cwd: string, sourceUpdatedAt?: number): void;
28
29
  export declare function getMemoryRoot(agentDir: string, cwd: string): string;
30
+ /**
31
+ * Append one lesson to the project's `learned.md` (newest-first, deduped,
32
+ * capped, secret-redacted, injection-neutralized). The file backs the `learn`
33
+ * tool when `memory.backend` is `local`.
34
+ */
35
+ export declare function saveLearnedLesson(agentDir: string, cwd: string, input: MemoryBackendSaveInput): Promise<MemoryBackendSaveResult>;
@@ -2,8 +2,9 @@ import type { MemoryBackend } from "./types";
2
2
  /**
3
3
  * Wraps the existing `memories/` module as a `MemoryBackend`.
4
4
  *
5
- * No behavioural change every call delegates to the legacy entry points so
6
- * the local memory pipeline (rollout summarisation SQLite → memory_summary.md)
7
- * keeps working exactly as before.
5
+ * The rollout-summarisation pipeline (rollouts SQLite memory_summary.md) is
6
+ * delegated unchanged. On top of it, `save()` persists `learn`-tool lessons to
7
+ * `learned.md` (so `status()` reports `writable: true`); structured search is
8
+ * still unavailable.
8
9
  */
9
10
  export declare const localBackend: MemoryBackend;
@@ -46,10 +46,10 @@ export interface MnemopiBankScope {
46
46
  export declare function computeMnemopiBankScope(configured: string | undefined, cwd: string, scoping: MnemopiScoping): MnemopiBankScope;
47
47
  /**
48
48
  * Discover sibling banks under `<dbDir>/banks/` whose `working_memory` rows
49
- * already carry the active `cwd` in `metadata_json.$.cwd`, and add them to
50
- * the recall set. This rescues memories stranded by a previous, less-stable
51
- * bank derivation (#2412) without changing the write target — only recall is
52
- * widened.
49
+ * all carry the active `cwd` in `metadata_json.$.cwd`, and add those safe
50
+ * single-cwd banks to the recall set. This rescues memories stranded by a
51
+ * previous, less-stable bank derivation (#2412) without recalling mixed-cwd
52
+ * legacy banks wholesale under per-project isolation.
53
53
  *
54
54
  * Robust by design: a missing banks directory, unreadable bank dir, or
55
55
  * corrupt SQLite file is silently skipped. Scanning is capped at
@@ -52,6 +52,12 @@ export interface AgentHubDeps {
52
52
  export declare class AgentHubOverlayComponent extends Container {
53
53
  #private;
54
54
  constructor(deps: AgentHubDeps);
55
+ /**
56
+ * Whether the table view has no agents to show (every registered agent except
57
+ * Main, after the persisted-subagent scan in the constructor). The double-←
58
+ * gesture reads this to stay inert when there is nothing to open.
59
+ */
60
+ get isEmpty(): boolean;
55
61
  /** Tear down every subscription and timer. Called by the overlay owner on close. */
56
62
  dispose(): void;
57
63
  render(width: number): readonly string[];
@@ -1,4 +1,4 @@
1
- import type { AssistantMessage, ImageContent, Usage } from "@oh-my-pi/pi-ai";
1
+ import type { AssistantMessage, ImageContent } from "@oh-my-pi/pi-ai";
2
2
  import { Container, type ImageBudget } from "@oh-my-pi/pi-tui";
3
3
  import type { AssistantThinkingRenderer } from "../../extensibility/extensions/types";
4
4
  /**
@@ -22,7 +22,6 @@ export declare class AssistantMessageComponent extends Container {
22
22
  getTranscriptBlockVersion(): number;
23
23
  markTranscriptBlockFinalized(): void;
24
24
  setToolResultImages(toolCallId: string, images: ImageContent[]): void;
25
- setUsageInfo(usage: Usage): void;
26
25
  updateContent(message: AssistantMessage, opts?: {
27
26
  transient?: boolean;
28
27
  }): void;
@@ -1,5 +1,5 @@
1
1
  import { type Component } from "@oh-my-pi/pi-tui";
2
- import type { CompactionSummaryMessage } from "../../session/messages";
2
+ import type { CompactionSummaryMessage, CustomMessage } from "../../session/messages";
3
3
  /**
4
4
  * Compaction point in the transcript, rendered as a slim horizontal divider:
5
5
  *
@@ -17,3 +17,17 @@ export declare class CompactionSummaryMessageComponent implements Component {
17
17
  invalidate(): void;
18
18
  render(width: number): readonly string[];
19
19
  }
20
+ /**
21
+ * Handoff is a compaction strategy too, but it is persisted as a custom message
22
+ * so the LLM sees the handoff-specific developer context. Render it with the
23
+ * same divider affordance as `/compact` instead of the generic `[handoff]` box.
24
+ */
25
+ export declare class HandoffSummaryMessageComponent implements Component {
26
+ #private;
27
+ private readonly message;
28
+ constructor(message: CustomMessage<unknown>);
29
+ setExpanded(expanded: boolean): void;
30
+ invalidate(): void;
31
+ render(width: number): readonly string[];
32
+ }
33
+ export declare function createHandoffSummaryMessageComponent(message: CustomMessage<unknown>, expanded: boolean): HandoffSummaryMessageComponent | undefined;
@@ -1,6 +1,13 @@
1
1
  import { Editor, type KeyId } from "@oh-my-pi/pi-tui";
2
2
  import type { AppKeybinding } from "../../config/keybindings";
3
3
  type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.display.reset" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.expand" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.clipboard.pasteImage" | "app.clipboard.pasteTextRaw" | "app.clipboard.copyPrompt">;
4
+ /** Plain spaces from one auto-repeat run that trigger the space-hold push-to-talk STT gesture.
5
+ * Holding the space bar makes the terminal emit a burst of spaces; once more than this many land
6
+ * in the editor we treat it as "space held", track them back out, and start recording. */
7
+ export declare const SPACE_HOLD_THRESHOLD = 5;
8
+ /** Idle gap (ms) after the last repeated space that counts as the space bar being released, ending
9
+ * the push-to-talk recording. Must comfortably exceed the OS key-repeat interval. */
10
+ export declare const SPACE_HOLD_RELEASE_MS = 250;
4
11
  export declare function extractBracketedImagePastePaths(data: string): string[] | undefined;
5
12
  export declare function extractBracketedImagePastePath(data: string): string | undefined;
6
13
  /**
@@ -12,10 +19,32 @@ export declare class CustomEditor extends Editor {
12
19
  /** Treat image/paste markers as indivisible: a stray backspace deletes the whole token
13
20
  * instead of corrupting `[Paste #1, +30 lines]` into plain text. */
14
21
  atomicTokenPattern: RegExp;
22
+ /** Magic-keyword shimmer cadence — drives one editor repaint every 70 ms while
23
+ * a keyword is on screen and the prompt is focused. ~14 frames/s is smooth
24
+ * without flooding the renderer. */
25
+ static readonly SHIMMER_FRAME_MS = 70;
26
+ /** Time for the gradient to sweep one full cycle across each keyword. */
27
+ static readonly SHIMMER_PERIOD_MS = 1800;
15
28
  /** Gradient-highlight the "ultrathink" / "orchestrate" / "workflowz" keywords as the user types
16
29
  * them, skipping any occurrence inside code spans, fenced blocks, or XML sections. Also make
17
- * pasted image placeholders visually distinct and hyperlink them once their blob file exists. */
30
+ * pasted image placeholders visually distinct and hyperlink them once their blob file exists.
31
+ * When the editor is focused, the buffer contains a magic keyword, and `magicKeywords.enabled`
32
+ * is on, the gradient shifts every frame to produce a Claude-Code-style shimmer; each render
33
+ * schedules the next frame, so losing focus, deleting the keyword, or flipping the setting
34
+ * stops the animation on its own. The static glow itself runs even when shimmering is gated
35
+ * off, matching existing behavior for the editor and sent bubbles. */
18
36
  decorateText: (text: string) => string;
37
+ /** Optional test/host override for the magic-keyword shimmer gate. When
38
+ * defined, takes precedence over the global `magicKeywords.enabled` setting,
39
+ * letting tests assert the gating behaviour without mutating the
40
+ * process-wide Settings singleton (which races with parallel test files —
41
+ * see issue #2582). Production wires this through the host's Settings
42
+ * reader and updates it on the relevant setting change. */
43
+ magicKeywordsEnabledOverride: boolean | undefined;
44
+ /** Bind the host's render request callback. Idempotent — the host wires this
45
+ * once after construction (and again after `setEditorComponent` swaps the
46
+ * editor). Passing `undefined` clears any pending frame. */
47
+ setShimmerRepaintHandler(handler: (() => void) | undefined): void;
19
48
  onEscape?: () => void;
20
49
  onClear?: () => void;
21
50
  onExit?: () => void;
@@ -44,6 +73,15 @@ export declare class CustomEditor extends Editor {
44
73
  onCapsLock?: () => void;
45
74
  /** Called when left-arrow is pressed while the editor is empty (cursor necessarily at start). */
46
75
  onLeftAtStart?: () => void;
76
+ /** Fired when a sustained space-bar hold is recognized — the push-to-talk STT start. The
77
+ * optimistically-typed spaces have already been deleted by the time this runs. */
78
+ onSpaceHoldStart?: () => void;
79
+ /** Fired when the held space bar is released (detected as an idle gap with no further repeated
80
+ * spaces) — the push-to-talk STT stop. */
81
+ onSpaceHoldEnd?: () => void;
82
+ /** Gate for the space-hold gesture. Returns false to keep the space bar inserting spaces
83
+ * normally; wired to `stt.enabled` so disabling STT restores plain space behavior. */
84
+ sttHoldEnabled?: () => boolean;
47
85
  setActionKeys(action: ConfigurableEditorAction, keys: KeyId[]): void;
48
86
  /**
49
87
  * Register a custom key handler. Extensions use this for shortcuts.
@@ -1,5 +1,5 @@
1
1
  import { type Component, Container } from "@oh-my-pi/pi-tui";
2
- import type { SessionInfo } from "../../session/session-manager";
2
+ import type { SessionInfo } from "../../session/session-listing";
3
3
  /** Returns the IDs of sessions whose recorded prompts match a query, best first. */
4
4
  export type SessionHistoryMatcher = (query: string) => string[];
5
5
  /**
@@ -1,6 +1,6 @@
1
1
  import type { SnapshotStore } from "@oh-my-pi/hashline";
2
2
  import type { AgentTool } from "@oh-my-pi/pi-agent-core";
3
- import { type Component, Container, type TUI } from "@oh-my-pi/pi-tui";
3
+ import { type Component, Container, type NativeScrollbackLiveRegion, type TUI } from "@oh-my-pi/pi-tui";
4
4
  /**
5
5
  * Transcript-side probe telling a block whether it is still inside the live
6
6
  * (repaintable) region. Implemented by `TranscriptContainer`; injected rather
@@ -33,10 +33,20 @@ export interface ToolExecutionHandle {
33
33
  setArgsComplete(toolCallId?: string): void;
34
34
  setExpanded(expanded: boolean): void;
35
35
  }
36
+ /** Drive pending-tool redraws at 30fps for live tool headers and displaceable
37
+ * poll blocks. The TUI throttles at the same cadence, and static frames diff to
38
+ * a no-op redraw at ~zero cost. */
39
+ export declare const SPINNER_RENDER_INTERVAL_MS: number;
40
+ /** Advance the spinner glyph at its classic ~12.5fps step, decoupled from the
41
+ * render cadence (mirrors `Loader`). */
42
+ export declare const SPINNER_GLYPH_ADVANCE_MS = 80;
43
+ /** Phase-locked spinner glyph index shared by every live tool block so parallel
44
+ * spinners advance in lockstep instead of each tracking its own start time. */
45
+ export declare function sharedSpinnerFrame(frameCount: number, now?: number): number;
36
46
  /**
37
47
  * Component that renders a tool call with its result (updateable)
38
48
  */
39
- export declare class ToolExecutionComponent extends Container {
49
+ export declare class ToolExecutionComponent extends Container implements NativeScrollbackLiveRegion {
40
50
  #private;
41
51
  constructor(toolName: string, args: any, options: ToolExecutionOptions | undefined, tool: AgentTool | undefined, ui: TUI, cwd?: string, _toolCallId?: string);
42
52
  updateArgs(args: any, _toolCallId?: string): void;
@@ -63,6 +73,14 @@ export declare class ToolExecutionComponent extends Container {
63
73
  details?: any;
64
74
  isError?: boolean;
65
75
  }, isPartial?: boolean, _toolCallId?: string): void;
76
+ /**
77
+ * Standalone harnesses may mount a tool component directly under `TUI`
78
+ * instead of inside `TranscriptContainer`. In that shape the component must
79
+ * report its own live-region seam for provisional previews, or the core
80
+ * renderer treats it like shell output and commits tail-window edit/eval/bash
81
+ * previews to immutable native scrollback before the result replaces them.
82
+ */
83
+ getNativeScrollbackLiveRegionStart(): number | undefined;
66
84
  /**
67
85
  * Whether this block has reached a terminal state for transcript freezing.
68
86
  * Reports `false` while it can still visually change so the
@@ -74,20 +92,12 @@ export declare class ToolExecutionComponent extends Container {
74
92
  isTranscriptBlockFinalized(): boolean;
75
93
  /**
76
94
  * Whether this still-live block's settled rows may enter native scrollback
77
- * (see `FinalizableBlock.isTranscriptBlockCommitStable`). Classification is
78
- * per renderer (`ToolRenderer.provisionalPendingPreview`): tail-window
79
- * streaming views (edit's streamed-diff tail, bash/ssh command caps, eval
80
- * cells) are re-anchored top-first by the result render, so promoting
81
- * their visually static head — e.g. an edit preview idling on its last
82
- * frame while the apply + LSP pass runs — would strand a stale copy of
83
- * the call box above the final block the moment the result lands. Every
84
- * other pending preview streams top-anchored append-shaped rows the
85
- * result render preserves (a task call's context/assignment markdown, a
86
- * write's content), so it stays commit-eligible — a call taller than the
87
- * viewport scrolls into native history mid-stream instead of reading as
88
- * cut off until the result. Expanded blocks always stream top-anchored
89
- * (the over-tall write/eval scrollback contract). Displaceable waiting
90
- * polls are removed wholesale by the next poll and must never commit.
95
+ * (see `FinalizableBlock.isTranscriptBlockCommitStable`). Renderers classify
96
+ * pending views by durability instead of by tool name: a provisional view is
97
+ * allowed to be useful on screen, but finalization may replace or re-anchor
98
+ * it wholesale, so committing any of its rows would strand stale preview
99
+ * bytes in immutable scrollback. Non-provisional views stream rows whose
100
+ * committed prefix survives the remaining transitions.
91
101
  */
92
102
  isTranscriptBlockCommitStable(): boolean;
93
103
  /**
@@ -1,4 +1,4 @@
1
- import { type Component, Container, type NativeScrollbackCommittedRows, type NativeScrollbackLiveRegion, type RenderStablePrefix } from "@oh-my-pi/pi-tui";
1
+ import { type Component, Container, type NativeScrollbackCommittedRows, type NativeScrollbackLiveRegion, type RenderStablePrefix, type ViewportTailProvider } from "@oh-my-pi/pi-tui";
2
2
  /**
3
3
  * Transcript container that renders every block's current content each frame
4
4
  * and reports the live-region seam (`NativeScrollbackLiveRegion`) that gates
@@ -22,7 +22,7 @@ import { type Component, Container, type NativeScrollbackCommittedRows, type Nat
22
22
  * through {@link RenderStablePrefix} so the engine can skip marker scanning,
23
23
  * line preparation, and the committed-prefix audit for those rows.
24
24
  */
25
- export declare class TranscriptContainer extends Container implements NativeScrollbackLiveRegion, NativeScrollbackCommittedRows, RenderStablePrefix {
25
+ export declare class TranscriptContainer extends Container implements NativeScrollbackLiveRegion, NativeScrollbackCommittedRows, RenderStablePrefix, ViewportTailProvider {
26
26
  #private;
27
27
  invalidate(): void;
28
28
  clear(): void;
@@ -30,6 +30,7 @@ export declare class TranscriptContainer extends Container implements NativeScro
30
30
  getRenderStablePrefixRows(): number;
31
31
  getNativeScrollbackLiveRegionStart(): number | undefined;
32
32
  getNativeScrollbackCommitSafeEnd(): number | undefined;
33
+ getNativeScrollbackSnapshotSafeEnd(): number | undefined;
33
34
  /**
34
35
  * Whether `component` sits below a still-mutating block — i.e. inside the
35
36
  * live region, where its rows cannot have been committed to native
@@ -52,6 +53,26 @@ export declare class TranscriptContainer extends Container implements NativeScro
52
53
  * become commit-eligible native-scrollback history.
53
54
  */
54
55
  isBlockInLiveRegion(component: Component): boolean;
56
+ /**
57
+ * Render only the bottom `maxRows` rows of the transcript at `width`, walking
58
+ * blocks from the last toward the first and stopping the instant enough rows
59
+ * are collected — blocks above the fold are never rendered. The engine's
60
+ * resize viewport fast path uses this so a drag (a SIGWINCH burst, each event
61
+ * a fresh width that misses every per-width cache) re-lays-out only the
62
+ * handful of visible blocks instead of the whole history every event.
63
+ *
64
+ * State-isolated by contract: touches none of the persistent full-compose
65
+ * fields (#lines, #segments, the per-block diff snapshots, the commit/stable
66
+ * bookkeeping), so the authoritative full render on settle reconciles exactly
67
+ * as if this never ran. Calling each block's render() still warms its own
68
+ * per-width cache, which that settle render then reuses for free.
69
+ *
70
+ * Consecutive visible blocks are joined by exactly one blank separator, the
71
+ * same rule render() applies, so the result equals the bottom of a full
72
+ * render except for an at-most-one-row separator on the topmost included
73
+ * block — a transient discrepancy the settle paint overwrites.
74
+ */
75
+ renderViewportTail(width: number, maxRows: number): readonly string[];
55
76
  render(width: number): readonly string[];
56
77
  }
57
78
  /**
@@ -1,6 +1,6 @@
1
1
  import { type Component, Container } from "@oh-my-pi/pi-tui";
2
2
  import type { TreeFilterMode } from "../../config/settings-schema";
3
- import type { SessionTreeNode } from "../../session/session-manager";
3
+ import type { SessionTreeNode } from "../../session/session-entries";
4
4
  /** Filter mode for tree display */
5
5
  type FilterMode = TreeFilterMode;
6
6
  declare class TreeList implements Component {
@@ -0,0 +1,3 @@
1
+ import type { Usage } from "@oh-my-pi/pi-ai";
2
+ import { Container } from "@oh-my-pi/pi-tui";
3
+ export declare function createUsageRowBlock(usage: Usage): Container;
@@ -29,14 +29,14 @@ export declare class CommandController {
29
29
  handleRenameCommand(title: string): Promise<void>;
30
30
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
31
31
  handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
32
- handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
32
+ handleCompactCommand(customInstructions?: string, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
33
33
  /**
34
34
  * TUI handler for `/shake`. `elide` drops heavy structural content and
35
35
  * `images` strips image blocks. Rebuilds the chat and reports counts.
36
36
  */
37
37
  handleShakeCommand(mode: ShakeMode): Promise<void>;
38
38
  handleSkillCommand(skillPath: string, args: string): Promise<void>;
39
- executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
39
+ executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
40
40
  handleHandoffCommand(customInstructions?: string): Promise<void>;
41
41
  }
42
42
  export declare function renderProviderSection(details: ProviderDetails, uiTheme: Pick<typeof theme, "fg">): string;
@@ -27,6 +27,20 @@ export declare class InputController {
27
27
  handleImagePathPaste(path: string): Promise<void>;
28
28
  handleImagePaste(): Promise<boolean>;
29
29
  handleClipboardTextRawPaste(): Promise<void>;
30
+ /**
31
+ * Editor `onLargePaste` hook: gate a marker-sized paste behind the large-paste menu. Returns
32
+ * `true` to intercept (the editor skips its default `[Paste]` marker) once the paste reaches the
33
+ * configured `paste.largeMenuThreshold` line count; otherwise `false` for default collapse-to-marker
34
+ * behavior. The async menu is fired and forgotten — the editor only needs the synchronous verdict.
35
+ */
36
+ handleLargePaste(text: string, lineCount: number): boolean;
37
+ /**
38
+ * Present the large-paste menu and apply the chosen action: wrap in a code block or in XML tags
39
+ * (both collapse to a `[Paste]` marker that expands on submit), or save the text to a file and
40
+ * reference its path so the agent can `read` it on demand. Cancelling (Esc) falls back to the
41
+ * default inline paste marker, so the pasted content is never lost.
42
+ */
43
+ presentLargePasteMenu(text: string, lineCount: number): Promise<void>;
30
44
  createAutocompleteProvider(commands: SlashCommand[], basePath: string): AutocompleteProvider;
31
45
  /** Copy the current editor line to the system clipboard. */
32
46
  handleCopyCurrentLine(): void;
@@ -43,5 +43,7 @@ export declare class SelectorController {
43
43
  showOAuthSelector(mode: "login" | "logout", providerId?: string): Promise<void>;
44
44
  showResetUsageSelector(): Promise<void>;
45
45
  showDebugSelector(): Promise<void>;
46
- showAgentHub(observers: SessionObserverRegistry): void;
46
+ showAgentHub(observers: SessionObserverRegistry, options?: {
47
+ requireContent?: boolean;
48
+ }): void;
47
49
  }
@@ -1,7 +1,12 @@
1
- /** A gradient keyword highlighter. `resetTo` is the SGR foreground sequence
2
- * re-emitted after each painted keyword so surrounding text keeps its color;
3
- * it defaults to a plain foreground reset (editor / default-colored text). */
4
- export type KeywordHighlighter = (text: string, resetTo?: string) => string;
1
+ /** A gradient keyword highlighter.
2
+ *
3
+ * - `resetTo` is the SGR foreground sequence re-emitted after each painted
4
+ * keyword so surrounding text keeps its color; it defaults to a plain
5
+ * foreground reset (editor / default-colored text).
6
+ * - `phase` ∈ [0, 1) rotates the gradient stops cyclically; pass `Date.now()`-
7
+ * derived values to animate a shimmer. Defaults to `0` (the static
8
+ * sent-bubble palette). */
9
+ export type KeywordHighlighter = (text: string, resetTo?: string, phase?: number) => string;
5
10
  /** Declarative spec for {@link createGradientHighlighter}. */
6
11
  export interface GradientHighlightSpec {
7
12
  /** Cheap, stateless presence probe used to skip the boundary regex on most lines. Must be non-global. */
@@ -4,6 +4,12 @@ import { type BlobPutResult } from "../session/blob-store";
4
4
  * Group 1 is the kind (`Image`/`Paste`), group 2 the 1-based index. The optional metadata
5
5
  * tail (`, …`) is captured loosely (no `]`/newline) so future label tweaks keep matching. */
6
6
  export declare const PLACEHOLDER_REGEX: RegExp;
7
+ /** Renumber every `[Image #N]` marker in `text` by `offset` (added to the
8
+ * existing index), preserving the optional `, WxH` tail. Paste markers are
9
+ * left untouched. Used when restoring queued image-messages back into a draft
10
+ * that already holds pending images so the merged text's positional markers
11
+ * still line up with `pendingImages`. */
12
+ export declare function shiftImageMarkers(text: string, offset: number): string;
7
13
  type ImageBlobWriter = (data: Buffer, options?: {
8
14
  extension?: string;
9
15
  }) => Promise<BlobPutResult>;
@@ -13,7 +13,8 @@ import type { MCPManager } from "../mcp";
13
13
  import { type PlanApprovalDetails } from "../plan-mode/approved-plan";
14
14
  import type { AgentSession } from "../session/agent-session";
15
15
  import { HistoryStorage } from "../session/history-storage";
16
- import type { SessionContext, SessionManager } from "../session/session-manager";
16
+ import type { SessionContext } from "../session/session-context";
17
+ import type { SessionManager } from "../session/session-manager";
17
18
  import type { ShakeMode } from "../session/shake-types";
18
19
  import type { LspStartupServerInfo } from "../tools";
19
20
  import type { EventBus } from "../utils/event-bus";
@@ -33,6 +34,18 @@ import { OAuthManualInputManager } from "./oauth-manual-input";
33
34
  import type { ObservableSession } from "./session-observer-registry";
34
35
  import type { Theme } from "./theme/theme";
35
36
  import type { CompactionQueuedMessage, InteractiveModeContext, InteractiveModeInitOptions, InteractiveSelectorDialogOptions, SubmittedUserInput, TodoItem, TodoPhase } from "./types";
37
+ /**
38
+ * Editor max-height cap for a terminal of `terminalRows` rows.
39
+ *
40
+ * Roomy terminals get the comfortable [6, 18] band. Small terminals shrink the
41
+ * cap so the editor leaves at least EDITOR_MIN_CHROME_ROWS rows for the
42
+ * transcript + status line. The editor is bordered, so it never renders fewer
43
+ * than EDITOR_MIN_RENDERED_ROWS rows; once the terminal is too small for both
44
+ * (terminalRows < EDITOR_MIN_RENDERED_ROWS + EDITOR_MIN_CHROME_ROWS) the cap is
45
+ * pinned to that floor — returning a smaller number would not shrink the editor
46
+ * any further, it would only misreport the rows it actually occupies.
47
+ */
48
+ export declare function computeEditorMaxHeight(terminalRows: number): number;
36
49
  /** Options for creating an InteractiveMode instance (for future API use) */
37
50
  export interface InteractiveModeOptions {
38
51
  /** Providers that were migrated during startup */
@@ -74,6 +87,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
74
87
  btwContainer: Container;
75
88
  omfgContainer: Container;
76
89
  errorBannerContainer: Container;
90
+ modelCycleContainer: Container;
77
91
  editor: CustomEditor;
78
92
  editorContainer: Container;
79
93
  hookWidgetContainerAbove: Container;
@@ -175,6 +189,13 @@ export declare class InteractiveMode implements InteractiveModeContext {
175
189
  updateEditorBorderColor(): void;
176
190
  updateEditorTopBorder(): void;
177
191
  rebuildChatFromMessages(): void;
192
+ /**
193
+ * Render the ctrl+p model-role cycle chip track into its own anchored
194
+ * container (just above the editor), mirroring the todo HUD: the container is
195
+ * cleared and rebuilt in place on every cycle, so rapid presses or concurrent
196
+ * chat activity can never stack duplicate tracks into the scrollback.
197
+ */
198
+ showModelCycleTrack(track: string): void;
178
199
  /** Apply any deferred model switch after the current stream ends. */
179
200
  flushPendingModelSwitch(): Promise<void>;
180
201
  showPlanReview(planContent: string, title: string, options: string[], dialogOptions?: {
@@ -189,6 +210,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
189
210
  }): Promise<string | undefined>;
190
211
  handlePlanModeCommand(initialPrompt?: string): Promise<void>;
191
212
  handleGoalModeCommand(rest?: string): Promise<void>;
213
+ handleGuidedGoalCommand(rest?: string): Promise<void>;
192
214
  /** Manually (re-)open the plan-review overlay — bound to `/plan-review`. Lets
193
215
  * the operator pull the review back up after dismissing it, or review a plan
194
216
  * the agent wrote without calling `resolve`. There is no fixed plan filename:
@@ -261,13 +283,15 @@ export declare class InteractiveMode implements InteractiveModeContext {
261
283
  handleMemoryCommand(text: string): Promise<void>;
262
284
  handleSTTToggle(): Promise<void>;
263
285
  showDebugSelector(): Promise<void>;
264
- showAgentHub(): void;
286
+ showAgentHub(options?: {
287
+ requireContent?: boolean;
288
+ }): void;
265
289
  resetObserverRegistry(): void;
266
290
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
267
291
  handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
268
292
  handleMCPCommand(text: string): Promise<void>;
269
293
  handleSSHCommand(text: string): Promise<void>;
270
- handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
294
+ handleCompactCommand(customInstructions?: string, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>): Promise<CompactionOutcome>;
271
295
  handleHandoffCommand(customInstructions?: string): Promise<void>;
272
296
  handleShakeCommand(mode: ShakeMode): Promise<void>;
273
297
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
@@ -10,5 +10,17 @@
10
10
  * pass the surrounding text color when decorating already-colored content (e.g.
11
11
  * a themed message bubble) so the gradient does not bleed into the rest of the
12
12
  * line. Defaults to a plain foreground reset for default-colored editor text.
13
+ *
14
+ * `phase` ∈ [0, 1) cyclically rotates each gradient — the editor passes a
15
+ * `Date.now()`-derived value to animate a Claude-Code-style shimmer while a
16
+ * keyword is on screen and the prompt is focused; sent message bubbles omit it
17
+ * to keep the static gradient.
18
+ */
19
+ export declare function highlightMagicKeywords(text: string, resetTo?: string, phase?: number): string;
20
+ /**
21
+ * Cheap test for "does this text contain any magic keyword as standalone prose?".
22
+ * Short-circuits on a substring probe before paying for the markdown-aware
23
+ * prose check, so the common "no keyword in buffer" path is just three
24
+ * `String#indexOf`s. Used by the live editor to gate the shimmer timer.
13
25
  */
14
- export declare function highlightMagicKeywords(text: string, resetTo?: string): string;
26
+ export declare function hasMagicKeyword(text: string): boolean;