Conversation
Set up developer experience infrastructure: - ESLint 9 flat config with TypeScript-ESLint and React Hooks plugins - Prettier with singleQuote and 100 char width - Vitest 4.1 with happy-dom environment and v8 coverage - Husky + lint-staged for pre-commit formatting/linting - Coverage badge auto-update script - Version bump to 0.4.0
… worker Split the single background.ts (3000+ lines) into focused modules: - handlers/bulk-handlers.ts — bulk update, close, open, delete, reorder, lock, pin - handlers/sprint-handlers.ts — sprint status, progress, end sprint - handlers/duplicate-handlers.ts — deep issue duplication with relationships - handlers/field-handlers.ts — repo metadata, project fields, reorder context - handlers/hierarchy-handlers.ts — parent/sub-issue relationships, previews - handlers/config-handlers.ts — PAT validation, options page Shared infrastructure extracted: - cache.ts — TTL-based caches (resolved items, hierarchy, fields, sprint progress) - concurrency.ts — operation guards (max 3 bulk/duplicate, max 1 sprint end) - helpers.ts — shared utilities (rate-limit retry, queue broadcast, field resolution) - types.ts — TypeScript interfaces for GraphQL responses
New features: - Keyboard shortcut registry with platform-aware symbols (⌘/Ctrl) - Help overlay (press ?) showing all registered shortcuts by context - Lazy-loaded bulk operation modals via React.lazy() + Suspense UI improvements across bulk modals, sprint tracking, queue tracker, toast notifications, onboarding coach, and shared UI primitives. Updated content scripts, popup, and options page. Added Firefox Add-ons badge and updated README with store links.
New test files: - keyboard.test.ts — shortcut registry, format, conflict detection, keydown handling - selection-store.test.ts — toggle, batch, clear, subscribe, focus - toast-store.test.ts — show, dismiss, auto-dismiss timer, MAX_TOASTS limit - z-index.test.ts — constant ordering verification - checkbox-portal-store.test.ts — add/deduplicate entries, subscribe - project-table-dom.test.ts — extractItemId, isEditableTarget, getAllInjectedItemIds - primer-live-region-stub.test.ts — stub function coverage - debug-logger.test.ts — conditional logging, error always logs Improved existing tests: - queue.test.ts — rate-limit retry (403/429), task detail broadcast, failed items - sprint-utils.test.ts — injectSprintFilter DOM manipulation 12 test files, 122 tests, 53% statement coverage on src/lib/**
There was a problem hiding this comment.
Cursor auto review
Found 1 actionable issue(s) on changed lines.
- Found a correctness issue in keyboard shortcut modifier matching:
ctrlshortcuts will never trigger on non-macOS platforms.
Generated automatically when this PR was submitted using Cursor CLI with --model auto.
There was a problem hiding this comment.
12 issues found across 94 files
Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed. We prioritized the most important files first.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="README.md">
<violation number="1" location="README.md:22">
P3: The README badge incorrectly advertises React 18 while the project depends on React 19.</violation>
</file>
<file name="scripts/update-coverage-badge.mjs">
<violation number="1" location="scripts/update-coverage-badge.mjs:59">
P2: The badge marker regex is not multiline-safe, so badge updates can silently fail when the marker block spans lines.</violation>
</file>
<file name="src/entries/background/handlers/sprint-handlers.ts">
<violation number="1" location="src/entries/background/handlers/sprint-handlers.ts:281">
P2: Silent rejection when sprint-end concurrency limit is reached. The handler returns `undefined` without broadcasting any status to the UI, leaving the user with no feedback. Consider broadcasting an error/status message or returning a structured error response.</violation>
<violation number="2" location="src/entries/background/handlers/sprint-handlers.ts:388">
P1: Inconsistent "done" classification between `getSprintProgress` and `endSprint`. When `notStartedOptionId` is configured, `isItemDone` in `getSprintProgress` treats everything except "Not Started" as done, but the `endSprint` filter only recognizes the exact `doneOptionId`. This means items the progress view reports as completed could still get moved to the next sprint.</violation>
</file>
<file name="src/entries/background/handlers/hierarchy-handlers.ts">
<violation number="1" location="src/entries/background/handlers/hierarchy-handlers.ts:74">
P2: Fetch `blockedBy` and `blocking` in parallel to avoid unnecessary preview latency.</violation>
</file>
<file name="src/components/ui/markdown-textarea.tsx">
<violation number="1" location="src/components/ui/markdown-textarea.tsx:101">
P2: Add `type="button"` to these UI buttons to prevent unintended form submission when used inside a form.</violation>
</file>
<file name="src/components/queue-tracker.tsx">
<violation number="1" location="src/components/queue-tracker.tsx:225">
P2: Handle `sendMessage` failure in Retry Failed action to avoid unhandled promise rejections and silent retry failures.</violation>
</file>
<file name="src/entries/background/handlers/duplicate-handlers.ts">
<violation number="1" location="src/entries/background/handlers/duplicate-handlers.ts:66">
P1: Early returns on error leave the progress UI stuck at "Fetching item…" with no completion broadcast. When `details.node` is missing or the item isn't an issue, the function returns without notifying the UI, so the progress indicator never clears. Broadcast an error/done status before each early return.</violation>
</file>
<file name="src/entries/background/handlers/bulk-handlers.ts">
<violation number="1" location="src/entries/background/handlers/bulk-handlers.ts:1240">
P2: Off-by-one in progress status: when `state.completed === reorderOps.length` on the final callback, this displays "Moving item N+1 of N…". The sibling `bulkReorder` handler correctly guards against this with a ternary check.</violation>
</file>
<file name="src/lib/keyboard.ts">
<violation number="1" location="src/lib/keyboard.ts:82">
P2: Normalize optional modifier flags in conflict detection; otherwise equivalent shortcuts (`undefined` vs `false`) can bypass duplicate/conflict warnings.</violation>
</file>
<file name="src/lib/queue-store.ts">
<violation number="1" location="src/lib/queue-store.ts:112">
P2: Reset failure metadata when a new run starts on an existing completed process; otherwise stale `failedItems`/`retryContext` can leak into the next operation.</violation>
</file>
<file name="src/components/bulk/bulk-actions-bar.tsx">
<violation number="1" location="src/components/bulk/bulk-actions-bar.tsx:269">
P1: The `?` help shortcut will never fire on standard keyboard layouts. Pressing `?` requires Shift, but `modifiers: {}` expects `shiftKey` to be `false`. The strict equality check in `matchesModifiers` (`wantsShift === e.shiftKey`) rejects the keystroke.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Outer array typed as `readonly PortalEntry[][]` prevented `.push()` calls, breaking typecheck in CI.
…, safety guards - Fix ctrl shortcuts on non-macOS (was hardcoded false) - Normalize modifier flags in conflict detection (undefined vs false) - Add shift modifier to ? help shortcut - Align endSprint done classification with getSprintProgress (notStartedOptionId) - Return structured error on sprint-end concurrency rejection - Broadcast done status on duplicate early-return errors - Add dotall flag to coverage badge regex - Parallelize blockedBy/blocking read queries - Add type="button" to markdown-textarea buttons - Handle sendMessage failure in retry action - Fix off-by-one in reorder progress display - Reset stale failedItems/retryContext on new queue run - Fix React badge version 18 → 19
There was a problem hiding this comment.
2 issues found across 13 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/lib/keyboard.ts">
<violation number="1" location="src/lib/keyboard.ts:37">
P1: This change makes `meta` shortcuts fail on non-Mac because pressing Ctrl now also forces `ctrl` to match. Meta-only shortcuts (the cross-platform pattern) will no longer trigger on Windows/Linux.</violation>
</file>
<file name="src/entries/background/handlers/duplicate-handlers.ts">
<violation number="1" location="src/entries/background/handlers/duplicate-handlers.ts:78">
P1: `releaseDuplicate()` is called in early returns and again in `finally`, causing double-decrement of the duplicate concurrency counter.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
…cate
- keyboard.ts: ctrlPressed was always e.ctrlKey on all platforms, so on
Windows/Linux pressing Ctrl set both metaPressed and ctrlPressed to true,
causing meta-only shortcuts ({meta:true, ctrl:false}) to never match.
Changed to `isMac ? e.ctrlKey : false` so Ctrl is exclusively consumed
as the meta equivalent on non-Mac platforms.
- duplicate-handlers.ts: three early-return paths (fetch error, !source,
!issue.title) each called releaseDuplicate() before returning, but the
outer finally block also calls it unconditionally. Removed the three
redundant calls; finally now owns the single release.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
?)React.lazy()+ Suspense for faster initial loadsrc/lib/**Architecture
Background service split:
background/index.ts→ slim orchestrator delegating to:handlers/bulk-handlers.tshandlers/sprint-handlers.tshandlers/duplicate-handlers.tshandlers/field-handlers.tshandlers/hierarchy-handlers.tshandlers/config-handlers.tsShared infrastructure:
cache.ts(TTL caches),concurrency.ts(operation guards),helpers.ts(utilities),types.ts(interfaces)New Features
⌘/Ctrlplatform detection, conflict warnings, and help overlayReact.lazy()code-splitting for BulkEditWizard, BulkDuplicateModal, BulkRenameModal, BulkMoveModal, BulkRandomAssignModalTest Coverage
src/lib/**Test Plan
pnpm test— 122 tests passpnpm test:coverage— 53% statement coveragepnpm build— clean production build?→ keyboard help overlay displays shortcuts🤖 Generated with Claude Code
Summary by cubic
Modularized the background worker, added a global keyboard shortcut system with a
?help overlay, and lazy‑loaded bulk modals for faster startup. Also improved dev tooling/tests and fixed cross‑platform meta shortcuts on Windows/Linux plus a duplicate‑flow guard (removed double release).New Features
?to see all shortcuts.React.lazy()+Suspensefor faster initial load.Refactors
eslint9 flat config,prettier,vitestwith@vitest/coverage-v8,husky+ lint-staged, coverage badge script.src/lib/**.Written for commit e8f2a61. Summary will update on new commits.