Fix CI platform workflow gates#5
Conversation
Promote keyword recall to the primary Explorer action while keeping mode, filter, pagination, and detail interactions visible. Add a pure optional-AI availability gate so disabled semantic and hybrid controls explain the actual release, provider, or settings blocker through the locale catalogs.
Reshape the ledger around health triage, run comparison, and artifact review without changing the underlying audit data contract. Keep health counts scoped to the active non-severity filters, expose pending/blocked states truthfully, and cover the new triage behavior in tests and locale copy.
Rework the Jobs route into an operations dashboard with queue status, local analysis, and review affordances that stay useful when the queue is idle. Limit failed-job jump behavior to visible failed work, respect reduced-motion preferences, and cover the interaction branches in the runtime tests.
Polish the domain deep-dive route with clearer loading, arrival mix, top pages, query, path-flow, and trend presentation. Precompute the trend maximum to avoid repeated scans, tighten path-flow step parsing, and add locale coverage for the new domain insights labels.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c79b24874
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| { key: 'search', value: detail.arrivalBreakdown.search }, | ||
| { key: 'link', value: detail.arrivalBreakdown.link }, | ||
| { key: 'typed', value: detail.arrivalBreakdown.typed }, | ||
| { key: 'other', value: detail.arrivalBreakdown.other }, |
There was a problem hiding this comment.
Add i18n copy for the new "other" arrival bucket
The arrival legend now includes other and renders t(domainDeepDiveArrival_${entry.key}), so any dataset with arrivalBreakdown.other > 0 will request domainDeepDiveArrival_other. The catalog currently only defines domainDeepDiveArrival_search, _link, and _typed (see src/lib/i18n/catalog/intelligence-secondary-patterns.ts), so this path falls back to a missing-key string instead of localized user copy.
Useful? React with 👍 / 👎.
| '--lib', | ||
| 'file_manager', | ||
| ]) | ||
| if (process.platform === 'win32') { |
There was a problem hiding this comment.
Restrict Windows facade-test skip to hosted CI only
This condition skips the Rust pathkeep-desktop facade tests on every Windows host, not just the broken GitHub-hosted runner scenario described in the docs/commit notes. As written, local Windows runs and self-hosted Windows CI never execute the updater/file-manager Rust tests, which can hide Windows-specific regressions. The skip should be scoped to the affected CI environment instead of win32 broadly.
Useful? React with 👍 / 👎.
c9b728b to
7542057
Compare
7542057 to
584f0b5
Compare
… i18n
Why
- Codex review flagged three Blocking/High issues against feat/v0.3-redesign-2:
(1) the ⌘K palette in shell.tsx sent `{ search, limit, offset }` to
query_history and tried to read `response.rows`, but the real
contract is `{ q, page, cursor, ... }` returning `items`. Result:
palette searches were silently empty on desktop, and the existing
tests had been mocking the wrong shape.
(2) Paper UI still leaked raw English copy (char/chars counter, "Remove
tag {tag}" aria, "Calendar" dialog label, "now"/"first" year-rail
footers, dashboard greetings). i18n is a shipping contract, not
polish.
(3) Theme was held twice — once by the shell as a private useState,
once by Settings → Appearance via applyPaperPreferences. Toggling
one didn't update the other, so the buttons drifted.
What
- shell.tsx: palette now calls `backend.queryHistory({ q, limit, sort })`
and maps `response.items` with the real HistoryEntry shape (id/url/
domain/title/visitedAt/visitTime). Removed the orphan PaletteRow
interface. shell.test.tsx mocks `backend.queryHistory` with valid
HistoryQueryResponse fixtures instead of the legacy rows shape.
- i18n: added 3-language entries for the paper detail panel's char
counter (singular + plural template), the remove-tag aria label, the
calendar dialog aria, the year-rail now/first footer captions, and
the dashboard morning/afternoon/evening greetings. The dashboard's
hand-rolled greeting map is gone — it now reads
`dashboard.greetingMorning/Afternoon/Evening` like every other copy
in that route. PaperDetailPanelCopy + PaperCalendarPopoverCopy +
PaperYearRailProps + paper-view.tsx copy interface all gained the
new keys; buildPaperDetailPanelCopy + buildPaperContactSheetCopy
thread them through. i18n parity 100% (2798 keys × 3 locales).
- paper-preferences.ts: applyPaperPreferences now dispatches a
`pathkeep.paperPreferencesChanged` CustomEvent (with the resolved
preferences in `detail.preferences`) after applying + persisting.
shell.tsx subscribes to that event so the topbar theme button stays
in sync with Settings → Appearance toggles; settings/appearance-
section.tsx subscribes too so flipping theme via the shell button
updates the radio without re-mount. shell.tsx's handleToggleTheme
now routes through applyPaperPreferences instead of mutating a
private useState — single source of truth, one persist call.
Context
- Codex findings #1, #5, #6. Findings #2 (paper pagination), #3
(og:image fetch trigger), #4 (coverage gate restoration) tracked
separately and remain pending in BACKLOG.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Why Claude review finding #5. The render-time "did the entry change?" comparison used `entry?.id ?? null`, which collapses `entry.id === 0` (or the empty string, given the `id: number | string` type) into the same value as `entry === null`. The notes-flush effect keyed on `trackedEntryId` would then treat the row with id 0 as "no entry," silently failing to load its notes and never flushing pending edits when the user switched away from it. Dormant today — SQLite ROWIDs start at 1, so no row in production actually carries id 0. But the existing type already permits string ids, and the next synthetic-id path (compare-set rows, derived sessions, anything that doesn't come straight from `rowid`) could land on a falsy id and reintroduce the bug. The explicit-null check is one line and removes the entire footgun class. What - Replace `entry?.id ?? null` with `entry == null ? null : entry.id` at both call sites (the `useState` initializer and the render-time comparison). Now `id === 0` and `id === ''` flow through as the literal `0` / `''` value, distinct from the `null` no-entry sentinel. - Tighten the `trackedEntryId` state type to `PaperDetailPanelEntry['id'] | null` so the union (`number | string`) survives through state and the comparison can't collapse to `any`. - Inline comment documents the contract so a future "just simplify this back to `?? null`" cleanup is rejected at code review. Verification - `bunx tsc -b` clean. - `bunx vitest run paper-detail-panel` — 23/23 tests pass; the new type does not break any existing state-driven assertion.
Summary
Local verification