Releases: ashlrai/ashlr-plugin
Release list
v1.36.2
Fixed
- Hook timing telemetry is now bounded, private, and rotation-safe. The
unbounded timing ledger is replaced by a locked 16 MiB active plus 16 MiB
retained ring with0600files, crash-aware stale-lock recovery, bounded
records and batches, and a disk-backed migration path for large legacy logs.
Hook flushes run in a worker so lock waits and migration cannot freeze the
hook event loop; contended batches are retried. - Timing reports no longer load the entire ledger or overstate incomplete
evidence. Readers scan retained then active data in fixed-size chunks,
filter finite windows while reading, detect writer transactions and source
damage, and explicitly mark dropped or unknown history as partial. Dashboard
and status conversion rates are withheld when coverage is incomplete. - Session-end health scans are truly bounded. Tail reads now cap bytes and
rows, include retained timing history, preserve complete newline-free legacy
rows, and reject malformed JSON values without suppressing independent
health nudges.
Internal
- Periodic collection during one-time legacy validation bounds the transient
JSON parser heap on Linux as well as macOS when migrating hundreds of
thousands of small timing rows. - Root tests now run in four isolated Bun workers, eliminating cross-file
process-global registry races while cutting the local suite from roughly
72 seconds to about 22 seconds.
v1.36.0
Added
- Community Ledger + public savings leaderboard. New
/communitypage
(plugin.ashlr.ai/community) shows the running total of tokens and dollars
ashlr has saved across all developers, a cumulative-savings graph, and an
opt-in per-developer leaderboard. Backed by two new read-only public-aggregate
endpoints —GET /public/stats/time-seriesandGET /public/leaderboard—
that expose aggregate counts and (for opted-in users) GitHub handle + savings
only; never email, code, or prompts. /ashlr-leaderboardcommand (on/off/status) — opt in or out of the
public leaderboard. OFF by default. When on, only your GitHub handle and
lifetime tokens/$ saved are published (the same number/ashlr-savingsshows).
Requires a stats-syncing account (Pro/Team). The cloud stats sync now sends
leaderboard_opt_inonly when you've explicitly set it. (Brings the slash
command count to 34.)
v1.35.4
Fixed
- Lifecycle hooks emitted an invalid output shape and errored at the end of
every session. TheStop,SubagentStop, andPreCompacthooks each wrote
{"hookSpecificOutput":{"hookEventName":…,"additionalContext":…}}, but those
three events are decision-control events in Claude Code — they do not accept
hookSpecificOutput/additionalContext. Claude Code rejected theStop
output on every turn withHook JSON output validation failed — (root): Invalid input. TheStopandSubagentStophooks now keep their side
effects (idempotent session-log finalization; subagent rollup + background
genome consolidation) and exit silently. ThePreCompacthook is removed:
its sole purpose was context injection, which the event cannot do, and the
same post-compaction re-orientation is already delivered by theSessionStart
(source: compact) hook, which can inject context. Net: two lifecycle hooks
(was three), and no more end-of-session validation error.
v1.35.3
Fixed
- Abstract classes were not chunked at all (
abstract_class_declarationwas missing
from the chunker's declaration map), soabstract classdeclarations were absent from
AST-read skeletons and genome RAG chunking. Now mapped to theclasskind — abstract
classes get the same member-signature treatment (and a regression test covers the harder
shapes: abstract methods, getters/setters, generic/async methods, static + readonly
fields, private#methods).
v1.35.2
Added
- AST-skeleton class member signatures:
ashlr__readAST skeletons now render a
class's shape — each method's signature (with the body elided as{ … }) plus
field/property/abstract/index signatures — instead of eliding the whole class body.
Gives the model a class's callable surface for orientation at a fraction of the tokens.
(chunker attachesmembersto class chunks — additive; genome RAG unaffected.)
v1.35.1
Added
- AST-skeleton enum coverage:
ashlr__readAST skeletons now includeenum/
export enumdeclarations, rendered in full (members are an enum's signal) rather than
dropped. Other declarations remain signature-only with bodies elided. (chunker emits
enumchunks — also enriches genome RAG chunking.)
Internal
- CI stability: widened the brittle stub-mode
bench-orchestrateperf bounds
(parallel-speedup floor and per-node-ms ceiling) that flaked under concurrent CI load —
they measured process-scheduling noise, not a perf SLA. Real regressions still trip them.
v1.35.0
Three WozCode-inspired token-mechanic features — the places a best-in-class
efficiency layer earns its biggest per-call wins. All additive, fallback-safe.
Added
- AST-truncated reads (
ashlr__readmode: auto|ast|snip, default auto): for large
wired code files (.ts/.tsx/.js/.mjs/.cjs/.jsx)ashlr__readreturns a SKELETON —
imports/exports + type/function/class signatures + docstrings, with function bodies
elided — for the file's shape at ~60–80% fewer tokens. Falls back to snipCompact on any
parse failure/timeout;bypassSummary:truestill returns the full file. New
servers/_ast-skeleton.ts(reuses the tree-sitter chunker). - Fuzzy edit matching (
ashlr__edit/ashlr__multi_edit): when an exactsearch
match fails, fall back to (1) whitespace-normalized unique match, then (2) bounded block
Levenshtein — applied ONLY on a single high-confidence match (≥0.90 + unique margin),
never ambiguously. Eliminates failed-edit retry round-trips from indentation/whitespace
drift. Exact-match-first and all uniqueness/error semantics preserved. Disable with
ASHLR_EDIT_FUZZY=off. Newservers/_edit-match.ts. - Post-edit validation loop: after an edit, the resulting content is syntax-checked
(tree-sitter for JS/TS,JSON.parsefor .json) and compared against the pre-edit state
so only edits that introduce a parse error are flagged. Default warns inline (the model
sees⚠ syntax …the same turn);ASHLR_EDIT_VALIDATE=blockrefuses the write before it
persists. Parser failures/timeouts never break an edit. Newservers/_edit-validate.ts.
Internal
- AST/JSON parsing in the edit/read paths is fully guarded (timeout + try/catch → safe
fallback); tree-sitter is dynamically imported in the edit path to keep subprocess
startup fast.
v1.34.1
Hardening pass. Security audit of the backend + capability-surface hardening +
honesty/labeling on experimental features + docs for the v1.34 surface.
Security
- Backend audit (server/): no critical/high app-logic issues — Stripe webhook
signatures are verified before any mutation, genome tenant isolation is enforced
(WHERE id=? AND org_id=?), SQL is parameterized, routes validate with Zod, secrets
are env-injected + AES-256-GCM enveloped. Fixes applied:- M1
/auth/statusrate limiter was disabled by a transposed-args bug
(windowMs/maxRequests swapped) — fixed to 20 req / 60s. - M2 GitHub OAuth could merge into an existing account by an unverified email —
now requiresprimary && verifiedvia/user/emailsbefore any merge. - M3 comp-tier grants never expired (nothing read
comp_expires_at) — now
enforced + persisted at thegetUserByTokenchokepoint. - M4 unbounded in-memory rate-limit + LLM-cache maps — added stale-entry sweeps.
- L3
/metricsBasic Auth now usestimingSafeEqual. - H1 bumped
hono→ 4.12.23 (bodyLimit-bypass / Vary-cache / JWT CVEs). Remaining
advisories are transitive (ws viaopenai, axios via@sendgrid/mail, fast-uri via
react-email) and need major upstream bumps — tracked, not request-path-exploitable.
- M1
ashlr__pipecapability surface:ctxnow defaults to read-only tools
(grep/read/ls/glob); shell (ctx.bash) requires a second explicit flag
ASHLR_PIPE_ALLOW_BASH=1. Tool marked[EXPERIMENTAL]. (Already off by default via
ASHLR_PIPE_ENABLE.)- Added a canonical
safeParse<T>hook helper + 127 hardening tests (all existing hook
JSON.parsesites were already guarded).
Changed
- Honest labeling of experimental/stub features:
/ashlr-orchestrateclearly marked an
experimental stub-by-default MVP; AST semantic features documented as TS-only (non-TS
falls back to line-based); staletrialEndsAt/ telemetry-route comments corrected.
Documentation
- New docs for the v1.34 surface: the four new skills +
ashlr-efficientoutput style,
the PreCompact/SubagentStop/Stop hooks, measured-savings mode ((API-measured)vs
(est.)), and the benchmark methodology + flags surfaced near the headline number.
v1.34.0
"Elite" — feature parity + a code-execution token lever + provable savings. First
capability-bearing release since v1.29; v1.30–v1.33 were stabilization. Three tracks
plus release-hygiene automation.
Added
- Code-execution mode —
ashlr__pipe(flag-gatedASHLR_PIPE_ENABLE=1): run a short
sandboxed expression that calls other ashlr tools (ctx.{grep,read,bash,ls,glob}),
filters/transforms results, and returns ONLY the distilled value — intermediate tool
output never enters context.AsyncFunctionisolation (no closure/module scope),
deny-list, ≤2000-char exprs, 10s/30s timeout, 64KB intermediate +max_output_bytes
caps, and single-aggregate savings accounting via a_noAccountingsuppress flag. - Three new hook events:
PreCompact(inject a ≤600-byte genome-ToC + session-state
"survival kit" right before auto-compaction),SubagentStop(roll a finished subagent's
savings into the session log + fire genome consolidation),Stop(deterministic,
idempotent session-accounting finalization complementing SessionEnd). - Four model-invoked Skills + SessionStart toggles:
ashlr-search,ashlr-lean-tools,
ashlr-genome-author,ashlr-cost-refactor. - Output style
ashlr-efficient— structural density (inline code, tables, inverted
pyramid); composable withashlr-brief. - Measured-savings mode —
servers/_token-measure.tsderives true cl100k token counts
from the Anthropic API (max_tokens:1, fire-and-forget, SHA-256 LRU cache). Savings now
label(API-measured)vs(est.)in/ashlr-savings, the dashboard, status line, and
the SVG badge once ≥10 measured calls accrue. - Reproducible benchmark —
run-benchmark.tsgains bootstrap confidence intervals,
--validate-tokenizer(heuristic-error vs API), and a--compareA/B table. - Honest genome retrieval — grep header shows
embedMode(cold/warm/hot/…), a
one-time cold-corpus nudge, TF-IDF re-ranking + camel/snake trigram expansion in
_genome-search.ts(no-regression on a cold corpus), and an Ollama auto-detect hint in
/ashlr-doctor. - Release-hygiene automation —
scripts/bump-version.ts(single source of truth across
package.json + plugin.json + marketplace.json) andscripts/check-version-sync.ts(CI
gate). Wired intoci.yml,release.yml, andpublish.sh.
Fixed
- Version drift — manifests were stuck at 1.29.0 while tags reached 1.33.0; now synced
to 1.34.0 and enforced by CI so it can't recur. - Stale
plugin-metadatatest — pinned to "31 slash commands" since PR #77; aligned to
the canonical 33.
Internal
_stats.tsschema extended additively (optionaltokensSavedMeasured/measuredCalls,
no schema-version bump, back-compatible).
v1.33 — Audit-driven polish + multi-host portability
18 PRs since v1.32 (#88-#105). A strategic audit pass identified 3 fatal first-touch UX cliffs + 1 underexploited competitive opportunity (multi-host MCP post-RooCode shutdown). All 4 shipped + Q1'27 wk 7-12 orchestration work landed.
UX cliffs closed
- #102 first-call savings projection — see your extrapolated annual savings on your very first ashlr call. Closes the audit's "$0.001 saved → user closes terminal" cliff.
- #104 Bun ≥ 1.3 prereq — bold callout above the install line. Closes the silent-install-failure cliff.
- #105 wizard restart enforcement — loud RESTART REQUIRED block + SessionStart hook detects missed restarts and warns. Closes the "wizard finished but plugin appears broken" cliff.
Multi-host portability
- #103 multi-host MCP — ASHLR_MCP_HOST env var gates Claude-Code-specific paths. Server now runs cleanly in Cline, Claude Desktop, OpenAI Codex CLI. Setup snippets at
docs/multi-host-mcp.md. Captures the post-RooCode-shutdown OSS replacement window.
Q1'27 wk 7-12 orchestration
- #83 cross-session discovery propagation aggregator — surfaces compounding knowledge across runs
- #78 multiplayer WAD-D breakdown — per-segment + top-mover indicators
- #81 WAD-D historical drilldown — date-range picker + sparkline grid
- #82 session replay UI v0 at
/admin/sessions - #94 orchestration telemetry table + dashboard panel
- #97 orchestrator overhead bench — measured ~5-30ms/node, 2.8× parallel speedup
- #98
/ashlr-orchestrate-status— inspect past runs - #99 central token quota accounting —
orchestration_usagetable + admin endpoint - #101 retry-with-backoff + handoff context budget — 3 attempts, exponential backoff, 8KB handoff cap
Fixes
- #96 pre-existing tsc errors + permanent dashboard projection date-drift fix via clock injection
- Discovery propagation aggregator wired into the daily WAD-D cron
Strategic artifacts
Four strategic audit docs filed at ~/.claude/plans/:
audit-code-quality.md— production-ready; 3 critical findings mitigated in practiceaudit-first-touch-ux.md— 5 minutes not habit-forming; value emerges Day 3-5competitive-landscape.md— positioning + RooCode shutdown opportunitygroundbreaking-bets.md— 5 post-northstar bets; Code Sandbox is the most ambitious