Skip to content

Stability & agent-UX: snapshot fingerprint + headless refresh, trash-first delete, settings diagnostics - #64

Merged
scscodes merged 3 commits into
mainfrom
claude/extension-stability-ux-ubf8eu
Jul 13, 2026
Merged

Stability & agent-UX: snapshot fingerprint + headless refresh, trash-first delete, settings diagnostics#64
scscodes merged 3 commits into
mainfrom
claude/extension-stability-ux-ubf8eu

Conversation

@scscodes

Copy link
Copy Markdown
Owner

Three high-ROI, low-impact improvements to stability and the human/agent report experience.

1. Latest-snapshot contract, completed for agents (ADR 020 addendum)

  • Repo staleness fingerprint. Every .meridian/latest/*.v1.json write now stamps an optional repo: { branch, head, isDirty, staged, unstaged, untracked } captured at write time. Agents compare repo.head against git rev-parse HEAD to know whether a snapshot predates recent commits, instead of guessing from wall-clock generatedAt. Fail-soft and all-or-nothing: any failed lookup omits the field; a fingerprint failure can never lose a snapshot. Resolved through an injectable provider wired from the GitProvider at activation — latest-snapshot.ts stays vscode-free and never shells git. New GitProvider.getHeadCommit().
  • Meridian: Refresh Latest Snapshots (meridian.latest.refresh). Snapshots previously refreshed only when a human rendered a webview. The new palette command dispatches all three report commands through the router and rewrites the snapshots without opening a panel (analytics first, so the briefing reuses the warmed analyzer cache). Semantics widen from "latest = last rendered" to "latest = last computed" — still pull-only, no daemon, no LM surface (the ADR 012 posture is untouched). Reports tree freshness rows update automatically.

Both are additive within the v1 envelope. ADR 020 addendum + FEATURES.md + generated AGENTS.md template updated.

2. Trash-first file deletion

WorkspaceProvider.deleteFile was a raw fs.unlink — a mis-confirmed Delete File was unrecoverable. Deletion now routes through an injected MoveToTrashFn (vscode.workspace.fs.delete with useTrash), falling back to permanent unlink with a logged warning where the host filesystem has no trash. Path-guard and the directory refusal are unchanged and run first. Confirmation dialog wording updated to match the real semantics.

3. .meridian/settings.json misconfiguration diagnostics

Unknown keys, type-mismatched values, and malformed JSON were silently ignored — a typo'd key did nothing, forever. Each reparse (keyed to file mtime, so at most once per file change) now audits the overrides and reports findings via one line in the Meridian output channel + a logger warn. Read-time fall-through semantics unchanged (including the JSON-null "not supplied" idiom). Bonus fix: a malformed file was re-read and re-parsed on every readSetting() call; the failed parse is now cached against its mtime.

Verification

  • Full suite: 51 files / 435 tests passing (16 new tests: envelope fingerprint, headless refresh orchestration incl. failure isolation, trash-first + fallback + path-guard ordering, settings diagnostics incl. once-per-mtime and throwing-listener safety).
  • tsc --noEmit clean; npm run bundle (esbuild) clean.
  • Manifest parity test extended for the new command.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DfWfFUQrqAoH7xETXyRrtU


Generated by Claude Code

claude added 3 commits July 12, 2026 17:46
…esh command

Two additive extensions to the ADR 020 v1 envelope, completing the agent
contract:

- Every snapshot write stamps an optional repo fingerprint ({ branch, head,
  isDirty, staged, unstaged, untracked }) captured at write time via an
  injectable provider wired from the GitProvider at activation, so agents
  can compare repo.head against git rev-parse HEAD to detect staleness.
  Fail-soft and all-or-nothing: any failed lookup omits the field; a
  provider failure can never lose a snapshot. New GitProvider.getHeadCommit.

- Meridian: Refresh Latest Snapshots (meridian.latest.refresh) recomputes
  all three reports through the router and rewrites .meridian/latest/
  without opening any panel — snapshots no longer go stale waiting for a
  human to render a webview. Semantics widen from 'latest = last rendered'
  to 'latest = last computed'; pull-only, no daemon, no LM surface.

Docs: ADR 020 addendum, FEATURES.md, AGENTS.md template.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DfWfFUQrqAoH7xETXyRrtU
…manent

deleteFile was a raw fs.unlink: a mis-confirmed Delete File lost the file
permanently. createWorkspaceProvider now accepts an injected MoveToTrashFn
(main.ts supplies vscode.workspace.fs.delete with useTrash) so the provider
stays vscode-free; path-guard and the directory refusal are unchanged and
run before the trash fn. Where the host filesystem has no trash (e.g. some
remotes) deletion falls back to a permanent unlink with a logged warning,
and the confirmation dialog wording now reflects the real semantics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DfWfFUQrqAoH7xETXyRrtU
… per change

Unknown keys, type-mismatched values, and malformed JSON in the workspace
overrides file were silently ignored — a typo'd key simply did nothing,
forever. Each reparse (keyed to the file's mtime, so at most once per file
change) now audits the overrides and emits diagnostics through an
injectable listener; main.ts wires it to a logger warn plus one line in the
Meridian output channel. Read-time fall-through semantics are unchanged,
including the JSON-null 'not supplied' idiom, which stays unflagged.

Also caches a failed parse against the file's mtime — a malformed file was
previously re-read and re-parsed on every readSetting() call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DfWfFUQrqAoH7xETXyRrtU
@scscodes
scscodes marked this pull request as ready for review July 13, 2026 10:41
@scscodes
scscodes merged commit 3e667ee into main Jul 13, 2026
1 check passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.16.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants