Skip to content

Releases: Lipen/nexus-raw

v0.24.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 15:58
2bc9051

[0.24.0] - 2026-10-24

Added

  • --ca-bundle FILE (also NXR_CA_BUNDLE) adds a PEM bundle of trust roots for a private CA.
    It is native only and conflicts with --tls-insecure.
  • get --range START-END|START- reads one byte span, to a file or stdout.
  • up --prefix PREFIX publishes only the names under a whole-segment prefix, keeping the relative path.
  • mirror --plan is the --dry-run alias.
  • nxr-tui --ca-bundle FILE (also NXR_CA_BUNDLE) and --tls-insecure apply one TLS policy to the session.
  • nxr-tui --no-color and a non-empty NO_COLOR drop the two semantic colours.
  • The Node bindings accept caBundle for a private CA and prefixes on up.
  • The Node get accepts range, with the same span rules as the CLI.
  • The Linux release archives carry nxr-mount next to nxr, and the Homebrew formula installs it when present.
  • Nxr::scan_prefixes and Nxr::get_range expose the scoped scan and the one-span read to library consumers.
  • Nxr::sibling_digest reads a .sha256 marker without a transfer. A malformed marker is Mismatch.

Changed

  • The repository's terminal output follows one model: results on stdout, failures, warnings and hints on stderr, and colour is decided per stream.
    Hints carry commands in backticks, check-docs and the real-Nexus battery stay quiet on success, and the battery keeps a TTY heartbeat without a hardcoded total.
    The demo reports its mock scenario count and aligns its -- comments.
  • The local scan refuses a symlink or any other non-regular entry with exit 2 and a hint, instead of silently dropping it from the upload.

Fixed

  • The mount evicts cached blocks per inode and counts the released bytes exactly, so the cache budget no longer drifts.
  • The mount help and reference state the minimum --block-kib and --cache-mib values.
  • The .part suffix joins the reserved names, and a local .part staging file is an explicit misuse in up instead of a silent omission.
  • get --range refuses a start past the end and replaces a symlinked output instead of following it.
  • The UnsafeName hint names the regular-file rule, so a symlink refusal no longer points only at the name grammar.
  • The help hides the NXR_CA_BUNDLE value instead of echoing the path.
  • up --prefix scans only the selected subtrees and validates explicit names path by path, so an unselected symlink no longer refuses the run and the tree is not walked twice.
  • The scan refuses a symlinked source root for plain up and diff, matching the scoped prefix scan.
  • The mount percent-encodes each path segment, so foreign names with spaces, ?, #, % or unicode resolve correctly.
  • The mount forgets a node when the kernel drops its last lookup and reports synthetic inodes for unvisited listing entries, so long browsing sessions stay bounded.
  • The wasm32 build compiles again: the native prefix helpers are gated, and the gate checks the core for the sandbox target.
  • The unreleased --cache-dir mount experiment was removed before it shipped. The mount stays memory-only.

v0.23.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 15:12
3cfca94

[0.23.0] - 2026-10-22

Added

  • The Homebrew formula, Formula/nexus-raw.rb, with this repository as its tap (brew tap lipen/nexus-raw https://github.com/Lipen/nexus-raw).
    just brew-formula regenerates it from a release's SHA256SUMS, and scripts/brew-formula.sh --check verifies it.
  • nxr-mount (Linux): a read-only FUSE view of a raw repository.
    Listings go through the search API, reads are lazy ranged GETs over a bounded block cache, and .sha256 markers stay hidden.
    Every write answers EROFS.
    The binary is a separate crate, so nxr keeps no FUSE dependency and stays portable.
  • Nxr::read_range, a byte span into memory that skips to the span without buffering the whole object when the server ignores Range, and Nxr::ls_at, a listing of any directory URL: the two core paths the mount is built on.
  • NexusClient::get_range, the transport primitive behind read_range.
  • nxr down <file-url> <dst-dir>, and the Node down with no names and no ls, download that one artifact with the same marker, resume and digest checks as a directory sync.
    The parent directory is the base and the leaf is the name, and an explicit --name, --names-from or --ls keeps the URL as the directory to enumerate.
  • The wasm sandbox lists and uploads.
    nxr_put PUTs the bytes and the .sha256 marker, the proxy forwards PUT with a request-body cap, and both the Node fake and the ServiceWorker fake store it.
    Nxr::put_bytes is part of the wasm surface: it is an in-memory POST-free path, not a file operation.

Fixed

  • The composite action installs the release named by its tag when version is empty, instead of always the latest release.
  • The mock server refuses an inverted Range and an oversized Content-Length or chunked size instead of panicking, honors spec.redirect, and lists each repository once in the scoped collection.
  • The mirror staging lock is held by the creating run, a pre-created symlink at the staging path is replaced instead of followed, and the segmented resume is gated on the object digest.
  • An artifact segment with the reserved .nxr prefix is refused, so local part, segment and cache files can never collide with a repository object.
  • put_bytes validates the marker name before the bytes are PUT, and a zero-length read_range still reports an absent object as None.
  • up --wait-index matches a grouped or repository-root base, service eula --accept propagates a 401/403 instead of reporting no gate, and service status reads a refused probe as false.
  • diff --prefix filters local-only entries too, and up --if-changed --plan uses the if-changed classification.
  • doctor falls through to the repository HEAD on a 404 status and builds the deep service probes at the origin, and service assets no longer slices a multibyte checksum.
  • mirror and mv fall back to the shared -u, --ls cannot be combined with --name or --names-from, and a clap parse error still carries a hint: line and the NDJSON error object.
  • The alias URL expansion no longer uses raw pointers, and a broken TOML line no longer echoes an inline password.
  • Server-supplied text is escaped in human output, credential-bearing base URLs are no longer echoed, and the 401/403 body read is bounded.
  • The TUI drops a repository URL whose origin differs from the configured server.
  • The PyPI publish waits for the gate, its action is pinned to a commit, and a new gate rejects any action pinned to a tag.
  • The panel and the wasm sandbox bound their targets to configured origins, validate upload names before writing, queue uploads, and ignore stale listing responses.
  • The wasm server answers 413 before closing an over-cap body, the page unregisters a stale worker, and the node example kills its mock on exit.

v0.22.1

Choose a tag to compare

@github-actions github-actions released this 21 Oct 19:00
b2dc863

[0.22.1] - 2026-10-21

Fixed

  • The shipped nxr skill teaches clone and --segments, lists every command that reads the search index, and includes mv in the enumeration contract.

v0.22.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 22:20
baae0d4

[0.22.0] - 2026-10-20

Added

  • down --segments N splits each artifact into N concurrent closed Range spans, 2..=64.
    A finished span survives an interrupted run, so a rerun fetches only the unfinished spans.
    The spans assemble into the usual part file, one pass hashes it, and the marker check decides the rename.
    The worker budget still caps the total concurrency, and a zero-byte object, an unsplittable one or a server that ignores Range falls back to the single-stream path.
    The core exposes the same transfer as Nxr::down_with_segments, and the Node bindings accept segments on NxrDownOpts.
  • nxr clone copies a whole repository into a local directory: every artifact and marker is verified, an interrupted run resumes, and a local object whose bytes match its remote marker but whose local marker is gone is sealed without fetching the bytes again.
    An optional local fact cache (<DIR>/.nxr-state.json, --state, --no-state, --verify) skips re-hashing files whose size, mtime and marker digest still agree.
    A missing, corrupt or foreign cache falls back to hashing.
    The summary gains the additive sealed count, and the Node bindings expose clone() and clonePlan().

v0.21.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 14:03
54637c4

[0.21.0] - 2026-10-19

Added

  • The transfer summary gains failures: the same artifacts as failed, as {"name","code"} objects whose code is the exit class (1 data, 2 misuse, 3 transport).
    failed keeps its legacy strings (a mismatch still carries name: detail), so the new array is additive for consumers.
    The Node bindings mirror the array on NxrSummary.
  • Nxr::audit_filtered and sync::audit::AuditFilter: an audit narrowed by exact names and whole-segment prefixes before any request.
  • The retry-after-503 mock scenario: the first request per path answers 503 with a Retry-After pause, so the 5xx pause is pinned without changing the plain-503 flaky contract.

Changed

  • The put source type is Uint8Array instead of Buffer.
    A Node Buffer is a Uint8Array, so existing callers stay compatible, and the shipped declarations no longer need @types/node.

Fixed

  • The composite action installs nxr again: it resolves the release from github.action_repository (the caller's repository was never the action's) and verifies the archive against the published SHA256SUMS instead of a per-archive .sha256 asset that the release never uploaded.
    The checksum check accepts the Windows binary-mode marker and falls back to shasum where GNU coreutils is absent.
    A CI job runs the action end to end on Linux, Windows and macOS.
  • get --continue keeps the partial file when a transfer fails, so the rerun the hint recommends resumes instead of starting from zero.
  • A resumed download refuses a symlinked or concurrently changed part, validates the Content-Range end and the bytes on disk, and restarts a stale part inside the same attempt, so --retry 1 still self-heals.
  • A down whose rename or destination check fails keeps the verified part for the rerun.
  • Retry-After is honored on every retryable status, not only 429: a restarting Nexus that answers 503 Retry-After: 30 is waited out instead of retried after half a second.
  • get --segments accepts 2 to 64 spans, runs them under the same worker ceiling as every other transfer, and completes an empty object instead of dividing by zero.
    A segment count outside the bounds is misuse (exit 2).
  • The uploader re-checks the source size per attempt and reads exactly the declared bytes, so a size change between the plan and the send is an I/O error instead of a body that disagrees with Content-Length.
  • scan rewrites backslashes only on Windows: on Unix a backslash is a filename byte and the grammar rejects it instead of uploading a phantom path.
  • audit --prefix obeys the same whole-segment grammar as every transfer filter, runs before marker and byte requests, and audited counts the objects the tree held rather than repeating the finding count.
    facts_available reports whether the index answered, not whether the filter selected anything.
  • mv --json writes a pure NDJSON stream: the plan phase headers are human output.
  • sha expands -R aliases for relative URLs, keeps an existing local path local, and reports a missing file or a non-http scheme as misuse (exit 2).
  • The live progress counter counts skipped files in its total.
  • doctor --deep without a URL is refused as misuse instead of silently skipping every server probe and reporting "all checks passed".
  • The release gate runs the full just check set (prek, cargo-deny, Python conformance), CI runs the prek hooks, the docs workflow rebuilds on the files its checkers read, and zensical is pinned.
  • The Rust example README teaches the current minor and joins the version gate.

v0.20.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 18:02
5cc9f22

[0.20.0] - 2026-10-18

Added

  • nxr ships a container image: ghcr.io/lipen/nexus-raw:<version> is the static release binary on a distroless base that carries the trust store TLS verification reads, runs as nonroot, and is published for linux/amd64 and linux/arm64 by the release workflow, from the archives that release already built.
    A COPY --from=ghcr.io/lipen/nexus-raw:<version> /nxr /usr/local/bin/nxr puts it in a downstream image.

Fixed

  • Enumeration survives a repository bigger than 5000 objects: the search walk was capped at 100 pages of 50 rows, so ls, down --ls, diff --via search and audit refused with cannot enumerate past that size.
    The bound is now per walk at 1000 pages, and a directory listing asks the search API with q=<directory>/, which cuts the pages down to that directory (13 to 61 pages instead of 122 on the measured 6095-object repository) while the client-side whole-segment filter stays the answer.
    The property that a directory query never drops a name is versioned, not verified at run time: the stand battery pins it against the pinned Nexus image.

v0.19.1

Choose a tag to compare

@github-actions github-actions released this 18 Oct 15:54
9854a77

[0.19.1] - 2026-10-18

Fixed

  • The npm platform packages ship an executable nxr: the artifact hop between the addon job and the publish job flattens file modes, so the staged binary arrived without its exec bit and the published package could not spawn it.
    The 0.19.0 platform packages are inert orphans (the main package never shipped at that version), and the publish job now restores the bit and refuses to pack a binary without it.

v0.18.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 11:34
7494ded

[0.18.0] - 2026-10-16

Added

  • put --stdin: the body streams from stdin as one PUT (printf … | nxr put URL --stdin [--sha]).
    The pipe is buffered whole (Content-Length is part of the protocol), the digest rides the same buffer.
    -f and --stdin are mutually exclusive, and calling with both (or neither) is refused as a misuse.
  • Nxr::put_bytes(url, body, sha): one-call PUT of an in-memory body, the library surface under --stdin.
  • nxr doctor --json and the human report carry a remediation on every failed check:
    next names the command or configuration to try next (credentials for 401/403, the base URL and
    --deep for a transport refusal, the EULA accept for the 403 write gate).
  • The Python reference client ships on PyPI as nexus-raw: pip install nexus-raw, the same
    stdlib-only nxr.py the conformance suite drives, trusted publishing, no tokens.
  • The unscoped npm name returns as a bridge: nexus-raw re-exports @nexus-raw/nxr 1:1
    (babel-core's bridge pattern), version in lockstep, so require('nexus-raw') keeps resolving
    to current code. Versions below 0.17.0 are deprecated with the rename message.
  • The release carries a llms.txt snapshot: site URLs rewritten to the raw markdown at the tag,
    so an agent pinned to a version reads that version's documentation.

Changed

  • cargo deny check joins just check and CI: RustSec vulnerabilities and yanked crates deny,
    licenses allowlist, sources policy. rustls moved to 0.23.46 (four advisories closed by upgrade).
  • The docs gain a how-to: comparing two servers through mirror --dry-run, the plan is the delta.

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 15 Oct 13:54
73cad87

[0.17.0] - 2026-10-15

Changed

  • up --wait-index polls the search index with exponential backoff instead of a fixed interval: 500ms, then 1s, 2s, 4s, capped at 5s.
    A 30s budget costs roughly 8 listing requests instead of roughly 60.

Removed

  • nxr point --clear <URL>: the --clear flag is gone, nxr point <URL> deletes directly.
    The flag-guarded misuse case never had a success path, so the guarded form was a dead branch of the interface.
  • Documentation advertised manifest-based enumeration that was removed in 0.12.0: the AGENTS.md down-source list, the core README example and the CLI README quick start now show the real sources (--name, --names-from, --ls).
    The rust example and its tutorial were ported to explicit enumeration, and the example compiles again against the published crate.
  • nxr clean: the command is gone, enumerate and delete with nxr rm itself.
    The command guessed versions by path-segment grammar, and a guessed scope is the one thing a destructive command must never do: a channel file named stable once passed as a "version".
    Retention is a policy, and policies live on the user side: the keep-N recipe builds it from ls, channel get and rm with explicit enumeration.
    The library surface loses Nxr::clean_plan, Nxr::clean_execute, Nxr::ls_versions, search_versions and validate_version with it, and the npm package loses lsVersions.
  • rm --dry-run and mv --dry-run: the flags are gone, both commands plan by default and delete only with --yes.
    Deletion being the default unless flagged was the dialect inversion: a destructive command must demand the explicit go.
    The npm rm surface follows: the promise resolves to the plan by default, confirm: true deletes, and dryRun is gone from NxrRmOpts.
  • The implicit version.json claim in mirror and mv: no name is special, the transfer order follows the user's enumeration verbatim.
    The explicit up --claim-first is untouched: an opt-in claim stays a user decision.

v0.16.0

Choose a tag to compare

@github-actions github-actions released this 14 Oct 22:28
30b1cbc

[0.16.0] - 2026-10-15

Added

  • nxr clean <BASE_URL> [--keep N] [--yes]: retention over whole versions.
    The plan names every version outside the newest --keep (dotted-numeric order) with the count of its names.
    A plan is the default and deletes nothing.
    --yes deletes the doomed versions through the regular rm machinery: markers before bytes, per-version atomic.
    Channel refs and names outside the recognized versions never enter the plan.
    Requires the search API (like audit's cross-check): a search-dead server refuses the run.
  • up --wait-index [--index-timeout SECS]: after the run, poll the search index until every uploaded name is visible.
    A real server's index lags behind writes by seconds, so a consumer reading through search right after up sees a stale world.
    The wait reports search visibility: N/M and degrades to a warning when the budget (default 30s) expires: the upload itself has succeeded.
  • doctor --deep gains the eula probe: GET /service/rest/v1/system/eula, strictly read-only.
    accepted: false is a warning naming the write gate and the accepting command, a 404 is a skip (no gate on this server), a refusal is a skip (admin rights).
  • The mock scenario search-lag: the search index serves the empty page for 6s after the first PUT, then a store-backed listing.
    The python reference client skip-lists it: its uploads are synchronous by construction.

Changed

  • The docker/CI images and the docs site ship a composite GitHub Action in this repository: uses: <owner>/nexus-raw@v… with command, args, version and auth (a secret, passed through the environment, never argv).
  • cargo binstall nexus-raw resolves the prebuilt release archives through the crate manifest metadata (present since 0.15.0, now documented).