Skip to content

fix(files): make generate export atomic at the directory level#167

Merged
bug-ops merged 1 commit into
masterfrom
fix/159-interrupted-index-ts
Jul 9, 2026
Merged

fix(files): make generate export atomic at the directory level#167
bug-ops merged 1 commit into
masterfrom
fix/159-interrupted-index-ts

Conversation

@bug-ops

@bug-ops bug-ops commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • FileSystem::export_to_filesystem now stages the entire export tree in a sibling temporary directory and publishes it via a single atomic directory rename, instead of writing files directly into the target directory.
  • A process interrupted mid-generate (e.g. killed) can no longer leave a partially written ~/.claude/servers/{id}/ directory — such as an index.ts re-exporting a tool file that was never actually written, with zero detection outside the skill code path.
  • Adds a best-effort sweep of orphaned staging/displaced directories left behind by a killed prior run, so they no longer accumulate indefinitely next to the target.
  • Drops ExportOptions.overwrite, which had no production callers and only complicated the staging model with subtly-different fs::copy semantics.

Closes #159

Test plan

  • cargo +nightly fmt --check
  • cargo +stable clippy --all-targets --all-features --workspace -- -D warnings
  • cargo nextest run --all-features --workspace --no-fail-fast (729 passed)
  • cargo test --doc --all-features --workspace
  • RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace
  • cargo bench --no-run --profile bench-fast -p mcp-execution-files
  • New unit tests cover: failure leaves existing target untouched, swap-into-place replace/rollback, export to a nonexistent target directory (fresh-generation fast path), staging cleanup on publish failure, sweep of orphaned artifacts from a prior crash (target-scoped, doesn't touch other targets' artifacts)

FileSystem::export_to_filesystem now stages the entire export tree in
a sibling temporary directory and publishes it via a single atomic
directory rename, instead of writing files directly into the target.
A process interrupted mid-generate can no longer leave a partially
written server directory (e.g. an index.ts re-exporting a tool file
that was never written), since the target is left exactly as it was
until every file has landed in staging.

Also sweeps orphaned staging/displaced directories left behind by a
killed prior run so they no longer accumulate indefinitely, and drops
ExportOptions.overwrite, which had no production callers and only
complicated the staging model.

Closes #159
@github-actions github-actions Bot added area: cli CLI commands and interface area: bridge MCP bridge and integration crate: mcp-files Changes to mcp-files crate (virtual filesystem) crate: mcp-cli Changes to mcp-cli crate (command-line interface) type: documentation Documentation changes (*.md, docs/, comments) type: dependencies Dependency updates (Cargo.toml, Cargo.lock) breaking change Contains breaking API changes (requires major version bump) release Release preparation (changelog, version bumps) labels Jul 9, 2026
@bug-ops
bug-ops enabled auto-merge (squash) July 9, 2026 18:52
@bug-ops
bug-ops merged commit 5fa3cc8 into master Jul 9, 2026
17 checks passed
@bug-ops
bug-ops deleted the fix/159-interrupted-index-ts branch July 9, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: bridge MCP bridge and integration area: cli CLI commands and interface breaking change Contains breaking API changes (requires major version bump) crate: mcp-cli Changes to mcp-cli crate (command-line interface) crate: mcp-files Changes to mcp-files crate (virtual filesystem) release Release preparation (changelog, version bumps) type: dependencies Dependency updates (Cargo.toml, Cargo.lock) type: documentation Documentation changes (*.md, docs/, comments)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

generate: interrupted export can leave a broken index.ts for direct .ts consumers, bypassing skill's sidecar cross-check

1 participant