From be2cded1ea7cfbfd7e0f8816880c2968c860f7d4 Mon Sep 17 00:00:00 2001 From: Christian Klotz Date: Tue, 11 Aug 2026 13:55:52 +0300 Subject: [PATCH] feat(coding-agent): internalize reload callbacks --- packages/coding-agent/src/core/agent-session.ts | 10 +++++----- packages/coding-agent/src/index.ts | 1 - .../src/modes/interactive/interactive-mode.ts | 4 ++-- .../regressions/5943-session-start-notify.test.ts | 4 ++-- .../6552-deferred-extension-reload.test.ts | 12 +++--------- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/packages/coding-agent/src/core/agent-session.ts b/packages/coding-agent/src/core/agent-session.ts index 9339a7e05..cf95b1bdc 100644 --- a/packages/coding-agent/src/core/agent-session.ts +++ b/packages/coding-agent/src/core/agent-session.ts @@ -202,7 +202,7 @@ export class RuntimeReloadError extends Error { } } -export interface RuntimeReloadHooks { +export interface RuntimeReloadCallbacks { beforeReload?(): void | Promise; beforeSessionStart?(): void | Promise; afterReload?(): void | Promise; @@ -248,7 +248,7 @@ export interface ExtensionBindings { abortHandler?: () => void; shutdownHandler?: ShutdownHandler; onError?: ExtensionErrorListener; - reloadHooks?: RuntimeReloadHooks; + reloadHooks?: RuntimeReloadCallbacks; } /** Options for AgentSession.prompt() */ @@ -376,7 +376,7 @@ export class AgentSession { private _extensionShutdownHandler?: ShutdownHandler; private _extensionErrorListener?: ExtensionErrorListener; private _extensionErrorUnsubscriber?: () => void; - private _runtimeReloadHooks?: RuntimeReloadHooks; + private _runtimeReloadHooks?: RuntimeReloadCallbacks; private _extensionsBound = false; private _runtimeAvailability: RuntimeAvailability = "available"; private _runtimeReloadError?: RuntimeReloadError; @@ -684,7 +684,7 @@ export class AgentSession { } } - private async _performReload(hooks: RuntimeReloadHooks | undefined): Promise { + private async _performReload(hooks: RuntimeReloadCallbacks | undefined): Promise { let runtimeInvalidated = false; this._runtimeAvailability = "reloading"; try { @@ -2774,7 +2774,7 @@ export class AgentSession { /** Tear down the old runtime, then enter the same load and start path used during startup. */ private async _reloadRuntime( - beforeSessionStart: RuntimeReloadHooks["beforeSessionStart"], + beforeSessionStart: RuntimeReloadCallbacks["beforeSessionStart"], onInvalidated: () => void, ): Promise { const oldRunner = this._extensionRunner; diff --git a/packages/coding-agent/src/index.ts b/packages/coding-agent/src/index.ts index b04ded684..55734556d 100644 --- a/packages/coding-agent/src/index.ts +++ b/packages/coding-agent/src/index.ts @@ -22,7 +22,6 @@ export { type PromptOptions, parseSkillBlock, RuntimeReloadError, - type RuntimeReloadHooks, type SessionStats, } from "./core/agent-session.ts"; export { readStoredCredential } from "./core/auth-storage.ts"; diff --git a/packages/coding-agent/src/modes/interactive/interactive-mode.ts b/packages/coding-agent/src/modes/interactive/interactive-mode.ts index 0e8243e42..b9fe2dc1a 100644 --- a/packages/coding-agent/src/modes/interactive/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive/interactive-mode.ts @@ -60,7 +60,7 @@ import { type AgentSession, type AgentSessionEvent, parseSkillBlock, - type RuntimeReloadHooks, + type RuntimeReloadCallbacks, } from "../../core/agent-session.ts"; import { type AgentSessionRuntime, SessionImportFileNotFoundError } from "../../core/agent-session-runtime.ts"; import { @@ -5662,7 +5662,7 @@ export class InteractiveMode { } } - private createReloadHooks(): RuntimeReloadHooks { + private createReloadHooks(): RuntimeReloadCallbacks { let previousEditor: Component | undefined; let reloadBoxDismissed = true; let chatRestoredBeforeSessionStart = false; diff --git a/packages/coding-agent/test/suite/regressions/5943-session-start-notify.test.ts b/packages/coding-agent/test/suite/regressions/5943-session-start-notify.test.ts index 682aeea52..ed5e8bef1 100644 --- a/packages/coding-agent/test/suite/regressions/5943-session-start-notify.test.ts +++ b/packages/coding-agent/test/suite/regressions/5943-session-start-notify.test.ts @@ -1,7 +1,7 @@ import { fauxAssistantMessage } from "@earendil-works/pi-ai"; import { Container, Text } from "@earendil-works/pi-tui"; import { describe, expect, it, vi } from "vitest"; -import type { AgentSessionEvent, RuntimeReloadHooks } from "../../../src/core/agent-session.ts"; +import type { AgentSessionEvent, RuntimeReloadCallbacks } from "../../../src/core/agent-session.ts"; import type { ExtensionUIContext } from "../../../src/core/extensions/index.ts"; import { InteractiveMode } from "../../../src/modes/interactive/interactive-mode.ts"; import { initTheme, type Theme, theme } from "../../../src/modes/interactive/theme/theme.ts"; @@ -137,7 +137,7 @@ type InteractiveModePrototype = { ): void; rebindCurrentSession(this: RebindContext, options?: { renderBeforeBind?: boolean }): Promise; handleReloadCommand(this: ReloadCommandContext): Promise; - createReloadHooks(this: ReloadCommandContext): RuntimeReloadHooks; + createReloadHooks(this: ReloadCommandContext): RuntimeReloadCallbacks; }; const interactiveModePrototype = InteractiveMode.prototype as unknown as InteractiveModePrototype; diff --git a/packages/coding-agent/test/suite/regressions/6552-deferred-extension-reload.test.ts b/packages/coding-agent/test/suite/regressions/6552-deferred-extension-reload.test.ts index ffbbf2a17..39a754d14 100644 --- a/packages/coding-agent/test/suite/regressions/6552-deferred-extension-reload.test.ts +++ b/packages/coding-agent/test/suite/regressions/6552-deferred-extension-reload.test.ts @@ -1,16 +1,10 @@ import { fauxAssistantMessage, fauxToolCall } from "@earendil-works/pi-ai"; import { Type } from "typebox"; import { afterEach, describe, expect, it } from "vitest"; -import { RuntimeReloadError } from "../../../src/core/agent-session.ts"; +import { type RuntimeReloadCallbacks, RuntimeReloadError } from "../../../src/core/agent-session.ts"; import { createEventBus } from "../../../src/core/event-bus.ts"; import { createExtensionRuntime, loadExtensionFromFactory } from "../../../src/core/extensions/loader.ts"; -import type { - ExtensionContext, - ExtensionFactory, - LoadExtensionsResult, - ResourceLoader, - RuntimeReloadHooks, -} from "../../../src/index.ts"; +import type { ExtensionContext, ExtensionFactory, LoadExtensionsResult, ResourceLoader } from "../../../src/index.ts"; import { assistantMsg, userMsg } from "../../utilities.ts"; import { createHarness, getAssistantTexts, type Harness } from "../harness.ts"; @@ -47,7 +41,7 @@ async function createReloadingResourceLoader(factory: ExtensionFactory): Promise }; } -const reloadHooks = (beforeReload?: () => void): RuntimeReloadHooks => ({ beforeReload }); +const reloadHooks = (beforeReload?: () => void): RuntimeReloadCallbacks => ({ beforeReload }); describe("issue #6552 deferred extension reload", () => { const harnesses: Harness[] = [];