Commit ed974fa
fix: audit followups — @-picker UTF-8, flag conflict, session prompt restore, MCP timeout + rustfmt CI (#103)
Five real bugs from the latest 6-agent audit pass. CI was also red
on rustfmt — included in this PR.
## Bug 1 — @-picker Esc handler corrupted UTF-8 buffers (CRITICAL)
`src/ui/input.rs` Esc handler in the file picker mixed byte
offsets with char counts:
let at = self.buffer.rfind('@'); // byte offset
let before: String = self.buffer.chars().take(at).collect(); // char count
let after: String = self.buffer.chars().skip(at + 1 + picker.query.len()).collect();
For any input containing multi-byte UTF-8 chars before the `@`
(accented letters, emoji, CJK), the offsets disagreed and the
buffer corrupted on Esc-cancel. Fixed by switching to byte-level
slicing, matching the Enter path right above which was already
correct.
## Bug 2 — Conflicting permission flags silently overridden (HIGH)
`src/main.rs::resolve_mode` checked `--yolo` first, then
`--accept-all`, then `--restrictive`. Passing `--yolo
--restrictive` silently picked yolo. User thought they restricted
permissions and got the opposite.
Now detects multiple CLI permission flags and emits a stderr
warning naming the active mode + the conflicting flags. Still
picks the most-permissive (first match) for non-breaking behavior,
but the user sees the conflict.
## Bug 3 — Session load didn't restore active prompt (MEDIUM)
`/sessions <id>` swapped `*session = s` and called
`render_session` but never read `session.current_prompt_name`
into the context. A session saved with `current_prompt_name =
Some("plan")` would resume with the default "code" prompt
because the agent gets rebuilt from the context (which still
held the previous prompt).
Now reads `session.current_prompt_name`, looks up the prompt
content in `context.prompts`, sets both context fields, and
rebuilds the agent with the restored prompt before
`render_session`. Loaded-message confirms with `; prompt: <name>`
when a prompt was restored.
## Bug 4 — MCP tool calls had no timeout (MEDIUM)
`src/extras/mcp/tool.rs` called `peer.call_tool(params).await`
unconditionally. If the MCP server hung (deadlock, lost stdio
pipe, internal error), the agent turn stalled forever — no way
out short of Ctrl+C to kill the whole agent.
Wrapped in `tokio::time::timeout(120s, …)`. Error message
names the offending server + tool (`MCP tool foo::bar timed
out after 120s`) so the user can identify which MCP to
restart/disable. 120s matches `bash`'s default timeout — any
real tool call done in less.
## Bug 5 — rustfmt CI failure
`src/ui/theme.rs:306` (from PR #102's load_custom_theme): a
single `let` line was slightly over the rustfmt width.
`cargo fmt` wraps it; that's what CI was failing on. Included
the format fix in this PR.
## False positives confirmed (NOT acted on)
The audit also flagged several items I verified as non-bugs:
- Theme JSON "not wired into startup" — actually wired in PR
#102 (`load_custom_theme` is called from `theme::init`).
- Subagent isolation "incomplete" — intentional by design,
documented in docs/PLUGINS.md.
- check_path dual matching (canonical + literal) — by design
for path tools.
- Restrictive mode precedence — by design, dense but correct.
- find_callees regex false positives — known limitation; LSP
references is the AST-aware path for high-confidence use.
## Tests
715 pass (no new — these are integration / behavioral fixes that
would need substantial mocking to unit-test, and the changes
either preserve existing behavior on the happy path or affect
narrow error paths). `cargo fmt --check` now passes.
Co-authored-by: Yogthos <yogthos@gmail.com>1 parent 7054561 commit ed974fa
5 files changed
Lines changed: 102 additions & 14 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
83 | | - | |
84 | | - | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
85 | 108 | | |
86 | 109 | | |
87 | 110 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
60 | 83 | | |
61 | 84 | | |
62 | 85 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
626 | 626 | | |
627 | 627 | | |
628 | 628 | | |
629 | | - | |
630 | | - | |
631 | | - | |
632 | | - | |
633 | | - | |
634 | | - | |
635 | | - | |
636 | | - | |
637 | | - | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
638 | 641 | | |
| 642 | + | |
639 | 643 | | |
640 | 644 | | |
641 | 645 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
383 | 383 | | |
384 | 384 | | |
385 | 385 | | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
386 | 420 | | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
387 | 424 | | |
388 | | - | |
| 425 | + | |
389 | 426 | | |
390 | 427 | | |
391 | 428 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
303 | 303 | | |
304 | 304 | | |
305 | 305 | | |
306 | | - | |
| 306 | + | |
| 307 | + | |
307 | 308 | | |
308 | 309 | | |
309 | 310 | | |
| |||
0 commit comments