perf(cli): ~10x faster startup — lazy heavy imports + onedir standalone build - #920
perf(cli): ~10x faster startup — lazy heavy imports + onedir standalone build#920devin-ai-integration[bot] wants to merge 4 commits into
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Greptile SummaryThis PR accelerates CLI startup and replaces standalone onefile releases with onedir bundles.
Confidence Score: 3/5The PR should not merge until failed installs and self-updates reliably preserve the previous executable and Both replacement paths can leave the installed CLI unusable: self-update rollback can retain a new runtime beside the old executable, while the shell installer deletes the working bundle before a fallible recursive copy. Files Needing Attention: strix/interface/update_check.py, scripts/install.sh Important Files Changed
|
| # Onedir app bundle (strix + _internal/). | ||
| rm -rf "$INSTALL_DIR/_internal" "$INSTALL_DIR/strix" | ||
| cp -R "$extracted/." "$INSTALL_DIR/" |
There was a problem hiding this comment.
Upgrade Deletes Working Bundle
When an upgrade copy is interrupted or fails because of insufficient disk space, permissions, or an I/O error, this branch has already deleted the working executable and _internal directory; set -e then exits with a partial installation, causing strix to stop launching.
Knowledge Base Used: Update Notifications and Self-Update
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/install.sh
Line: 176-178
Comment:
**Upgrade Deletes Working Bundle**
When an upgrade copy is interrupted or fails because of insufficient disk space, permissions, or an I/O error, this branch has already deleted the working executable and `_internal` directory; `set -e` then exits with a partial installation, causing `strix` to stop launching.
**Knowledge Base Used:** [Update Notifications and Self-Update](https://app.greptile.com/strix-org-3/-/custom-context/knowledge-base/usestrix/strix/-/docs/update-check-and-self-update.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
✅ Full runtime test — CLI startup perf (onedir + lazy imports + install-script self-update)Tested end-to-end on Linux x86_64. All 6 areas pass; no breakage. Startup timing (3 runs,
~3x faster — per-run self-extraction eliminated. Scan TUI fully boots (deferred imports OK)litellm loads lazily, agent spawns a Reconnaissance Agent, LLM connects, and the Build / install / self-update / regression
|
Summary
strix --help(andview/auth/arg errors) took ~3.2s from pipx/source and ~8s+ from the standalone binary. Two fixes:1. Standalone binary: onefile → onedir (no per-run self-extraction)
The PyInstaller onefile binary unpacked the full ~87MB bundle to a temp dir on every invocation (~4s on fast Linux; 8s+ on macOS with Gatekeeper). Switched to onedir (
EXE(exclude_binaries=True)+COLLECT), so nothing is extracted at runtime:strix-{version}-{target}/(strix+_internal/);build.sh/build-release.ymlupdated accordinglyinstall.shextracts the bundle contents into~/.strix/bin/(sostrixstays on PATH at the same location, and re-running the installer cleanly replaces an old single-file install)strix --updatenow just pipes the hosted install script into bash withVERSION=<latest>(same approach as opencode'sInstallation.upgrade), deleting ~130 lines fromupdate_check.pyNote: binaries already installed from ≤1.4.1 run the old self-update code, which won't understand the new archive layout — their
strix --updatefails with the standard "reinstall via curl" hint, and the reinstall lands them on the new layout.2. Defer the two heaviest imports off the
--helppathrun_cli/run_tui(→strix.core.runner→ litellm ~1.3s + textual) now import insidemain()right where the scan startsconfigure_dependency_loggingno longer doesimport litellmjust to silence it — it only patches litellm if it's already insys.modules(setup_scan_loggingre-runs it on the scan path after litellm is loaded)Measured on Linux x86_64: source/pipx
--help3.2s → 1.2s; standalone binary ~8s → ~1.2s (extraction gone + lazy imports).Import-time was flat from v1.1.0→v1.4.1, and the onefile format dates to ~v0.5, so this wasn't a code regression.
All tests pass (installer/update tests adjusted to the new layout); ruff/mypy/pyright/bandit at parity with main.
Link to Devin session: https://app.devin.ai/sessions/bbaf548ef3ab442c833c4fca488c1ecc
Requested by: @0xallam