github apmantza/pi-lens v4.1.4

3 hours ago

Added

  • Deliver test-runner failures after the agent settles (refs #2366)
  • Shared config core (refs #2425).
  • pilens_effective_config / effective_config answer "why is X running" (closes #2427)
  • pi-lens now learns which third-party tools edit files by watching (closes #2430)
  • Agent worktree and orphan-process hygiene (closes #2435)
  • BoundedFifoMap<K,V> sibling of BoundedLruCache (refs #2442)
  • bounded() and a governance guard for hook awaits (refs #2523)
  • Config resolution now proves it happened (closes #2526)
  • scripts/ci-verdict.mjs: one REST read of Unit tests + Lint & type-check conclusions on an exact head SHA (closes #2539)
  • Add a flake-shape ratchet over every *.test.ts under tests/ (closes #2547)
  • Release-readiness QA pass: a witnessed feature × modality matrix against a real pi (refs #2606)
  • Roll up declined concurrent session starts (refs #2130, closes #2249)
  • install-smoke gains a PR-gating host-range lane and a nightly @latest advisory lane (closes #2613)

Changed

  • Exercise the per-server touch verdict with two auxiliaries, so a sibling scanner's findings must survive a slow scanner's lapsed … (#1549)
  • Bound a multi-file review-graph rebuild's edge removal (refs #2074)
  • Registered-or-fail sweep for topology-derived caches (closes #2294)
  • Exercise workspace-diagnostics sweep attribution and error-path closure through a pull-advertising server on the real JSON-RPC … (#2332)
  • Exercise full session-start topology re-derivation through the live path (closes #2333)
  • Govern lsp-spawn-heavy lane membership (refs #2344).
  • A broken LSP config now warns once per problem, not once per load attempt (refs #2418)
  • Cross-file staleness now works for the languages the registry reconnected (refs #2424)
  • One canonical language registry behind LSP, tree-sitter, dispatch, read expansion and the review graph (closes #2424)
  • symbol_search's lang filter answers from the registry (refs #2424)
  • One canonical config file, one documented lookup order (refs #2426)
  • A globally disabled language server can no longer be re-enabled by a repository (refs #2427)
  • One shared registration helper for the read and mutation bridges (refs #2437, refs #2423)
  • One process-table seam replaces five hand-rolled snapshotters (closes #2443)
  • BoundedSet sibling in clients/bounded-cache.ts; four hand-rolled membership-Set caps migrated (refs #2460)
  • Analyzer bootstrap clients load on demand, not at session start (closes #2467)
  • Every "deadline AND abort signal" bound now goes through one primitive (refs #2523)
  • escapeRegExp folded onto one runtime export (refs #2558)
  • One dialect-parameterized workspace-member glob matcher (closes #2591)
  • Migrated the last 18 hand-rolled LSPService test doubles (17 files) onto
  • Test names state behavior, not hope (closes #2602)
  • One fixture-workspace bootstrap for the five LSP dev-harness scripts, home-pinned (closes #2670, closes #2658)
  • CI production-dependency audit is bounded and retried
  • tools/lsp-diagnostics.ts's directory-scan language table is now a registry projection (refs #2434)
  • Config parse errors keep line L col C locality for every V8 SyntaxError shape, derived from the source text instead of the message (refs #2451)
  • tests/config/bounded-eviction-idiom-sweep.test.ts's exemptions are keyed by content, not line number (closes #2475)
  • effective_config/pilens_effective_config reject a file outside cwd instead of silently answering from a foreign tree (closes #2520)
  • Turn-end test runner: integration/e2e targets excluded, and an unfinished batch is deferred instead of reported clean (closes #2522)
  • Consolidate LSP service test doubles (refs #2582)
  • LSP
  • Pinned that git init is never worktree-mutating, and that an ephemeral test fixture is never a shared checkout (refs #2345)

Deprecated

  • Deprecation windows for the legacy LSP config surfaces (refs #2418)
  • The legacy config locations now say so, once per setting (refs #2426)

Fixed

  • Bound re-raised auxiliary coverage-gap detail (#2356)
  • Formatter config-signature lookup is warm-path cached (closes #1603)
  • Keep word-index persists incremental after a session reload (refs #2068)
  • The availability probe consults pi-lens's own managed bin dir, not just PATH (closes #2140)
  • Normalize escaped-newline flattened PR bodies for checking (refs #2145)
  • Stop starving auxiliary LSP resyncs behind a cold primary spawn (closes #2239)
  • Bound per-file session-fact growth in dispatch's FactStore (refs #2282)
  • The ast-grep napi fallback now reports at the LSP's severity floor (closes #2336)
  • Classify machine-emitted text as generated by content shape (refs #2346)
  • Restore embedded-<script> ast-grep coverage under the napi fallback: HTML script bodies are now scanned with `language: … (#2347)
  • Honor runner language scope inside dispatch groups (closes #2353)
  • Remove the unused runner default declaration (closes #2354)
  • Run review-graph changed-symbols and entity snapshots under one normalized key per file (refs #2355)
  • Re-arm late auxiliary coverage after notify-stall teardown (refs #2356)
  • Coalesce superseded LSP document notifications (refs #2357)
  • The LSP breaker's CPU-liveness verdict reads its own sample window (closes #2358)
  • Make the #2358 CPU-liveness regression proof clock-boundary safe (refs #2358).
  • Preserve unknown root identity in session_start_total (refs #2129).
  • Replay exact-SHA master validation after merge-train merges (closes #2380)
  • Approve the installed ast-grep CLI lifecycle script (refs #2401)
  • Recognize already-applied edits instead of re-applying them on retry (closes #2402)
  • An unavailable formatter no longer reads as a code failure (closes #2413)
  • Model-facing analyze counts no longer fold hint/info findings into warnings (closes #2420)
  • File mutations from any tool now reach the analysis pipeline (refs #2423)
  • Config notices now name only settings pi-lens recognizes, and one file can no longer flood you with them (refs #2426)
  • A truncated config-notice list now says how much it truncated, and stops calling a valid file invalid (refs #2426)
  • A legacy config file's notices are bounded whichever loader reads it, and a warm config load no longer pays for the enumeration twice (refs #2426)
  • "None of this config is in effect" is never one of the notices the bound suppresses (refs #2426)
  • A malformed ~/.pi-lens/config.json now says so, as a global-config problem (closes #2445)
  • Separate the mutation bridge's recordability from --no-read-guard (closes #2465)
  • recordEntitySnapshotDiff enforces its absolute-filePath invariant (closes #2477)
  • A nested executeCommand no longer strips the outer LSP call mutation receipt (closes #2479)
  • The SubagentStop hook now reaps the stopped agent's worktree (closes #2486)
  • Stop cross-project delta-baseline contamination on the warm MCP server (closes #2489)
  • turn_end no longer blocks the terminal on a stale worklist (closes #2504)
  • NDJSON log sinks bound themselves mid-session, not only at session start (closes #2505)
  • Send a stray probe's LOGS to a scratch dir instead of the real ~/.pi-lens, without moving its tools or registry (closes #2506)
  • A headless pi child no longer exits 0 in the middle of a tool call (closes #2507)
  • Deflaked four shared-slot-contention test races (closes #2512, closes #2495)
  • Close out the #2508/#2511 ndjson-logger and log-dir leftovers (refs #2515, refs #2516)
  • Turn-end advisories name the resolved cache path, not a hardcoded .pi-lens/ one (closes #2521)
  • LSP wait and sweep-warm-up records name only rooted candidates (closes #2525)
  • lens_diagnostics mode=full and --lens-guard now treat a test RUNNER error as advisory, matching the turn-end message (closes #2532)
  • Overlap auxiliary LSP warmup with primary server during resync (closes #2540)
  • Label-manifest governance test now derives its full requirement, and prune: true is explicit where it lives (refs #2553)
  • Label syncer no longer deletes the priority labels on every merge-train lane merge (refs #2553)
  • compat-smoke Layer A resolves each pinned contract's source file independently (refs #2581)
  • peerDependencies["@earendil-works/pi-tui"] no longer excludes pi 0.85.x (closes #2586)
  • pi.skills no longer escapes the published package (closes #2587)
  • Merge gate no longer false-fails on a concurrency-superseded cancelled check-run (closes #2632)
  • ci-verdict.mjs's absent-required-checks reason now says why (refs #2664)
  • Use project Python environments without shell activation (closes #2407, refs #1513)
  • Memoize package-manager global bin dirs (closes #1602)
  • Log session-start classification alongside mode (closes #2129)
  • Emit availability_decision telemetry on the LSP-launch managed-bin fast path (refs #2140)
  • Cap the widget footer's dependency-drift re-serves (refs #2275, sibling of #1950)
  • The #2117 arena-recompaction regression test no longer flakes on a scheduling accident (closes #2293)
  • Session-state sweep flags process-singleton-backed state and accepts closure-located resets (refs #2319)
  • Rule tooling handles mixed-case language tags (closes #2331)
  • Enforce ast-grep-napi's skipTestFiles on the write-group dispatch path (refs #2337)
  • Breaker teardown tells dead from busy (#2358).
  • Isolate post-agent test delivery (refs #2366)
  • Nightly tool-smoke
  • Unconfigured HTML and YAML files no longer auto-format with Prettier (closes #2384)
  • Biome lint and autofix no longer produce import-type rewrites for projects without a Biome config (refs #2385)
  • Keep alternate language servers as fallbacks during all-scope diagnostics (closes #2400)
  • Bound post-merge reconciliation by its time window (refs #2405)
  • Parse pytest counts only from its terminal summary (closes #2408)
  • Stop presenting hint/info findings as code warnings (refs #2414)
  • Stop leaking config file contents into diagnostics on a JSON parse error (refs #2431)
  • tests/fixtures/fake-lsp-server.mjs can no longer outlive a killed parent (refs #2436)
  • Wire oxlint into npm run lint and CI for plain .mjs/.cjs/.js files (refs #2439)
  • LSP-applied edits (rename, workspace/executeCommand) now always bookkeep through the existing LSP mutation seam, and name the specific operation (closes #2450)
  • Extend npm run lint:js (oxlint --deny-warnings) to clients/, tools/, mcp/, and root index.ts TypeScript (refs #2439, #2454, #2462)
  • Session-state sweep detector no longer hard-codes container class names, no longer gates on a clear()/delete() method name, and no longer misses an exported container (refs #2442, #2455)
  • Analyse every observed (unclassified-tool) mutation — the tool's FIRST call included — and apply the post-pipeline post-conditions on that path (#2464)
  • rustfmt now carries the Cargo package edition (closes #2466)
  • ktfmt now carries the project's Gradle ktfmt { } style selection (closes #2468)
  • Wait for the persisted snapshot instead of racing it in word-index-lifecycle.test.ts's absent-snapshot test (closes #2471)
  • php-cs-fixer now carries its detected ancestor config into --config (closes #2472)
  • Monorepo module-graph crate names are now read from [package] only (closes #2473)
  • Project-config discovery with no config file anywhere is bearing-scoped, not $HOME-wide (refs #2426, closes #2483)
  • Rust workspace-root hoisting reads [workspace] presence through the shared Cargo.toml reader, not a second hand-rolled regex (closes #2498)
  • tests/support/sweep-kit.ts's stripSource tracks ${ nesting depth in template literals, including nested templates inside the expression (closes #2502)
  • A formatter installed only at your home directory is no longer used as a project's formatter (closes #2514)
  • prune-agent-worktrees.test.ts's R2 gitlink-corruption case no longer races a wall clock (closes #2519), and the SubagentStop orphan sweep's restrictToPath scoping is now covered end to end (closes #2501)
  • Resource-sampler scanner timeouts are recorded under their own kind, not the orphan backstop's (closes #2524)
  • Compat-smoke Layer B reads the latency log it actually wrote (fixes #2570)
  • Reject literal control bytes in tracked source (closes #2571)
  • Deflake hook-await-fold-bounds by settling its abandoned bootstrap loads (closes #2574)
  • Extend Python SQL-rule safe-builder recognition with same-file provenance (fixes #2576)
  • Run pytest in uv-managed project environments (closes #2580)
  • Resolve bundle:dist's esbuild independent of the project tree (closes #2590)
  • build:dist now avoids a network fetch for tsc when the local pinned version is already installed, while still isolating the fallback path from #2590's collision (refs #2590)
  • Workspace-member globs no longer wedge a turn on an interleaved `
  • ci-verdict.mjs gates on every check-run, not just Unit tests/Lint (closes #2609)
  • Skills
  • package.json now declares engines.node, and the managed installer no longer resolves typescript-language-server unpinned (closes #2633)
  • tests/packaging-pack-manifest.test.ts no longer writes into the developer's real ~/.pi-lens/install.log (closes #2634)
  • ast-grep / tree-sitter rules
  • Managed CSS/HTML Language Server installs no longer target dead or mismatched npm packages, and a genuine install failure is no longer silently folded into "toolchain absent" (refs #2638)
  • Infra-kill auto-rerun now covers master pushes and bot merges, not only PRs (closes #2668)
  • Tests
  • Tests
  • Install

Security

  • Scope workflow permissions per job (closes #2403)
  • An operator's LSP denial survives traffic to other project roots (closes #2518)

🙏 Thanks

Thanks to the external contributors in this release:

Don't miss a new pi-lens release

NewReleases is sending notifications on new releases.