Skip to content

fix: keep the project folder inside a long cache root; leave no test temp files - #105

Merged
oakimov merged 4 commits into
mainfrom
fix/test-tmp-cleanup
Oct 18, 2026
Merged

oakimov merged 4 commits into
mainfrom
fix/test-tmp-cleanup

Conversation

@oakimov

@oakimov oakimov commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

Fixes #102.

Problem

A clean bun test leaves entries in TMPDIR, and they pile up with every run. On main, with a TMPDIR of about 90 characters per test file, 18 files left 197 entries. One cause also affects real use.

Causes and fixes

Project folder outside a long cache root (real use too). opencodeProjectDir cut the whole path to 84 characters plus a hash. When the cache root itself is long, the cut lands inside the root, so agent-tools/ and terminals/ are created next to the cache dir.

  • Cursor CLI doesn't shorten its project folder at all; it shortens only a path that has to fit a socket-path limit. The provider had applied that shortening to the project folder.
  • While the 84-character cut falls after projects/ (a projects root shorter than 84 characters), the name is the old one verbatim, so existing project folders don't move. A longer root, where the old cut fell inside the root, now names the folder by its hash inside projects/.

Background spawns. Three tests ran the real buildBackgroundShellCommand and kept its cursor-opencode-bg.* log. One also left a detached sleep 10 running. reapBackgroundSpawn (in test/background-spawn.ts) reads the printed marker, kills the child and removes the log.

A stop's save after cleanup. In write-drain's "cancels an unregistered replacement upload", the cancelled Run saves its snapshot from the host-interrupt handler. That happens about 30 ms after the test's finally has removed the cache dir. The Node drain scenario does the same.

  • A test-only export, settleRunSavesForTests, waits for host-interrupt cancels and every in-progress Run save.
  • Both tests call it before removing the dir. The lifecycle test also closes its held Run and waits for the held Run's save.

A cache root left set for later tests (Linux file order). createCursor({ cacheDir }) sets the process-wide host cache root. Three tests never restored it, so later files wrote project folders, model and client-version caches into their removed temp dirs. With some file orders, tests that expect the default root failed too. Those three tests now restore the root after each test.

Terminal supervisors after afterEach. A launcher that hadn't written ready yet was skipped by cleanup, then started and recreated its job files. runtime-files-pump has the same race with a managed terminal.

  • stopProcessesUsing(dir) (in test/process-cleanup.ts) waits for every process that names the test root, kills those that don't finish within 3 s, and only then lets the root go.
  • terminal-runner calls it only when a job directory exists.

Guard so this stays fixed:

  • bunfig.toml preloads test/preload.ts. It gives every bun test run a private TMPDIR, fails the run if anything is left in it, and removes it either way.
  • test/node-tmpdir.mjs does the same for the Node HTTP/2 scripts.
  • I checked both guards: each catches the leaks above before its fix. The error lists the leftover files.

AGENTS.md now has a working-convention rule: never leave TMPDIR remnants, whether from tests, scripts or scratch work.

Validation of rebased head bd08dfc

Rebased onto main after #104 merged as 83506c2. All four #105 commits are retained. Only the overlapping release-publication lesson needed a conflict resolution; both changelog entries remain under unreleased 0.8.3.

  • Source/test typecheck and build pass.
  • bun test --coverage: 2,377 pass, 0 fail across 108 files; the TMPDIR guard passes.
  • bun run test:node-http2 passes, including its temporary-file guards.
  • bun run check:pricing covers all 54 priced model fixtures.
  • 76 focused path, background-process, cleanup and shell-result regressions pass on the combined tree.

Original validation (before the rebase)

main this branch
Per-file sweep, each file in a fresh TMPDIR (~90 chars) 18 files leave 197 entries 106 of 106 files exit 0 and leave nothing
Full bun test — 2367 pass, 0 fail, no TMPDIR entries
Linux container, bun test --coverage as in CI 16 fail, entries left in /tmp 2367 pass, 0 fail, no entries
bun run test:node-http2 cursor-node-upload-cancel-* left exit 0, no entries
  • bun run typecheck, bun run build and test/architecture.test.ts pass.
  • terminal-runner.test.ts runs about 5 s slower (one process listing per test that started a job). The whole suite is about 4 s slower.
  • New tests in paths.test.ts: a long cache root keeps the folder inside projects/, the name an existing folder already has stays the same, and 83- and 84-character projects roots get the expected names.

The changelog entry is under 0.8.3, which is not tagged yet, and covers only the project-folder fix that users can notice.

@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new blocking issue was found.

Summary

Keeps project folders inside long cache roots and adds test cleanup and TMPDIR guards.

  • Cursor’s project folders stay inside long cache roots.
  • Test cleanup waits for temporary-directory writers to stop.
  • Test runs use private temporary folders and report leftovers.
  • The debug test checks the log body, and the lesson clarifies release labels.

Reviews (4) · Last reviewed commit: "docs: keep pending changelog entries und..." · Reviewed by Greptile

Comment thread src/context/paths.ts Outdated
@codecov

codecov Bot commented Oct 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@nkoynov

nkoynov commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Retested 4fbd4df as in #102, each test file alone in a fresh TMPDIR (/tmp, 48 and 52 to 70 characters): main leaves 6, 60 and 189 entries plus a detached sleep 10 and sleep 1, and this branch leaves nothing in all 108 files, with or without the preload, while the full bun test (2371 pass, 0 fail, /tmp empty), typecheck and build pass. opencodeProjectDir now always stays inside <root>/projects/ and names don't change while the projects root is under 84 characters; only cache roots of 75 to 83 characters move, from <root>/proj…-<hash> into projects/. One correction to my issue: the old cut left the cache root only from 84 characters up, not 74.

…temp files

opencodeProjectDir cut the whole path to 84 characters, so with a long cache
root the project folder (agent-tools, terminals) was created next to the cache
directory. Cut only the slug. Below an 83-character root the name is the one
the old cut produced, so existing folders keep their location.

The suite left about 200 TMPDIR entries per run with a long TMPDIR:
- background-spawn tests kept their logs and a detached child
  (reapBackgroundSpawn)
- a stop saved the cancelled Run after the test removed its cache dir
  (settleHostInterruptsForTests, in write-drain and the Node drain script)
- terminal supervisors wrote job files after cleanup (stopProcessesUsing, in
  terminal-runner and runtime-files-pump)

bunfig.toml preloads test/preload.ts: every bun test run gets a private TMPDIR,
fails when anything is left in it, and removes it. Node test scripts import
test/node-tmpdir.mjs for the same guard. AGENTS.md now says never to leave
TMPDIR remnants.

Fixes #102
…ache roots

Review: with an 83-character projects root the old cut already ended at
`projects/` and named the folder `-<hash>`; cutting only the slug renamed it
to `<hash>`. Keep the old name whenever the cut falls after `projects/`, and
name the folder by the hash alone only for longer roots.

CI (Linux): three tests left the process-wide host cache root that
createCursor({ cacheDir }) sets pointing at their removed temp dirs, so later
files wrote project folders, models and client-version caches there, and on
some file orders tests expecting the default root failed. Restore the root
after each test. The lifecycle test also closes its held Run and waits for
its save before removing the dir; settleRunSavesForTests now waits for every
in-progress Run save, not only host-interrupt cancels.

The TMPDIR guard now lists the leftover files.
@oakimov
oakimov force-pushed the fix/test-tmp-cleanup branch from 4fbd4df to bd08dfc Compare October 18, 2026 13:56
@oakimov
oakimov merged commit cf5822d into main Oct 18, 2026
6 checks passed
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.

Test suite leaves files in TMPDIR (cursor-opencode-bg.*, cursor-* dirs); long TMPDIR also misplaces the project folder

2 participants