Skip to content

feat(desktop): add a Storage view, autopilot cleanup, and pressure notifications - #1149

Merged
janicduplessis merged 5 commits into
mainfrom
feat/1116-desktop-storage
Sep 25, 2026
Merged

janicduplessis merged 5 commits into
mainfrom
feat/1116-desktop-storage

Conversation

@janicduplessis

@janicduplessis janicduplessis commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Stim Desktop shows free disk and per-workspace CPU and memory, but not what uses the disk, and it never cleans up on its own even though it is always running. Reclaiming space on 2026-09-25 took terminal commands and du to find where 150+ GB went. The maintainer decided that Desktop autopilot is on by default.

Solution

All Stim state still comes from CLI JSON, and every action is a stim command. The app never reads or writes $STIM_HOME.

Storage view (sidebar, Machine > Storage)

  • Workspaces table. Build outputs and their gc --delete verdict come from stim gc --json. node_modules and the workspace's owned simulators and AVDs are sized by the app with du. du runs in the background at low priority, and the results are cached for 15 minutes, so opening the view never waits on it.
  • Lifecycle column.
    • Merged into main comes from gc's linkedWorktrees (feat: gc removes worktrees whose branch is merged #1133).
    • PR #n open comes from gh pr list in each repository when gh is on the login shell's PATH. Without gh the view shows a note, and merged and stale still work.
    • Stale Nd means no recorded use for 7 days or more. Otherwise the column reads Active.
  • Remove merged worktrees first runs gc --json again, then confirms using that fresh list, then runs stim worktree remove <path> for each merged worktree, one after another in a single activity run.
  • Stim caches and devices. Each row (build outputs of idle workspaces, each shared cache, and parked, orphaned or stale devices) previews a scoped dry run such as gc --json --cache <name>. The activity sheet's Delete now runs that same scope with --delete, so a preview of one cache can no longer escalate into a full gc --delete.
  • Outside Stim is information only, with Reveal in Finder: simulators Stim does not own, DerivedData, Gradle caches, and ~/Library/Caches. Stim caches inside those folders are subtracted so nothing is counted twice.
  • Reclaim everything safe previews gc --json, then runs gc --delete.

Autopilot (App preferences, on by default; checks every minute)

Pressure notifications and plan. While disk is under the budget:

  • The Storage view shows a plan built from the gc preview, for example "Clear the build outputs of 3 idle workspaces and remove 1 merged worktree to free about 300 MB", with a Do it button (stim gc --delete). The sidebar also marks Storage.
  • When autopilot pressure is off, a notification with a Do it action is posted once per episode. When autopilot acts, a notification reports each run instead. A notification's Do it runs only while disk is still under the budget; otherwise it opens Storage. Delivered pressure notifications are removed when the episode ends.

Trade-offs

  • There is no per-workspace build-output reclaim, because the CLI has no command that targets one workspace. A workspace row offers stim worktree remove instead, and build outputs are cleared through the --cache workspaces row.
  • A workspace's node_modules is measured at the worktree root.

CLI quirk (not changed here). stim settings --json reports a value set by an environment variable as the variable's raw string (for example "40"). StimKit accepts numeric strings for the budget.

Test plan

Automated

  • swift build completes, and swift test passes 78 tests. New StimKit tests cover:
    • Storage attribution without double counting (a Stim cache inside Gradle caches, Stim simulators versus the user's)
    • du parsing with partial output
    • lifecycle precedence, including the fallback without gh
    • gh output parsing
    • nightly scheduling, including catch-up and no double run
    • idle shutdown blocked by a screen the app saw change
    • the pressure plan's budget, hard floor and wording
    • the log cap
    • --cache name uniqueness (the CLI matches by substring, so Empty… is disabled when a name would also select another cache)
    • scoped --delete arguments
    • budget values that arrive as strings
  • pnpm run format:check, lint, typecheck and knip pass.

Manual, bundled app

  • Ran the bundled app against a scratch STIM_HOME with scratch worktrees (one merged, one active, one idle for 12 days) and STIM_BIN set to this branch's CLI, with STIM_BUDGET_MIN_FREE_DISK_GB=40. One real worktree of this repo with an open PR was registered only in the scratch home, and only for the dry-run screenshot.
  • Real du and gh pr list both ran.
  • Do it ran stim gc --delete against the scratch home only: it cleared 286 MB of build outputs and removed the merged worktree. The view refreshed afterwards, and the run appeared in the activity log.
  • The screen was locked, so these images were rendered from the app's own windows with a temporary local hook that is not in this diff.

Storage view with the pressure plan, lifecycle column (merged, PR open from gh, stale) and sizes:
storage

Do it runs stim gc --delete:
do it

After the run:
after

Autopilot preferences and activity log:
preferences

Not verified: the Do it action on a delivered notification, because banners can't be interacted with while the screen is locked. An idle-device shutdown run was also not seen: the scratch home had no booted devices.

Fixes #1116

@janicduplessis
janicduplessis force-pushed the feat/1116-desktop-storage branch from 2f9d395 to 05ad1da Compare September 25, 2026 06:46
@janicduplessis
janicduplessis merged commit dafbf12 into main Sep 25, 2026
1 check passed
@janicduplessis
janicduplessis deleted the feat/1116-desktop-storage branch September 25, 2026 06:47
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.

desktop: add a Storage view, autopilot cleanup, and pressure notifications

1 participant