Files
paseo/scripts/trace-daemon-dist.test.mjs
T
Dominic Anaeto f2d8cbf5b9 fix(claude): keep the daemon responsive during conversation rewind
The SDK parses and copies the complete transcript while forking a Claude
conversation. Running that work in the daemon's event loop blocks all
connected clients, even though only one conversation is being rewound.

Run the fork in a worker, stream transcript records, and append in bounded
chunks. Preserve the SDK's fork content, transcript location, and error
fields. Share the existing compiler worker loader and verify that the
installed daemon closure contains and starts the rewind worker.

Retain Dominic Anaeto's implementation and regressions from #8444, rebased
onto main to include the correction for the moved worktrees documentation
page in the website test.

Fixes #8209

Co-authored-by: Dominic Anaeto <dominic.anaeto@gmail.com>
2026-11-01 07:28:09 +00:00

85 lines
3.2 KiB
JavaScript

import assert from "node:assert/strict";
import { execFile } from "node:child_process";
import { randomUUID } from "node:crypto";
import { cp, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { fileURLToPath, pathToFileURL } from "node:url";
import { promisify } from "node:util";
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const bridgeModule = "packages/server/dist/server/server/agent/providers/opencode/bridge.js";
const claudeDist = "packages/server/dist/server/server/agent/providers/claude";
const workerThreadEntrypoints = [
"packages/server/dist/server/server/plugins/compiler-worker.js",
`${claudeDist}/rewind-worker.js`,
`${claudeDist}/rewind-session-store.js`,
];
// Mirrors nix/package.nix's installPhase: copy every traced path into $out.
async function installTracedDaemon(outRoot) {
const { stdout } = await promisify(execFile)(
process.execPath,
[path.join(repoRoot, "scripts/trace-daemon.mjs")],
{ cwd: repoRoot, maxBuffer: 64 * 1024 * 1024 },
);
const files = stdout.split("\n").filter(Boolean);
for (const file of files) {
await cp(path.join(repoRoot, file), path.join(outRoot, file), {
recursive: true,
verbatimSymlinks: true,
});
}
return files;
}
test("traced daemon closure ships the OpenCode bridge plugin for every OpenCode version", async () => {
const outRoot = await mkdtemp(path.join(os.tmpdir(), "trace-daemon-dist-"));
try {
await installTracedDaemon(outRoot);
const installedBridgeUrl = pathToFileURL(path.join(outRoot, bridgeModule)).href;
const { loadOpenCodeBridgePluginArtifact } = await import(installedBridgeUrl);
for (const version of [1, 2]) {
const artifact = await loadOpenCodeBridgePluginArtifact(
installedBridgeUrl,
undefined,
version,
);
assert.ok(artifact.byteLength > 0, `OpenCode v${version} bridge plugin is empty`);
}
} finally {
await rm(outRoot, { recursive: true, force: true });
}
});
test("traced daemon closure ships the worker-thread entrypoints and what they load", async () => {
const outRoot = await mkdtemp(path.join(os.tmpdir(), "trace-daemon-dist-"));
try {
const files = await installTracedDaemon(outRoot);
for (const file of workerThreadEntrypoints) {
assert.ok(files.includes(file), `${file} is missing from the traced closure`);
}
const { realClaudeRewindSdk } = await import(
pathToFileURL(path.join(outRoot, claudeDist, "rewind.js")).href
);
const sessionId = randomUUID();
const user = randomUUID();
const transcriptPath = path.join(outRoot, `${sessionId}.jsonl`);
await writeFile(
transcriptPath,
`${JSON.stringify({ type: "user", uuid: user, parentUuid: null, sessionId, message: { role: "user", content: "first" } })}\n`,
);
const fork = await realClaudeRewindSdk.forkSession(sessionId, {
upToMessageId: user,
transcriptPath,
});
const forked = await readFile(path.join(outRoot, `${fork.sessionId}.jsonl`), "utf8");
assert.equal(JSON.parse(forked.split("\n")[0]).forkedFrom.messageUuid, user);
} finally {
await rm(outRoot, { recursive: true, force: true });
}
});