fix(tui): synchronize HelpPanelOverlay keybinding display with actual app BINDINGS #3471
Labels
Clear labels
auto/needs-reevaluation
controller-managed
overdue
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Needs Feedback
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
Controller deferred this PR; awaiting Phase 6+ scope-evaluator or operator re-enablement.
Auto-agents controller manages this PR/issue (see tools/controller/deploy/RUNBOOK.md). Remove this label to abandon controller management.
PR blocked by an open issue dependency. Operator must close the dep (or remove the dependency link) before the merge driver can act. Auto-cleared by merge_drive when no open deps remain.
Most recent merge cycle hit CI timeout. Driver excludes this PR while last merge_cycle row is < 30 min old; label persists thereafter as visible history.
Currently being processed by an implementer worker.
Currently being processed by the merge driver.
Currently being processed by a reviewer worker.
Merge driver heartbeat stale; pipeline halted. Closed automatically on next clean tick.
Detected master commit violating the strict merge invariant. Tracked as an issue (not a PR label); kept here for label completeness.
In-cycle escalation: most recent attempt ran at the Tier 0 slot (`tier-0`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 1 slot (`tier-1`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 2 slot (`tier-2`). Slot's model defined in .opencode/models/tiers.yaml. Gated behind IMPLEMENTER_ESCALATION_TIER2_ENABLED.
In-cycle escalation: most recent attempt ran at the Tier -1 slot (`tier-min`). Slot's model defined in .opencode/models/tiers.yaml. Suffix is ``-min`` (not ``--1``) so the Forgejo UI reads naturally.
Tracking issues used by the AI Automation system for agents to communicate and report.
Rebase conflict needs LLM conflict-resolver.
Failing CI needs implementer attention.
Documenting a driver incident or rollback.
Reviewer has APPROVED this PR and no later REQUEST_CHANGES is outstanding. The merge driver requires this label to even consider a PR for merging. Set by the reviewer worker on APPROVE; cleared on REQUEST_CHANGES.
Train repeatedly lost master-tempo races. Driver excludes via merge_cycle until cooldown elapses; label persists as visible history.
Revert PR backing out an invariant violation. Fast-tracked through the merge driver.
Sentinel PR duplicated from upstream into a personal fork by tools/duplicate_prs_to_fork.py for pipeline testing. Lives only in the fork; the canonical pipeline never sees it.
No implementer activity for N days. Flagged for human review. Auto-cleared on next push to head branch.
Repeatedly fails on current master (>= 3 ci-fail-on-rebased-sha releases in 12 h). Excluded from driver until human triage.
A ticket in a blocked state and unable to complete until some other task is completed first.
Bounty
$100
A bounty of $100 for any open-source contributor who provides a MR that solves this issue
Bounty
$1000
A bounty of $1000 for any open-source contributor who provides a MR that solves this issue
Bounty
$10000
A bounty of $10000 for any open-source contributor who provides a MR that solves this issue
Bounty
$20
A bounty of $20 for any open-source contributor who provides a MR that solves this issue
Bounty
$2000
A bounty of $2000 for any open-source contributor who provides a MR that solves this issue
Bounty
$250
A bounty of $250 for any open-source contributor who provides a MR that solves this issue
Bounty
$50
A bounty of $50 for any open-source contributor who provides a MR that solves this issue
Bounty
$500
A bounty of $500 for any open-source contributor who provides a MR that solves this issue
Bounty
$5000
A bounty of $5000 for any open-source contributor who provides a MR that solves this issue
Bounty
$750
A bounty of $750 for any open-source contributor who provides a MR that solves this issue
MoSCoW
Could have
Could have feature in order to satisfy the epic/legendary.
MoSCoW
Must have
Must have feature in order to satisfy the epic/legendary.
MoSCoW
Should have
Should have feature in order to satisfy the epic/legendary.
There are questions in the ticket that can not be completed until the project owner provides clarity.
Points
1
1 man-hours worth of work for an expert with no learning curve.
Points
13
13 man-hours worth of work for an expert with no learning curve.
Points
2
2 man-hours worth of work for an expert with no learning curve.
Points
21
21 man-hours worth of work for an expert with no learning curve.
Points
3
3 man-hours worth of work for an expert with no learning curve.
Points
34
34 man-hours worth of work for an expert with no learning curve.
Points
5
5 man-hours worth of work for an expert with no learning curve.
Points
55
55 man-hours worth of work for an expert with no learning curve.
Points
8
8 man-hours worth of work for an expert with no learning curve.
Points
88
88 man-hours worth of work for an expert with no learning curve.
Priority
Backlog
This ticket has backlogged priority and is not to be worked on yet
Priority
CI Blocker
Critical priority issue that blocks CI/CD pipeline and prevents PR merges
Priority
Critical
The priority is critical
Priority
High
The priority is high
Priority
Low
The priority is low
Priority
Medium
The priority is medium
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
A ticket for learning a tool or technology that is needed to be able to do future planning and design.
State
Completed
The ticket has been fully implemented, completed, and merged with the source code. This label should only be applied once a ticket is closed.
State
Duplicate
A ticket that represents the same content as an existing ticket.
State
In Progress
A ticket that is actively being developed.
State
In Review
A ticket that has had some code completed to implement but is waiting to pass peer review and is not yet merged in.
State
Paused
This ticket's work started but wasn't finished. It's on hold (likely in a feature branch) and will be resumed later, either due to a blocker or a delay.
State
Unverified
All new tickets start in this state. A developer may set it to show the ticket is unverified. This means we haven't agreed to work on it. It will either move to a verified state or be closed as wontdo.
State
Verified
The issue has been verified by a developer as legitimate. It will be worked on and verified tickets are now considered part of the backlog.
State
Wont Do
This ticket has been decided it wont be done. This may mean the bug has been determined to not be real (cant verify) or the feature is one we have decided we dont want to adopt.
Type
Automation
Any edits or discussion about the AI automated coding system.
Type
Bug
Something that doesnt work as intended.
Type
Discussion
Anytime a ticket represents a discussion about a subject and doesnt fall into one of the other categories.
Type
Documentation
An error or improvement needed in the documentation.
Type
Epic
Any first tier epic. That is, an epic which contains only issues as children and will not have sub-epics.
Type
Feature
Some new functionality not present.
Type
Legendary
A type of Epic which will contain other Epics.
Type
Refactor
A code change that restructures existing code without changing its external behavior.
Type
Support
Someone needs help using the project.
Type
Task
A generic task that doesnt fit into the other type categories.
Type
Testing
Work exclusively focusing on fixing or expanding testing.
No Label
Projects
Clear projects
No project
Assignees
aditya (Aditya Chhabra)
aleenaumair (Aleena Umair)
brent.edwards (Brent Edwards)
CoreRasurae (Luis Mendes)
drew (Drew Morris)
eugen.thaci (Eugen Thaci)
freemo (Jeffrey Phillips Freeman)
HAL9000 (HAL 9000)
HAL9001 (HAL9001)
hamza.khyari (Hamza Khyari)
hurui200320 (Rui Hu)
justin.morris
khird (Kyle Hird)
org.cleveragents
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cleveragents/cleveragents-core#3471
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/tui-help-panel-keybinding-accuracy"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
This PR fixes a double-inconsistency in the TUI help panel where
HelpPanelOverlaydisplayedctrl+tabfor preset cycling while the actual registered binding inapp.pyisctrl+t. It also removes a staletab→ "Cycle to next persona" entry that had no correspondingBINDINGSentry (tracked in #3338).Root cause: The static
_CONTEXT_ITEMSdict inhelp_panel_overlay.pywas not kept in sync with theBINDINGSlist inapp.py, causing users who followed the help panel instructions to press the wrong key and get no response.Changes
src/cleveragents/tui/widgets/help_panel_overlay.py_CONTEXT_ITEMS["Main Screen"]: removed staletabentry, changedctrl+tab→ctrl+tfeatures/tui_help_panel_overlay_coverage.featurefeatures/steps/tui_help_panel_overlay_coverage_steps.pyshould not containstep definition; improved assertion messagesMotivation
Per ADR-044, the help panel should "dynamically reflect the current context's available hotkeys." The static
_CONTEXT_ITEMSdict was out of sync withapp.BINDINGS, creating a double-inconsistency:ctrl+tabfor preset cycling, but the actual binding isctrl+ttab→ "Cycle to next persona", but no such binding exists inapp.BINDINGSUsers following the help panel instructions would press the wrong key and get no response — actively misleading behavior.
Approach
_CONTEXT_ITEMSwere changed — no logic changes, no new code pathsapp.py: All three Main Screen context entries (ctrl+q,F1,ctrl+t) now match the actual registeredBINDINGSctrl+tand negative absence ofctrl+taband staletabentry_CONTEXT_ITEMSfromapp.BINDINGSat runtime is noted in the issue but correctly deferred as a separate enhancementTesting
New BDD scenarios in
features/tui_help_panel_overlay_coverage.feature:help panel Main Screen keybindings match actual app BINDINGS: Assertsctrl+tis present,ctrl+tabis absent, staletabentry is absenthelp panel global keybindings match actual app BINDINGS: Assertsctrl+qandF1are present as regression guardsNew step definition
should not containadded to support negative-assertion scenarios, with descriptive failure messages that include the actual rendered help panel text.Related Issues
ctrl+tinstead of spec-correctctrl+tab)tabfor persona cycling, no such binding exists)Automated by CleverAgents Bot
Supervisor: Implementation | Agent: ca-issue-worker
Code Review — PR #3471
Focus areas: specification-compliance, behavior-correctness, code-maintainability
Summary
This PR fixes a double-inconsistency in the TUI help panel where
HelpPanelOverlaydisplayedctrl+tabfor preset cycling, but the actual registered binding inapp.pyisctrl+t. It also removes a staletab→ "Cycle to next persona" entry that had no correspondingBINDINGSentry (tracked in #3338).Changes Reviewed
src/cleveragents/tui/widgets/help_panel_overlay.py_CONTEXT_ITEMS["Main Screen"]: removed staletabentry, changedctrl+tab→ctrl+tfeatures/tui_help_panel_overlay_coverage.featurefeatures/steps/tui_help_panel_overlay_coverage_steps.pyshould not containstep definition; improved assertion messages✅ Specification Compliance
_CONTEXT_ITEMSagainstapp.pyBINDINGS(ctrl+q,f1,ctrl+t). All three Main Screen context entries now match the actual registered bindings. ✓app.BINDINGSis noted in the issue but correctly deferred — that would be a separate enhancement.("tab", "Cycle to next persona")is correct — no such binding exists inapp.BINDINGS, and the discrepancy is tracked in #3338.✅ Behavior Correctness
ctrl+tin_CONTEXT_ITEMSnow matches("ctrl+t", "cycle_preset", "Cycle Preset")inapp.pyBINDINGS. Users following the help panel will now press the correct key.render_help_panel("Main Screen")output will correctly showctrl+tin the keybinding column with proper formatting via the{key:<10}f-string.✅ Test Quality
ctrl+tis present in the rendered help panel text.should not containstep correctly verifies bothctrl+tab(old incorrect binding) andtab(stale persona cycling entry) are absent. The substring check is safe here —"tab"does not appear as a substring of any Main Screen entry in the rendered output.ctrl+qandF1are present, providing a regression guard for global keybindings.should containstep now includes the actual help panel text in failure messages, which aids debugging. Good improvement.✅ Code Quality
# type: ignoresuppressions ✓ISSUES CLOSED: #3444footer present ✓Closes #3444in PR body ✓Type/Buglabel present ✓⚠️ Process Issue: Missing Milestone
The linked issue #3444 is assigned to milestone v3.7.0, but this PR has no milestone assigned. Per CONTRIBUTING.md: "Every PR must be assigned to the same milestone as its linked issue." Please assign milestone v3.7.0 to this PR.
💡 Minor Observations (Non-blocking)
Test fragility note: The
should not contain "tab"assertion works correctly for the current Main Screen context, but is worth noting that it checks the entire rendered text (including global section). If a future global binding description happened to contain the substring "tab", this test would fail. This is acceptable as a regression guard — it would flag the change for review — but worth being aware of.Static vs. dynamic approach: As noted in issue #3444 subtask 3, the long-term solution per ADR-044 would be to derive
_CONTEXT_ITEMSdynamically fromapp.BINDINGS. The current static approach is correct for this bug fix, but the drift risk remains for future binding changes. Consider filing a follow-up enhancement issue if one doesn't already exist.Step definition type annotations: The new step functions (
step_standalone_help_panel_text_not_contains) lack parameter type annotations. This is consistent with the existing step definitions in the same file, so not a new issue, but worth noting for a future cleanup pass.Decision
The code changes are correct, well-scoped, and well-tested. The single process issue (missing milestone) should be addressed before merge. No code changes required.
Automated by CleverAgents Bot
Reviewer: Code Quality | Agent: ca-pr-self-reviewer
@@ -45,1 +45,3 @@assert text in context.help_panel._textassert text in context.help_panel._text, (f"Expected {text!r} in help panel text, got:\n{context.help_panel._text}")Nice addition of the
should not containstep with a clear failure message. The improved assertion message on the existingshould containstep (line 40-42) is also a welcome improvement over the bareassertin master.@@ -25,3 +25,16 @@ Feature: TUI Help Panel Overlay CoverageAnd the standalone help panel text should contain "Help: Slash Commands"When I toggle help for context "Slash Commands"Then the help panel should be hiddenGood regression guard. The combination of positive (
ctrl+tpresent) and negative (ctrl+tababsent,tababsent) assertions provides strong coverage against both the original bug and the stale entry.@@ -36,3 +35,3 @@("ctrl+tab", "Cycle to next argument preset"),("ctrl+t", "Cycle to next argument preset"),("@", "Open Reference Picker overlay"),("/", "Open Slash Command overlay"),✅ Correctly updated from
ctrl+tab→ctrl+tto matchapp.pyBINDINGS. Also correctly removed the stale("tab", "Cycle to next persona")entry (tracked in #3338).Code Review — PR #3471
Review Focus: architecture-alignment, module-boundaries, interface-contracts
Review Type: initial-review
Reviewed PR #3471 with focus on architecture-alignment, module-boundaries, and interface-contracts.
This PR fixes a user-facing bug where
HelpPanelOverlaydisplayedctrl+tabfor preset cycling while the actual registered binding inapp.pyisctrl+t. It also removes a phantomtab→ "Cycle to next persona" entry that had no corresponding binding. The fix is correct, well-scoped, and includes good regression tests.✅ Specification Compliance
The code change correctly aligns
_CONTEXT_ITEMSinhelp_panel_overlay.pywith the actualBINDINGSinapp.py:ctrl+tab→ctrl+tfor preset cycling — verified againstapp.pyline 95:("ctrl+t", "cycle_preset", "Cycle Preset")("tab", "Cycle to next persona")— verified no such binding exists inapp.BINDINGS(tracked in #3338)✅ Architecture Alignment (Deep Dive)
Module boundaries respected:
help_panel_overlay.pylives correctly intui/widgets/and does not import fromapp.py(which would create a circular dependency). The widget maintains proper encapsulation.Interface contracts preserved: All public interfaces (
show_context(),hide(),toggle(),visible,context_name,resolve_help_context(),render_help_panel()) are unchanged. Only internal data (_CONTEXT_ITEMS) was modified.Architectural observation (non-blocking): The static
_CONTEXT_ITEMSdict approach still requires manual synchronization withapp.BINDINGS, which conflicts with ADR-044's "dynamically reflect the current context's available hotkeys" requirement. This is acknowledged in the issue (#3444 subtask 3) and is a separate concern from this bug fix. However, the current approach remains fragile — any future change toBINDINGSrequires a corresponding manual update to_CONTEXT_ITEMS. I note this for awareness, not as a blocking concern for this PR.✅ Code Correctness
✅ Test Quality
New BDD scenarios are well-structured:
ctrl+tis present in Main Screen help textctrl+tabandtabare absent from Main Screen help textctrl+qandF1verified presentshould not containstep definition has clear error messagesThe existing
should containstep was also improved with a descriptive assertion message — good housekeeping.✅ Commit Message & Branch
fix(tui): synchronize HelpPanelOverlay keybinding display with actual app BINDINGS— correct Conventional Changelog format ✅ISSUES CLOSED: #3444✅fix/tui-help-panel-keybinding-accuracy— matches issue metadata ✅Type/Bugpresent ✅⚠️ Required Change Before Merge
Minor Suggestions (Non-blocking)
ctrl+qandF1but omitsescape— consider adding it for completeness.should not contain "tab"assertion works correctly for Main Screen context, but note that "tab" does appear in Shell Mode's description ("Tab-complete file or directory path"). The test is correctly scoped to Main Screen rendering, so this is fine — just worth being aware of if tests are later expanded.Decision: REQUEST CHANGES 🔄
The code itself is correct and well-tested. The only required change is a metadata fix: assign milestone v3.7.0 to this PR to comply with CONTRIBUTING.md requirements. Once the milestone is assigned, this PR is ready for approval.
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: ca-pr-self-reviewer
Addressed the process issue flagged in the review:
The code changes themselves were already correct and well-tested per the review. No code modifications were needed.
Automated by CleverAgents Bot
Supervisor: Implementation | Agent: ca-issue-worker