Skip to content

feat(feedback): add structured feedback reporting#31

Merged
elkaix merged 3 commits into
mainfrom
feature/structured-feedback
May 31, 2026
Merged

feat(feedback): add structured feedback reporting#31
elkaix merged 3 commits into
mainfrom
feature/structured-feedback

Conversation

@elkaix
Copy link
Copy Markdown
Contributor

@elkaix elkaix commented May 31, 2026

Summary

  • add structured /feedback support with feedback types, redacted session context, opt-in transcript/diff/tool details, and default send confirmation
  • add compact GitHub fallback URLs and richer feedback-worker issue responses
  • add tests for parsing, redaction, confirmation, fallback behavior, update/welcome banner behavior, and related update state handling
  • keep existing branch changes to welcome/update UX and Dependabot configuration

Verification

  • make check-pythinker-code
  • make test-pythinker-code
  • uv run pytest tests/ui_and_conv/test_shell_feedback_slash.py -q
  • cd examples/feedback-worker && npm exec --package typescript@5.9.3 -- tsc --noEmit --strict --target ES2022 --module ESNext --moduleResolution Bundler src/index.ts
  • git diff --check
  • graphify update .

Summary by CodeRabbit

  • New Features

    • Async feedback submission: structured, redacted session reports (bug/feature/ux/wrong) with prompts, optional diff/transcript/tool-details, confirmation, and GitHub fallback.
    • CLI welcome banner that surfaces update availability and one‑time “what’s new” post‑upgrade.
  • Bug Fixes / Improvements

    • More robust feedback flow: JSON error handling, network timeout/retry fallbacks, clearer success messages.
  • Tests

    • Expanded coverage for feedback parsing/submission, redaction, fallbacks, and welcome/update banner behaviors.
  • Chores

    • Dependabot: weekly schedule, PR limits, grouping, and ignores for specified packages.

Add privacy-aware /feedback submissions with redacted session context, GitHub fallback handling, and worker support for structured payloads.

Also keep the welcome/update refinements and Dependabot config changes currently present on the branch.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a2560b84-90af-48d2-b8f1-8de7f06a54d3

📥 Commits

Reviewing files that changed from the base of the PR and between bc029cd and 1a648a3.

📒 Files selected for processing (4)
  • src/pythinker_code/feedback.py
  • src/pythinker_code/ui/shell/update.py
  • tests/ui_and_conv/test_shell_feedback_slash.py
  • tests/ui_and_conv/test_shell_update.py

📝 Walkthrough

Walkthrough

Adds a structured feedback submission flow with redaction and async backend submission (with GitHub fallback), integrates a welcome-banner update/what's-new chip, expands tests for both features, and tightens Dependabot configuration.

Changes

Feedback and Update Notification System

Layer / File(s) Summary
Dependabot configuration: schedule, limits, and dependency ignores
.github/dependabot.yml
Sets schedule to weekly (Mondays), caps open PRs to 3, groups minor/patch updates, and ignores ruff >=0.15 and click >=8.4.
Backend payload handling and sanitizers
examples/feedback-worker/src/index.ts
Expands FeedbackPayload schema, adds JSON parse error handling, computes nested/top-level recent_errors, introduces MAX_CONTEXT_ITEMS, implements sanitizeValue/sanitizeRecord/sanitizeArray, appends JSON sections to GitHub body, returns {number, html_url}, and adds unique() helper.
Feedback types, limits, and contracts
src/pythinker_code/feedback.py
Adds feedback kind aliases, secret/token regexes, truncation and size limits, and exported FeedbackOptions and FeedbackSubmission dataclasses.
Core feedback logic: parsing, redaction, payload building, and submission
src/pythinker_code/feedback.py
Parses /feedback args, implements redact_text/redact_value, builds a structured payload with git/context snapshots and recursive redaction, and submits via aiohttp with tolerant JSON parsing returning a FeedbackSubmission.
Context collection: git snapshot, messages, tools, and subagents
src/pythinker_code/feedback.py
Collects git branch/head/dirty/diff, recent visible messages (excluding ThinkPart), tool-call summaries and hints, and subagent meta.json records; supports truncation, permissive JSON parsing, and redaction.
Async /feedback slash command with prompts and submission
src/pythinker_code/ui/shell/slash.py
Replaces the synchronous command with an async flow that parses args, prompts for message/confirmation (unless --yes), builds payload, submits async, falls back to creating/opening a GitHub issue on error, emits telemetry, and prints contextual success/fallback messages.
Update notification helpers and persisted marker
src/pythinker_code/ui/shell/update.py
Adds LAST_SEEN_VERSION_FILE, concurrency-safe read/write, cached update candidate computation, welcome_update_target() for banner display, and consume_whats_new() for one-time post-upgrade notifications; refactors pending_update_notice().
Welcome banner UI: imports and integration with update/what's-new chip
src/pythinker_code/ui/shell/__init__.py
Imports update helpers, adds _welcome_banner_chip() with precedence (update > what's-new), updates Shell.run to pass banner, and adjusts _print_welcome_info() layout to render the chip.
Tests and changelog updates
tests/ui_and_conv/*, CHANGELOG.md
Adds/extends tests for /feedback fallback and submission paths, redaction and helpers, welcome/update helpers and banner rendering, and documents the new /feedback behavior in CHANGELOG.

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

enhancement

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.12% which is insufficient. The required threshold is 70.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title follows conventional commits format with type 'feat' and scope 'feedback', clearly describing the main feature addition of structured feedback reporting.
Description check ✅ Passed The description includes a summary of changes, verification steps, and addresses the template requirements with substantive detail about the feature implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/structured-feedback

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pythinker_code/feedback.py`:
- Around line 148-154: The try/except around Path.home() is too broad and
silently swallows errors; replace the bare except with a narrow catch for the
specific exceptions that Path.home() can raise (e.g., RuntimeError and OSError)
and log the failure instead of passing silently — update the block that calls
Path.home() (and modifies the redacted variable) to except (RuntimeError,
OSError) as e: and call the module/logger (e.g., logger.warning or
processLogger) with a short message including the exception before continuing to
return redacted.

In `@src/pythinker_code/ui/shell/update.py`:
- Around line 387-391: The _read_last_seen_version function currently catches
all OSError and returns None, which hides real failures; change the exception
handling so that FileNotFoundError (or PermissionError due to a missing file)
returns None but other OSError cases are not silently swallowed—either re-raise
them or log and re-raise. Specifically, update the try/except around
LAST_SEEN_VERSION_FILE.read_text(...) so it catches FileNotFoundError and
returns None, and lets other OSError exceptions propagate (or log via the module
logger before raising) to preserve actionable errors.

In `@tests/ui_and_conv/test_shell_feedback_slash.py`:
- Around line 94-150: The test uses SimpleNamespace(...) as the mocked return
for submit_mock in test_submits_structured_payload; replace that with an actual
FeedbackSubmission instance to make the test robust to type changes: import
FeedbackSubmission from pythinker_code.feedback (or the module where it’s
defined), create FeedbackSubmission(number=42, html_url="https://issue/42") for
the AsyncMock return (the submit_mock used via
monkeypatch.setattr("pythinker_code.feedback.submit_feedback_payload",
submit_mock)), and keep the rest of the assertions the same so
submit_mock.assert_awaited_once() and payload inspection continue to work.

In `@tests/ui_and_conv/test_shell_update.py`:
- Around line 1010-1020: The test only checks the baseline file is non-empty;
instead assert it contains the actual recorded version so a wrong value can't
slip through: after calling update.consume_whats_new() in
test_consume_whats_new_baseline_on_first_launch, read
last_seen_file.read_text(...).strip() and assert it equals the expected version
exported by the module (e.g. update.__version__ or the module's canonical
version symbol), referencing update.consume_whats_new and
update.LAST_SEEN_VERSION_FILE to locate the logic to validate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 05bb6b68-e18a-474f-ac54-f34d9ee3ea32

📥 Commits

Reviewing files that changed from the base of the PR and between 87bad36 and 22aaaf1.

📒 Files selected for processing (9)
  • .github/dependabot.yml
  • examples/feedback-worker/src/index.ts
  • src/pythinker_code/feedback.py
  • src/pythinker_code/ui/shell/__init__.py
  • src/pythinker_code/ui/shell/slash.py
  • src/pythinker_code/ui/shell/update.py
  • tests/ui_and_conv/test_shell_feedback_slash.py
  • tests/ui_and_conv/test_shell_update.py
  • tests/ui_and_conv/test_shell_welcome_info.py

Comment thread src/pythinker_code/feedback.py
Comment thread src/pythinker_code/ui/shell/update.py
Comment thread tests/ui_and_conv/test_shell_feedback_slash.py
Comment thread tests/ui_and_conv/test_shell_update.py
- redact_text: narrow blind `except Exception` to (RuntimeError, OSError)
  and log at debug instead of silently swallowing home-resolution failures
- _read_last_seen_version: return None for missing file but log real OSError
  (e.g. permission) instead of masking it
- test_shell_feedback_slash: use real FeedbackSubmission dataclass instead of
  duck-typed SimpleNamespace for both submit mocks
- test_consume_whats_new_baseline: assert the baseline equals the current
  VERSION rather than merely non-empty
@elkaix
Copy link
Copy Markdown
Contributor Author

elkaix commented May 31, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@elkaix elkaix merged commit a3f9600 into main May 31, 2026
27 checks passed
@elkaix elkaix deleted the feature/structured-feedback branch May 31, 2026 05:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant