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
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@
!src/crates/services/relay-service/Cargo.toml
!src/crates/services/relay-service/src/
!src/crates/services/relay-service/src/**
!src/crates/services/page-function-runtime/
!src/crates/services/page-function-runtime/Cargo.toml
!src/crates/services/page-function-runtime/src/
!src/crates/services/page-function-runtime/src/**
39 changes: 39 additions & 0 deletions docs/superpowers/plans/2026-07-22-cargo-target-latest-only-gc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Cargo Target Latest-Only GC Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** On desktop:dev exit and desktop:build end, prune Cargo target caches so only the latest useful artifacts remain for the active profile.

**Architecture:** A shared Node module `scripts/cargo-target-gc.mjs` owns prune logic and CLI. `scripts/dev.cjs` and `scripts/desktop-tauri-build.mjs` call it best-effort after the session/build ends.

**Tech Stack:** Node.js (`node:test`, `fs`, `path`, `child_process`)

## File map

| File | Responsibility |
|---|---|
| `scripts/cargo-target-gc.mjs` | Prune incremental / fingerprint / deps; CLI + exported API |
| `scripts/cargo-target-gc.test.mjs` | Fixture tests for keep-latest rules |
| `scripts/dev.cjs` | Call GC after desktop / preview exit |
| `scripts/desktop-tauri-build.mjs` | Call GC after tauri build |
| `package.json` | `target:gc` script |
| `src/apps/desktop/AGENTS.md` (+ CN) | One short note on GC behavior |

## Tasks

### Task 1: Core GC module + tests

- [x] Write failing tests for incremental keep-latest and fingerprint/deps orphan cleanup
- [x] Implement `scripts/cargo-target-gc.mjs`
- [x] Pass `node --test scripts/cargo-target-gc.test.mjs`

### Task 2: Wire desktop entrypoints

- [x] Hook `dev.cjs` desktop + preview shutdown/`finally`
- [x] Hook `desktop-tauri-build.mjs` after build
- [x] Add `pnpm run target:gc`

### Task 3: Docs + verify

- [x] Brief AGENTS note
- [x] Re-run unit tests; dry-run against real target if present
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Cargo Target Latest-Only GC

**Date:** 2026-07-22
**Status:** Approved (timing: exit of `desktop:dev` / end of `desktop:build`)

## Problem

`target/debug` grows without bound across `pnpm run desktop:dev` / build sessions (observed ~139GB). Growth is dominated by:

1. Multiple `incremental/<crate>-<hash>/` roots for the same crate (rustc only GCs sessions *inside* one hash root).
2. Stale `.fingerprint` / `deps` artifacts left after feature or unit-graph changes.

## Goal

After a desktop dev session exits or a desktop build finishes, keep only the latest *useful* cache for the active profile so disk usage stops ratcheting upward, without `cargo clean` and without disabling incremental compilation.

## Non-goals

- Changing default `profile.dev` debuginfo (optional later).
- GC on every incremental rebuild during a live `tauri dev` session.
- Guaranteeing a single hash per third-party crate when Cargo legitimately needs two units (lib vs build-dep).

## Design

### Trigger (option B)

| Entry | When GC runs |
|---|---|
| `pnpm run desktop:dev` | After `tauri dev` exits (including Ctrl+C), in a `finally` path |
| `pnpm run desktop:preview:debug` | On preview shutdown |
| `pnpm run desktop:build*` (`scripts/desktop-tauri-build.mjs`) | After `tauri build` returns (success or fail; GC is best-effort) |
| `pnpm run target:gc` | Manual |

Skip GC when `BITFUN_TARGET_GC=0`. Dry-run when `BITFUN_TARGET_GC_DRY_RUN=1`.

Skip when another `cargo` / `rustc` process still appears active (avoid deleting in-use artifacts).

### What is pruned

For `target/<triple?>/<profile>/` (default host triple omitted; profile `debug` for dev, build profile from argv):

1. **incremental** — group directories by crate prefix (name before final `-`); keep the newest mtime; delete older roots. Inside a kept root, keep the newest finalized `s-*` session when multiple remain.
2. **.fingerprint** — group by package stem; keep newest **1** for `bitfun_*` / workspace-app stems, newest **2** for other packages (build-dep dual units). Delete older groups.
3. **deps** — delete artifacts whose trailing hash no longer appears in any remaining fingerprint directory name. Do not delete by “crate name latest only” (unsafe for dual feature units).

### Safety

- Never delete the profile root or final binaries by name (`bitfun-desktop`, `.app`, etc.) except via normal cargo replacement.
- GC failures must not fail the user command (log and continue).
- No dependency on `cargo-sweep` (macOS atime is unreliable).

## Verification

- Unit tests for grouping / keep-latest / deps orphan deletion on a temp fixture.
- `node --test scripts/cargo-target-gc.test.mjs`
- Manual: run GC dry-run against real `target/debug`, confirm incremental crate counts drop to 1 per prefix without requiring a full clean rebuild afterward for desktop:dev.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"desktop:dev": "node scripts/dev.cjs desktop",
"desktop:preview:debug": "node scripts/dev.cjs desktop-preview",
"desktop:dev:raw": "cross-env-shell CI=true \"cd src/apps/desktop && tauri dev\"",
"target:gc": "node scripts/cargo-target-gc.mjs",
"desktop:build": "node scripts/desktop-tauri-build.mjs",
"desktop:build:fast": "node scripts/desktop-tauri-build.mjs --debug --no-bundle",
"desktop:build:release-fast": "node scripts/desktop-tauri-build.mjs --no-bundle -- --profile release-fast --features devtools",
Expand Down
Loading
Loading