openpetswithchatandmcp/apps/desktop/tests/agent-setup-command-runner.test.ts
2026-06-19 20:49:00 +00:00

82 lines
3.9 KiB
TypeScript

import assert from "node:assert/strict";
import { mkdtempSync, mkdirSync, readFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import {
createAgentSetupCommandEnv,
getAgentSetupClaudeCommandCandidates,
getAgentSetupExtraCommandPaths,
runAgentSetupCommand,
summarizeAgentSetupCommandResult,
} from "../src/agent-setup-command-runner.js";
const desktopRoot = process.env.FAMILIAROS_DESKTOP_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..");
const agentSetupClaudeStatusSource = readFileSync(resolve(desktopRoot, "src/agent-setup-claude-status.ts"), "utf8");
const agentSetupCommandRunnerSource = readFileSync(resolve(desktopRoot, "src/agent-setup-command-runner.ts"), "utf8");
assert.match(agentSetupClaudeStatusSource, /from "\.\/agent-setup-command-runner(?:\.js)?"/, "Agent setup Claude status seam must import the extracted command-runner seam.");
assert.match(agentSetupCommandRunnerSource, /export async function runAgentSetupCommand/, "Agent setup command-runner seam must export the command executor.");
assert.match(agentSetupCommandRunnerSource, /export function createAgentSetupCommandEnv/, "Agent setup command-runner seam must export PATH environment shaping.");
assert.match(agentSetupCommandRunnerSource, /export function getAgentSetupClaudeCommandCandidates/, "Agent setup command-runner seam must export Claude command candidate selection.");
assert.match(agentSetupCommandRunnerSource, /export function summarizeAgentSetupCommandResult/, "Agent setup command-runner seam must export command result summarization.");
assert.deepEqual(getAgentSetupClaudeCommandCandidates("claude", "claude", "win32"), ["claude", "claude.cmd"]);
assert.deepEqual(getAgentSetupClaudeCommandCandidates("claude", "/custom/bin/claude", "linux"), ["/custom/bin/claude"]);
assert.deepEqual(getAgentSetupClaudeCommandCandidates("node", "claude", "linux"), ["node"]);
assert.deepEqual(getAgentSetupExtraCommandPaths({ platform: "win32", env: {}, homeDir: "C:\\Users\\Familiar" }), []);
const root = mkdtempSync(join(tmpdir(), "familiaros-agent-setup-runner-"));
try {
mkdirSync(join(root, "bin"), { recursive: true });
mkdirSync(join(root, ".local", "bin"), { recursive: true });
mkdirSync(join(root, ".volta", "bin"), { recursive: true });
const env = createAgentSetupCommandEnv({
platform: "linux",
homeDir: root,
env: {
PATH: ["/usr/bin", join(root, "bin"), "/usr/bin"].join(":"),
VOLTA_HOME: join(root, ".volta"),
},
});
const pathEntries = String(env.PATH).split(":");
assert.equal(pathEntries.filter((entry) => entry === join(root, "bin")).length, 1, "command env PATH must dedupe duplicate entries.");
assert.ok(pathEntries.includes(join(root, ".local", "bin")), "command env PATH must include discovered local bins.");
assert.ok(pathEntries.includes(join(root, ".volta", "bin")), "command env PATH must include discovered Volta bins.");
const success = await runAgentSetupCommand(
{
command: process.execPath,
args: ["-e", "process.stdout.write('hello'); process.stderr.write('warn');"],
},
{
platform: process.platform,
homeDir: root,
env: process.env,
sanitizeOutput: (value) => value,
},
);
assert.equal(success.ok, true);
assert.equal(success.stdout, "hello");
assert.equal(success.stderr, "warn");
assert.equal(
summarizeAgentSetupCommandResult(
{ ok: false, timedOut: true, exitCode: null, stdout: "", stderr: "", error: "timeout" },
() => "<safe>",
),
"command timed out.",
);
assert.equal(
summarizeAgentSetupCommandResult(
{ ok: false, timedOut: false, exitCode: 1, stdout: "", stderr: "raw stderr", error: undefined },
() => "<safe>",
),
"<safe>",
);
} finally {
rmSync(root, { recursive: true, force: true });
}
console.error("Agent setup command runner seam validation passed.");