Repository navigation
v1.38.0
Accumulated release since 1.37.1: the /ashlr-selftest command, self-tuning compression, the companion handshake and doctor probes, lazy MCP tool loading, and reliability fixes for brief-eval, hook timing and macOS child-process waits.
Added
/ashlr-selftest(scripts/selftest.ts, alsoashlr-plugin selftest): runs every command's entry point against a throwaway fixture repo with--jsonand reports pass/fail per command. Builds a temp git repo + isolated$HOME, probes every/ashlr-*command's backing script, everyashlr-pluginsubcommand, and the real MCP stdio path (tools/list +ashlr__read/ashlr__savingscalls). Pro-gated commands count their designed refusal as a pass; agent-only commands are listed as skipped; anycommands/*.mdfile without a declared probe is reported asuncoveredand fails the run.--jsonprints anashlr.selftestv1 report;--only,--keep-tmpand--timeout-msare supported.scripts/brief-eval.ts --jsonprints the eval report as JSON on stdout.- Self-tuning compression, on by default (
ASHLR_TUNING=offto disable): ashlr tracks per repo when a compressedashlr__readorashlr__grepresult is followed by a native re-read of the same target, and adjustsashlr__grepdetail per extension within bounds (level -2 to +2, 20-sample minimum, one step per 20 results). Level 0 output is unchanged./ashlr savingsadds, per repo and UTC week, tokens saved, estimated re-read cost, net tokens saved (est.) and miss rate; per-repo savings are recorded in~/.ashlr/repo-savings/next to the unchanged global stats. State is local counts only under~/.ashlr/{miss-stats,tuning,repo-savings}/, capped and owner-only. Seedocs/self-tuning.md. ashlr doctor --json(scripts/doctor.ts --json) carries the sharedashlr.doctorv1 wrapper (kind,schema_version,tool,status,native_status,checks): failures are fail, else warnings are warn;checksflatten the section lines. Additive: every existing field and the exit code are unchanged. The vendored handshake contract and checker are re-vendored from ashlr-stack with thedoctorsection.- Handshake conformance test (
__tests__/handshake-conformance.test.ts): validatesashlr-plugin --ashlr-handshake --jsonand every health combination against the Ashlr handshake v1 contract vendored from ashlr-stack (__tests__/contract/, pinned by sha256). The plugin advertises no gated capability, so no doctor argv is run. ashlr doctorcompanions: a degraded lexicon or ashlr-md that lists thedoctor-fixhandshake capability gets the hintrun lexicon doctor --fixorrun mdopener-mcp doctor --fix, the same capability-only rule locus already had. Probes still run with no secrets in the environment.ashlr doctorcompanions: a degraded locus that lists thedoctor-fixhandshake capability gets the hintrun locus doctor --fix(same rule asstack doctor --ecosystem). Lines show the reported health, a timeout or unreadable handshake reads asunknowninstead ofoutdated, and--jsonaddshealthandnext_stepsto each companion.ashlr doctorhas a companions section: phantom, phantom-secrets, locus, lexicon, ashlr-md and ashlr-stack are probed with--ashlr-handshake --json(2s timeout, no secrets in the env) and shown with version, readiness and a one-line fix hint when missing, outdated or degraded. Informational only; never a warning or failure.scripts/doctor.ts --jsonprints the report as JSON with acompanionsarray.ashlr-plugin --ashlr-handshakeprints the Ashlr companion handshake v1 (name, version, protocols, capabilities, local health, files the plugin may edit) as one JSON line. Answered by the node launcher before the bun check, so it works without bun. Contract: docs/ashlr-handshake.md.- Deterministic lane-side merge-conflict resolution:
.gitattributesgivesCHANGELOG.mdgit'smerge=uniondriver, andbun scripts/resolve-mr-conflicts.tsresolves stopped conflicts with no model call —CHANGELOG.md,CLAUDE.mdandREADME.mdkeep the onto-branch version with the PR's hunks re-applied via union merge, whilebun.lock,package-lock.jsonandCargo.lockare regenerated by the package manager (frozen/locked mode first) rather than hand-merged.__tests__/resolve-mr-conflicts.test.tsrebases a fixture conflict end to end.
Changed
- Per-repo savings use locked, atomic writes, with bounded retries even for malformed lock paths. The self-tuning report shows
n/anet tokens when re-reads have no recorded savings. - The savings dashboard abbreviates the stats path in its empty state, keeping long home directories within its 80-column layout. First-run Bun installation is detected using the updated PATH under Bun as well as Node.
- Hook timing batches count each row's bytes once before joining, avoiding repeated scans of growing batches that delay the hook safety timeout.
- The MCP router answers
initializeandtools/listfromservers/_tool-catalog.json, generated bybun run gen:tool-catalog. Each tool module is loaded on the firsttools/callfor that tool. Tool names, descriptions, input schemas, and call results are unchanged.
Removed
scripts/prune-old-memories.tsandscripts/context-db-migrate.ts: no command, hook, skill, doc or workflow invoked them. If you ran either by hand: the context database already migrates itself when a server opens it (openContextDb), and stale auto-memory files can be reviewed and deleted directly under your Claude projectsmemory/directory.
Fixed
scripts/brief-eval.tsno longer crashes on unrelated flags:--level/--outlookups previously readargs[0]whenever the flag was absent, sobrief-eval.ts --jsonthrewTypeError(and--outcould write a file literally named after the first argument). An invalid--levelnow exits 2 with a clear message.- CI documentation drift: the README CI badge queried the removed
pushtrigger (never rendered a status), anddocs/architecture.md,docs/platform-support.md,docs/launch-post.md,docs/producthunt.mdanddocs/press-kit/founder-bio.mdstill described the pre-restructure model — platform legs on every push, a weekly schedule andci:full-oslabels. All now describe the current model: PRs and merge-queue entries run only the seconds-fastfastgate; the full Linux/macOS/Windows suite and benchmark run on the daily schedule andworkflow_dispatch.__tests__/ci-docs.test.tspins the badge event parameter to a real workflow trigger and the documented cadence to the cron expression. runWithTimeout(servers/_run-with-timeout.ts) no longer loses a finished child on macOS under bun, where the runtime can dropexitandcloseforever while the child sits as a zombie (oven-sh/bun#34069); the happy-pathechotest flaked this way on loaded CI runners. On POSIX the command now runs under a thin/bin/shwrapper that reports its real exit status on a stderr trailer, so runs settle quickly with the true code even when process events never arrive. Missing and non-executable commands still returnexitCode: -1, resolved the way execvp would before spawning.warmUpSpawnwarms with the same spawn shape (detached, piped stdio) and retries inside its budget until an event is observed.