Skip to content

fix(shell-init,completions): skip update check and trust prune for shell-eval'd commands#416

Merged
avihut merged 2 commits intomasterfrom
fix/suppress-version-check-on-shell-init
Apr 27, 2026
Merged

fix(shell-init,completions): skip update check and trust prune for shell-eval'd commands#416
avihut merged 2 commits intomasterfrom
fix/suppress-version-check-on-shell-init

Conversation

@avihut
Copy link
Copy Markdown
Owner

@avihut avihut commented Apr 27, 2026

Summary

daft shell-init and daft completions <shell> both emit shell code that users eval from their rc files (~/.bashrc, ~/.zshrc, …), so they run on every interactive shell startup. Two problems on this codepath:

  1. Per-shell startup latency. The unconditional update-check and trust-prune calls in src/main.rs run a git config --global subprocess, read ~/.config/daft/update-check.json, and (when stale) fork-spawn daft __check-update which itself forks curl to GitHub.
  2. Stray banner on shell startup. print_notification writes to stderr; eval only captures stdout, so when a newer release is cached and the 24h-per-version throttle has elapsed, the banner leaks straight into the user's terminal at shell startup.

This PR:

  • Generalises the existing is_background_task gate in src/main.rs into a small pure helper daft::skip_startup_tasks_for (src/lib.rs) that matches __* background tasks plus the two shell-eval'd commands shell-init and completions.
  • Routes both maybe_check_for_update and maybe_prune_trust through the helper.
  • Documents the hot-path constraint in CLAUDE.md (covers shell-init, completions, and the __complete tab-completion helper that is already gated via the __ prefix) so future commands with similar requirements are added to the same gate rather than introducing a parallel one.

Test plan

  • mise run fmt
  • mise run clippy — zero warnings
  • cargo test --lib skip_startup_tasks — 11/11 helper tests pass (covers empty argv, no subcommand, daft shell-init, git-daft shell-init, daft completions, git-daft completions, __check-update, __prune-trust, daft clone …, daft list, no-substring-match guard)
  • Manual: built target/release/daft, seeded ~/.config/daft/update-check.json with latest_version: 999.0.0, ran daft shell-init bash — no banner on stderr, pgrep confirmed no __check-update/__prune-trust background processes spawned

🤖 Generated with Claude Code

`daft shell-init` is sourced from `~/.bashrc`, `~/.zshrc`, etc. via
`eval "$(daft shell-init …)"` on every interactive shell startup, so
its codepath must stay lean. Previously it unconditionally ran a
`git config --global` subprocess, read the update-check cache from
disk, and (when stale) spawned `daft __check-update` which then forks
`curl`. The version-upgrade banner is also written to stderr, which
`eval` does not capture, so it leaked straight into the user's
terminal at shell startup.

Generalise the existing `is_background_task` gate in `src/main.rs`
into a pure helper `daft::skip_startup_tasks_for` that also matches
`shell-init`, and route both `maybe_check_for_update` and
`maybe_prune_trust` through it. Document the hot-path constraint in
CLAUDE.md so future commands with similar requirements are added to
the same gate rather than introducing a parallel one.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avihut avihut added this to the Public Launch milestone Apr 27, 2026
@avihut avihut added the fix Bug fix label Apr 27, 2026
@avihut avihut self-assigned this Apr 27, 2026
`daft completions <shell>` emits shell code to stdout that some users
`eval` from their rc files (when they don't go through `shell-init`,
which already bundles completions). That makes it the same hot path as
`shell-init`: subprocess calls, file IO, and background spawns add
latency to every new shell, and any stderr output (e.g., the update
banner) leaks past `eval`'s stdout capture into the user's terminal.

Extend `daft::skip_startup_tasks_for` to also match `completions`, and
update the CLAUDE.md note to cover both shell-eval'd commands plus the
`__complete` tab-completion helper that is already gated via the `__`
prefix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avihut avihut changed the title fix(shell-init): skip update check and trust prune on shell startup fix(shell-init,completions): skip update check and trust prune for shell-eval'd commands Apr 27, 2026
@avihut avihut merged commit 83eb5af into master Apr 27, 2026
8 checks passed
@avihut avihut deleted the fix/suppress-version-check-on-shell-init branch April 27, 2026 20:40
This was referenced Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant