Repository navigation
Notes: fix cross-project move, add right-click menu (desktop) + move-to-project & fixes (mobile) - #84
Conversation
updateNote's UPDATE had no project_id/workspace_id, so moving a note between projects was silently dropped — the row (and its .md file, left in the old project folder) kept the old project, and a refresh / file re-scan / device sync resurfaced the note where it started. Add a dedicated moveNoteToProject query + db:note:moveToProject IPC handler that writes both columns, deletes the old-project .md file, and rewrites it under the new project. Route the store action and move undo/redo through it. Covered by new query tests.
… icons Notes now open their actions menu on right-click (Pin/Unpin, Reveal, Archive, Move to folder, Move to project, Delete), mirroring the hover ellipsis dropdown via the shared ContextMenu primitive. Archived notes get a right-click Restore / Delete permanently menu too. Also fix MoveNoteModal rendering a project's Lucide icon NAME as text (e.g. 'Briefcase', 'Rocket') — now draws it via ProjectIcon.
Chat stopped after only 8 steps ('couldn't finish in a reasonable
number of steps'), too few for introspective research that chains many
single-tool reads. Match the desktop default of 30 and clarify the
exhaustion message.
Returning from background left translucent vertical bands over the transcript — an iOS snapshot artifact where the composer's native Liquid Glass layer samples a stale backdrop until the next paint. Bump a key on the AppState 'active' transition to remount the scroll content and force a repaint. Also register move_note_to_project in the tool-ref map so its chip is tappable.
Mobile had no way — manual or via chat — to move a note to another project. Add a moveNoteToProject query (updates project_id + workspace_id; DB-only, no .md files) and a move_note_to_project chat tool. Add a long-press action menu on note rows (native action sheet / Alert) with Pin/Unpin, Move to project, Move to folder, Delete, plus a reusable NotePickerSheet for the project/folder pickers. Project options render their Lucide icon via ProjectIcon (not the raw name).
|
Warning Review limit reached
Next review available in: 40 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughChangesDesktop note workflows
Mobile note workflows
Mobile chat behavior
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant NoteListItem
participant notesSlice
participant ElectronAPI
participant db_note_moveToProject
participant WorkspaceSync
NoteListItem->>notesSlice: select destination project
notesSlice->>ElectronAPI: moveToProject(noteId, projectId, workspaceId)
ElectronAPI->>db_note_moveToProject: invoke db:note:moveToProject
db_note_moveToProject->>WorkspaceSync: relocate note markdown file
db_note_moveToProject->>notesSlice: return updated note
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@electron/db/queries.test.ts`:
- Around line 229-234: Strengthen the “bumps version and updated_at” test around
moveNoteToProject by asserting that the moved note’s version increases from
before.version and that updatedAt is strictly later than before.updatedAt,
rather than using a non-strict comparison. Preserve the existing setup and
verify both promised changes.
In `@electron/db/queries.ts`:
- Around line 276-280: Update moveNoteToProject to look up the destination
project by projectId before updating the note, reject the operation when the
project is missing, and use the project's authoritative workspaceId in the
UPDATE instead of the caller-provided workspaceId. Preserve the existing
timestamp and version updates.
In `@electron/ipc/db-handlers.ts`:
- Around line 256-266: Make the relocation flow around suppressNextChange,
q.moveNoteToProject, deleteNoteFile, and writeNoteFile failure-safe: stage the
destination file before committing the database move, then remove the old file
only after the move succeeds. Add compensating cleanup and database/file
rollback for every filesystem or database failure so ownership and Markdown
files remain consistent, preserving the dashboard exclusion.
In `@mobile/app/`(tabs)/chat/index.tsx:
- Around line 133-147: Restrict the resumeKey update in the AppState change
handler to iOS only, using the platform check already available in the
component. Preserve the active-transition remount behavior on iOS while leaving
Android scroll state unchanged.
In `@mobile/src/chat/agent.ts`:
- Line 244: Update the final message construction around finalText so exhausting
MAX_TURNS always reports the turn-limit message, regardless of whether an
earlier tool-requesting turn produced text; do not let finalText suppress the
limit notification.
In `@mobile/src/chat/tools.ts`:
- Around line 176-183: Update the move_note_to_project tool’s run handler to
adapt the successful q.moveNoteToProject result from projectId/workspaceId to
the documented project_id/workspace_id field names, while preserving error
behavior and the existing input handling.
In `@mobile/src/components/NotePickerSheet.tsx`:
- Around line 64-70: Update the selected row handling in NotePickerSheet’s
renderItem so the row whose item.value equals selectedValue is disabled. Pass
the disabled state to Pressable and ensure onSelect cannot be triggered for that
row, while preserving normal selection behavior for other destinations.
In `@mobile/src/screens/ProjectScreen.tsx`:
- Around line 186-195: Update onPickProject so that when moveNoteToProject
returns an error, it displays the error and returns immediately before closing
the picker or clearing actionNote. Keep the success haptic and existing state
reset/load flow for successful moves.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0c17d788-adad-4b3c-9900-ab6cfc44160f
📒 Files selected for processing (19)
changelogs/v2.4.10.mdelectron/db/queries.test.tselectron/db/queries.tselectron/ipc/db-handlers.tselectron/ipc/registry.test.tselectron/preload.tsmobile/app/(tabs)/chat/index.tsxmobile/changelogs/v0.1.3.mdmobile/src/chat/agent.tsmobile/src/chat/tools.tsmobile/src/components/NotePickerSheet.tsxmobile/src/db/queries.tsmobile/src/screens/ProjectScreen.tsxsrc/components/notes/notes-view/ArchivedNoteListItem.tsxsrc/components/notes/notes-view/MoveNoteModal.tsxsrc/components/notes/notes-view/NoteListItem.tsxsrc/lib/commands/note-commands.tssrc/store/slices/notes.tstests/fixtures/ipc-mock.ts
- desktop moveNoteToProject resolves the target project's workspace itself and rejects a missing project (no more caller-supplied workspace mismatch) - db:note:moveToProject relocation is now failure-safe: write the new-project file first, roll the DB move back if it fails, best-effort delete the old file - strengthen the query test (version increases, strictly later updatedAt) and cover authoritative-workspace + missing-project rejection - mobile: restrict chat resume-remount to iOS (Android keeps scroll state) - mobile: exhausting MAX_TURNS always reports the limit (append to partial text) - mobile: move_note_to_project adapts result to project_id/workspace_id - mobile: NotePickerSheet disables the already-current row - mobile: onPickProject surfaces move errors and keeps the picker open
What does this PR do?
Notes fixes and enhancements across desktop and mobile. Fixes the bug where moving a note between projects didn't stick (it reappeared in the old project), adds a right-click context menu for notes on desktop, and brings note-move-between-projects to mobile (both a long-press action menu and a chat tool). Also fixes two mobile chat issues (resume ghost bands, too-low agent step limit) and a project-icon rendering bug in the move-to-project pickers.
Type of change
Screenshots / recording
Checklist
npm run type-check:allpassesnpm run lintpassesnpm testpasses (runsnpm run compilefirst soelectron/bundle-guard.test.tsactually executes —npm run test:bundleto run just that)npm run test:e2epasses (run before merging UI changes or cutting a release)var(--accent),var(--text-primary), etc.)text-[Npx]pixel font classes — rem equivalents only (text-[0.714rem],text-xs, etc.)handle()and returnIpcResult<T>schema.ts— n/a (no schema change; reuses existing columns)electron/db/queries.ts— single source of truth (imported by both Electron main process and MCP server); never construct aDatabaseinstance outsidedb/client.ts(Electron) ormcp-server.ts(MCP runtime)dependenciesordevDependenciesadded toROLE_MAPinscripts/generate-licenses.jsandlicenses.jsonregenerated — n/a (no new deps)electron/mcp/tools/index.tsdispatch +electron/lib/tool-schemas.tsZod schema — n/a (mobile chat tool only; not an MCP tool)--external:<pkg>flag in thecompilescript — n/aNotes for reviewer
Desktop — note move (
fix(desktop): persist note move between projects)updateNote()inelectron/db/queries.tshad noproject_id/workspace_idin itsUPDATE, sonote.update({ projectId })was silently dropped. The row (and its.mdfile, left in the old project folder) kept the old project, so a refresh / file re-scan / device sync resurfaced the note.moveNoteToProjectquery +db:note:moveToProjectIPC handler (writes both columns, deletes the old-project.md, rewrites under the new project, recomputes relationships/embeddings). Store action + move undo/redo routed through it. New query unit tests added.project_idin its full-row op and the old file is removed, so it should land and stay.Desktop — right-click menu
NoteListItem/ArchivedNoteListItemwrapped in the sharedContextMenuprimitive (same pattern askanban/card.tsx); mirrors the hover ⋯ dropdown. Worth confirming a right-click opens the menu without also triggering the row'sonClick.MoveNoteModalrendering a project's Lucide icon name as text (e.g. "Briefcase") → now uses<ProjectIcon>.Mobile
moveNoteToProjectquery (DB-only, no.mdfiles) +move_note_to_projectchat tool. This is the first way to move a note between projects on mobile — there was no manual UI either.NotePickerSheet. Only touch-tested via type/lint here; a device check of the long-press + pickers would be good.MAX_TURNS8 → 30 (matches desktop); resume-repaint key to clear iOS Liquid-Glass ghost bands after backgrounding.Changelogs:
changelogs/v2.4.10.md(desktop) andmobile/changelogs/v0.1.3.md(mobile, the pending release ahead of 0.1.2).Summary by CodeRabbit