fix: bind-mount local --target by default to avoid slow file-by-file …#840
fix: bind-mount local --target by default to avoid slow file-by-file …#840khangpanarnd wants to merge 5 commits into
Conversation
…import (usestrix#725) A local directory passed via --target was handed to the SDK LocalDir manifest entry, which copies the tree into the sandbox file-by-file at session.start(). On large repositories this stalls for a very long time with no report produced (issue usestrix#725). Default local_code targets to a read-only bind mount (applied at container-create time, effectively instant) instead of the file-by-file copy. An explicit mount: False still forces the copy. Also soften the STRIX_MAX_LOCAL_COPY_MB oversize guard from a hard error to a warning so a large --target reaches the fast path instead of being rejected at parse time. Preserves --mount, cloned-repository, and explicit-copy behavior. Adds tests/test_fast_local_import.py (incl. a bug-condition regression test) and updates tests/test_local_sources.py for the new default.
Greptile SummaryThis PR makes local targets use read-only bind mounts by default. The main changes are:
Confidence Score: 4/5Oversized explicit copies and remote-Docker targets can still break the changed flow.
strix/interface/main.py and strix/interface/utils.py Important Files Changed
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
strix/interface/main.py:650-656
**Explicit Copies Bypass Size Guard**
An oversized `local_code` target with `mount: False` still reaches this warning, but `collect_local_sources` preserves that flag and `build_session_entries` creates a file-by-file `LocalDir` copy. The command now proceeds into the same long import that the size guard previously blocked while incorrectly reporting that the target will be bind-mounted.
### Issue 2 of 2
strix/interface/utils.py:1237
**Remote Daemon Cannot See Target**
When Docker uses a remote daemon, this default passes the CLI machine's local path directly as a host bind source. The daemon resolves that path on its own host, so an ordinary `--target` can fail during container creation or expose the wrong directory; the previous `LocalDir` path uploaded the client-side files.
Reviews (1): Last reviewed commit: "fix: bind-mount local --target by defaul..." | Re-trigger Greptile |
| # longer stalls the scan. Warn for visibility and proceed. | ||
| logger.warning( | ||
| "Large local target(s) detected: %s. Bind-mounting read-only " | ||
| "into the sandbox (no file-by-file copy); the scan starts " | ||
| "immediately. Set STRIX_MAX_LOCAL_COPY_MB to tune this check.", | ||
| details, | ||
| ) |
There was a problem hiding this comment.
Explicit Copies Bypass Size Guard
An oversized local_code target with mount: False still reaches this warning, but collect_local_sources preserves that flag and build_session_entries creates a file-by-file LocalDir copy. The command now proceeds into the same long import that the size guard previously blocked while incorrectly reporting that the target will be bind-mounted.
Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/interface/main.py
Line: 650-656
Comment:
**Explicit Copies Bypass Size Guard**
An oversized `local_code` target with `mount: False` still reaches this warning, but `collect_local_sources` preserves that flag and `build_session_entries` creates a file-by-file `LocalDir` copy. The command now proceeds into the same long import that the size guard previously blocked while incorrectly reporting that the target will be bind-mounted.
How can I resolve this? If you propose a fix, please make it concise.| "source_path": details["target_path"], | ||
| "workspace_subdir": workspace_subdir, | ||
| "mount": bool(details.get("mount", False)), | ||
| "mount": bool(details.get("mount", True)), |
There was a problem hiding this comment.
Remote Daemon Cannot See Target
When Docker uses a remote daemon, this default passes the CLI machine's local path directly as a host bind source. The daemon resolves that path on its own host, so an ordinary --target can fail during container creation or expose the wrong directory; the previous LocalDir path uploaded the client-side files.
Prompt To Fix With AI
This is a comment left during a code review.
Path: strix/interface/utils.py
Line: 1237
Comment:
**Remote Daemon Cannot See Target**
When Docker uses a remote daemon, this default passes the CLI machine's local path directly as a host bind source. The daemon resolves that path on its own host, so an ordinary `--target` can fail during container creation or expose the wrong directory; the previous `LocalDir` path uploaded the client-side files.
How can I resolve this? If you propose a fix, please make it concise.Adds report/html_report.py (render_html_report) and writer.write_html_report, invoked best-effort from ReportState._save_artifacts, to write a single self-contained report.html into strix_runs/<run-name>/ alongside the existing markdown/CSV/JSON/SARIF outputs. The report renders parity with the markdown findings report (severity summary + per-finding detail) with all attacker-influenced content HTML-escaped, handles the zero-finding empty state, and is generated by default but disableable via STRIX_HTML_REPORT=0. Adds tests/test_html_report.py (incl. an escaping/XSS test).
The scan thread delivered every SDK event to the Textual UI with a per-event blocking App.call_from_thread, which blocked the scan thread and flooded the UI message pump during streaming, starving input handling and making the TUI feel hung. Add interface/tui/event_pump.drain_queue and a thread-safe queue: the scan thread now enqueues events non-blocking and a UI-loop timer drains bounded FIFO batches (lossless, error-resilient). Also surface a hint when a message is typed with no agent selected instead of dropping it silently. Adds tests/test_event_pump.py. Stdlib-only.
…import (#725)
A local directory passed via --target was handed to the SDK LocalDir manifest entry, which copies the tree into the sandbox file-by-file at session.start(). On large repositories this stalls for a very long time with no report produced (issue #725).
Default local_code targets to a read-only bind mount (applied at container-create time, effectively instant) instead of the file-by-file copy. An explicit mount: False still forces the copy. Also soften the STRIX_MAX_LOCAL_COPY_MB oversize guard from a hard error to a warning so a large --target reaches the fast path instead of being rejected at parse time.
Preserves --mount, cloned-repository, and explicit-copy behavior. Adds tests/test_fast_local_import.py (incl. a bug-condition regression test) and updates tests/test_local_sources.py for the new default.