Skip to content

feat(tui): save ask permission rules from approvals#3301

Open
greyfreedom wants to merge 3 commits into
Hmbown:mainfrom
greyfreedom:feat/permissions-save-ask-rules-ui
Open

feat(tui): save ask permission rules from approvals#3301
greyfreedom wants to merge 3 commits into
Hmbown:mainfrom
greyfreedom:feat/permissions-save-ask-rules-ui

Conversation

@greyfreedom

Copy link
Copy Markdown
Contributor

Summary:
Add an ask-only approval UI action that persists the current shell approval as a permissions.toml ask rule.

Scope:

  • Generate ask-only ToolAskRule::exec_shell(...) proposals for exec_shell approval prompts
  • Show a TOML preview for the ask rule in the approval modal
  • Add s shortcut to approve once and save the ask rule
  • Persist saved ask rules through ConfigStore::append_ask_rules
  • Refresh the in-memory Config.exec_policy_engine after saving so later turns can use the rule
  • Add approval-view and UI persistence tests

Not in this slice:

  • Typed allow/deny rules
  • File-tool/path rule persistence
  • Full permission DSL or glob editing UI
  • Changes to existing approve-once / approve-for-session / deny / abort behavior

Builds on:

  • The landed ask-only permissions.toml schema/loading work
  • The landed runtime wiring for ask permission rules

Issues:
Refs #1186 (partial)
Refs #2242 (partial)

Validation:

  • cargo fmt --all
  • cargo fmt --all -- --check
  • cargo check -p codewhale-tui --bin codewhale-tui
  • cargo test -p codewhale-tui --bin codewhale-tui ask_rule -- --nocapture
  • git diff --check

Note:

  • cargo clippy -p codewhale-tui --bin codewhale-tui --all-features -- -D warnings was attempted, but current upstream/main fails on pre-existing warnings outside this diff, including uninlined_format_args and too_many_arguments.

@greyfreedom greyfreedom requested a review from Hmbown as a code owner June 18, 2026 08:54

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@github-actions

Copy link
Copy Markdown

Thanks @greyfreedom for taking the time to contribute.

This repository is observing a maintainer-managed PR intake gate in dry-run mode, so this pull request is staying open. This note helps maintainers prepare the allowlist before any enforcement is considered.

Please read CONTRIBUTING.md for the expected contribution shape. A maintainer can grant recurring PR access by commenting /lgtm on a pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the ability to persist "ask-only" permission rules directly from the TUI approval view, specifically targeting exec_shell commands. It adds a shortcut ('s') to approve and save the rule, renders a preview of the rule in the approval widget, and handles persistence via the configuration store. The feedback highlights a logical issue where session-only approvals (ApprovedForSession) would incorrectly persist rules permanently. Additionally, it recommends using the established localization system (tr(locale, MessageId::...)) for the new UI hints and status messages instead of hardcoding or manually matching locales.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread crates/tui/src/tui/ui.rs
Comment on lines +9039 to +9046
if matches!(
event.decision,
ReviewDecision::Approved | ReviewDecision::ApprovedForSession
) && !event.persistent_ask_rules.is_empty()
&& !event.timed_out
{
persist_ask_rules_from_approval(app, config, &event.persistent_ask_rules);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The condition checks ReviewDecision::ApprovedForSession to decide whether to persist the ask rules. However, 'Approved for Session' is intended to be a temporary, session-only approval. Persisting rules to permissions.toml under this decision contradicts the user's choice of a session-only approval. We should only persist rules when the decision is permanently Approved.

    if event.decision == ReviewDecision::Approved
        && !event.persistent_ask_rules.is_empty()
        && !event.timed_out
    {
        persist_ask_rules_from_approval(app, config, &event.persistent_ask_rules);
    }

Comment on lines +1637 to +1649
fn save_ask_rule_hint(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => " s 批准并保存询问规则",
_ => " s approve + save ask rule",
}
}

fn label_ask_rule_preview(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => "询问规则预览:",
_ => "Ask rule preview:",
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The helper functions save_ask_rule_hint and label_ask_rule_preview use manual match locale blocks to return hardcoded translations. This bypasses the established internationalization pattern of using tr(locale, MessageId::...) seen elsewhere in this file (e.g., footer_controls and selection_hint_prefix). To maintain consistency and keep all translations centralized, these strings should be added to the localization system (e.g., MessageId).

Comment thread crates/tui/src/tui/ui.rs
Comment on lines +9081 to +9095
Ok((added, path)) if added > 0 => {
app.status_message = Some(format!(
"Saved {added} ask permission rule(s) to {}",
path.display()
));
}
Ok((_added, path)) => {
app.status_message = Some(format!(
"Ask permission rule already saved in {}",
path.display()
));
}
Err(err) => {
app.status_message = Some(format!("Failed to save ask permission rule: {err:#}"));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The status messages set in persist_ask_rules_from_approval are hardcoded in English. Since the TUI supports multiple locales (such as Chinese/ZhHans), these user-facing status messages should be localized using the project's established internationalization/localization patterns rather than being hardcoded.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@Hmbown Hmbown added the v0.8.63 Targeting v0.8.63 label Jun 18, 2026
@Hmbown Hmbown added this to the v0.8.63 milestone Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v0.8.63 Targeting v0.8.63

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants