diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 1500849a..6aff0e07 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added +- **Extension API switchSession**: Added `ctx.switchSession(sessionPath)` to `ExtensionCommandContext` for programmatic session switching in extension commands ([#1187](https://github.com/badlogic/pi-mono/issues/1187)). - **Clear on shrink setting**: New `terminal.clearOnShrink` setting (and `/settings` toggle) controls whether empty rows are cleared when content shrinks. Disabled by default to reduce flicker. Enable via settings or `PI_CLEAR_ON_SHRINK=1` env var. ## [0.51.0] - 2026-02-01 diff --git a/packages/coding-agent/src/core/extensions/index.ts b/packages/coding-agent/src/core/extensions/index.ts index 7a3e3ad0..14cbe658 100644 --- a/packages/coding-agent/src/core/extensions/index.ts +++ b/packages/coding-agent/src/core/extensions/index.ts @@ -14,6 +14,7 @@ export type { NavigateTreeHandler, NewSessionHandler, ShutdownHandler, + SwitchSessionHandler, } from "./runner.js"; export { ExtensionRunner } from "./runner.js"; export type { diff --git a/packages/coding-agent/src/core/extensions/runner.ts b/packages/coding-agent/src/core/extensions/runner.ts index 791c85ae..bcdd9fa5 100644 --- a/packages/coding-agent/src/core/extensions/runner.ts +++ b/packages/coding-agent/src/core/extensions/runner.ts @@ -106,6 +106,8 @@ export type NavigateTreeHandler = ( options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string }, ) => Promise<{ cancelled: boolean }>; +export type SwitchSessionHandler = (sessionPath: string) => Promise<{ cancelled: boolean }>; + export type ShutdownHandler = () => void; /** @@ -165,6 +167,7 @@ export class ExtensionRunner { private newSessionHandler: NewSessionHandler = async () => ({ cancelled: false }); private forkHandler: ForkHandler = async () => ({ cancelled: false }); private navigateTreeHandler: NavigateTreeHandler = async () => ({ cancelled: false }); + private switchSessionHandler: SwitchSessionHandler = async () => ({ cancelled: false }); private shutdownHandler: ShutdownHandler = () => {}; private shortcutDiagnostics: ResourceDiagnostic[] = []; @@ -221,6 +224,7 @@ export class ExtensionRunner { this.newSessionHandler = actions.newSession; this.forkHandler = actions.fork; this.navigateTreeHandler = actions.navigateTree; + this.switchSessionHandler = actions.switchSession; return; } @@ -228,6 +232,7 @@ export class ExtensionRunner { this.newSessionHandler = async () => ({ cancelled: false }); this.forkHandler = async () => ({ cancelled: false }); this.navigateTreeHandler = async () => ({ cancelled: false }); + this.switchSessionHandler = async () => ({ cancelled: false }); } setUIContext(uiContext?: ExtensionUIContext): void { @@ -436,6 +441,7 @@ export class ExtensionRunner { newSession: (options) => this.newSessionHandler(options), fork: (entryId) => this.forkHandler(entryId), navigateTree: (targetId, options) => this.navigateTreeHandler(targetId, options), + switchSession: (sessionPath) => this.switchSessionHandler(sessionPath), }; } diff --git a/packages/coding-agent/src/core/extensions/types.ts b/packages/coding-agent/src/core/extensions/types.ts index 0e927b82..1136609a 100644 --- a/packages/coding-agent/src/core/extensions/types.ts +++ b/packages/coding-agent/src/core/extensions/types.ts @@ -293,6 +293,9 @@ export interface ExtensionCommandContext extends ExtensionContext { targetId: string, options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string }, ): Promise<{ cancelled: boolean }>; + + /** Switch to a different session file. */ + switchSession(sessionPath: string): Promise<{ cancelled: boolean }>; } // ============================================================================ @@ -1214,6 +1217,7 @@ export interface ExtensionCommandContextActions { targetId: string, options?: { summarize?: boolean; customInstructions?: string; replaceInstructions?: boolean; label?: string }, ) => Promise<{ cancelled: boolean }>; + switchSession: (sessionPath: string) => Promise<{ cancelled: boolean }>; } /** diff --git a/packages/coding-agent/src/modes/interactive/interactive-mode.ts b/packages/coding-agent/src/modes/interactive/interactive-mode.ts index 3ac56d36..b1363be2 100644 --- a/packages/coding-agent/src/modes/interactive/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive/interactive-mode.ts @@ -1059,6 +1059,10 @@ export class InteractiveMode { return { cancelled: false }; }, + switchSession: async (sessionPath) => { + await this.handleResumeSession(sessionPath); + return { cancelled: false }; + }, }, shutdownHandler: () => { this.shutdownRequested = true; diff --git a/packages/coding-agent/src/modes/print-mode.ts b/packages/coding-agent/src/modes/print-mode.ts index 2a5b0c1b..834954db 100644 --- a/packages/coding-agent/src/modes/print-mode.ts +++ b/packages/coding-agent/src/modes/print-mode.ts @@ -59,6 +59,10 @@ export async function runPrintMode(session: AgentSession, options: PrintModeOpti }); return { cancelled: result.cancelled }; }, + switchSession: async (sessionPath) => { + const success = await session.switchSession(sessionPath); + return { cancelled: !success }; + }, }, onError: (err) => { console.error(`Extension error (${err.extensionPath}): ${err.error}`); diff --git a/packages/coding-agent/src/modes/rpc/rpc-mode.ts b/packages/coding-agent/src/modes/rpc/rpc-mode.ts index 994d50e0..91b1a16d 100644 --- a/packages/coding-agent/src/modes/rpc/rpc-mode.ts +++ b/packages/coding-agent/src/modes/rpc/rpc-mode.ts @@ -277,6 +277,10 @@ export async function runRpcMode(session: AgentSession): Promise { }); return { cancelled: result.cancelled }; }, + switchSession: async (sessionPath) => { + const success = await session.switchSession(sessionPath); + return { cancelled: !success }; + }, }, shutdownHandler: () => { shutdownRequested = true;