Skip to content

Add inline comments to Docs - #5731

Draft
brsbl wants to merge 32 commits into
mainfrom
bb/docs-inline-comments-thr_dxfjrhdzmm
Draft

brsbl wants to merge 32 commits into
mainfrom
bb/docs-inline-comments-thr_dxfjrhdzmm

Conversation

@brsbl

@brsbl brsbl commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

Human comments

What was wrong

Docs had no way to discuss selected text without changing the Markdown document or moving feedback into chat.

What changed

  • Add inline comment threads (select text, then Comment or ⌘⌥M), with replies, resolve/reopen, and edit/delete of your own messages. Threads whose text is gone show "Text not found"; there is no Reattach in v1.
  • Store comments in a hidden <doc dir>/.bb-comments/<file>.json sidecar, anchored by quote plus surrounding context. Every write uses compare-and-swap with up to 3 re-applies before returning conflict. The Markdown is never touched, and rename, move and delete through Docs carry the sidecar along.
  • Add bb docs comments list/add/reply/resolve and RPC methods that share one service. HTTP exposes only /comments/list and /comments/folder. Authors are set on the server: the Docs UI posts as the user, and the CLI posts as the invoking thread (BB_THREAD_ID). No input field sets an author, and edit/delete is UI-only. @mentioning a thread sends it the comment with a Docs context block, and "New thread" spawns one.
  • Known limit: bb plugin RPC can't tell the Docs UI from an agent calling bb plugin rpc call, so an agent that goes around the CLI can still post as the user. Closing that needs a core caller identity, which is tracked separately.
  • Comments belong to a document only while Docs knows its identity. Each comments file records the document hash Docs last saw, and Docs re-saves it only for changes it vouches for: Docs saves, comment writes, bb docs write, push, proposal accept, and Docs moves. After an outside change, such as a direct file edit, a replaced file, or a reused path, the document shows a Keep on this document / Leave banner instead of highlights. The same choice is available as bb docs comments keep|leave.
  • Never delete: deletes through Docs, bb docs remove, folder deletes, and push --delete move comments to <vault>/.bb-comments/orphaned/. These, plus comments stranded by external moves, appear in a read-only N without a document list with View, Copy text, and a confirmed Delete (comments list --folder, read-file, delete-file --yes). There is no cross-document attach or merge in v1.
  • Folder deletes move each .bb-comments directory to the orphan area whole, and are refused if the subfolder listing is truncated. Docs creating a document at a path with leftover comments orphans them first. The watcher, the inventory, and failed reads move comments of missing documents to the orphan area, so a later file at that path starts clean. One known limit, documented in the spec: identical bytes re-created outside Docs before any sweep keep the old comments.
  • A comment re-anchors only when its quote plus context occur exactly once, with no fuzzy matching. Duplicates and edited text become "Text not found" with Reattach. External reloads clear highlights before they can be saved, and a refreshed anchor is accepted only if its quote is unchanged.
  • Horizontal rules count as atomic blocks in the stored visible text, matching the editor, so anchors after --- or *** stay aligned.
  • While a proposal is pending, highlights are re-anchored onto the draft by quote and context. Adding and reattaching comments wait until the proposal is accepted or rejected.
  • Show the margin when the pane is wide enough, and fall back to the shared responsive drawer on phones and in panes narrower than 720px.
  • Document the workflow in the Docs skill. Additive only: the simple-notes ID, existing files, vaults, settings and sync are unchanged, and older builds ignore the hidden folder.

How you verified

  • Remote CI on the latest head. Regression coverage includes concurrent sidecar writes, malformed sidecars (read as empty, writes fail closed), anchor recovery after external edits, and sidecar moves and deletes alongside documents.
  • Branch web app, isolated data dir: bb docs comments list, add --json, ambiguous_quote (lists occurrences, exit 1) and quote_not_found (exit 1), plus the UI flows below.
  • Full Slop Cop and full e2e are reserved for the requesting lead. Do not merge.

Screenshots (2×, branch web app)

Before After
Desktop Before desktop After desktop: highlights and open count
Desktop, wide pane — After desktop: expanded thread in the margin
390px Before 390px After 390px: highlights and open count
390px, thread — After 390px: thread in the drawer
Desktop, outside change and without a document — After desktop: outside-change banner and comments without a document
390px, outside change — After 390px: Keep or Leave banner
390px, without a document — After 390px: comments without a document

BB-Thread-ID: thr_dxfjrhdzmm

🤖 Generated with Claude Code

AGENT GENERATED

brsbl and others added 30 commits October 18, 2026 23:47
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…osal highlights

- Drop HTTP comment writes so authors come only from the UI or the invoking CLI thread
- Project Markdown horizontal rules as atomic blocks like the editor does
- Refuse moves onto unrelated stranded comments and adopt externally renamed ones
- Re-anchor highlights onto pending proposal drafts and pause commenting until resolved

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…edits

- Transfer sidecars to the renamed file when push --delete pairs a deletion with an identical write, including folder renames
- Index sidecar locations by document hash so external moves into any folder adopt their comments without scanning folders
- Re-find stale highlight offsets by exact quote and refuse anchor refreshes that leave the server-resolved span

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Re-anchor only when quote plus context occur exactly once; no fuzzy matching
- Clear highlights on external reloads and accept refreshed anchors only with unchanged quotes
- Remove content-hash move detection and its index table; only Docs moves carry comments
- Move comments of documents deleted by push --delete to an orphan area instead of deleting them
- Add attachComments (RPC, bb docs comments attach, Document moved? UI) for stranded and orphaned comments

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Rename the source sidecar to a private claim before reading, so writes during attach stay at the source path
- Return a failed claim to its path or the orphan area instead of deleting it
- Treat every anchor field as thread state when merging attached comments

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Never rename or delete the source sidecar; merge into the destination with CAS
- Append a fingerprinted attached record to the source with CAS and retry on conflict
- Hide a source from orphan listings only while all its threads are fingerprinted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Skip threads whose fingerprint is in an attached record when listing and re-anchoring
- Show threads changed after the tombstone, so late writes remain recoverable
- Offer Document moved? whenever no comments display

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Record the document hash in each sidecar; re-save it only for Docs writes, bb docs write/push, proposal accept, and Docs moves
- Hide comments after outside changes behind a Keep / Leave banner (UI, RPC and CLI)
- Move comments to the orphan area on Docs, CLI, folder and sync deletes instead of deleting them
- Replace attach with a read-only Comments without a document list: view, copy text, confirmed delete

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r files

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Move each .bb-comments directory into the orphan area on folder delete; refuse when the subfolder listing is truncated
- Orphan a left-behind sidecar before Docs creates a document at that path
- Sweep comments of missing documents into the orphan area from the watcher, the inventory and failed reads
- Remove Reattach from the UI, RPC and service

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…phaning and reply-command quoting

- Drop the note pane's unfiltered vault refresh so autosave keeps the editor, undo history and selection
- Place highlights from server offsets only when they describe the shown, unedited document; otherwise keep mapped positions
- Check the rename destination before orphaning its comments and roll back if the move fails
- Accept only Docs-generated comment IDs and shell-quote every argument of the generated reply command

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tions

- Orphan a leftover sidecar only after confirming the path is free, and restore it if the create fails or conflicts
- Have createNote check real absence past truncated listings and retry on conflict
- Restore orphaned comments when a move or delete fails, including folder comment directories
- Serialize document writes, re-binds, moves, deletes and sweeps with comment writes in one lane
- Keep mapped highlights until a completed save's anchors are persisted, and drop stale in-flight lists

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ng sibling

- Run comment lists (RPC, CLI, mention context) in the comments lane so none lands between a document write and its re-bind
- Restore each orphaned comments file independently and only for documents that survived a failed delete
- Never let a rollback error replace the original failure

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…delete

- Create the sidecar's parent before the non-overwriting restore move, as the host move requires
- Make the test host reject moves into a missing parent, like the real daemon
- Cover fail-before-removal, partial removal and failed preservation of a later folder

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… rich Markdown anchors, live inventory

- Refuse folder deletes whose comment folders exceed what rollback can list, before any change
- Re-read the document after Keep so text and highlights recover without reload
- Keep unsent reply drafts per thread across incoming replies, refreshes and collapse
- Project raw HTML, attributed tags, plain-paragraph checkboxes and soft breaks exactly like the editor
- Refresh the comments-without-a-document list on vault and comment events

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brsbl and others added 2 commits October 19, 2026 12:57
- Track open HTML tags with in-place stacks so projection stays linear on hostile input
- Map anchors between stored and editor text so ordered checklists and inline images highlight correctly
- Mark whole images and rules with node decorations
- Keep source lines across soft breaks
- Signal comments-changed after Leave, documentless delete and sweeps so polling panes refresh
- Route CLI comment lists through the observed-deletion cleanup and never mask the original error

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Build the line table as a typed array from per-block line changes instead of variadic pushes
- Test single paragraphs from 100 KB up to the 25 MiB read limit and a 150 KB document end to end

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant