Skip to content

v4.9.0 — mark a page by moving things and striking things out - #3

Merged
DeyangChan merged 4 commits into
mainfrom
review/proven-presence
Aug 5, 2026
Merged

v4.9.0 — mark a page by moving things and striking things out#3
DeyangChan merged 4 commits into
mainfrom
review/proven-presence

Conversation

@DeyangChan

Copy link
Copy Markdown
Contributor
  • Two new ways to mark up a page: Move and Delete. A toolbar beside the page
    holds Comment, Move and Delete — what Annotate draws with, on keys c, m
    and d. Neither new tool needs a note: the mark is the instruction, and
    anything you type adds to it. Both outline whatever the pointer is over, so
    the element the gesture will take is settled before you press.
    • Move draws an arrow from a thing to where it should go. It records the
      element you dropped it on and which side of it — inside, before, or after —
      so your agent is told "after the Cancel button" rather than "180px right",
      which stops meaning anything the moment the page reflows.
    • Delete strikes out what should go. Drag across text and exactly those
      words are marked for removal; the strike finds them again by their text when
      the page is rebuilt, so it stays on them. Click an element instead and the
      whole thing is marked.
  • A watcher finds a review whose page lives outside the directory it was
    started from.
    A review's files sit beside the page under review, and
    watch --all found them by walking the directory it ran in. A page written to
    a temp directory took its files with it, so the watcher walked straight past a
    running review and the workspace said Unlinked while a session was in fact
    listening. Serving now leaves a pointer where it was run from, and the watcher
    follows it.
  • A watcher that covers no review says so. It reports UNLINKED instead of
    LINKED, because nothing is listening to any workspace at that point whatever
    the handshake proved. A handshake also carries the token it printed, so one
    watcher's answer no longer brings a different watcher live.

DeyangChan and others added 4 commits August 5, 2026 11:58
The workspace's link state now rests on evidence a session can only produce
by being there:

- A stream watcher opens with a HANDSHAKE line naming a command. Its
  `watching` heartbeat starts when `ack` answers it, and it exits 3 after
  two minutes (`--handshake-timeout <seconds>`) if nothing does.
- Presence also requires the rounds to move: a queued round unclaimed past
  90 seconds drops the link, and `check` names it on every call.
- The cog menu shows the version the workspace loaded with and the one the
  server is on, and offers a reload when they differ.

An answer written on a comment carried in from an earlier version is kept.
`postReply` and the composer's note edit copy the comment into the current
version first, so the reply lands in the file the workspace reads.

Stop is withdrawn to docs/review-wishlist.md, with interrupting the agent's
turn as its first acceptance criterion. The `cancel` sentinel, `/api/cancel`,
the `cancelled` command and the CANCELLED event go with it; `check` always
exits 0. Rounds still on disk with status `cancelled` stay terminal.

Host profiles move to plugins/vstack/host-profiles/, leaving `hosts/` to the
adapter markdown that maps ops to a product's tools.

A fitted page follows its canvas: the refit watches #stageArea, whose box no
scrollbar of its own can change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…s started from

A review's store sits beside the page under review, and `watch --all` found
stores by walking the directory it was run from. A page written to a temp
directory — where an agent puts a file it has just generated — takes its store
with it, so the watcher walked straight past a running review. It then
heartbeated into nothing while the workspace said Unlinked.

`serve` now leaves a pointer under the directory it was run from,
`.vstack/local/review/.serving/<key>`, naming the store it is serving. The
watcher follows those pointers as well as walking. A pointer whose store has no
`url` behind it belongs to a server that was killed, and the reader deletes it.

A handshake now carries the token it printed, so only the watcher that asked
acts on the answer — a second watcher's handshake is not an answer to the first.
A watcher that is answered but covers no review reports UNLINKED rather than
LINKED, because nothing is listening to any workspace at that point whatever the
handshake proved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…oved

Two annotation tools beside Comment, on a toolbar down the left of the canvas.
The bar still decides whether the pointer clicks through the page or annotates
it; the toolbar decides what annotating leaves behind. It takes its own strip
rather than floating over the canvas, because a toolbar in the top-left corner
covers the part of a design people look at first, and it stays in both modes so
switching to View and back does not move the page.

Each button is an icon, so hovering one says what it is, what key picks it, and
what gesture it takes: a picture of a pen does not say that clicking leaves a
point and dragging leaves a box. The same three parts go to a screen reader as
one sentence.

Both new tools are optional-note: the mark is the instruction, and anything
typed adds to it rather than supplying it. Both outline whatever the pointer is
over, so the element the gesture will take is settled before the press rather
than after it. Comment does not — it works on the place you press, and a box
following the pointer everywhere is noise.

Move draws an arrow from a thing to where it should go. A pixel delta alone
stops meaning anything the first time the page reflows, so a move also captures
the element it was dropped on and which side of it — inside, before, or after.
The brief leads with that and keeps the delta for the case where nothing was
under the drop and direction is all the reviewer gave.

Delete strikes out what should go. Dragging across text takes exactly those
words, through the page's own caret positions, so the agent is told the phrase
to remove rather than the paragraph it sat in; the words are found again by
their text when the page is rebuilt, so the strike stays on them. Clicking takes
a whole element, and strikes every line written inside it — a box drawn round a
paragraph leaves the words standing, which is not what was asked for.

Also carries a pending one-line fix in shell.css out to every page: the
[hidden] rule for the cog's version row.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two new annotation tools on a toolbar beside the page, and a watcher that finds
a review whose page lives somewhere else.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@DeyangChan
DeyangChan merged commit b43fa7c into main Aug 5, 2026
4 checks passed
@DeyangChan
DeyangChan deleted the review/proven-presence branch August 5, 2026 10:02
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