Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (21)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 208775767c
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8405a6eb92
ℹ️ 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".
| const projectedCandidates = findTextCandidates( | ||
| projectedMarkdown.text, | ||
| selection.text, | ||
| ) | ||
| .map((startOffset) => ({ | ||
| resolved: mapProjectedRange(projectedMarkdown, startOffset, selection), | ||
| score: scoreCandidate(projectedMarkdown.text, selection, startOffset), |
There was a problem hiding this comment.
Reject protected selections before trying duplicates
When the user selects text inside rendered code and the same text appears later outside code, this fallback drops the protected candidate (mapProjectedRange returns undefined) and then resolves the selection to the unprotected duplicate instead of rejecting it. For example, in `target` target selecting the first rendered target sends rendered offsets for the code span; the protected match is filtered out here, and the plain target is highlighted, so the saved highlight appears on text the user did not select. Fresh evidence in this version is that protected ranges are filtered during projected candidate resolution, creating a wrong-location highlight rather than the earlier raw-code insertion failure.
Useful? React with 👍 / 👎.
| const sourceEndOffset = lastSourceOffset + 1; | ||
| if (sourceEndOffset - sourceStartOffset !== selection.text.length) { | ||
| return undefined; | ||
| } |
There was a problem hiding this comment.
Preserve selections that span markdown syntax
Selections that cross any skipped markdown syntax are currently unresolvable because the projected rendered text maps to non-contiguous source offsets and this check rejects the range. For example, selecting a bold b in rendered a **bold** b, or selecting text that starts before a markdown link and continues after it, hits this branch and then the raw-markdown fallback cannot find the rendered phrase contiguously, so normal reader selections fail and roll back even though the text is visible and selectable.
Useful? React with 👍 / 👎.
| class={readerArticle} | ||
| data-reader-content | ||
| innerHTML={props.result.rendered.html} | ||
| onKeyUp={handleSelectionToggle} |
There was a problem hiding this comment.
Do not toggle highlights on ordinary key releases
Because every keyup inside the reader calls the same toggle handler, a user who selects text just to copy it and releases Ctrl+C/Cmd+C will create a highlight, and doing the same over highlighted text can remove it. This only needs a current selection inside [data-reader-content]; the handler does not check the key or modifier state, so normal keyboard actions mutate persisted reader content unexpectedly.
Useful? React with 👍 / 👎.
| text.push(markdown[cursor] ?? ""); | ||
| sourceOffsets.push(cursor); |
There was a problem hiding this comment.
Decode rendered entities when resolving selections
The projected text is built from raw markdown characters, but the reader is rendered through MarkdownIt, so HTML entities are decoded before the browser selection is captured. If content contains visible text like Tom & Jerry, selecting Tom & Jerry cannot be resolved because this projection still contains &, and the raw fallback also searches for the decoded text in the encoded markdown; highlights fail for selectable text containing common entities.
Useful? React with 👍 / 👎.
Summary
Implements TRA-8 highlight workflow:
POST /api/highlightsvalidates the selection payload and persists highlight toggles through SQLite plusCONTENT.md/highlightsnow loads repository-backed highlight rows with source memory titles and links title/quote rows to/memories/:id#<highlight-id><mark data-highlight-id>and emits matchingidanchorsSelection anchoring strategy
The frontend sends selected text, prefix, suffix, and offsets from the reader DOM. The server resolves against
CONTENT.mdafter stripping persisted highlight marks: offsets are preferred when they match, and text/context disambiguates repeated selections when rendered-reader offsets differ from raw markdown.Toggle and mark behavior
<mark data-highlight-id="...">selected text</mark>intoCONTENT.md.<mark>tags remain for the sanitizer boundary.Browse and search behavior
/highlightsrows show source memory title, muted prefix, highlighted text, and muted suffix./memories?q=...continues to include highlight text/prefix/suffix through existing browse filtering, now backed by repository highlight data.Failure and backup behavior
The reader restores the previous HTML and shows
Highlight failedif persistence fails. The server writes markdown, replaces highlight rows transactionally, attempts content restore on DB failure, and enqueues backup after the markdown write through the existing Task 8 boundary.Mark insertion example
Validation
npm run typecheck-> passnpm test-> pass, 20 files / 110 tests; non-fatalmisetracked-config symlink warnings due sandboxOperation not permittednpm run build-> passGIT_DIR=.tmp/gitdir GIT_WORK_TREE=$PWD git diff --check-> passPATH="$HOME/.local/share/mise/installs/bun/1.3.13/bin:$PATH" npm run test:e2e-> blocked before app code by local Chromium/macOS sandbox:bootstrap_check_in org.chromium.Chromium.MachPortRendezvousServer... Permission denied (1100); 11/11 tests fail at browser launchNote:
bunis not on the default PATH in this workspace, so npm-equivalent commands were used locally; the pushed branch's pre-push hook reran typecheck, tests, and build successfully.