fix: route feedback issue links by category (#6840)

## Summary
- TUI feedback note now only links to the bug-report template when the
category is bug/bad result.
- Good result/other feedback shows a thank-you+thread ID instead of
funneling people to file a bug.
- Added a helper + unit test so future changes keep the behavior
consistent.

## Testing
  - just fmt
  - just fix -p codex-tui
  - cargo test -p codex-tui

  Fixes #6839
This commit is contained in:
Weiller Carvalho 2025-11-20 18:20:03 -03:00 committed by GitHub
parent e4257f432e
commit a8a6cbdd1c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -26,7 +26,8 @@ use super::popup_consts::standard_popup_hint_line;
use super::textarea::TextArea;
use super::textarea::TextAreaState;
const BASE_ISSUE_URL: &str = "https://github.com/openai/codex/issues/new?template=2-bug-report.yml";
const BASE_BUG_ISSUE_URL: &str =
"https://github.com/openai/codex/issues/new?template=2-bug-report.yml";
/// Minimal input overlay to collect an optional feedback note, then upload
/// both logs and rollout with classification + metadata.
@ -88,26 +89,38 @@ impl FeedbackNoteView {
match result {
Ok(()) => {
let issue_url = format!("{BASE_ISSUE_URL}&steps=Uploaded%20thread:%20{thread_id}");
let prefix = if self.include_logs {
"• Feedback uploaded."
} else {
"• Feedback recorded (no logs)."
};
self.app_event_tx.send(AppEvent::InsertHistoryCell(Box::new(
history_cell::PlainHistoryCell::new(vec![
Line::from(format!(
"{prefix} Please open an issue using the following URL:"
)),
let issue_url = issue_url_for_category(self.category, &thread_id);
let mut lines = vec![Line::from(match issue_url.as_ref() {
Some(_) => format!("{prefix} Please open an issue using the following URL:"),
None => format!("{prefix} Thanks for the feedback!"),
})];
if let Some(url) = issue_url {
lines.extend([
"".into(),
Line::from(vec![" ".into(), issue_url.cyan().underlined()]),
Line::from(vec![" ".into(), url.cyan().underlined()]),
"".into(),
Line::from(vec![
" Or mention your thread ID ".into(),
std::mem::take(&mut thread_id).bold(),
" in an existing issue.".into(),
]),
]),
]);
} else {
lines.extend([
"".into(),
Line::from(vec![
" Thread ID: ".into(),
std::mem::take(&mut thread_id).bold(),
]),
]);
}
self.app_event_tx.send(AppEvent::InsertHistoryCell(Box::new(
history_cell::PlainHistoryCell::new(lines),
)));
}
Err(e) => {
@ -320,6 +333,15 @@ fn feedback_classification(category: FeedbackCategory) -> &'static str {
}
}
fn issue_url_for_category(category: FeedbackCategory, thread_id: &str) -> Option<String> {
match category {
FeedbackCategory::Bug | FeedbackCategory::BadResult | FeedbackCategory::Other => Some(
format!("{BASE_BUG_ISSUE_URL}&steps=Uploaded%20thread:%20{thread_id}"),
),
FeedbackCategory::GoodResult => None,
}
}
// Build the selection popup params for feedback categories.
pub(crate) fn feedback_selection_params(
app_event_tx: AppEventSender,
@ -514,4 +536,22 @@ mod tests {
let rendered = render(&view, 60);
insta::assert_snapshot!("feedback_view_other", rendered);
}
#[test]
fn issue_url_available_for_bug_bad_result_and_other() {
let bug_url = issue_url_for_category(FeedbackCategory::Bug, "thread-1");
assert!(
bug_url
.as_deref()
.is_some_and(|url| url.contains("template=2-bug-report"))
);
let bad_result_url = issue_url_for_category(FeedbackCategory::BadResult, "thread-2");
assert!(bad_result_url.is_some());
let other_url = issue_url_for_category(FeedbackCategory::Other, "thread-3");
assert!(other_url.is_some());
assert!(issue_url_for_category(FeedbackCategory::GoodResult, "t").is_none());
}
}