Skip to content

test(windows): make the test suite pass on Windows - #22

Open
NancyBraun wants to merge 9 commits into
noogalabs:mainfrom
NancyBraun:fix/windows-test-portability
Open

NancyBraun wants to merge 9 commits into
noogalabs:mainfrom
NancyBraun:fix/windows-test-portability

Conversation

@NancyBraun

Copy link
Copy Markdown
Contributor

What

Portability fixes so the full test suite runs green on Windows. Result on Windows: 2574 passed / 0 failed / 37 skipped (was ~78 failing). Build and tsc --noEmit clean.

⚠️ Stacked on #11 — please merge #11 first

This branch builds on #11 (fix/windows-native-portability) and depends on its 0cd1b07 fast-checker runtime fix. The first four commits shown here (852cb1a, b889ebd, ee1a699, 0cd1b07) belong to #11; once #11 merges, this PR's diff narrows to just the test commits below. Please review/merge #11 first.

The commits to review here:

  • ac1c83d dashboard sync + 3 test suites
  • 7652096 portability fixes for 11 more test suites
  • 5017687 last 5 failures (kb config guard, comms-lint homedir)
  • 917aef8 extend hook/subprocess timeouts for git-heavy tests under Windows AV

Approach (test-only, plus one path-normalize in a migration script)

  • Normalize \/ and strip CRLF before path / frontmatter assertions, or use path.basename/relative instead of string slicing.
  • skipIf(isWindows) for suites that require capabilities Windows lacks without elevation: symlink creation (Developer Mode), Unix domain sockets (codex app-server), and a couple of fake-timer scheduling tests that hang under Windows fake timers (confirmed: advanceTimersByTimeAsync never resolves). The production paths these cover are exercised elsewhere.
  • Two genuine bug-class fixes:
    • knowledge-base.test: the missing-config mock compared a forward-slash path, but production builds it via path.join (backslashes on Windows), so the missing-config guard was skipped and execFileSync ran. Normalize separators in the mock.
    • comms-lint tests sandbox the home dir via process.env.HOME, but os.homedir() reads USERPROFILE on Windows — so the outbound-message log escaped into the real ~/.cortextos. Pin USERPROFILE to the temp dir too.

🤖 Generated with Claude Code

