zy v1.0.41
Official binary release for zy 1.0.41.
What's changed in 1.0.41
Added
spinnerbuiltin and a reusable spinner engine. A newspinnercommand
drives a terminal spinner for long-running work. Wrap a command and it animates
until the command exits, then prints a green check or red cross and passes the
command's exit status through:spinner -s moon "Building" -- make -j8. It can
also spin for a fixed time (spinner -d 3 "Warming up"), list the presets
(spinner --list), or preview them animating (spinner --demo). The animation
draws to stderr, so a wrapped command's stdout stays clean for a pipe.
Forty-two presets ship across all six families: single-glyph spinners (dots,
braille, moon, dice, …), scrolling "linear" rows, sweeping "bar" arcs (including a
two-row Zed/Claude-style bar), and the 2D braille rings (a rotating arc around a
circle, or a filled square or rectangle). The bar, linear, and ring families render
live instead of from a fixed frame table, so the bar fills the terminal width (a
full-width sweep, re-filling on resize) and you can reshape any of them per run:
--width,--height(multi-row bar),--spin cw|ccw,
--motion bounce|loop|squeeze|radiate,--bar-style(sixteen glyph sets),
--track,--radius/--size/--arc/--fade,--centre filled|empty,
--direction/--flow,--slots/--lit, and--phasefor a flux travelling-wave.
The rings rotate smoothly (frames that would not change the rasterized output are
collapsed).spinner --listgroups them by family. They
ship in/usr/share/zy/spinners.tomland are also compiled into the binary, so
spinners work even without the file; a~/.zy/spinners.tomlcan override or add to
them, andscripts/dev/gen_spinners.pyis the single source that generates both.
The families are modeled on the MIT-licensed tui-spinner crate. The engine
(08_ui/src/spinner.cplus the pure rendererspinner_render.c) is shared, so
other zy TUIs can use it too.- Redesigned install banner. The post-install experience moved to a bolder,
on-brand look: the same braille spinner runs the setup steps, sections are drawn
as colored "pills" built from block glyphs (so they render without a Nerd Font,
which may not be installed yet), and the Terms and Setup screens share that
vocabulary. No prompts or behavior changed, just the presentation. - fff-grep inline path scoping. A leading
ext:/path:/glob:/name:
constraint (with!to negate) in the pattern now scopes the search to
matching files:fff-grep "ext:rs TODO"grepsTODOonly in.rsfiles,
fff-grep "!ext:md TODO"skips.md. A plain pattern is unchanged. This is
what AI/MCP callers reach for to avoid grepping the whole tree. - fff-grep context lines (
-A/-B/-C).fff-grep -C 2 foonow returns the
2 lines before and after each match (or-A/-Bfor one side), likegrep.
Context lines are taggedmatch_type = "context"so structured/MCP consumers
can distinguish them, and they're captured from the full file so a match near a
scan-chunk boundary still gets its surrounding lines. - fff-find query:
name:filter + case-insensitiveext:.name:foohard-
filters to files whose basename containsfoo;ext:now matches
case-insensitively (ext:RSfinds.rsfiles), and!ext:rsexcludes them. - fff differential rebuild (L.3). When a file is deleted or a new subdirectory
appears, the fff index used to re-walk the entire tree to refresh. It now re-walks
only the changed directory and copies the rest of the entries from the previous
snapshot, so a localized change no longer pays for a full-tree readdir/stat. The
result is published as a fresh immutable snapshot through the same path as a full
rebuild, so search results are identical. Renames and.gitignoreedits still do
a full rebuild (they can change filtering tree-wide). Covered by a new
thread-sanitizer gate,tests/unit/0714_fff_differential_rebuild.c. libzy_fff.so— the fff engine as a shared library (N).make libzy_fff.so
builds the recursive index + AI-grade grep + watcher into a self-contained shared
object that other tools can link, exporting just thefff_*engine API (the
shell-coupled CLI shims are left out). Output is byte-identical to the in-binary
engine, checked bytests/validation/fff_libzy_so.sh.- The
github_prpill is now recolorable per state. New[github_pr]keys
open_color,draft_color,merged_color,closed_color, andapproved_color
set the pill background for each PR state. Each takes a palette slot name like
color4or a hex like#9d7cd8, resolved against the active theme. To restyle
the whole pill at once, overridestyleas before. customizegained a "GitHub PR colors" picker. Under Appearance, it lets you
set each PR state's background with arrow keys (←/→ cycles the theme palette,d
resets to the default), with a live swatch and sample pill. It writes the
*_colorkeys above, so it is the first per-pill color editor in the wizard.
Changed
- fff-find ranking is sharper. A query that matches a file's name now ranks
that file above one where the match is buried in a parent directory, with an
exact-filename match (user→user.rs) weighted highest, and a gentle
path-depth tiebreaker that prefers the shallower of two otherwise-equal hits. - The fff frecency database now self-maintains. On first use per process it
ages out access history older than 90 days and hard-caps the table, so the
~/.zy/fff.dbaccess log can't grow without bound or accumulate dead rows for
long-deleted files over a long-lived install. Ranking is unchanged (the score
already decays old entries to ~1%). - fff-grep is now ReDoS-resistant and emits less fuzzy noise. Regex matching
is bounded by PCRE2 match + backtracking-depth limits, so a pathological pattern
(e.g.(a+)+$on a long line) can no longer hang the grep — it caps the work and
reports no match for that line instead. And the fuzzy grep path now rejects
widely-scattered matches (a needle whose characters are sprinkled across a wide
span), so low-signal noise doesn't flood results.
Fixed
- fff git-status now works in repos using index format v4. The
.git/index
parser previously bailed on version 4 (prefix-compressed path names) and left the
status cache empty, so the file explorer's git chips were blank for any repo that
enabled v4 (index.version=4/feature.manyFiles). It now decodes v4's varint
path compression, so modified/untracked/clean status resolves correctly. See
KNOWN_ISSUES ZY-028. - fff now honors nested
.gitignorefiles. Previously only the.gitignores
from the repo root down to the indexed directory were applied, so a.gitignore
inside a subdirectory was ignored. The walker now loads each directory's
.gitignoreas it descends and matches rules relative to that directory (the way
git does), in both the single-threaded and parallel walkers — sosub/.gitignore
hides files undersub/without affecting siblings, and root rules still apply
throughout. See KNOWN_ISSUES ZY-026. - fff: four correctness fixes surfaced by an architecture review against fff.nvim.
(1)glob:in a find query now actually globs viafnmatch(glob:*.rsmatches.rs
files by basename) instead of literal substring matching, which matched nothing.
(2)fff-grepwith a regex no longer drops matches past byte 8191 on a long/minified
line — the regex runs over the whole line, and a match-centered window shows long-line
hits correctly. (3) The file watcher now recovers fromIN_Q_OVERFLOW(a dropped-events
burst, e.g. a biggit checkout) by forcing a full rebuild instead of going silently
stale. (4)fff-findresults are now deterministic on score ties (stable path
tiebreaker). See KNOWN_ISSUES ZY-023..ZY-025, ZY-027. - The
github_prpill now actually changes color with PR state. It pushed the
state color into the runtime palette by its slot name (color8,color2, ...),
but the palette setter only accepts a hex literal, so the push was silently
dropped and the pill fell back to the terminal background, looking the same dark
color for every state. The color is now resolved to a hex first, so draft, open,
merged, and closed render distinct backgrounds. - Release notes now carry the "What's changed" block, and re-publishing refreshes
them. The release publisher read the CHANGELOG section after its orphan-branch
step had already wiped the working tree, so the GitHub release body fell back to
bare boilerplate. v1.0.40 hit this first and its notes were patched in afterward.
The section is now captured before the wipe. Re-publishing an existing release also
updates its notes and title now, instead of only replacing the assets.
Verify your download
curl -LO https://github.com/iskandarputra/zyshell/releases/download/v1.0.41/zy_1.0.41_amd64.deb
curl -LO https://github.com/iskandarputra/zyshell/releases/download/v1.0.41/SHA256SUMS
curl -LO https://github.com/iskandarputra/zyshell/releases/download/v1.0.41/SHA256SUMS.minisig
curl -LO https://github.com/iskandarputra/zyshell/releases/download/v1.0.41/zy-release.pub
minisign -Vm SHA256SUMS -p zy-release.pub # confirms maintainer signature
sha256sum -c SHA256SUMS --ignore-missing # confirms the .deb hash matchesFull signing policy: docs/ops/RELEASE_SIGNING.md
VirusTotal scan
This release was uploaded to VirusTotal at publish time. Click through to see the live verdict from 65+ AV engines:
(Scans run within ~5 minutes of upload. If the page shows "Item not found", wait a moment and refresh.)
Try without installing
docker run --rm -it ghcr.io/iskandarputra/zyshell:1.0.41Install (Debian / Ubuntu)
The recommended path is the zy APT repository which handles upgrades automatically:
curl -1sLf 'https://dl.cloudsmith.io/public/iskandarputra/zyshell/setup.deb.sh' | sudo -E bash
sudo apt install zyOr direct .deb install:
sudo dpkg -i zy_1.0.41_amd64.deb
sudo apt-get install -f