Skip to content
Merged
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
76 changes: 0 additions & 76 deletions .github/workflows/nightly.yml

This file was deleted.

6 changes: 3 additions & 3 deletions apps/cli/__tests__/integration/wiring.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, expect, test } from "bun:test";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { rm } from "node:fs/promises";
import { join } from "node:path";
import type { AgentEvent } from "@cyrus/schemas/rtc/chat";
import { createTempCyrusHome } from "@cyrus/test/fixtures/cyrus-home";
import { Result } from "better-result";
import { runTurn } from "../../src/utils/run-turn";
import { createMockPromptStream } from "../helpers/acp-runtime";
Expand Down Expand Up @@ -87,7 +87,7 @@ describe("acp mock runtime", () => {

describe("cli process integration", () => {
test("exits when start is invoked without a login token", async () => {
const home = await mkdtemp(join(tmpdir(), "cyrus-cli-test-"));
const home = await createTempCyrusHome("cyrus-cli-test-");

try {
const proc = Bun.spawn(["bun", "src/cli.ts", "start"], {
Expand Down
1 change: 1 addition & 0 deletions apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"zod": "catalog:rpc"
},
"devDependencies": {
"@cyrus/test": "workspace:*",
"@cyrus/typescript": "workspace:*",
"@types/bun": "catalog:core",
"@types/diff": "^7.0.0",
Expand Down
17 changes: 2 additions & 15 deletions apps/cli/src/commands/service/status.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import { afterEach, describe, expect, test } from "bun:test";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { tempCyrusHomeFixture } from "@cyrus/test/fixtures/cyrus-home";
import { markHealthReady, markHealthStarting } from "@/store/health";

const CLI = join(import.meta.dir, "../../cli.ts");
const homes: string[] = [];

async function tempHome(): Promise<string> {
const home = await mkdtemp(join(tmpdir(), "cyrus-status-"));
homes.push(home);
return home;
}
const tempHome = tempCyrusHomeFixture(afterEach, "cyrus-status-");

async function runStatus(home: string): Promise<{
exitCode: number;
Expand All @@ -37,12 +30,6 @@ async function runStatus(home: string): Promise<{
return { exitCode, stdout, stderr };
}

afterEach(async () => {
await Promise.all(
homes.splice(0).map((home) => rm(home, { recursive: true, force: true }))
);
});

describe("cyrusd status", () => {
test("exits 1 when the worker is not running", async () => {
const home = await tempHome();
Expand Down
18 changes: 2 additions & 16 deletions apps/cli/src/store/health.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { afterEach, describe, expect, test } from "bun:test";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { tempCyrusHomeFixture } from "@cyrus/test/fixtures/cyrus-home";
import {
clearHealth,
DEFAULT_HEALTH_STALE_MS,
Expand All @@ -12,19 +10,7 @@ import {
touchHeartbeat,
} from "@/store/health";

const homes: string[] = [];

async function tempHome(): Promise<string> {
const home = await mkdtemp(join(tmpdir(), "cyrus-health-"));
homes.push(home);
return home;
}

afterEach(async () => {
await Promise.all(
homes.splice(0).map((home) => rm(home, { recursive: true, force: true }))
);
});
const tempHome = tempCyrusHomeFixture(afterEach, "cyrus-health-");

describe("worker health file", () => {
test("isHealthy is false when no health file exists", async () => {
Expand Down
2 changes: 2 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@
"!@cyrus/errors/**",
"!@cyrus/schemas",
"!@cyrus/schemas/**",
"!@cyrus/test",
"!@cyrus/test/**",
"!@cyrus/utils",
"!@cyrus/utils/**"
],
Expand Down
27 changes: 1 addition & 26 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/adr/0017-vitest-default-bun-only-cli-desktop.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Vitest is the default test runner; Bun stays only for `apps/cli` and `apps/desktop`

_Decided 2026-07-20. Supersedes [0016](./0016-server-test-runner-split-by-cloudflare-api-surface.md)._
_Decided 2026-07-20. Supersedes [0016](./0016-server-test-runner-split-by-cloudflare-api-surface.md). Its `tests/e2e` claims (paragraphs 3–4) are superseded by [0019](./0019-remove-end-to-end-test-suite.md)._

The repo's test-runner rule flips: Vitest is now the default everywhere, and `bun:test` is kept only where the app itself must keep running on Bun at runtime — `apps/cli` and `apps/desktop`. This is permanent, not transitional: there is no Vitest execution environment or pool for Bun or Deno (no `vitest-environment-bun`, no `@vitest/pool-bun`, no Deno equivalent — Vitest's only documented Bun awareness is being invoked via `bun run test` as a package-manager convenience), so if `apps/cli` later moves off Bun onto Deno, its tests migrate with it into whatever Deno's own tooling is, not into this Vitest setup. Every other package moves to Vitest specifically to shrink what has to be touched when that migration happens — including the `shared/*` packages `apps/cli` itself depends on (`connections`, `database`, `schemas`, `utils`), since a package's test-runner choice is independent of which runtime later imports it, and none of them have Bun-specific runtime code today; their only Bun coupling was the `bun:test` import itself.

Expand Down
11 changes: 11 additions & 0 deletions docs/adr/0019-remove-end-to-end-test-suite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# The end-to-end test suite is removed

_Decided 2026-07-27. Supersedes the `tests/e2e`-specific claims in [0017](./0017-vitest-default-bun-only-cli-desktop.md) (paragraphs 3–4)._
Comment thread
coderabbitai[bot] marked this conversation as resolved.

`tests/e2e/` is deleted in full: both the harness-driven Vitest + shell-use terminal tier (`tests/e2e/harness/`, covering `cyrusd login`/`start`/`stop`/`status`/`agents doctor` through a real PTY) and the Playwright browser suite (`tests/e2e/web/`, covering cross-peer flows — `worker-connects`, `catalog`, `thread-lifecycle`, `thread-sync`, `cold-resume`). `.github/workflows/nightly.yml` goes with it, all three jobs: the e2e run itself, build smoke (`build:web`, CLI compile), and the real-WebRTC check (`node-datachannel` against `shared/connections`) — none of the latter two were e2e-specific, but nothing else depended on the nightly workflow file existing. The tooling that only existed to run the suite goes too: `mise.toml`'s `process-compose` and `github:microsoft/shell-use` tools, and the e2e-only fixtures in `tooling/test/` (`fixtures/wrangler-env-file.ts`, `fixtures/terminal-session.ts`, `fixtures/cli-worker-state.ts`, `mocks/cli-worker-config.ts`, `helpers/process.ts`). `tooling/test/fixtures/cyrus-home.ts` and `tooling/test/mocks/auth-env.ts` stay — both are used outside `tests/e2e` too (`apps/cli`'s own unit tests, and the root `@cyrus/server` Vitest project's Miniflare bindings, respectively) — so removing them would have cut real, unrelated coverage for no reason tied to this decision.

The reason is scope, not fidelity. The suite's entire cost — a compiled `cyrusd` binary rebuilt fresh on every run, a `wrangler dev` + local D1 + Vite stack orchestrated through process-compose, a PTY driver for the terminal tier, Playwright browsers — was carried off the path every contributor actually feels: it ran only on manual `workflow_dispatch`, never on PRs or pushes to `main`, and cron was deliberately deferred pending "a stable pass history" (per the now-superseded `docs/guides/TESTING_FRAMEWORK.md` text) that it never reached in its short life. Real infrastructure cost, zero automatic runs, no established reliability track record: that combination is pure maintenance surface without a safety net anyone could actually depend on day to day. Nothing about the approach itself — real process orchestration over mocking, PTY-driven terminal assertions, Playwright for cross-peer browser flows — was found lacking; this trades that fidelity for not carrying its cost right now.

Some OpenSpecs lose their only cross-process/browser-level coverage as a result: `acp-provider-cli`, `acp-session-router`, `connection-providers`, and `conversation-persistence` had it in the removed terminal tier or Playwright specs (see the prior `docs/guides/TESTING_FRAMEWORK.md` OpenSpec coverage map) and now rely solely on their existing unit/integration tests. `docs/guides/VERIFY_LOOP.md`'s manual full-stack loop — starting the server, web controller, and CLI worker by hand and driving the browser with `playwright-cli` — is now the only way to exercise these flows end to end, where `bun test:e2e` previously gave a repeatable automated substitute.

If a future need re-justifies this cost — e.g. a recurring class of bug that only manifests across the real process boundary — the removed harness is fully recoverable from git history (branch `chore/e2e-harness-cleanup`, the session that did this removal). A fresh implementation should reconsider the fidelity-vs-cost tradeoff from scratch rather than resurrect the same shape verbatim, given it never reached the "stable pass history" bar this ADR's predecessor was written against.
Loading