Releases: stropdev/strop
Release list
strop v0.34.0
The architecture release: readonly rendering behind a narrow admitted
API, real draft recovery, a modal terminal, vim grammar in every input
field, a process UI protocol, and the first whole-core verification
lanes.
Added
-
Modal terminal (0065): the embedded terminal presents honestly as
its own state — a distinct TERMINAL chip, every escape discoverable in
?help (Esc stays with the child; Ctrl-\ Ctrl-N and Ctrl-W N enter
inspection), a strop-owned palette (singlestrop-coretheme seed
configuring the emulator through a new native palette FFI), and
:terminal-refreshto pull the latest output into the pinned
inspection view. Motions, visual yank and search work over terminal
text like any buffer. -
Real dirty/scratch draft recovery (0056 AR04): unsaved changes
checkpoint continuously to a private, bounded, atomically-published
store — coherent multi-document cohorts, never half-mixed, whole
records demoted rather than truncated.:recoverlists checkpoints
with origin, time/revision and conflict state and restores into a
checked draft without touching disk, recreating deleted targets or
re-granting remote authority; remote drafts persist only with
explicit consent. Crash, kill and power-loss keep the last completed
checkpoint. -
Non-graphical UI protocol,
strop --ui-stdiobackend and Rust
driver (0056 AR09/AR10): a bounded, versioned process protocol for
frontends without a terminal. Content-Length-framed envelopes (the
LSP byte convention, distinct envelopes) carry a
version/build/capability handshake keyed by backend incarnation;
admitted actions reuse the engine's exact admitted input surface (no
parallel command table); semantic views publish as snapshots/deltas
keyed by incarnation + view generation + pane document revisions; a
dropped delta poisons the client until an explicit resync ships a
complete snapshot; stale-generation, wrong-incarnation, oversized and
malformed traffic earn typed refusals/errors, never a panic or silent
divergence; OSC52 clipboard writes cross as host effect
request/result; shutdown is authorized and orderly. The
strop-ui-protocolcrate ships the pure client state machine plus a
stdio driver whose deterministic schedules barrier on
acknowledgements, generations and named view states — closure tests
spawn the real binary over pipes (the WSL stdio lane) and pin
open/edit/undo/search/save/terminal parity with the headless driver.
Improved
- Pure render cutover (0056 AR01/AR03): painting is now a readonly
query over the engine. Hunk refresh, visible-window analysis/preview
admission and viewport/caret adjustment moved out of the renderer into
Editor::prepare_view, an admitted engine update keyed by an explicit
terminal-cell geometry and a stamp over view-relevant state — an
unchanged repaint admits zero worker tickets and touches no viewport.
The engine publishes a prepared view (per-pane windows keyed by
document revision and view generation, with declared
complete/partial/loading/stale/error bounds) that the TUI borrows; no
whole-editor clones. Picker card/pane/gutter geometry lives in the
engine as plain cell arithmetic, pinned cell-for-cell against the
historical layout. - Input fields speak the real vim grammar (0003 §2): picker
query/replace fields and the: / ? |line are backed by persistent
one-line buffers whose normal mode resolves through the same
strop_grammar::resolveas the document —dw/db/de/cw/dfx/
2dw/diwwork in every field, a completed operator reranks exactly
once, pure motions never do, and unsupported keys refuse with a
message instead of vanishing. - One narrow admitted engine API (0056 AR02):
Editorno longer has
public fields — the frontend boundary is one module of readonly
borrowed queries and admitted writers. Paint cannot mutate anything;
document/selection/pane mutation is engine-internal. - Bounded event and LSP transport (0056 AR06): the event channel and
LSP wire queue have real byte/count bounds. Semantic events (input,
paste, outcomes) are never dropped or reordered — admission refuses
visibly instead; wake hints coalesce legally; superseded unsent
LSP snapshots coalesce only when no request barrier needs them;
shutdown drains without hangs. - Container execution tells the truth (0056 AR07): exec requests pin
the selected engine context, cwd, principal and container incarnation
— a recycled container never receives a stale request. A supervised
lease reaps the whole session's descendants on close or client death;
missing programs and shim toolchains are typed diagnostics. :explainnames real owners (0056 AR08/AR14): readonly buffers
carry typed reasons (filesystem, remote capability, command,
recovery, terminal…) instead of a generic hint, config shows the
winning layer per knob, and one privacy classifier now governs
capture/persistence across local, SSH and container targets.- Identities refuse to wrap (0056 AR13): arena document identities
check exhaustion instead of incrementing blindly — a slot at the
generation limit retires forever, so a stale id can never alias a new
document. - Installs and updates are one verified transaction (0056 AR11/12):
install.sh and the updater share staged, sha256-verified, atomic
publishing (interruption preserves the old binary); channel identity
comes from an installation receipt, never path guessing; releases
generate a single catalog that installer, updater and site consume. - Build inputs are pinned (0056 AR15): every Docker base image is
digest-pinned multi-arch, with the bump procedure documented.
Fixed
- Preview caches could survive a rename through a symlinked path
(0056 AR05): purges now cover the operation's logical spellings, not
only resolved ones.
Verification
- The 0057 whole-core assurance programme opened: a machine-readable
boundary/claim inventory with hash-pinned evidence and candidate
freeze tooling guards the tree in CI (VF01); a pinned TLAPS lane
proves the search lifecycle's safety invariants inductively — with the
kept mutant failing proof on exactly its own steps — and the 0045
batch-composition obligation is now proved in production editmap.rs
(Verus); new Verus kernels verify mutation authority, projection
admission, recovery cohort, UI freshness and ID-exhaustion decisions
the production guards call; admission-freshness trace correspondence
replays the protocol model through the real handlers; new gated TLA+
models cover terminal and install domains with kept mutants and
witnesses (VF02–VF04, VF12, VF16–VF18 partial — the recovery and
LSP-wire models exist but are not gate-chained yet: state-space
calibration resumes in 0.35.0).
strop v0.33.0
One canonical query language across every search surface, automatic
workspace symbols, per-pane scrollbars with a Git overview, and the
optional cursor fade.
Added
- One typed Boolean query grammar everywhere: standalone
AND/OR/
NOT(balanced-paren grouping, NOT > AND > OR, juxtaposition is an
implicit AND),kind:/repo:qualifiers decided exactly from the
syntax-fallback index and project catalog, and three-valued admission
that never drops a line on undecidable evidence. Files, Search,
Replace, the Directory filter and both symbol pickers share the one
parser; operator-free queries behave byte-identically to before. - Workspace symbols without ceremony (
Space S): open a parent
directory and every declaration is listed through the bounded
syntax-fallback index — nested repositories, worktrees and marker
projects discovered automatically, no repository list to configure.
Eligible unopened projects warm their language servers behind the
picker (at most four in flight) and merge server symbols into the same
list; per-project status rows name missing or blocked server
configuration (cold,no srv,trust,no exec) instead of
leaving silence, and Enter on a status row opens the project. - Per-pane scrollbars: every editor and terminal pane reserves its
rightmost column for a quiet track carrying the fractional viewport
thumb and the document's added/changed/deleted Git spans; terminal
panes show position over their bounded history. - Optional cursor fade: the Normal-mode block cursor fades back in
over 160 ms after focus returns or a large jump (cursor_fade = falsein config.toml disables it wholesale). - Stored-query syntax versioning: persisted queries carry an
explicit syntax version with typed rejection of unknown versions and a
fixed-point v1→v2 migration that keeps previously-literal operator
words and qualifiers literal.
Improved
- Replacement through the Boolean grammar: With/Review decides one
identifiable target by NOT-parity and re-checks every span, so foreign
or stale provider spans never edit. - Symbol pickers filter with the real query: document and workspace
symbols narrow by content andkind:through the same admission as
search; only bare content text ever reaches language servers, and
replies are filtered locally before merging.
Fixed
- Query-wide options no longer leak into Boolean branches:
case:/hidden:/ignored:inside an operator expression used to
become inert atoms that silently broadenedORadmission; they now
live only as query-wide options and canonical formatting places them
in a leading preamble. - Wildcard globs match unanchored stars correctly:
*.rsno longer
missesa/src/x.rs(found by the differential reference interpreter).
Verification
- The search lifecycle is modeled in TLA+ with a kept mutant the model
checker kills on exactly the named invariants; the publication
boundary's guards are a Verus-verified kernel the production handlers
call, with model traces replayed through the real admission paths; and
the end-to-end mixed-directory fixture now covers worktrees, dirty
sources, cancellation, supersede, Unicode locations and remote
namespace isolation.
strop v0.32.4
Captures of terminal sessions cost a third of 0.32.3's bytes.
Improved
- Repeating rows travel once per frame: rows that recur anywhere in a
terminal frame serialize into a first-appearance dictionary and are
referenced by index runs; unique rows stay inline, so varied content
pays nothing. A flooded frame collapses to its few distinct rows and
repeated positions decode back to one shared row — the same session
that recorded ~2.4 MB now records ~0.7 MB, complete and replayable,
and slow-runner drains halve. Traces from every earlier version still
decode.
strop v0.32.3
Captures of terminal sessions cost a tenth of the bytes.
Improved
- Terminal frames and per-action checks stopped shipping padding and
duplicate text: each row's trailing default-styled space padding is
re-derived from the frame's geometry on decode, and observation checks
witness document text by SHA-256 digest plus its true byte length
instead of serializing the whole buffer every action (the startup seed
still carries full text). The same flooded-terminal session that
recorded ~20 MB now records ~2.4 MB, still complete and replayable —
cheaper captures, faster drains on slow runners. Traces written by
earlier versions still replay.
strop v0.32.2
Forensic captures survive real terminal sessions.
Fixed
- A flooded terminal no longer fails the editor's exit (
:qaafter
sustained output exited 1 withincomplete trace): three stacked capture
bugs, each fixed at its source. Terminal frames now serialize as cell runs
with the projection derived on decode, so a full-history frame costs its
content size instead of ~180 MB; mutation, history, document and paste
records carry bounded, explicitly-marked text excerpts beside true byte
counts, so opening a large buffer can no longer degrade the whole capture;
and an honestly-degraded capture (value or budget cap) is reported by the
file's terminal marker instead of failing the process exit — writer I/O
failures remain fatal. The opt-in capture byte bound rose to 512 MB to
match what consented interactive terminal sessions legitimately record.
Captures written by earlier versions still replay; the sustained-output
test now asserts the trace stays complete and replays execution-free.
strop v0.32.1
Picker previews and terminal navigation, from first real-use feedback.
Fixed
- Picker previews never loaded (find-file stuck on
loading…, grep and
symbols without syntax highlighting): the readonly-rendering split left the
preview's bounded read and syntax analysis with no admission site — paint
only reads caches. Frame preparation now admits both with exactly the window
paint will query, restoring content, line numbers, the ▶ hit marker and
syntax colors across all workspace pickers.
Added
Ctrl-Wis an editor window prefix inside terminal input (Vim's
documentedt_CTRL-Wgrammar):h/j/k/l/w(and arrows) move or cycle panes,
Nenters the pinned-snapshot inspection (same asCtrl-\ Ctrl-N), and
.delivers the literal byte to the child. Any other follow-up passes
through unchanged, and the message line hints the grammar while the prefix
is open.- Terminals are real switchable buffers: the buffers picker lists them
with Vim's!job badge and their live phase (terminal #N · dir · running), jump rows use the same truthful labels, and entering a terminal
records a jump soCtrl-Oreturns to your editing position.
strop v0.32.0
Embedded local terminals, full-screen pickers with wider previews, and a
folder-view refresh (plans 0054/0055 TUI milestones; all GUI work remains
deferred).
Added
- Local terminals (
:terminal): a real PTY-backed shell in the editor
(strop-terminal, pinned static Ghostty VT engine; source builds require
explicitly installed Zig 0.16.0 — prebuilt users need neither). Terminal
input keeps Esc/Ctrl-C/Ctrl-R/Alt/F-key meanings for the child; Ctrl-\ Ctrl-N
(legacy terminals may spell it Ctrl-4) enters editor Normal inspection over a
pinned read-only text snapshot; i/a follow the live cursor again. An exited
session stays readable and never restarts implicitly. :terminal COMMAND, directory Terminal here,:terminal-localfor an
explicit local shell from SSH/container contexts (interactive execution is
refused there, never silently redirected),:terminal-stop, and
:terminal-paste/:terminal-paste-cancelfor held multiline/control paste
consent.:qarefuses live sessions and:qa!stops and drains them.- Terminal buffers are real read-only buffers: normal motions,
/search,
selection and yank; splits mirror the live cell grid while one focused view
owns PTY geometry. Background descendants are reaped (pidfd-supervised on
Linux); deliberately detached processes are explicitly out of scope. - Terminal privacy: content is excluded from traces even with
--log-content.
Entering a terminal records an opaque marker and downgrades the capture to
metadata-only; replay refuses the omitted history.--log-terminal-content
is the separate explicit consent, visibly marked REC. Full--replay
reproduces terminal sessions with no PTY/process/clipboard/network effects;
input-only extraction refuses terminal traces honestly. - Keyboard capability advertisement is captured per session; legacy frontends
get a truthful legacy profile and the child's kitty-protocol queries are
masked to it (no fabricated enhanced keys, focus reporting follows mode 1004). inputheadless directive for complete physical key/text/paste events with
modifiers and repeat/release information;keysnow accepts chords
(<a-x>,<f5>) and physical facts are preserved until the engine selects
the input owner.
Changed
- Folder views align human-readable sizes and permissions behind full filenames.
A quieter breadcrumb header, restrained type accents and full-width cursor/mark
bands make the listing easier to scan without changing native entry identity. - Folder marks have visible gutter indicators. Empty folders and filtered-empty
listings show an explicit state instead of file-buffer filler rows; parent rows
expose the existing open/actions affordances. - Find File, Symbols and Search share one stable near-full-frame workspace
instead of a smaller floating card. The file preview gets the wider share
(grep 60/40, files/symbols 55/45), so source evidence reads comfortably
next to the decision list. Transient pickers keep the floating card. - Picker previews keep the rootle-style line gutter (▶ marker on the focused
line, right-aligned numbers,│divider) across files, grep and symbols;
the marker now reads accent+bold on the selection band. - Rendering is readonly (0056 AR01 core): an idempotent preparation step owns
every paint-path admission and viewport adjustment behind a state/geometry
stamp; repeated paints allocate no worker tickets and painting itself is a
pure&Editorquery.
strop v0.31.1
One filesystem workspace: browse, edit names, review operations (0054).
The 0.31.0 tag was not published: its hosted release gate caught a
scheduler-dependent trace-capture failure. This release includes the correction
without moving the existing tag.
Added
- One namespace-aware Directory buffer for local, SSH and read-only container
browsing, with current-file reveal, native-name completion, filtering and preview. - Checked filesystem creation, rename/move, stored/buffer copy, local Trash and
explicit permanent removal. Missing parents are reviewed separately; occupied
destinations are never silently replaced. - Modal filename drafts use ordinary edits, yank/paste and undo without touching
disk. Review and Apply share the explicit filesystem-operation planner. - Filesystem receipts retain committed, cancelled, partial and unconfirmed
outcomes independently of their views, with verification and checked recovery. - Directory Search here (
:fs search/Space a) captures a local or SSH
namespace/root without changing cwd. Capable SSH hosts run read-onlyrg
through supervised argv transport; source previews, opening and collection
loading preserve endpoint and native filename identity. - Search source previews have absolute line-number gutters and focused-hit
markers. SSH Search explicitly disables With/Review.
Fixed
- Trace admission uses the capture's byte/event budgets rather than a 64-record
scheduling window. Valid bursts survive a delayed writer without blocking
input; real capture limits and writer failures still produce incomplete traces. - Filesystem operations explicitly unlock cooperative name locks when they end.
A concurrent process fork can no longer retain a completed operation's lock
through an inherited descriptor and spuriously refuse the next batch step. - Search grouping, exclusions, preview caches and tab-width lookup distinguish
local files and different SSH hosts even when native paths are identical. - Invalid rg records, escaped paths, unsupported source text and oversized
records fail explicitly instead of disappearing from the result set. - Filename-review cancellation returns directly to the intact draft. Browsing
or refreshing its directory preserves edited names, undo history and provenance. - Directory selections follow confirmed renames through re-sorting and name
reuse. Stale path completions and transferred LSP navigation cannot restore old
bindings; deferred format-and-save work blocks conflicting relocation. - Native Ex open operands remain local outside Directory buffers. Directory
operands and completion share the captured directory namespace. - Search bounds decoded batches, source enumeration, total result rows and
retained row data; a small rg record cannot amplify into an unbounded batch. - Local save/save-as and filesystem mutations serialize in both directions,
including unresolved symlinked-parent destinations. - Move verification and recovery require an owned post-publication version;
pathname occupancy or a reused inode cannot authorize recovery. - Empty-directory removal can retire validated, quiescent protocol locks without
splitting active lock domains. Cancellation retains confirmed cleanup counts. - Admitted effects keep their actual receipts through cancellation and cleanup
failures; uncertain Trash publication retains its recovery metadata. - Remote source identity stays with the filename under modeline width pressure,
rather than disappearing with optional Git context.
strop v0.30.0
One Search workspace, replacement on demand (0053).
Changed
Space /andSpace Renter one retained Search investigation.Ctrl-R
shows/hides With without relaunching search or discarding drafts, field carets,
modal state, selection, scope or inclusion decisions.- One large responsive card, common source/delta rows, visible workset counts,
filename/parent identity and distinct source-preview background in both modes.
Tiny terminals prioritize the active field and preserve the result viewport. - Find Enter opens the selected source; With Enter prepares an owned background
review. Apply edits real buffers; Save remains explicit for every target. Ctrl-XandCtrl-Dcurate one workset shared by Collect and Review.
Same-query re-entry restores only exact witnesses and reports lost decisions.- Query, replacement/workset and review generations are independent. Late review
completions cannot retarget or steal newer focus; changed sources are refused. - Full replay semantics advance for the new keyboard and owned-review contract.
Fixed
- Stale Search hits cannot open or collect unrelated current source coordinates.
- Review preparation coalesces canonical aliases, retains dirty-buffer authority
and reports read-only, stale and unavailable sources alongside exact diffs. - Long captured roots cannot overwrite Search error headlines.
- Container integration gates include the Docker client and fail, rather than
silently skip, when an explicitly required engine is unavailable.
strop v0.29.0
Whole-editor polish and one query language (0051).
Added
- Shared
language:,path:,glob:,text:,regex:, visibility and case
qualifiers across file finding, grep and replacement. Filter-only file queries
work; invalid/incomplete queries cannot silently broaden a search or apply edits. - Parser-driven highlighting and Ctrl-Space query suggestions, shared modal field
geometry, and separate visible hidden/ignored controls. Unignored dotfiles are
included by default; repository internals remain excluded. - Source-specific indentation controls (
:tab-size, numeric/Auto forms and
:indent-style) with conservative detection and explicit provenance. - Passive source-aware delimiter highlighting through the shared cancellable
resolver, including collection projection and stale-result rejection. - Explicit replacement review, Apply and Save stages.
:save-changeopens an
owned per-file persistence receipt; open and previously unopened files behave alike.
Changed
- Collection edits publish to sources and other views while typing, with source
syntax, context expansion, independent match counts and ordinary Insert grouping. - Temporary outputs and jump history share complete, journal-remapped view records.
Modelines identify the effective input owner; split identity, source settings,
Unicode clipping and full logical-row selection share display-cell geometry. - Replacement rows and review buffers use source identities and exact diff roles.
Shell output preserves command/cwd, both streams and the completion/failure stage. - Ranking coalesces updates while one snapshot is in flight. The 100k-result probe
fell from roughly 2 GB peak live heap to 51 MB, rather than queueing a snapshot for every stream batch. - Source-to-view publication uses exact journal edits, preserving collection
carets, marks and jump history through undo and structural source refreshes. - Oversized collection, renderer, LSP and regression modules are split by responsibility.
Fixed
- Dirty source previews refresh on picker re-entry; cancelled/failed reads are
retryable without relabeling old content as a new source. - Replacement checks complete line witnesses, including regex context and empty
matches. Edited review buffers cannot apply a hidden older proposal. - Collection save/close tracks admitted source writes, including remote receipts;
unrelated completions, failures and newer edits cannot close the view. - Grouped collection history preflights every source's authority and revision capacity.
Formatter warnings survive persistence, and stale formatting cannot save newer edits. - Late hover replies cannot consume typing; query diagnostics remain visible without
overlapping titles or advertising controls that the active field does not own.
Migration: old -t/-g picker syntax is now ordinary literal text; use the named
qualifiers and :help query. In-buffer Vim search is unchanged. Replacement values
remain literal, including $1. Older unversioned semantic captures refuse replay.