Skip to content

fix: improve feedback problem report upload flow#179

Merged
Astro-Han merged 4 commits into
devfrom
codex/fix-i84-feedback-flow
Apr 23, 2026
Merged

fix: improve feedback problem report upload flow#179
Astro-Han merged 4 commits into
devfrom
codex/fix-i84-feedback-flow

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Apr 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Copy a short problem report summary to the clipboard instead of the full report.
  • Save the full markdown problem report under Electron userData/problem-reports for manual upload in the feedback form.
  • Add failure fallbacks for session export, file save, reveal, cleanup, and form open paths.
  • Bound summary fields so long logs, route query prompts, session IDs, and local paths do not make the Feishu form hard to use.

Why

The Feishu feedback form rejects or becomes impractical with the full problem report pasted into a text field. This follow-up keeps the form payload short and moves detailed diagnostics into an uploadable markdown file.

Related Issue

Refs #84. This only covers the feedback report upload flow and does not close all remaining #84 scope.

How To Verify

cd packages/desktop-electron
bun test src/main/problem-report.test.ts src/main/problem-report-files.test.ts src/main/feedback.test.ts src/main/menu.test.ts src/main/menu-labels.test.ts
bun run typecheck
cd ../..
git diff --check origin/dev..HEAD

Screenshots or Recordings

N/A. Native confirmation dialog copy changed; localized copy and flow behavior are covered by unit tests.

Checklist

  • I linked the related issue, or stated why there is no issue
  • This PR has type, scope, and priority labels, or I requested maintainer labeling
  • I listed the relevant verification steps, including tests when behavior changed
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for desktop, packaging, updater, signing, paths, shell, or permissions changes
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, or generated/local file changes when relevant
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Summary by CodeRabbit

  • New Features

    • Saves a full problem report to disk while copying a concise localized summary to the clipboard; offers to reveal/open the saved report or open the external feedback form.
  • Improvements

    • Feedback dialog text updated; session export supports timeouts/abort and more robust diagnostics, sanitization, and size-limited summaries.
    • Report filenames, location hints, and retention behavior refined.
  • Bug Fixes

    • Improved recovery when export/save/reveal/cleanup fail; concurrent feedback actions are prevented.
  • Tests

    • Expanded end-to-end and unit coverage for summaries, persistence, cleanup, and failure scenarios.

@Astro-Han Astro-Han added bug Something isn't working P2 Medium priority platform Electron shell, OS integration, packaging, updater, signing, paths, and permissions labels Apr 23, 2026
@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@Astro-Han has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 22 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 2 minutes and 22 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c2188b87-0063-4c59-845e-e9ff5b0dd940

📥 Commits

Reviewing files that changed from the base of the PR and between 6f09aff and 0044776.

📒 Files selected for processing (5)
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📝 Walkthrough

Walkthrough

Feedback now copies a short summary to the clipboard and writes a full problem-report markdown to disk (deterministic filename), attempts to reveal/open the saved file, cleans old reports, uses an AbortSignal-aware session export with timeout, and surfaces secondary failures via an optional handled-error hook while preventing concurrent runs.

Changes

Cohort / File(s) Summary
Problem Report Core
packages/desktop-electron/src/main/problem-report.ts, packages/desktop-electron/src/main/problem-report.test.ts
Adds required reportId and validated generatedAt; buildProblemReport returns { markdown, reportId, generatedAt }; exports DEFAULT_PROBLEM_REPORT_MAX_BYTES, defaultReportId(), and new buildProblemReportSummary() for redacted/truncated summaries; tests updated for sanitization, size limits, and payload validation.
Problem Report File Management
packages/desktop-electron/src/main/problem-report-files.ts, packages/desktop-electron/src/main/problem-report-files.test.ts
New deterministic filename scheme and helpers (problemReportsRoot, reportLocationHint); writeProblemReportFile() writes via exclusive temp + hardlink, errors with "Problem report already exists" on collision, and ensures temp cleanup (with optional removeTemp); cleanupProblemReports() enforces retention and preserves current file; tests cover atomic writes, collision, location hints, and selective cleanup.
Feedback Handler & Tests
packages/desktop-electron/src/main/feedback.ts, packages/desktop-electron/src/main/feedback.test.ts
Handler now copies a short summary and persists full report via saveReport; adds inFlight concurrency guard, session export timeout/AbortSignal support, fallback diagnostics, normalized failure reasons, reveal via showItemInFolder with openPath fallback, cleanupReports calls, and optional onHandledError for secondary failures; tests expanded for concurrency, export timeout/failure, save/write failure, reveal/fallback errors, cleanup failure, and updated localized dialog strings.
Main Integration
packages/desktop-electron/src/main/index.ts
Wires problemReportRoot under userData, exposes saveReport/cleanupReports/showItemInFolder/openPath, adds FEEDBACK_SESSION_EXPORT_TIMEOUT_MSsessionExportTimeoutMs, forwards AbortSignal into sessionExport, and supplies onHandledError logging hook.
New Tests (files)
packages/desktop-electron/src/main/problem-report-files.test.ts, packages/desktop-electron/src/main/feedback.test.ts
Adds end-to-end tests for filename determinism, write-once semantics, cleanup behavior, and comprehensive feedback handler scenarios (concurrency, timeout, save/reveal/cleanup error handling, and localization assertions).

Sequence Diagram

sequenceDiagram
    actor User
    participant Dialog as Feedback Dialog
    participant Handler as Feedback Handler
    participant ReportGen as Problem Report Builder
    participant Session as Session Export
    participant FileOps as File Persistence
    participant Logger as onHandledError/onError

    User->>Dialog: confirm
    Dialog->>Handler: onConfirm()
    Handler->>Handler: acquire inFlight guard
    Handler->>ReportGen: buildProblemReportSummary()
    ReportGen-->>Handler: short summary
    Handler->>Session: sessionExport(context, signal)
    note right of Session: timeout wrapper with AbortController
    Session-->>Handler: session data or failure
    Handler->>ReportGen: buildProblemReport(reportId, generatedAt)
    ReportGen-->>Handler: {markdown, reportId, generatedAt}
    Handler->>FileOps: saveReport(markdown) -> writeProblemReportFile
    FileOps-->>Handler: savedPath, fileName
    Handler->>FileOps: showItemInFolder(savedPath)
    alt reveal succeeds
        FileOps-->>Handler: revealed
    else reveal fails
        FileOps-->>Handler: error
        Handler->>FileOps: openPath(dirname)  %% fallback
        FileOps-->>Handler: opened or error
        Handler->>Logger: onHandledError(error)
    end
    Handler->>Dialog: copy summary to clipboard
    Dialog->>User: open external form
    Handler->>FileOps: cleanupReports(root, keep, currentPath)
    FileOps-->>Handler: cleanup result
    Handler->>Handler: release inFlight guard
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 A nibble of summary hops to clipboard bright,
The full report burrows safe on disk tonight,
Guards keep one hopper, timeouts tidy the trail,
If reveal trips, a fallback tells the tale,
Hop — saved, revealed (or noted), then off I sail!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.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 accurately summarizes the main change: improving the feedback problem report upload flow by shifting from copying the full report to clipboard to saving it as a file.
Description check ✅ Passed The description covers all required template sections: summary explains the changes, why section provides context and problem statement, related issue is linked, verification steps are detailed with specific test commands, and all checklist items are checked.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-i84-feedback-flow

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/desktop-electron/src/main/feedback.ts`:
- Around line 73-125: reportId() duplicates defaultReportId()—remove the local
reportId function and instead import and reuse defaultReportId from
problem-report.ts; export defaultReportId (or rename/export an equivalent) from
the ProblemReport module and replace any local calls to reportId() in
feedback.ts with the imported defaultReportId to ensure a single source of truth
for report ID generation.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4f751938-0ebe-4400-b839-148a09f5c2fa

📥 Commits

Reviewing files that changed from the base of the PR and between 4274751 and dd9553f.

📒 Files selected for processing (7)
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/problem-report.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: smoke-macos-arm64
  • GitHub Check: unit-windows-app
  • GitHub Check: unit-windows-opencode-session
  • GitHub Check: unit-windows-desktop
  • GitHub Check: unit-windows-opencode-server-tools
  • GitHub Check: unit-windows-opencode-config-project
  • GitHub Check: unit-opencode
  • GitHub Check: unit-desktop
  • GitHub Check: unit-app
  • GitHub Check: typecheck
  • GitHub Check: analyze-js-ts
  • GitHub Check: e2e-artifacts
🧰 Additional context used
📓 Path-based instructions (1)
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)

Renderer process should only call window.api from src/preload

Files:

  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
🧠 Learnings (15)
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
Learning: Applies to packages/desktop-electron/src/main/ipc.ts : Main process should register IPC handlers in `src/main/ipc.ts`

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-22T05:24:42.404Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:24:42.404Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.

Applied to files:

  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-22T08:49:44.563Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:44.563Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test files should be named with the pattern `feature-name.spec.ts`

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `expect.poll(...)` for probing mock or backend state rather than transient DOM visibility

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts
🔇 Additional comments (27)
packages/desktop-electron/src/main/index.ts (2)

35-35: LGTM!

The timeout constant, imports, and report root computation are correctly wired. The 3-second timeout is reasonable for the session export operation, and computing problemReportRoot once at initialization is appropriate since userData path is stable.

Also applies to: 61-61, 105-105


186-224: LGTM!

The feedback handler wiring correctly passes all new dependencies:

  • File operations (saveReport, cleanupReports) are properly bound with the report root
  • Reveal/open fallbacks use shell.showItemInFolder and shell.openPath
  • The 10-report retention limit is reasonable
  • onHandledError appropriately routes secondary failures to the logger
packages/desktop-electron/src/main/problem-report-files.test.ts (4)

13-24: LGTM!

The temporary directory management pattern is well-implemented with proper cleanup in afterEach. Using rm with recursive: true, force: true ensures reliable cleanup even if tests fail.


27-40: LGTM!

The test correctly validates that filenames are generated using local time components and include the reportId for collision resistance.


42-60: LGTM!

The test correctly validates the non-destructive write semantics: duplicate writes are rejected and original content is preserved.


62-101: LGTM!

Excellent test coverage for location hints and cleanup behavior. The cleanup test comprehensively validates that:

  • Current report is preserved
  • Non-matching files are skipped
  • Non-regular entries (directories, symlinks) are skipped
  • Only matching regular files beyond the retention limit are deleted
packages/desktop-electron/src/main/problem-report.test.ts (5)

34-45: LGTM!

The test correctly validates that caller-provided reportId and generatedAt values are propagated both in the function return and in the parsed payload.


47-80: LGTM!

The tests correctly validate:

  • Updated markdown instruction text for the file upload workflow
  • Required reportId in payloads
  • Summary content inclusion/exclusion rules (no sensitive paths, logs, or session data)
  • Compact summary size constraint (≤28 lines)

82-132: LGTM!

Comprehensive coverage for failure modes and error handling:

  • Failed report status messaging with fallback instructions
  • Error line limit (10) and single-line extraction
  • Truncation of oversized error lines to maintain compact summary (<1000 chars)

134-226: LGTM!

Thorough sanitization test coverage:

  • Route query parameters and hash fragments are stripped (prevents prompt leakage)
  • Session IDs are truncated and path-cleaned
  • Platform-specific filesystem paths are redacted (Windows, Linux, macOS, network paths)
  • All tests verify the summary remains compact

336-430: LGTM!

JSON fixtures correctly updated to include the now-required reportId field, and the parser validation test correctly verifies that incomplete payloads (missing generatedAt) are still rejected.

packages/desktop-electron/src/main/feedback.test.ts (4)

20-71: LGTM!

The test setup correctly mocks all new dependencies:

  • File operations (saveReport, showItemInFolder, openPath, cleanupReports)
  • Call trackers for verification (shown, openedPath, savedMarkdown, handledErrors)
  • Fast timeout (10ms) for test efficiency
  • Separate tracking for handled vs fatal errors

73-94: LGTM!

Dialog label tests correctly validate the updated user-facing copy that explains the new two-artifact workflow (clipboard summary + full report file for upload).


96-136: LGTM!

The tests correctly validate:

  • Separation of clipboard summary vs saved full report
  • File reveal behavior
  • Concurrency guard preventing duplicate operations
  • Guard release on cancel

164-263: LGTM!

Excellent failure scenario coverage:

  • Session export failures/timeouts still produce report artifacts
  • File write failures provide graceful degradation (summary-only)
  • Diagnostics failures fall back to minimum summary
  • Non-critical failures (reveal, cleanup) use onHandledError and don't block the form
  • Critical failures (form open, copy) properly report errors
packages/desktop-electron/src/main/problem-report.ts (5)

1-63: LGTM!

Well-defined constants for summary field limits and properly extended types. The Options type correctly makes reportId and generatedAt optional (with defaults generated internally), while the Payload type requires them for validation.


69-88: LGTM!

The defaultReportId() generates collision-resistant IDs with a compact format (base36 timestamp + random suffix), and the markdown instruction text correctly reflects the file upload workflow.


160-242: LGTM!

buildProblemReport correctly:

  • Uses default values for reportId and generatedAt when not provided
  • Includes them in the payload
  • Returns all three values for downstream consumers (feedback handler needs them for file naming and summary)

255-323: LGTM!

The summary sanitization functions provide comprehensive protection:

  • redactLocalPathFragments() handles Windows (drive letters, UNC), macOS (/Users), Linux (/home, /tmp), and common temp directories
  • safeSummaryRoute() strips query parameters and hash fragments (prevents prompt leakage)
  • Error lines are single-lined, truncated, and capped at 10
  • The summary format is well-structured and consistently safe

375-388: LGTM!

Payload validation correctly requires reportId to be a non-empty string, ensuring parsed payloads conform to the updated schema.

packages/desktop-electron/src/main/feedback.ts (3)

1-41: LGTM!

The imports and type definitions correctly support the new workflow:

  • dirname for parent folder fallback on reveal failure
  • SavedReport and SaveReportInput types match the file utilities contract
  • FeedbackDeps extended with all required dependencies for the two-artifact flow

43-71: LGTM!

The dialog labels clearly explain the new workflow to users:

  • Summary copied to clipboard
  • Full report saved locally for upload
  • Post-submission cleanup instructions

127-219: LGTM!

The feedback handler implementation is robust:

  • Concurrency guard via inFlight prevents duplicate operations
  • Context is captured before confirmation to handle focus changes
  • Comprehensive error handling with graceful degradation at each step
  • Secondary failures (reveal, cleanup) use onHandledError without blocking the form
  • Users always receive at least a summary even when the full report fails
packages/desktop-electron/src/main/problem-report-files.ts (4)

1-21: LGTM!

The filename generation correctly:

  • Validates generatedAt as a valid ISO timestamp
  • Uses local time components for human-readable sorting
  • Produces a deterministic, collision-resistant filename with the reportId

23-30: LGTM!

The utility functions correctly:

  • problemReportsRoot() computes the reports directory path
  • reportLocationHint() provides a privacy-respecting hint with platform-appropriate prefix

32-60: LGTM!

The atomic write implementation is robust:

  • Exclusive create (wx) for temp file prevents overwrites
  • Hardlink provides atomic final file creation
  • EEXIST on link correctly indicates collision (not retry-safe)
  • Temp file cleanup in both success and error paths
  • Restrictive permissions (0o600) for user-only access

62-90: LGTM!

The cleanup logic correctly:

  • Excludes the current report from consideration
  • Only processes matching regular files (skips directories, symlinks)
  • Sorts by mtime (newest first) to preserve recent reports
  • Keeps keep - 1 files from the list (plus the excluded current = keep total)
  • Gracefully handles missing directories and stat/delete errors

Comment thread packages/desktop-electron/src/main/feedback.ts Outdated

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

Copy link
Copy Markdown

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 refactors the problem reporting system to save full reports as local files while copying a redacted summary to the clipboard. It introduces a more robust error handling mechanism, localized labels, and automated cleanup of old reports. Feedback focuses on improving the reliability of asynchronous operations and filesystem interactions. Specifically, it is noted that shell.openPath returns an error string rather than throwing, requiring a manual check to trigger fallback logic. Additionally, using fs.promises.rename instead of link is recommended for atomic file operations across different partitions, and passing abort signals to timed-out session exports would prevent background resource usage.

Comment thread packages/desktop-electron/src/main/feedback.ts
Comment thread packages/desktop-electron/src/main/feedback.ts
Comment thread packages/desktop-electron/src/main/index.ts Outdated
Comment thread packages/desktop-electron/src/main/problem-report-files.ts
@Astro-Han Astro-Han force-pushed the codex/fix-i84-feedback-flow branch from dd9553f to dc9bdc0 Compare April 23, 2026 03:18
@Astro-Han

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor
✅ 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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/desktop-electron/src/main/feedback.ts`:
- Around line 158-162: The catch block for sessionExport loses the original
error by replacing it with safeFailureReason(error); instead, preserve the real
error in sessionExport so the saved report includes the actual fetch/status
error: when sessionExportWithTimeout throws, set sessionExport = { status:
"failed", error: error } (letting the downstream problem-report truncation
handle oversized values) rather than calling safeFailureReason; update the catch
around sessionExportWithTimeout to assign the original thrown error to the
sessionExport.error field.

In `@packages/desktop-electron/src/main/problem-report.ts`:
- Around line 160-165: In buildProblemReport, validate any caller-provided
overrides before using them: ensure options.reportId (used with
defaultReportId()) is a non-empty string (trim and reject empty) and ensure
options.generatedAt is a valid ISO timestamp (parseable to a Date and finite)
before assigning generatedAt; if either is invalid, either fall back to
defaultReportId()/new Date().toISOString() or throw a clear error so downstream
functions like parseProblemReportPayload() and problemReportFileName() never
receive invalid values. Locate and update buildProblemReport to perform these
checks on options.reportId and options.generatedAt immediately before they are
assigned to reportId and generatedAt.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 95d36af9-752b-497c-a24b-119be6b66e73

📥 Commits

Reviewing files that changed from the base of the PR and between dd9553f and dc9bdc0.

📒 Files selected for processing (7)
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/problem-report.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)

Renderer process should only call window.api from src/preload

Files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/feedback.test.ts
🧠 Learnings (21)
📓 Common learnings
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:24:42.404Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
Learning: In Astro-Han/pawwork (`packages/ui/src/theme/context.tsx` and related files), the renaming of localStorage theme keys from `opencode-*` to `pawwork-*` (THEME_ID, COLOR_SCHEME, THEME_CSS_LIGHT, THEME_CSS_DARK) is intentional and should NOT include a migration path from the old keys. Migrating would re-couple PawWork and OpenCode browser storage namespaces, which the PR is explicitly designed to avoid. A reset to the PawWork default theme on upgrade is acceptable by design.
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-22T08:49:44.563Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:44.563Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Call `project.trackSession(sessionID, directory?)` and `project.trackDirectory(directory)` for any resources created outside the fixture so teardown can clean them up

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test files should be named with the pattern `feature-name.spec.ts`

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
Learning: Applies to packages/desktop-electron/src/main/ipc.ts : Main process should register IPC handlers in `src/main/ipc.ts`

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `FileSystem.FileSystem` instead of raw `fs/promises` for effectful file I/O in Effect services

Applied to files:

  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : In terminal tests, type through the browser using `runTerminal()` and `waitTerminalReady()` instead of writing to the PTY through the SDK

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`

Applied to files:

  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
📚 Learning: 2026-04-22T05:24:42.404Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:24:42.404Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.

Applied to files:

  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Never use wall-clock waits like `page.waitForTimeout(...)` to make a test pass

Applied to files:

  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-20T14:21:51.047Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 71
File: packages/app/src/components/session/session-status-connections.tsx:146-147
Timestamp: 2026-04-20T14:21:51.047Z
Learning: In the Astro-Han/pawwork repository (SolidJS app), `sync.data.config` is always initialized to `{}` at `packages/app/src/context/global-sync.tsx` line 71 and is never `undefined` at runtime. Non-optional property access like `sync.data.config.plugin` is intentional and consistent with the pattern used in `packages/app/src/components/status-popover-body.tsx` line 243. Do not flag `sync.data.config.plugin` as needing optional chaining.

Applied to files:

  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `expect.poll(...)` for probing mock or backend state rather than transient DOM visibility

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts

Comment thread packages/desktop-electron/src/main/feedback.ts
Comment thread packages/desktop-electron/src/main/problem-report-files.ts
Comment thread packages/desktop-electron/src/main/problem-report.ts
@Astro-Han Astro-Han force-pushed the codex/fix-i84-feedback-flow branch from dc9bdc0 to 48c3b12 Compare April 23, 2026 03:44

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/desktop-electron/src/main/feedback.ts`:
- Line 208: The call to deps.openExternal(deps.feedbackUrl) can throw and
currently lets the flow hit the generic onError path; wrap this call in a
try/catch inside the feedback flow (where deps.openExternal is invoked) so
failures are handled locally: on error, log the exception, do NOT rethrow, and
surface a manual fallback that presents deps.feedbackUrl to the user (e.g., show
a dialog or notification with the URL and an action to copy it) so the prepared
summary/markdown is not treated as a full failure; reference deps.openExternal
and deps.feedbackUrl when locating the change and ensure no existing onError
path is triggered by this catch.

In `@packages/desktop-electron/src/main/problem-report-files.ts`:
- Around line 6-20: The filename builder problemReportFileName currently
interpolates reportId directly which can allow path separators or unsafe chars;
update problemReportFileName to validate reportId against a whitelist (e.g.
/^[A-Za-z0-9_]+$/) before using it, and throw a clear error (or return a
failure) if the value does not match; reference the function
problemReportFileName and the existing cleanup code/REPORT_FILE_PATTERN in the
repo so you ensure the same allowed character class is used and invalid reportId
values are rejected rather than written into the filename.

In `@packages/desktop-electron/src/main/problem-report.ts`:
- Around line 163-166: The generatedAt check currently uses Date.parse which
accepts date-only strings; tighten validation by requiring a canonical ISO 8601
timestamp (full datetime + timezone) — e.g., validate that
Date.parse(generatedAt) is valid and that new Date(generatedAt).toISOString()
=== generatedAt (or otherwise match a strict ISO-datetime regex) before
accepting it; update the validation in the block that sets reportId/generatedAt
(referencing generatedAt and reportId) so problemReportFileName receives a
canonical timestamp.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d6a69724-541c-402f-90d9-4cb9a5659535

📥 Commits

Reviewing files that changed from the base of the PR and between dc9bdc0 and 48c3b12.

📒 Files selected for processing (7)
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/problem-report.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: smoke-macos-arm64
  • GitHub Check: unit-windows-app
  • GitHub Check: unit-windows-opencode-config-project
  • GitHub Check: unit-windows-opencode-server-tools
  • GitHub Check: unit-opencode
  • GitHub Check: unit-windows-opencode-session
  • GitHub Check: unit-desktop
  • GitHub Check: unit-windows-desktop
  • GitHub Check: unit-app
  • GitHub Check: typecheck
  • GitHub Check: e2e-artifacts
  • GitHub Check: analyze-js-ts
🧰 Additional context used
📓 Path-based instructions (1)
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)

Renderer process should only call window.api from src/preload

Files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:24:42.404Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-22T08:49:44.563Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:44.563Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test files should be named with the pattern `feature-name.spec.ts`

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `FileSystem.FileSystem` instead of raw `fs/promises` for effectful file I/O in Effect services

Applied to files:

  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : In terminal tests, type through the browser using `runTerminal()` and `waitTerminalReady()` instead of writing to the PTY through the SDK

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
Learning: Applies to packages/desktop-electron/src/main/ipc.ts : Main process should register IPC handlers in `src/main/ipc.ts`

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-22T05:24:42.404Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:24:42.404Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.

Applied to files:

  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Never use wall-clock waits like `page.waitForTimeout(...)` to make a test pass

Applied to files:

  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-20T14:21:51.047Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 71
File: packages/app/src/components/session/session-status-connections.tsx:146-147
Timestamp: 2026-04-20T14:21:51.047Z
Learning: In the Astro-Han/pawwork repository (SolidJS app), `sync.data.config` is always initialized to `{}` at `packages/app/src/context/global-sync.tsx` line 71 and is never `undefined` at runtime. Non-optional property access like `sync.data.config.plugin` is intentional and consistent with the pattern used in `packages/app/src/components/status-popover-body.tsx` line 243. Do not flag `sync.data.config.plugin` as needing optional chaining.

Applied to files:

  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `expect.poll(...)` for probing mock or backend state rather than transient DOM visibility

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts
🔇 Additional comments (1)
packages/desktop-electron/src/main/index.ts (1)

137-163: Abort propagation is wired cleanly.

Bridging the optional external AbortSignal into a local controller and unregistering the listener in finally avoids the timeout leak/race that usually shows up in this pattern.

Comment thread packages/desktop-electron/src/main/feedback.ts Outdated
Comment thread packages/desktop-electron/src/main/problem-report-files.ts
Comment thread packages/desktop-electron/src/main/problem-report.ts Outdated
@Astro-Han Astro-Han force-pushed the codex/fix-i84-feedback-flow branch 2 times, most recently from 6a8732f to 6f09aff Compare April 23, 2026 04:02

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/desktop-electron/src/main/problem-report-files.ts`:
- Around line 1-10: The isCanonicalIsoTimestamp implementation in
problem-report-files.ts is duplicated from problem-report.ts; extract that logic
into a shared utility function (e.g., export function
isCanonicalIsoTimestamp(value: string)) in a common module and update both
problem-report-files.ts and problem-report.ts to import and use that exported
function instead of keeping local copies; remove the local
isCanonicalIsoTimestamp definition from problem-report-files.ts, update imports
to reference the new shared symbol, and run types/checks to ensure no
unused/duplicate definitions remain.
- Line 92: The retention slice is off-by-one: in the loop that starts with "for
(const entry of entries.slice(Math.max(0, input.keep - 1)))" change the start
index to Math.max(0, input.keep) so that when input.keep is 10 you keep 10
entries rather than 9; update the slice call referencing entries and input.keep
(the same statement that begins the for loop) to use input.keep instead of
input.keep - 1.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b3d9fc72-a90c-425e-acc8-a3ca6c86c320

📥 Commits

Reviewing files that changed from the base of the PR and between 48c3b12 and 6f09aff.

📒 Files selected for processing (7)
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/problem-report.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: unit-windows-opencode-config-project
  • GitHub Check: unit-windows-opencode-server-tools
  • GitHub Check: unit-windows-app
  • GitHub Check: unit-windows-desktop
  • GitHub Check: unit-windows-opencode-session
  • GitHub Check: typecheck
  • GitHub Check: unit-desktop
  • GitHub Check: smoke-macos-arm64
  • GitHub Check: e2e-artifacts
  • GitHub Check: analyze-js-ts
🧰 Additional context used
📓 Path-based instructions (1)
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)

Renderer process should only call window.api from src/preload

Files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/feedback.test.ts
🧠 Learnings (25)
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-22T08:49:44.563Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:44.563Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report.test.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test files should be named with the pattern `feature-name.spec.ts`

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.test.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `FileSystem.FileSystem` instead of raw `fs/promises` for effectful file I/O in Effect services

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-22T09:32:52.535Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
Learning: In Astro-Han/pawwork (`packages/ui/src/theme/context.tsx` and related files), the renaming of localStorage theme keys from `opencode-*` to `pawwork-*` (THEME_ID, COLOR_SCHEME, THEME_CSS_LIGHT, THEME_CSS_DARK) is intentional and should NOT include a migration path from the old keys. Migrating would re-couple PawWork and OpenCode browser storage namespaces, which the PR is explicitly designed to avoid. A reset to the PawWork default theme on upgrade is acceptable by design.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-22T05:24:42.404Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:24:42.404Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-21T13:45:41.773Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 99
File: packages/desktop-electron/src/renderer/i18n/index.ts:30-35
Timestamp: 2026-04-21T13:45:41.773Z
Learning: In Astro-Han/pawwork, the locale normalization helpers in `packages/app/src/context/language.tsx` (`normalizeLocale`) and `packages/desktop-electron/src/renderer/i18n/index.ts` (`parseLocale`) are intentionally kept separate and have different fallback shapes: `normalizeLocale` always returns a concrete `Locale` (falling back to `"en"`), while `parseLocale` returns `Locale | null` so the desktop shell can decide whether to fall back to browser detection. Do not suggest extracting a shared normalization helper across these two runtimes.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-20T14:21:51.047Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 71
File: packages/app/src/components/session/session-status-connections.tsx:146-147
Timestamp: 2026-04-20T14:21:51.047Z
Learning: In the Astro-Han/pawwork repository (SolidJS app), `sync.data.config` is always initialized to `{}` at `packages/app/src/context/global-sync.tsx` line 71 and is never `undefined` at runtime. Non-optional property access like `sync.data.config.plugin` is intentional and consistent with the pattern used in `packages/app/src/components/status-popover-body.tsx` line 243. Do not flag `sync.data.config.plugin` as needing optional chaining.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-20T17:03:37.710Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 73
File: packages/opencode/src/cli/cmd/tui/context/sync.tsx:486-489
Timestamp: 2026-04-20T17:03:37.710Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/cli/cmd/tui/context/sync.tsx`), `sync.ready` returning `true` when `process.env.OPENCODE_FAST_BOOT` is set is intentional. The plugin-facing data properties `state.config` (initialized to `{}`) and `state.provider` (initialized to `[]`) expose safe-empty defaults, so they are safe to access before bootstrap completes. Do not flag these as needing null-guards or conditional patterns to match `vcs` — the difference is intentional because `vcs` starts as `undefined` while the others have initialized defaults. Changing this would alter the plugin API contract without a concrete failing case.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.ts
📚 Learning: 2026-04-21T16:00:43.416Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/model-id.ts:9-11
Timestamp: 2026-04-21T16:00:43.416Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/config/model-id.ts`), `ConfigModelID` uses a regex that requires a non-empty provider segment and a non-empty model segment separated by `/`, but intentionally allows additional slashes within the model segment. This is because `Provider.parseModel` supports model IDs like `synthetic/hf:zai-org/GLM-4.7`. Do not flag the permissive slash handling as a bug.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.ts
📚 Learning: 2026-04-21T16:57:22.813Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/agent.ts:108-119
Timestamp: 2026-04-21T16:57:22.813Z
Learning: In `packages/opencode/src/config/agent.ts` (Astro-Han/pawwork), `ConfigPermission.Info` only accepts permission objects or the three action strings `"ask"`, `"allow"`, `"deny"`, and transforms those action strings into `{ "*": action }` before `normalize()` runs. By the time `normalize()` is reached, `configuredPermission` is always either `undefined` or a `Record<string, Rule>` — never a raw arbitrary string. The `Object.assign(permission, configuredPermission)` pattern is therefore safe. Do not flag it as corrupting string permission references.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
  • packages/desktop-electron/src/main/problem-report.ts
  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-21T16:57:20.257Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/command.ts:23-29
Timestamp: 2026-04-21T16:57:20.257Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/config/`), `Schema.Struct` and `Schema.Class` are both valid and intentionally used patterns across config modules (e.g. `formatter.ts`, `provider.ts`, `permission.ts`, `lsp.ts`, `config.ts`, `keybinds.ts`, `command.ts`). Do not flag `Schema.Struct` usage in config schemas as needing conversion to `Schema.Class` — the choice is driven by upstream alignment and local context, not inconsistency.

Applied to files:

  • packages/desktop-electron/src/main/problem-report-files.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : In terminal tests, type through the browser using `runTerminal()` and `waitTerminalReady()` instead of writing to the PTY through the SDK

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
Learning: Applies to packages/desktop-electron/src/main/ipc.ts : Main process should register IPC handlers in `src/main/ipc.ts`

Applied to files:

  • packages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Never use wall-clock waits like `page.waitForTimeout(...)` to make a test pass

Applied to files:

  • packages/desktop-electron/src/main/feedback.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Prefer fluent helpers and drivers when they make intent obvious and reduce locator-heavy noise in tests

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `expect.poll(...)` for probing mock or backend state rather than transient DOM visibility

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.

Applied to files:

  • packages/desktop-electron/src/main/feedback.test.ts
🔇 Additional comments (28)
packages/desktop-electron/src/main/index.ts (3)

35-35: LGTM!

The 3-second timeout constant for session export is reasonable and appropriately named with the _MS suffix for clarity.


137-163: Signal handling and cleanup are correct.

The sessionExport function properly:

  1. Checks for immediate abort before adding the listener
  2. Wires the external signal to the internal controller
  3. Cleans up the listener in finally to prevent memory leaks
  4. Clears the timeout in all cases

190-237: LGTM!

The createFeedbackHandler integration is well-structured:

  • All FeedbackDeps properties are correctly wired
  • showFeedbackUrlFallback provides graceful degradation when the form can't open
  • saveReport and cleanupReports properly delegate to the new problem-report-files utilities
  • onHandledError routes secondary failures to the logger without triggering the generic error dialog
packages/desktop-electron/src/main/problem-report.test.ts (4)

1-57: LGTM!

The tests properly verify:

  • Caller-provided reportId and generatedAt are honored and embedded in the payload
  • The updated markdown instructions reference file upload
  • The parsed payload correctly includes the reportId

59-132: Comprehensive summary builder coverage.

The tests thoroughly verify:

  • Summary includes report metadata and excludes sensitive paths/logs
  • Line count bounds (≤28 lines)
  • Failed/unavailable report messaging with fallback instructions
  • Recent errors limited to 10 single-line entries
  • Oversized error truncation with "..." and character limit enforcement

134-226: Good sanitization coverage.

Tests verify path and sensitive data redaction across:

  • Query parameters and hash fragments in routes
  • Long session IDs with embedded paths
  • Windows paths (including non-ASCII usernames and spaces)
  • Linux home/temp paths and network shares

336-348: LGTM!

The validation tests correctly verify rejection of:

  • Empty and whitespace-only reportId
  • Non-canonical timestamps (date-only, missing milliseconds)
packages/desktop-electron/src/main/feedback.test.ts (4)

77-98: LGTM!

Localization tests correctly verify the updated confirmation dialog labels for both English and Chinese, including the new "copy summary and open form" messaging and full report file instructions.


107-140: Good coverage of the core flow and concurrency guard.

The tests verify:

  • Summary is copied (not the full JSON report)
  • Full markdown is saved separately
  • File is revealed in folder
  • Form opens after artifacts are ready
  • Busy guard prevents concurrent confirmations and releases properly on cancel

181-200: LGTM!

The timeout test properly verifies:

  • AbortSignal is fired on timeout
  • Summary and saved report are still produced despite timeout
  • The "session export timed out" error is captured in the saved markdown

202-295: Comprehensive failure recovery coverage.

Tests verify graceful degradation when:

  • File write fails (summary-only, no attachment instructions, no reveal)
  • Report construction fails (minimum summary still copied)
  • Form open fails (fallback URL shown, logged via onHandledError)
  • File reveal fails (directory open fallback attempted)
  • Cleanup fails (form still opens, logged via onHandledError)
packages/desktop-electron/src/main/problem-report-files.test.ts (4)

1-24: LGTM!

The test setup properly manages temporary directories with cleanup in afterEach to prevent test pollution.


27-62: Good validation coverage.

Tests verify:

  • Deterministic filename generation with local time formatting
  • Rejection of unsafe reportId values (path separators, dots, spaces, hyphens)
  • Rejection of non-canonical timestamps

64-100: LGTM!

The write tests correctly verify:

  • First write succeeds
  • Second write to same target throws "Problem report already exists"
  • Original file content is preserved on collision
  • Temp cleanup failure after linking doesn't corrupt the saved report

117-141: No action needed. Symlink support on Windows is handled correctly.

Modern Node.js (including Bun 1.3.11) supports unprivileged symlinks on Windows 10+ without requiring elevated privileges, and the test runs successfully on the Windows CI matrix. The cleanupProblemReports function correctly filters out non-regular files (including symlinks) using stat.isFile(), so symlinks are safely skipped during cleanup rather than causing issues.

			> Likely an incorrect or invalid review comment.
packages/desktop-electron/src/main/problem-report.ts (5)

1-7: LGTM!

The constants define reasonable limits for summary fields to prevent overly long content from breaking the Feishu form.


69-76: LGTM!

The isCanonicalIsoTimestamp round-trip check is stricter than regex-based validation and correctly rejects date-only strings and non-UTC offsets. The defaultReportId generates collision-resistant IDs using timestamp and random components.


165-171: LGTM!

Validation correctly:

  • Rejects empty/whitespace-only reportId
  • Requires canonical ISO timestamp format for generatedAt

262-298: LGTM!

The sanitization helpers properly:

  • Extract only the first line and normalize whitespace
  • Redact Windows paths, UNC paths, and Unix home/tmp paths
  • Truncate with "..." suffix when exceeding limits
  • Strip query parameters and hash fragments from routes

300-330: LGTM!

The summary builder correctly assembles a compact report with:

  • Conditional messaging based on full report status
  • Redacted diagnostics (route, session ID)
  • Bounded recent errors list
packages/desktop-electron/src/main/feedback.ts (5)

45-87: LGTM!

The dialog labels are properly localized for both English and Chinese, with clear messaging about the new copy-summary + save-full-report flow. The formOpenFailedTitle and formOpenFailedMessage provide helpful fallback instructions.


89-123: LGTM!

The helper functions are well-designed:

  • safeFailureReason maps errors to safe, non-sensitive classifications
  • fallbackDiagnostics provides minimal viable info when diagnostics collection fails
  • recentKeyErrors extracts relevant log lines with proper filtering and bounds

125-141: LGTM!

The timeout wrapper correctly:

  • Creates an AbortController to propagate cancellation
  • Races the export against the timeout
  • Cleans up the timeout in finally to prevent leaks
  • Aborts the controller when timing out

143-201: LGTM!

The report preparation flow correctly:

  1. Snapshots context before confirmation (preventing focus-change issues)
  2. Handles diagnostics/logTail failures gracefully with fallbacks
  3. Preserves the original error message in failed session exports
  4. Builds summary with appropriate status based on save success/failure

202-245: LGTM!

The post-preparation flow correctly:

  • Copies summary to clipboard
  • Attempts to reveal the saved file with directory-open fallback
  • Handles Electron's openPath error strings (non-empty string = error)
  • Routes secondary failures through onHandledError instead of onError
  • Cleanup failures don't block form opening
  • Form-open failures show a fallback dialog with the URL
  • Concurrency guard prevents multiple confirmations and releases on completion
packages/desktop-electron/src/main/problem-report-files.ts (3)

12-28: LGTM!

The filename builder correctly:

  • Validates reportId against the safe character pattern to prevent path traversal
  • Requires canonical ISO timestamps
  • Uses local time for human-readable filenames
  • Produces collision-resistant names with millisecond precision

39-69: LGTM!

The atomic write implementation is robust:

  • Creates the directory if needed
  • Uses exclusive creation (wx) for the temp file to prevent races
  • Hard links to the final path for atomic visibility
  • Converts EEXIST to a clear error message
  • Best-effort temp cleanup doesn't fail the operation after successful link
  • Outer catch cleans up temp on any failure before the link

71-95: LGTM!

The cleanup logic correctly:

  • Filters to only matching report filenames (prevents deleting unrelated files)
  • Preserves the current report via currentPath check
  • Uses lstat to skip symlinks and directories
  • Sorts by mtime descending to keep newest
  • Silently ignores read/stat/delete failures for resilience

Comment thread packages/desktop-electron/src/main/problem-report-files.ts
Comment thread packages/desktop-electron/src/main/problem-report-files.ts Outdated
@Astro-Han Astro-Han force-pushed the codex/fix-i84-feedback-flow branch from 6f09aff to 0044776 Compare April 23, 2026 04:47
@Astro-Han

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor
✅ 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.

@Astro-Han

Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor
✅ 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.

@Astro-Han Astro-Han merged commit 53e5d56 into dev Apr 23, 2026
23 checks passed
@Astro-Han Astro-Han deleted the codex/fix-i84-feedback-flow branch April 23, 2026 07:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working P2 Medium priority platform Electron shell, OS integration, packaging, updater, signing, paths, and permissions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant