Skip to content

Releases: stropdev/strop

strop v0.34.0

Choose a tag to compare

@github-actions github-actions released this 17 Sep 22:36

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 (single strop-core theme seed
    configuring the emulator through a new native palette FFI), and
    :terminal-refresh to 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. :recover lists 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-stdio backend 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-protocol crate 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::resolve as the document — dw/db/de/cw/dfx/
    2dw/diw work 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): Editor no 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.
  • :explain names 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

Choose a tag to compare

@github-actions github-actions released this 16 Sep 23:09

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 = false in 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 and kind: 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 broadened OR admission; they now
    live only as query-wide options and canonical formatting places them
    in a leading preamble.
  • Wildcard globs match unanchored stars correctly: *.rs no longer
    misses a/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

Choose a tag to compare

@github-actions github-actions released this 14 Sep 16:42

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

Choose a tag to compare

@github-actions github-actions released this 14 Sep 15:38

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

Choose a tag to compare

@github-actions github-actions released this 14 Sep 13:49

Forensic captures survive real terminal sessions.

Fixed

  • A flooded terminal no longer fails the editor's exit (:qa after
    sustained output exited 1 with incomplete 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

Choose a tag to compare

@github-actions github-actions released this 14 Sep 06:45

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-W is an editor window prefix inside terminal input (Vim's
    documented t_CTRL-W grammar): h/j/k/l/w (and arrows) move or cycle panes,
    N enters the pinned-snapshot inspection (same as Ctrl-\ 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 so Ctrl-O returns to your editing position.

strop v0.32.0

Choose a tag to compare

@github-actions github-actions released this 14 Sep 05:24

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-local for an
    explicit local shell from SSH/container contexts (interactive execution is
    refused there, never silently redirected), :terminal-stop, and
    :terminal-paste/:terminal-paste-cancel for held multiline/control paste
    consent. :qa refuses 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).
  • input headless directive for complete physical key/text/paste events with
    modifiers and repeat/release information; keys now 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 &Editor query.

strop v0.31.1

Choose a tag to compare

@github-actions github-actions released this 13 Sep 11:25

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-only rg
    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

Choose a tag to compare

@github-actions github-actions released this 12 Sep 10:53

One Search workspace, replacement on demand (0053).

Changed

  • Space / and Space R enter 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-X and Ctrl-D curate 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

Choose a tag to compare

@github-actions github-actions released this 12 Sep 08:08

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-change opens 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.