fix(coding-agent): deferred hub tool renderer access to avoid temporal dead zone

- Convert the hub tool renderer to a lazy getter to prevent initialization-order temporal dead zone issues.
- Add session move support to the fake ACP builtin session runtime.
This commit is contained in:
can1357
2026-07-23 21:54:35 +02:00
parent fcf2274b2f
commit 7158dcd9b3
2 changed files with 12 additions and 1 deletions
+7 -1
View File
@@ -90,7 +90,13 @@ export const toolRenderers: Record<string, ToolRenderer> = {
grep: grepToolRenderer as ToolRenderer,
lsp: lspToolRenderer as ToolRenderer,
inspect_image: inspectImageToolRenderer as ToolRenderer,
hub: hubToolRenderer as ToolRenderer,
// Lazy getter: `hubToolRenderer` lives in a module whose deps (messaging →
// persisted-agents → vibe/runtime → task/executor → sdk) close an import
// cycle back here, so reading it at init order-dependently hits its
// temporal dead zone. Deferring the read to first access sidesteps it.
get hub(): ToolRenderer {
return hubToolRenderer as ToolRenderer;
},
read: readToolRenderer as ToolRenderer,
// Keyed by xd:// resolution-device names: the write dispatch delegates here
// by dispatch tool, and historical `resolve` tool transcripts still render
@@ -38,6 +38,7 @@ interface FakeAcpBuiltinSession {
model: { provider: string; id: string } | undefined;
newSession(opts?: { drop?: boolean; parentSession?: string }): Promise<boolean>;
switchSession(sessionPath: string): Promise<boolean>;
moveSession(newCwd: string, targetSessionDir?: string): Promise<void>;
markMovedFromEmptySessionFile(sessionFile: string): void;
fork(): Promise<boolean>;
handoff(instr?: string): Promise<{ document: string; savedPath?: string } | undefined>;
@@ -121,6 +122,10 @@ function createRuntime() {
await fakeSessionManager.setSessionFile(this._switchedTo);
return true;
},
async moveSession(newCwd: string, _targetSessionDir?: string) {
if (!fakeSessionManager) throw new Error("fake session manager not initialized");
await fakeSessionManager.moveTo(newCwd);
},
markMovedFromEmptySessionFile(sessionFile: string) {
this._movedFromEmptySessionFile = path.resolve(sessionFile);
},