Add quick action buttons to session detail header#231
Merged
dhilgaertner merged 2 commits intomainfrom May 1, 2026
Merged
Conversation
dgershman
approved these changes
May 1, 2026
Collaborator
dgershman
left a comment
There was a problem hiding this comment.
Code & Security Review
Critical Issues
None found.
Security Review
Strengths:
- Prompts are deterministic string templates — no user-controlled input is interpolated unsafely into shell commands.
parsePRNumber(from:)safely parses viaInt(last), which returns nil for non-numeric input rather than crashing or allowing injection.- The
--force-with-leaseflag in the rebase prompt is the correct safe alternative to--force. dispatchManualre-validates terminal state (managed terminal exists, surface initialized, PR link present) before sending, rather than trusting the UI'scanDispatchQuickActiongate alone. Defense in depth.
Concerns:
- None material. The prompt text is sent to a local terminal, not an external API, so the blast radius of any prompt content issue is limited to the local Claude Code session.
Code Quality
Well done:
- Clean separation:
QuickActionenum in CrowCore (view layer),QuickActionPromptsin the app layer alongsideAutoRespondPrompts. The model doesn't depend on prompt-building logic. addressChangesandfixCheckscorrectly delegate toAutoRespondPrompts.buildvia syntheticPRStatusTransitionvalues — single source of truth for prompt text.- The
@ViewBuilderpattern inquickActionButtonsis idiomatic SwiftUI. Conditional rendering based onPRStatusfields (mergeable,reviewStatus,checksPass,isReadyToMerge) is clean and maps directly to the existing status badges. - Disabled state + tooltip for sessions without a managed terminal is good UX.
AutoRespondCoordinatoris@MainActor, and theonQuickActionclosure is called from SwiftUI button actions (main thread), so thread safety is correct.
Minor observations (non-blocking):
Session.provideris optional (Provider?) —dispatchManualdefaults to.githubvia?? .githubwhen nil. This matches the existingdispatch(_:)pattern at line 56, so it's consistent, but worth noting that a session with no explicit provider will silently get GitHub-flavored prompts.- Synthetic
PRStatusTransitionusesUUID()forsessionID— this is fine sinceAutoRespondPrompts.buildnever readssessionID, but it's a slight code smell. A static sentinel UUID or makingsessionIDnon-required for prompt building would be cleaner, though not worth the refactor now. - Multiple quick action buttons can show simultaneously (e.g., conflicts + failing checks). This seems intentional and correct — a PR can have multiple issues at once.
Summary Table
| Priority | Issue |
|---|---|
| 🟢 | Synthetic UUID() in QuickActionPrompts — cosmetic, matches existing pattern |
| 🟢 | provider ?? .github fallback — consistent with existing code |
Recommendation: Approve — clean feature addition that correctly extends the existing auto-respond architecture with a manual dispatch path. Good separation of concerns, proper guard chains, and consistent prompt reuse. All 136 CrowCore tests pass.
Maps each PR status badge to a button that injects the next-step prompt (Rebase & Fix Conflicts, Address Review, Fix Checks, Merge PR) into the session's managed Claude Code terminal so the user can act in one click without switching focus. Reuses the auto-respond dispatch path; the addressChanges and fixChecks prompts share text with AutoRespondPrompts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auto-respond and the new quick action dispatch were calling TerminalManager.shared.send and existingSurface(for:) directly. That silently fails for terminals on the tmux backend (CROW_TMUX_BACKEND=1) since the surface check returns nil for tmux-backed terminals. Switch both paths to TerminalRouter.send and add a backend-aware TerminalRouter.canSend gate (Ghostty: surface exists; tmux: window binding registered). Adds TmuxBackend.isRegistered(id:) to support it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6f0930f to
e284f41
Compare
This was referenced May 2, 2026
dhilgaertner
added a commit
that referenced
this pull request
May 4, 2026
…xes (#238) Closes #235 ## Summary - Adds `docs/automation.md` as the canonical guide to Settings → Automation and the full auto-flow lifecycle. - Updates `docs/architecture.md` with the dual Ghostty/tmux backend (#229), the new `TerminalRouter` dispatch, the Settings tab split (#228), and the Review Board surface (#188, #205, #207, #210, #212, #220, #226, #231). - Adds `crow rename-terminal` (#206) to `docs/cli-reference.md`. - Adds troubleshooting rows for tmux backend missing, Ghostty surface retry (#218), GitLab nested groups (#233), `GITLAB_HOST` silent skip (#215), auto-respond not firing, and the silent no-op `hook-event` behavior (#234). - Adds `CROW_TMUX_BACKEND` and `CROW_HOOK_DEBUG` to the `docs/configuration.md` env-var table. - Backfills `CHANGELOG.md` `[Unreleased]` with every PR from #137 through #234, grouped by theme. - Updates `README.md` features list and docs index for the new automation suite, review board, terminal renaming, and tmux opt-in. - Appends an "Implementation Status (2026-05)" footer to `docs/terminal-runtime-research.md` noting #229 shipped the headless-PTY backend recommended in the original research. The audit checklist called out as deliverable #1 in the issue is posted as a [comment on #235](#235 (comment)). ## Test plan - [ ] `git diff --stat main` shows only the listed `docs/`, `CHANGELOG.md`, and `README.md` files - [ ] Render each modified doc on GitHub and confirm anchors / cross-links resolve - [ ] Confirm `crow --help` matches the command list in `docs/cli-reference.md` (only `rename-terminal` was missing pre-PR) - [ ] Walk every PR number in the CHANGELOG against `git log --since=2026-04-15 main --oneline` and confirm each one resolves - [ ] Re-export `docs/crow-screenshot.jpeg` against the current Settings/Review-Board UI — **deferred to a follow-up**, called out in the audit comment 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
dispatchManualonAutoRespondCoordinator→ injects a deterministic single-line prompt into the session's managed Claude Code terminal viaTerminalManager.shared.send.addressChangesandfixChecksprompts share text with the existing auto-respond pipeline (AutoRespondPrompts) so manual and auto paths stay consistent. New prompts added forfixConflictsandmergePR, including GitLab variants.Test plan
make buildpassesmake testpasses (CrowCore + Tests/)Closes #230
🤖 Generated with Claude Code