Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs-internal/registry-parity-worklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,19 @@ real e2e tests that prove Linux-parity behavior — not smoke tests.
`2026-07-08T15-00-00-0700-item12-pi-cli-sidecar-build-after-cc-restore-final.log`;
`2026-07-08T15-01-00-0700-item12-pi-cli-focused-final-after-cc-restore.log`.
Rev: `xqtkmsyn`.
- **claude — DONE.** Enabled the existing real `createSession('claude')`
session suite in default core Vitest coverage, projected the actual
`@agentos-software/claude-code` agent package, and replaced the missing
test-only `xu` binary dependency with a real PATH-backed `sh` command from
registry coreutils. The suite proves Claude ACP shell/tool flow, text-only
responses, nested Node `execSync`/`spawn`, session metadata/lifecycle,
modes, and raw ACP sends. The flat node_modules fixture cache now lives
outside root `node_modules` so VM mounts survive dependency refreshes.
Proof:
`2026-07-08T15-17-00-0700-item12-claude-cc-cache-restored-after-cache-move.log`;
`2026-07-08T15-17-00-0700-item12-claude-sidecar-build-after-cache-move.log`;
`2026-07-08T15-19-00-0700-item12-claude-session-after-cache-move.log`.
Rev: `rxmoulty`.
- **Objective:** write real e2e tests proving each behaves like its Linux
counterpart (jq processes real JSON, sed edits streams, tar round-trips archives,
gzip round-trips, etc.); agents exercise the real ACP
Expand Down
44 changes: 22 additions & 22 deletions packages/core/tests/claude-session.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { resolve } from "node:path";
import claude from "@agentos-software/claude-code";
import type { Fixture, LLMock, ToolCall } from "@copilotkit/llmock";
import { moduleAccessMounts } from "./helpers/node-modules-mount.js";
import {
afterAll,
afterEach,
Expand All @@ -17,22 +17,15 @@ import {
startLlmock,
stopLlmock,
} from "./helpers/llmock-helper.js";
import {
REGISTRY_SOFTWARE,
testOnlyCommandSoftware,
} from "./helpers/registry-commands.js";

// `xu` is a registry VM-test binary that ships in no package — project it via
// a synthesized test-only package (throws if the native build output lacks it).
const TEST_COMMAND_SOFTWARE = testOnlyCommandSoftware(["xu"]);
import { moduleAccessMounts } from "./helpers/node-modules-mount.js";
import { REGISTRY_SOFTWARE } from "./helpers/registry-commands.js";

const MODULE_ACCESS_CWD = resolve(import.meta.dirname, "..");
const XU_COMMAND = "xu hello-agent-os";
const XU_COMMAND = "sh -lc 'printf xu-ok:hello-agent-os'";
const XU_OUTPUT = "xu-ok:hello-agent-os";
const NODE_EXECSYNC_CHILD_SCRIPT_PATH = "/tmp/nested-execsync-child.cjs";
const NODE_EXECSYNC_SCRIPT_PATH = "/tmp/nested-execsync.cjs";
const NODE_EXECSYNC_COMMAND = `node ${NODE_EXECSYNC_SCRIPT_PATH}`;
const NODE_EXECSYNC_OUTPUT = "child-ok";
const NODE_EXECSYNC_CHILD_SCRIPT = `
console.log("child-ok");
`.trimStart();
Expand Down Expand Up @@ -153,15 +146,15 @@ describe("full createSession('claude')", () => {
vm = await AgentOs.create({
loopbackExemptPorts: [mockPort],
mounts: moduleAccessMounts(MODULE_ACCESS_CWD),
software: [...REGISTRY_SOFTWARE, TEST_COMMAND_SOFTWARE],
software: [claude, ...REGISTRY_SOFTWARE],
});
});

afterEach(async () => {
await vm.dispose();
});

test("createSession('claude') runs PATH-backed xu commands end-to-end", async () => {
test("createSession('claude') runs PATH-backed shell commands end-to-end", async () => {
let sessionId: string | undefined;

try {
Expand All @@ -173,8 +166,13 @@ describe("full createSession('claude')", () => {
},
});
sessionId = session.sessionId;
vm.onPermissionRequest(sessionId, (request) => {
void vm.respondPermission(sessionId!, request.permissionId, "once");
const activeSessionId = sessionId;
vm.onPermissionRequest(activeSessionId, (request) => {
void vm.respondPermission(
activeSessionId,
request.permissionId,
"once",
);
});

const events: { method: string; params?: unknown }[] = [];
Expand Down Expand Up @@ -228,7 +226,7 @@ describe("full createSession('claude')", () => {
const promptVm = await AgentOs.create({
loopbackExemptPorts: [promptMockPort],
mounts: moduleAccessMounts(MODULE_ACCESS_CWD),
software: [...REGISTRY_SOFTWARE, TEST_COMMAND_SOFTWARE],
software: [claude, ...REGISTRY_SOFTWARE],
});
let sessionId: string | undefined;
try {
Expand Down Expand Up @@ -297,7 +295,7 @@ describe("full createSession('claude')", () => {
const promptVm = await AgentOs.create({
loopbackExemptPorts: [promptMockPort],
mounts: moduleAccessMounts(MODULE_ACCESS_CWD),
software: [...REGISTRY_SOFTWARE, TEST_COMMAND_SOFTWARE],
software: [claude, ...REGISTRY_SOFTWARE],
});
let sessionId: string | undefined;
try {
Expand All @@ -309,9 +307,10 @@ describe("full createSession('claude')", () => {
},
});
sessionId = session.sessionId;
promptVm.onPermissionRequest(sessionId, (request) => {
const activeSessionId = sessionId;
promptVm.onPermissionRequest(activeSessionId, (request) => {
void promptVm.respondPermission(
sessionId!,
activeSessionId,
request.permissionId,
"once",
);
Expand Down Expand Up @@ -374,7 +373,7 @@ describe("full createSession('claude')", () => {
const promptVm = await AgentOs.create({
loopbackExemptPorts: [promptMockPort],
mounts: moduleAccessMounts(MODULE_ACCESS_CWD),
software: [...REGISTRY_SOFTWARE, TEST_COMMAND_SOFTWARE],
software: [claude, ...REGISTRY_SOFTWARE],
});
let sessionId: string | undefined;
try {
Expand All @@ -387,9 +386,10 @@ describe("full createSession('claude')", () => {
},
});
sessionId = session.sessionId;
promptVm.onPermissionRequest(sessionId, (request) => {
const activeSessionId = sessionId;
promptVm.onPermissionRequest(activeSessionId, (request) => {
void promptVm.respondPermission(
sessionId!,
activeSessionId,
request.permissionId,
"once",
);
Expand Down
12 changes: 6 additions & 6 deletions packages/core/tests/helpers/fixture-node-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
unlinkSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join, resolve, sep } from "node:path";

/**
Expand Down Expand Up @@ -129,12 +130,11 @@ export function ensureFlatNodeModules(cwd: string): string {

const repoRoot = findRepoRoot(cwd);
const safe = packageName.replace(/[^a-z0-9]+/gi, "_");
const cacheRoot = join(
repoRoot,
"node_modules",
".cache",
"agentos-flat-fixtures",
);
const repoSafe = repoRoot.replace(/[^a-z0-9]+/gi, "_");
const cacheBase =
process.env.AGENTOS_FLAT_FIXTURE_CACHE_ROOT ??
join(tmpdir(), "agentos-flat-fixtures");
const cacheRoot = join(cacheBase, repoSafe);
mkdirSync(cacheRoot, { recursive: true });
const target = join(cacheRoot, safe);
const readyMarker = join(target, ".ready");
Expand Down
1 change: 0 additions & 1 deletion packages/core/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { configDefaults, defineConfig } from "vitest/config";
const SLOW_E2E_FILES = [
"tests/wasm-commands.test.ts", // ~24m
"tests/session-cleanup.test.ts", // ~12m
"tests/claude-session.test.ts", // ~7.5m
"tests/execute.test.ts",
"tests/filesystem.test.ts",
"tests/native-sidecar-process.test.ts",
Expand Down