NancyBraun and others added 9 commits June 24, 2026 10:14
The "--dangerously-skip-permissions" first-run warning defaults its
highlight to "No, exit", so the prior bare-Enter auto-accept exited the
agent process, crash-looping the daemon. Detect the "Bypass Permissions"
screen and send Down+Enter (\x1b[B\r) to select "Yes, I accept"; keep the
plain Enter path for the folder-trust prompt. Extend the retry timers to
cover the slower bypass render.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Containment/traversal guards compared with `base + '/'`, but on Windows
path.resolve()/join() return '\' separators, so the startsWith check
failed for legitimately-nested paths and the guard tripped — disabling
the hook dispatcher (fast-checker), and rejecting valid worker dirs
(ipc-server spawn-worker), catalog installs, and skill auto-PRs.

Switch all six sites to `base + sep`, matching the existing correct
pattern in src/bus/message.ts. Also normalize separators before the
SKILL.md regex in hook-skill-autopr so the path match is platform-independent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Google is migrating Gemini/AI Studio keys from the legacy AIza format to
new "auth keys" with an AQ. prefix (standard keys get rejected mid-2026).
Key acceptance here was always format-agnostic (verifyGeminiKey hits the
live API; other checks are non-empty only), so AQ. keys already work — but
the two console hints still said "starts with AIza..." and could confuse
users pasting a new auth key. Update the hints to list both formats.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t-checker

The heartbeat watchdog and usage-tier checker called execFile('cortextos', ...)
with a bare command name. On Windows the npm global is a `cortextos.cmd` shim
that execFile (no shell) cannot resolve, so both fired `spawn cortextos ENOENT`
on every tick. Effects: idle agents never refreshed their heartbeat (the
dashboard then falsely marked them "down" after 5h) and rate-limit tier alerts
never ran.

Switch both call sites to `process.execPath` + `<frameworkRoot>/dist/cli.js`,
matching the existing convention in hook-skill-autopr.ts and setup.ts. Fully
portable; no PATH/shim dependency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Authored by the cpm-dev agent as part of its task to resolve the Windows test
failures it identified (78/2611). Verified by Claude Code: the 3 test files pass
(38 passed, 8 correctly skipped on Windows), main build is clean, and
dashboard/sync.ts type-checks.

- dashboard/src/lib/sync.ts: normalize Windows backslashes to forward slashes
  before path containment checks in syncFile() and the extract* helpers, so the
  dashboard file-sync (tasks/approvals/events/heartbeat) works on Windows.
- tests/support-access.test.ts, tests/unit/cli/enable-agent-validation.test.ts:
  set USERPROFILE (os.homedir() reads it on Windows, not HOME); skip the two
  chmod-permission cases on Windows.
- tests/unit/utils/atomic.test.ts: skipIf(isWindows) on tests asserting Unix
  file modes (0o600) and POSIX symlink behavior that do not apply on Windows.

Partial fix — covers these 4 files; remaining Windows test failures stay tracked
under the cpm-dev task.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sweep of cpm-dev's autonomous Windows-portability work plus two
completions found during verification.

cpm-dev's fixes (verified):
- Normalize `\`→`/` and strip CRLF before path/frontmatter assertions
  (agent-process, agent-process-hermes, cron-teaching-scanner,
  sprint1-templates, sprint4-catalog, cron-management-skill,
  migrate-runtime-field).
- skipIf(isWindows) on suites needing symlinks (Developer Mode) or Unix
  domain sockets (codex-app-server-pty, lifecycle-codex, add-agent-codex,
  media-route) and on fake-timer scheduling tests that hang under Windows
  fake timers (fast-checker heartbeat watchdog). Production paths these
  cover are verified elsewhere/live.

Completions added during verify:
- add-agent-codex: skip the PR-10 describe too (it also calls symlinkSync;
  cpm-dev only skipped PR-02) — was 4 EPERM failures.
- message.test: skip the processed/ symlink-traversal test (EPERM on
  Windows without Developer Mode).

Full suite on Windows: build + tsc clean; remaining known failures are
unrelated (knowledge-base missing-config guard, comms-lint real-homedir
isolation) and tracked separately.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nt homedir)

Clears the remaining Windows test failures so the full suite is green
(2574 passed, 0 failed, 37 skipped).

- knowledge-base.test: mockMissingKbConfig() compared the config path with
  a forward-slash `.endsWith('/knowledge-base/config.json')`, but production
  builds it via path.join → backslashes on Windows. The check never matched,
  so existsSync fell through to `true`, the missing-config guard was skipped,
  and execFileSync ran (3 failures). Normalize separators before the check.

- comms-lint (both files): tests sandbox the home dir via process.env.HOME,
  but os.homedir() reads USERPROFILE on Windows, so the outbound-message log
  escaped into the REAL ~/.cortextos and a stale file failed the
  "no file written when blocked" assertions. Pin USERPROFILE to the temp dir
  too (saved/restored alongside HOME).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rge subprocess timeout

autoCommit beforeEach runs 4 git processes (init, 2x config, commit) which
exceeds the 10s hookTimeout on Windows under AV scanning. Batch to 2 shell
invocations with shell:true and set hookTimeout to 30s.

forge-load-gate spawns node child processes per test; under full-suite
parallelism (16 workers) the cold-start overhead can exceed 10s.
Add describe-level { timeout: 30000 } to keep the file portable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@noogalabs

Copy link
Copy Markdown
Owner

This contains real Windows work. In particular, normalizing dashboard sync paths before task/approval/event/heartbeat classification and setting USERPROFILE alongside HOME in test sandboxes address Windows-specific failures that remain absent from current main.

We are not merging this branch as-is because it carries the full #11 commit chain plus a broad set of test skips and now conflicts with current main. That makes the branch scope materially larger than the Windows-test title and prevents a safe current-tree review.

The work is wanted, but this stacked branch is not mergeable. We will extract the path normalization and environment-isolation fixes into clean current-main patches with your credit. The delay and the need to untangle the stack are ours; you should have received this specific answer when the PR was opened.

@noogalabs

Copy link
Copy Markdown
Owner

Wanted - full verdict and a rebase plan for the whole stack is on #11 (one comment covering #11#22#25#26 so it reads in order). Short version for this one: adopt after the sequenced rebase, including your two test-bug fixes. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants