You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
Review signals (opt-in): Stet grades each incoming change locally, warns
accept-all about significant changes, and adds a per-document change
summary. Off by default; local-only.
Hybrid review mode for local edits: a new "Hybrid" option between Needs
approval and Auto-accept. Small edits land on their own; significant
changes wait for you as a pending proposal, exactly like Needs approval.
Needs review signals turned on (Signals tier) to take effect.
Sharing activation nudges: an inline invite prompt after creating your
first workspace, and a "share this doc" card after your first real AI
review accept.
Share menu in the document header with copy-link, invite, and founding
member deal progress (share and feedback bars, days remaining).
Feedback claim flow: log feedback you gave outside the app (email,
Discord, Twitter) so it counts toward the founder deal.
Automatic founder deal credit tracking: sharing a review link or
submitting in-app feedback silently records progress toward the deal.
Changed
The document you have open is now marked in the file list with a red dotted
underline, the same proofreader's mark Stet leaves on text you have just
accepted. One motif for "this is the thing in hand", in both places you look.
Review signals now live in the existing right rail as a third Changes | Review | Comments mode. Review provides a local summary and a
Significant-first decision queue; selecting a row jumps to the same pinned
document preview used by Changes. Accept and Reject stay attached to each
row or pill with Stet's floating icon treatment, while the left rail remains
navigation-only.
macOS change notifications now wait for intake's result. Hybrid edits that
land quietly no longer interrupt; a newly held change sends one reason-aware
“needs your review” notification, and clicking it opens the affected file in
Review. Further saves to an already-pending file stay quiet, while recent
activity still records every external write. Daily digests remain out of
scope.
Fixed
A quote that starts with bold text is no longer dressed up as a comment. Only
a quote that opens with an author, like **@drew:**, gets the comment
treatment now. A meeting note beginning > **Attendees:** ... reads as the
quote you wrote. Nothing about the file on disk was ever affected, but the
document was telling you something untrue about itself.
Your own edits can no longer come back as changes to review. After you
accepted a change to a document, the next time you edited that same document
Stet could show your writing as a proposed change, with the old text on the
accepted side. Accepting it reverted what you had just written. Stet was
treating a change as resolved only while the document stayed byte-identical
to it, so editing the file broke that match and the settled change
reappeared. Stet now keeps its record of pending changes caught up with the
document, so a change you have already decided on stays decided. Workspaces
carrying this drift are repaired when you next open them; anything discarded
in that repair is kept on a stet-backup/ branch.
Accepting a change can no longer overwrite an edit you made yourself. If you
rewrite the paragraph a pending change targets, Stet refuses the accept and
tells you the text is gone. That held for the first click, but the change
was being re-measured against your new words every time the document
refreshed, so a second click could match your sentence and quietly replace
it with the agent's. A pending change is now always measured against the
document as it stood when the change arrived, so it stays refused.
Removing Stet from the open workspace can no longer strand the app in that
folder's unwatched browser or crash when another document is opened. Every
left-sidebar context now has a visible return to Workspaces, and even the
render-recovery screen can return there safely.
"Set up the demo" now opens the demo's getting-started document instead of
leaving you in an empty editor. The folder was created and watched, but no
document opened, so clicking a button that promises a 5-minute demo looked
like it had done nothing.
The welcome screen scrolls when the window is too short for it, instead of
clipping its bottom card with no way to reach it. This was most likely on a
brand-new install, where an extra card appears offering to make Stet the
default markdown editor, and least likely on a machine that already has Stet
set up.
An agent's rapid successive edits to the same document no longer go
missing. When a change was captured, Stet restored the file on disk and
ignored anything written to that path for the next 1.5 seconds — so a
follow-up edit landing in that window disappeared with no proposal and no
warning. Stet now compares the file's contents, so it only ignores an echo
of its own write and every real edit reaches review.
The branch bubble (accept-all) no longer disappears when the changes
sidebar is open — it shifts left of the sidebar instead.
Internal
QA conversions: right-rail-review-modes (6 of 9 cases) and auto-change-overlay (10 of 15) now have automated specs. The second one
matters most: it is the oldest open P0, and it had never been run. Both docs
name what did not convert and why, rather than papering over it with a
weaker assertion. order-safe-accept gains a C5 case for the accept
overwrite fixed above.
E2E: a before hook in wdio.conf.ts now dismisses any banner left on
screen before each spec file runs. Spec files share one app process, and StaleAcceptNotice is dismissed by the user rather than the app, so a banner
from an earlier file satisfied a later file's wait instantly — three specs
that each passed alone failed together. The reset is deliberately narrow;
also closing tabs took the suite from 2 failing files to 9.
QA conversions: order-safe-accept, project-aware-file-tree and sidebar-keyboard-and-header now have automated specs, so three more docs get re-checked on
every run instead of once on the day they were written. Their honest
conversion rates are 6 of 6, 4 of 5 and 2 of 4 — the shortfalls are cases
describing UI the app no longer has, now recorded in each doc.
E2E: scripts/e2e-locked.sh (npm run e2e:locked) serializes suite runs
behind a lock, so several agents converting QA docs in one checkout can each
verify their own spec instead of writing it blind. Running a spec needs no
rebuild — e2e:build only matters after a src/ change — which makes the
conversion loop about 20 seconds.
scripts/release.sh now runs npm test and the end-to-end suite before it
touches anything, and syncs Cargo.lock and package-lock.json alongside
the other three version bumps. It verified the artifact thoroughly — universal binary, no stray
dylibs, signature, notarization, Gatekeeper — and the software not at all, so
a release could be signed and notarized on a red suite. Tests run before the
CHANGELOG cut, so a failure leaves the tree untouched. STET_RELEASE_SKIP_TESTS=1 overrides, with a warning.
E2E harness: openFileFromOutside reproduces a Finder or command-line file
handoff by emitting the open-file event the real path already uses, and writeShareConfig is documented as a way to drive provider-gated UI without
putting a workspace into a shared state the suite cannot tear down. Both
came out of classifying the remaining QA docs and convert cases that read as
impossible from the docs' prose.
QA docs: removed qa/folder-controls-ui.md, which documented a component
deleted in Phase 4, and flagged six more docs that assert behavior the app no
longer has, so nobody converts a stale doc into a regression net.
LinkPopover's outside-mousedown dismissal listener now attaches in a
layout effect instead of a passive effect, closing a race where the
popover could be in the DOM before its dismissal listener existed —
a mousedown landing in that window was silently lost. This was the
cause of the flaky "mousedown OUTSIDE the popover closes it" test
under heavy CPU load (React's scheduler can yield between the commit
and a passive-effect flush).
Audited the app's other seven click-away dismissal listeners for the
arming race that LinkPopover hit (a popover reaching the DOM before the
passive effect that guards it). All seven — App.tsx's share and view
menus, ProfileRailFooter, AllFoldersView's add menu, TableControls'
context menu and grid picker, and FileTree's row context menu — open
from a discrete user event, whose passive effects React flushes inside
the same commit that renders the panel, so none of them has the gap and
none needed changing. New clickAwayArming.test.tsx pins that
invariant, along with the rAF case that does have the gap, so a future
panel opened asynchronously has a written rule to fail against.
Local comments stamp the signed-in author name from a ref instead of
React state, so a comment created immediately after opening a document
can no longer be attributed to "You" while the auth status is still
committing. Also fixes the intermittent full-suite failure of the
"uses the signed-in display name" test, which raced that commit.
End-to-end test suite (e2e/, npm run e2e): WebdriverIO driving a real
build via the embedded provider, since tauri-driver has no macOS support.
Behind a wdio cargo feature and a tauri.e2e.conf.json overlay, so
shipping builds carry neither the WebDriver server nor withGlobalTauri.
Runs are isolated from real app state by an overridden HOME plus a
separate bundle identifier, and every run asserts that isolation held: a
harness workspace appearing in the real watched-workspace registry fails
the run, while drift from the real Stet running alongside is reported and
allowed. First three qa/ docs converted to specs (find-replace,
hybrid-mode, per-source-review); the Definition of Done now asks for a spec
alongside each QA doc.
STET_TOKEN_STORE=file keeps the Stet account refresh token in the app-data
file instead of the macOS keychain. Test-only, default unchanged. The
keychain item is keyed on a fixed service name rather than the bundle
identifier, so every build on a machine shares one credential; file storage
follows $HOME and lets two instances hold different accounts, which is what
makes automated sharing tests possible.