fix(session): reopen replaced targets

This commit is contained in:
N0zoM1z0 committed 2026-07-14 20:35:26 +00:00
1 parent 528c05e2fa
commit 5c559998e1
2 files changed
+66 -2

No files matched your search

+8 -2
View File
@@ -35,7 +35,10 @@ import type { AnalysisOperation } from "./AnalysisProvider.js";
import { enhancedToolNameSchema } from "../contracts/enhancedInputs.js";
import { OFFICIAL_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
import type { AnalysisSnapshot } from "../domain/analysisSnapshot.js";
import { snapshotMatchesTarget } from "../domain/analysisSnapshot.js";
import {
snapshotMatchesTarget,
snapshotTarget,
} from "../domain/analysisSnapshot.js";
import {
AnalysisSnapshotCache,
isSnapshotCacheable,
@@ -348,7 +351,10 @@ export class BinarySession implements BinarySessionPort {
);
if (isAborted(options.signal))
return err(new AnalysisCancelledError("open_binary"));
if (this.#active?.target.path === parsed.value.path) {
if (
this.#active?.target.path === parsed.value.path &&
snapshotMatchesTarget(snapshotTarget(this.#active.target), parsed.value)
) {
if (options.snapshot !== undefined) {
const imported = this.importAnalysisSnapshot(options.snapshot);
if (!imported.ok) return imported;
+58
View File
@@ -365,6 +365,64 @@ describe("binary session", () => {
expect(clients[0]?.closed).toBe(1);
});
it("replaces the active client when a canonical path changes contents", async () => {
directory = await mkdtemp(join(tmpdir(), "bb-session-"));
const path = join(directory, "mutable.hop");
await writeFile(path, "one");
const clients: Array<{
readonly targetSha256: string;
readonly calls: string[];
closed: number;
}> = [];
const session = new BinarySession((target) => {
const state = {
targetSha256: target.sha256,
calls: [] as string[],
closed: 0,
};
clients.push(state);
return {
execute: (operation) => {
state.calls.push(operation);
return Promise.resolve(
ok(operation === "health" ? null : target.sha256),
);
},
close: () => {
state.closed += 1;
return Promise.resolve();
},
};
});
const first = await session.open(path);
expect(first.ok).toBe(true);
await writeFile(path, "two");
const second = await session.open(path);
expect(second.ok).toBe(true);
if (!first.ok || !second.ok) return;
expect(second.value.sha256).not.toBe(first.value.sha256);
expect(session.activeTarget()?.sha256).toBe(second.value.sha256);
expect(await session.execute("binary_overview", {})).toMatchObject({
ok: true,
value: { result: second.value.sha256 },
});
expect(clients).toMatchObject([
{
targetSha256: first.value.sha256,
calls: ["health"],
closed: 1,
},
{
targetSha256: second.value.sha256,
calls: ["health", "binary_overview"],
closed: 0,
},
]);
await session.close();
});
it("waits for an active call before closing its client during a switch", async () => {
const [first, second] = await targets();
const active = deferred<ReturnType<typeof ok>>();