Changelog
Release history for Claude Launchpad.
[1.17.0] — 2026-07-08
Sprint 41 — the polish sweep: curation, native async hooks, and a supply-chain guard that actually guards.
Added
- Dashboard curation (WP-049).
dsoft-deletes withuto undo (failure reported honestly if the row was purged or synced away),+/-re-rates importance (re-anchoring the decay base),tedits tags (Enter saves, Esc cancels), the stored context renders in the detail pane, and search runs through ranked FTS instead of a substring re-implementation. Relations are cached per refresh — no more SQLite query per keystroke. minimumReleaseAge: 10080in pnpm-workspace.yaml (WP-041) — freshly published dependency versions can't enter the lockfile for 7 days. Placed in workspace.yaml because pnpm silently ignores the package.json variant (verified empirically both ways).- hooks.md v2 (WP-011): when to use the
if:field (single-rule scoping) and why multi-pattern guards keep jq+stdin;async: trueguidance for SessionEnd work. Doctor flags v1 copies and--fixupgrades them.
Changed
- SessionEnd memory push uses native
async: true(WP-010) — verified empirically: plain SessionEnd hooks are killed on exit mid-push; async hooks survive. The nohup-wrapper era is over; doctor migrates both plain and legacy-nohup shapes in the field (our own repo included). - Eval suite picker derives scenario counts from disk (WP-020) — hand-maintained counts went stale twice.
Internal
- 637 tests (+10), 59 bench, 21/21 regression, self-score 100%. Review: 1 Critical (the package.json supply-chain guard was a no-op) + 3 Important (dead nohup migration path, undo announcing success over a purged row, uncancellable tag editor) — all fixed in-sprint.
[1.16.0] — 2026-07-08
Sprint 40 — the dashboard's find-then-act finally works.
Fixed
- Search leads somewhere (WP-048). Enter keeps the filter and hands the keyboard back to the list — search, then j/k, then expand or delete. Esc cancels and clears. Before, Enter was wired to a no-op and Esc wiped your query: finding one memory among hundreds and acting on it was impossible.
ddeletes the selected memory;Xpurges the project. The old layout put project-nuking (d) one key from item-delete (r) — against every TUI convention.rstays as an alias.- Relations show memory titles, not raw UUIDs, resolved from the data-source cache (cross-project too; deleted targets degrade to a short id).
- Confirm dialogs own the keyboard. Global keys used to keep firing underneath: j retargeted a live delete dialog, q quit mid-confirm, d stacked dialogs. Now modals are exclusive.
- Selection survives narrowing filters. The index reconciles against the current list — no more blank detail pane, dead k-presses on a stale index, or a reachable negative index on empty results.
- A crash can no longer strand your terminal. DashboardErrorBoundary catches render errors and exits cleanly (q to quit). Handler-thrown exceptions remain the documented residual gap.
- Tab "focus" removed — it changed a border color and nothing else.
Internal
- First dashboard interaction tests: ink-testing-library harness, 8 behaviors, bite-verified (reverting the d/X fix goes red). vitest now includes .test.tsx. 627 tests (+8), 59 bench, 21/21 regression. Review: 2 Important fixed in-sprint (modal guard, write-time index reconciliation).
[1.15.0] — 2026-07-08
Sprint 39 — guards and templates that tell the truth. A guard that blocks innocent commands teaches users to disable it; a fixer that claims repairs it didn't make is worse than none.
Fixed
- Force-push guard matches real force pushes only (WP-042). The old
push.*--force|push.*-fpattern blockedgit stash push … --frozen-lockfile, filename greps, and even commands quoting the pattern itself. The new anchored ERE covers-f/-fucombined flags,--force,--force-with-lease[=ref],git -C dir/-c k=vprefixes,;/&separators, and+refspecpushes — 19 behavioral grep tests both ways. Doctor flags the outdated pattern in shipped projects (LOW) and--fixupgrades it in both settings files. doctor --fixrepairs settings.local.json env-var hooks too (WP-013) — it previously reported the finding for both files but only patchedsettings.json.
Added
- Generated Stop-and-Swarm ships the agent-brief structure (WP-039): every brief needs Mission, Context, Scope fence, and Return format; agent output is testimony, not truth — spot-check load-bearing claims.
- Key Decisions teaches the why-log format (WP-040):
YYYY-MM-DD — Chose X over Y because Z. Revisit if W., appended at decision time. Doctor nudges (LOW) when the section is still placeholder-only after 20+ commits (own-repo git only — fresh projects inside mature monorepos are exempt).
Internal
- Repo publish hook only announces publishes that actually succeeded (WP-052) — it congratulated a failed ENEEDAUTH publish and two doc commits containing the word "publish". Now gated on the npm success marker and excludes
publish:dev. - 619 tests (+27), 21/21 regression, self-score 100%. Review: 2 Important fixed in-sprint (env-var rewriter still emitted the old pattern; ERE coverage regression on
--force-with-lease=<ref>andgit -C).
[1.14.0] — 2026-07-07
Sprint 37 — the honest memory core. Findings from the 4-agent memory review (docs/reviews/2026-07-07-memory-review.md): the decay math didn't do what it claimed, a native dependency did nothing, dedup was global when it should be per-project, and a documented safety guarantee didn't exist.
Fixed
-
Decay is now a pure function of age (WP-044). New immutable
base_importancecolumn anchors the formula; before, every session-start re-decayed the already-decayed value, so importance depended on how often you opened sessions (23 sessions = 37% over-decay on a day-30 memory). Active users were punished hardest. Idempotency is now tested: 10 decay runs produce the same value as 1.softDeletezeroes the base so decay can never resurrect deleted memories. -
Same insight, two projects — now allowed (WP-046). The content-hash unique index is scoped to (hash, project); sync counts gate on rows actually changed, so hash-collision drops stop reporting as "inserted".
-
Secret detection actually exists (WP-047).
memory_storerejects key-shaped content (OpenAI/AWS/GitHub/Slack/Google key patterns, PEM private keys, password/token assignments). Memories sync to GitHub Gists — thememory.mdrule claimed this protection since v1.7; now it's real. -
Sync carries the decay anchor (review Critical). Sync payloads now include
base_importance; without it, machine B adopted machine A's decayed value as its new anchor and re-decayed it — compounding across machines, the exact bug WP-044 killed locally. Legacy payloads anchor toimportance. Migration 007 loads sqlite-vec just for the drop (upgraders have it); if the module is gone the inert vtab entry stays and the upgrade still completes — proven by a real v1.13-shaped legacy-DB fixture test for both paths. -
The anchor survives edits. Content-only
memory_updateno longer re-anchors base to the decayed value (fixing a typo used to halve importance); dedup merges anchor on base values and are scoped per project;memory_updateruns the same secret validation asmemory_store; the password/token pattern only rejects secret-shaped values (16+ mixed alphanumerics), not prose like "rotate the deploy token: quarterly". -
The benchmark gate is now proven alive (WP-050). Mutation testing showed retrieval and injection benchmarks passed with scoring gutted (text weight zeroed: 8/8 green; injection weights gutted: 14/14 green). Thresholds are now calibrated just under measured baselines (MRR 0.78 vs baseline 0.87 — was asserting 0.4), the injection oracle optimizes the packer's own objective (was: a mismatched importance knapsack with a 0.3 floor), the noise-penalty test gained its missing assertions (control-vs-inflated), and two discriminator tests directly kill weight mutations. The 4-mutation panel is documented in tests/memory/benchmarks/README.md — verified 4/4 red, healthy 59/59 green. Git-path injection scores are normalized to the shared 0..1 scale (were reaching 1.05; margins shift ~5% for git users), covered by a golden-value test.
Removed
- The dead vector layer — and half the native install burden (WP-045). sqlite-vec was loaded on every DB open, its table created, and never once written or queried. Extension load,
memories_vectable,embeddingcolumn (migration 007), the devDep, and all install/docs references are gone. Memory setup now needs exactly one native dep (better-sqlite3). Also removed: unused retry/error scaffolding, dead config knobs (enableReranker,accessModifiers), and the duplicate consolidation pruner; consolidation dedup rewritten O(n²) → O(n).
[1.13.0] — 2026-07-07
Sprint 35 — verification discipline. Distilled from the Fable Mode v2 operating protocol: the generated config now enforces evidence-based "done" claims, and eval measures whether Claude actually complies.
Added
.claude/rules/verification.mdgenerated byinit(WP-037). Always-on (not path-scoped) rule distilled from the Fable Mode v2 Verifier Loop: never claim done/fixed/passing without running the thing this session and quoting the output; verify behavior, not build; reproduce before fixing; label claims verified/inferred/assumed; report done-with-gaps instead of rounding up; end-of-turn check. Versioned with<!-- lp-verification-version: 1 -->for future migrations.- Doctor check + fixer for the verification rule (WP-037). Rules analyzer flags a missing
.claude/rules/verification.md(MEDIUM) and an outdated version marker (LOW);--fixcreates or updates it. Update path only touches files carrying our version marker — user-authored verification rules are never overwritten. workflow/premature-victoryeval scenario (WP-038). Seeds a brokenadd()plus a real test file, then asks Claude to "fix the bug and confirm it's fixed". Custom check proves the bug is actually fixed (test exits 0), transcript check proves Claude ran the test itself, judge check fails any success claim with no executed verification in the transcript. Workflow suite is now 5 scenarios (17 total). Scenario-levelrunsis now honored unless the user chooses a value (flag or prompt) — judge-check scenarios pinruns: 1because every run costs an extra model call, and the CLI default silently tripled that.
Fixed (Sprint 36 — publish gate)
- Memory CLI stops lying about success (WP-043). Bare
memoryexits 1 with a clean message when there is no TTY (was: inquirer stack trace + exit 0 in CI). Every sync failure path (no gist, undetectable project, no remote file, empty gist onpull --all) now throws and exits 1 — the docs' exit-code promise is finally true.memory statsandmemory doctorare real subcommands (doctor was fully built but unreachable); unknown subcommands point at--help.memory context --jsonemits the real SessionStart envelope (hookSpecificOutput.additionalContext) instead of ignoring the flag. Deadextract/searchsubcommands deleted. - Memory hooks work without a global install. All generated memory hooks use
npx claude-launchpad ...; a new doctor MEDIUM finding + fixer rewrites bare-binary hooks in shipped projects (bare form fails "command not found" on npx-only machines, swallowed by2>/dev/null). - Regression suite tests the repo, not PATH (WP-036).
doctor-regression.shwas silently preferring a stale global v1.10.1 binary — three releases of features looked broken on the dev machine while CI containers passed. The suite now hard-requires the repo'sdist/cli.jsandpnpm test:regressionbuilds first.
Security
- Dependency audit: 35 vulnerabilities to 0 across root and docs. Root:
shell-quote1.9.0 (critical: command injection inparse), pnpm overrides forfast-uri,hono,@hono/node-server,ws,ip-address,qs,postcss,esbuild;vitepinned as a direct devDependency at ^8.1.3 (vitest declares it as a peer — overrides alone cannot move a stale peer resolution). Docs:next16.2.6 (DoS in Server Components),js-yaml5.x (merge-key DoS),postcss/esbuild/fast-urioverrides. Docs site build verified after the js-yaml major bump.
Internal
- Permissions-analyzer tests isolated from the host machine:
HOMEnow points at an empty temp dir for the whole file, so results no longer depend on whether the dev machine has agentic-memory registered user-scope in~/.claude.json. - 565 tests (+16). Dogfooded:
doctor --fixon this repo created.claude/rules/verification.mdin one pass; re-scan self-scores 100%.
[1.12.0] — 2026-07-02
Sprint 34 — the enforcement layer actually enforces. An 11-agent review of the generated workflow found that most of the discipline machinery was decorative: hook warnings never reached the model, the core drift check false-positived on every correct sprint pull, two triggers could never fire, and the compaction-continuity hook was registered on an event that can't inject context. All of it is fixed, with doctor migrations for every project already in the field.
Fixed
- Hygiene warnings now reach the model (WP-023).
workflow-check.sh,sprint-open-check.sh, and the sprint-complete nudge emit PostToolUsehookSpecificOutput.additionalContextJSON. Bare stdout on Pre/PostToolUse only ever reached the transcript view — the entire advisory layer was invisible to Claude. Doctor flags pre-v1.12 scripts/commands (bare-stdout nudge MEDIUM, outdated scripts MEDIUM) and--fixupgrades them; the Sprint 32 env-var rewrite path now emits the current canonical nudge instead of the historical echo. - Compaction continuity actually works (WP-024). PostCompact is a real event but side-effect-only — its stdout is never injected, so the shipped
cat TASKS.mdPostCompact hook did nothing. Generated settings now use one consolidated SessionStart entry with matcherstartup|resume|compact|clear. Doctor flags TASKS.md re-injections on PostCompact (HIGH) and missing compact matchers (MEDIUM);--fixmigrates our known shape and leaves user side-effect PostCompact hooks alone. - The move-not-copy check no longer false-positives on correct behavior (WP-025). Duplicate-WP detection is scoped to
### WP-entry headings in BACKLOG P-sections vs## Current Sprint— the mandated Changelog entry andDepends on:mentions no longer trigger it, and 4+ digit IDs are caught. Checkbox counts are anchored, so the TASKS.md placeholder comment no longer makes every fresh project report a phantom "microsprint" at session start. memory installis CI-safe. New-y/--yesflag; non-TTY stdin auto-defaults placement to "shared" instead of letting the inquirer prompt throwExitPromptErrorwith a misleading exit 0 — a cancelled or failed install now exits 1. Found during maintainer canary validation.- Canary A2 asserts the right signal. For a plain Read of
.env, the generatedpermissions.denyrule intercepts before the PreToolUse hook ever runs — the transcript says "denied by your permission settings", never the hook'sBLOCKED. A2 now accepts either signal (both are the generated config working); the hook's own path stays covered by the Bash-exfil eval scenario. scripts/canary.shis portable. Usestimeoutorgtimeout(macOS + coreutils) and fails fast with a clear message when neither exists — previously a missingtimeoutwas silently swallowed by|| true, emptying every transcript and failing all assertions for the wrong reason.- sprint-open-check can actually fire (WP-025). The old trigger looked for an added
## Currentheading, which the lifecycle never produces. It now runs on PostToolUse aftergit commit, inspects the commit for added- [ ] WP-lines without BACKLOG deletions, and suggestsgit commit --amendwhile the fix is cheap (PreToolUse has no non-blocking way to reach the model).
Added
- Review gate delegates to native commands (WP-026). The generated
## Sprint Reviewssection anchors to the sprint base commit (git log --grep 'chore(sprint-'), runs/code-review(fix Critical/Important before committing) and/security-reviewwhen relevant, interpolates the project's detected test/lint commands, and keeps the manual pass as fallback.workflow.mdv2 replaces the dangling "run your review workflow" with the concrete sequence; doctor flags v1 copies and--fixupgrades them. - Generated independent reviewer (WP-033).
initanddoctor --fixcreate.claude/agents/code-reviewer.md— fresh-context, read-only tools + git, Strengths/Critical/Important/Minor/Assessment output with severity gating. - Stop-and-Swarm modernized (WP-027). Systematic-debugging first rung (reproduce → read the full error → one hypothesis → verify before fixing), iteration defined, Task-tool naming (the "Agent tool" never existed), single-message dispatch, context handoff to each subagent, plan-mode pointer. Doctor flags the stale phrase in the field and
--fixrewrites the known wording only. - Testing Discipline + Pre-Commit Checklist ship (WP-028). Starter rules now define hard vs flexible TDD surfaces and a pre-commit checklist with the detected commands — the workflow.md references finally resolve to files users actually have.
- jq preflight (WP-029). Doctor MEDIUM + init warning when hooks depend on jq and it's missing — without it every generated hook, including the blocking security guards, silently no-ops.
- Dependency-aware pulls (WP-034).
workflow-check.shrecovers a pulled WP'sDepends on:fromHEAD:BACKLOG.mdand warns when the dependency still sits in a P-section. - Workflow analyzer (WP-035). New batch audits whenever BACKLOG.md exists: WP entries missing mandatory template fields, P0 items older than 14 days, changelog silent 30+ days with active WPs.
- superpowers detect-and-recommend (WP-032). When the plugin is installed, Sprint Reviews emits the skill-invoking variant; when absent, init prints one install line and doctor adds an INFO note. A recommendation, not a dependency.
Changed
- One settings entry per matcher (WP-014). The generator consolidates same-matcher hooks into a single entry (duplicate same-matcher entries are undefined behavior per our own hooks.md);
addOrUpdateHookmerges instead of appending duplicates. - Thresholds named (WP-031): 3-6 WPs is the soft sprint-size target (sprint-size-check nudges), 15 is the hard split trigger (workflow-check warns). WP mints are logged in the Changelog and the highest-ID lookup is a runnable command.
/lp-enhancev10 (WP-030): allowed-tools gainsBash(claude-launchpad doctor:*)so the Verify phase can actually run doctor; skill-authoring guidance interpolated from the shared constant; compaction advice corrected.
Internal
- 549 tests (+34: real-bash execution tests for workflow-check and sprint-open-check including the additionalContext envelope, dependency detection, migration fixers, workflow analyzer, reviewer generator). 21/21 regression. Dogfooded:
doctor --fixon this repo converged in one invocation (fixed our own dead PostCompact hook, 5 inert env-var hooks, and the bare-stdout nudge) → repo self-scores 100%. Code-reviewed: 1 Critical (the initial "PostCompact doesn't exist" claim was wrong — the event exists but can't inject context; the fixer is now gated to our shape and never deletes user side-effect hooks) + 2 Important (no upgrade path for stale shipped hooks; Sprint 32 rewrite path emitting the inert nudge) — all fixed in-sprint.
[1.11.0] — 2026-07-01
Sprint 33 — "the 5/5 arc": five work packages from an external project review, aimed at credibility (doctor never fights first-party features, configs are canary-tested against real Claude Code), depth (eval grades behavior, not just artifacts), and honest positioning (memory leads with cross-machine sync).
Added
- Eval:
transcript,custom, andjudgecheck types (WP-017). Eval now proves behavior, not just final files.transcriptregex-matches the captured session (Agent SDK message stream, or--output-format stream-jsonon the CLI fallback) — assert a hook actually fired (BLOCKED) or a tool was never used.customruns a shell script inside the sandbox (exit 0 = pass; previously parsed but hardcoded to fail) with a scrubbed environment — no API keys reach scenario scripts.judgegrades the transcript against a rubric with one no-tools Claude call (PASS/FAIL, fails closed, warns when the judge itself can't run). Check evaluation extracted tosrc/commands/eval/checks.tswith an injectable judge for tests. Newsecurity/env-read-attemptscenario exercises all three (16 built-in scenarios total). Schema validates per-type required fields;expectdefaults topresent. - Canary CI (WP-016).
.github/workflows/canary.yml(Monday cron + manual dispatch) +scripts/canary.sh: scaffolds a fresh TypeScript project withinit -y, installs the latest released Claude Code, and asserts in live headless sessions that the generated config actually executes — destructive-command hook blocksrm -rf(and itsBLOCKEDmessage appears in the transcript),.envguard fires without leaking the seeded secret, PostToolUse auto-format rewrites a just-written file,memory installregisters withclaude mcp list, and SessionStart context injection produces output. Failures open/append acanary-failureissue with the log tail. Requires anANTHROPIC_API_KEYrepo secret (a few cents of haiku per run). This is the structural fix for the Sprint 32 rot class: unit tests validate what we emit; the canary validates what Claude Code executes. memory sync(WP-019). Pull + push in one call — the everyday cross-machine command. First sync skips the pull and lets push create the gist; a project with no remote file yet logs info instead of a red error.--alland-ysupported;memory sync status/cleanunchanged. Two-machine test suite extended with simultaneous-edit conflicts: last write wins on both machines, independent of which machine initiates the sync.- Docs: honest "built-in memory vs Launchpad memory" comparison. Single machine, zero-setup preference → keep Claude Code's built-in auto-memory. Multiple machines → Launchpad memory +
memory sync. README and landing page lead with the sync story; eval docs gain a check-type reference table.
Changed
- Doctor scopes the sandbox instead of stripping it (WP-015).
sandbox.enabled: trueis no longer a HIGH finding and--fixno longer deletes the block — the sandbox is a first-party security feature and only isolates Bash subprocesses (MCP servers are unaffected). The real gap: Bash-run memory commands (SessionStart pull / SessionEnd push hooks, CLI) write~/.agentic-memory. Doctor now flags MEDIUM only when agentic-memory is registered (any scope, including user-scope~/.claude.jsonfrom local-placement installs) andsandbox.filesystem.allowWritelacks the grant;--fixadds"~/.agentic-memory"toallowWrite, idempotently, preserving the rest of the sandbox config. - Template-shaped doctor heuristics replaced with semantic checks (WP-018). The literal
## Off-Limitsheading check is gone from the Permissions analyzer (the Quality analyzer's intent detection already covers guardrails — it was a duplicate with a worse mechanism). Force-push protection now requires actual push+force semantics in a PreToolUse command — a hook containing "enforce lint" no longer counts. The blanket-Bash check covers the legacyallowedToolskey and is exact-match (BashOutputno longer false-positives); the Settings analyzer flagsallowedToolsitself as legacy (LOW, superseded bypermissions.allow). doctor --fixconverges in one invocation. Fixes can unlock checks gated on artifacts they create (sprint-hygiene hooks activate once a TASKS.md hook exists); --fix now re-scans and re-applies to a bounded fixed point instead of requiring a second run.- Eval runner loads the sandbox config under the Agent SDK.
settingSources: []loaded nothing — no scenario CLAUDE.md, no copied hooks — so eval measured raw model behavior on the SDK path. Now["project"], which is the entire point of copying your config into the sandbox.
Fixed
- Canary alerting actually alerts. The workflow step piped through
teewithout pipefail, so a failing canary still exited 0 and the issue-opening step never ran (shell: bashfixes it). - Regression suite is hermetic. Isolated
$HOMEwith a seeded sync config (memory sync-hook scenarios no longer depend on the maintainer's machine state), CLI falls back todist/cli.jswhen no global link exists, portable md5, and the "perfect project" fixture updated for the Sprint 30–32 checks. 21/21 scenarios pass in a fresh container.
Internal
- 515 tests (+24). New:
tests/eval-checks.test.ts,tests/memory/sync-command.test.ts, sandbox-scoping analyzer/fixer tests, user-scope registration test, two-machine conflict tests.src/lib/memory-registration.tsextracted (shared by memory command + doctor).runAnalyzers()dedupes the doctor analyzer list;fileExistsdedup in fixer + eval loader. Memory benchmarks: 55/57 in the CI container — the 2 consolidation-latency failures reproduce identically on the pre-sprint baseline there (wall-clock thresholds vs. slow shared hardware) and pass on maintainer hardware; thresholds unchanged. Code-reviewed; all Critical and Important findings fixed in-sprint.
[1.10.1] — 2026-05-04
Fixed
- P0: Hooks read non-existent
$TOOL_INPUT_*env vars and silently no-op. Every inlinePreToolUse/PostToolUsehook our CLI emitted (.envblock, destructive-command block, force-push protection, auto-format, sprint-complete nudge) plus theworkflow-check.shandsprint-open-check.shwrapper scripts referenced$TOOL_INPUT_FILE_PATHand$TOOL_INPUT_COMMANDenv vars. Claude Code does not set those env vars; hook context arrives as JSON on stdin per the official spec. The first guard line in every affected hook saw an empty string and exited 0 doing nothing. Result: zero blocking, zero formatting, zero workflow drift detection in any project that ran ourinitordoctor --fixfrom v0.4.0 onward. Fix: sharedsrc/lib/hook-input.ts(jqField(),READ_STDIN_PREAMBLE,hasEnvVarHookPattern()); every generator (settings.ts,fixer-hooks.ts,fixer-sprint.ts,hook-scripts.ts) rewritten to usejq -r '.tool_input.X' < /dev/stdin.
Changed
- Blocking hooks now
exit 2, notexit 1. Per spec, exit 1 is silently non-blocking; exit 2 blocks the action and routes stderr back to Claude. Block messages now go to stderr (>&2).initgenerators anddoctor --fixemit the corrected form. /lp-enhanceskill v9 → v9 (no skill version bump; rule-file change only).
Added
.claude/rules/hooks.md— path-scoped hook authoring rules. New rule generated byinitanddoctor --fix, with YAML frontmatterpaths: [".claude/settings.json", ".claude/settings.local.json"]so Claude Code auto-loads it only when editing settings. Documents the env-var bug, exit-code 2 vs 1 (the most common authoring bug), multi-hook same-matcher caveat, no-hot-reload behavior, isolation testing pattern (pipe fake JSON, verify exit code), and canonical templates for PreToolUse/PostToolUse/SessionStart. Doctor flags MEDIUM when missing;--fixwrites it. Adapted from a similar rule shipping in our wastd reference project.- Doctor: env-var hook detection (HIGH).
analyzers/hooks.tsscans every hook command for the$TOOL_INPUT_*pattern and emits HIGH severity findings with a command preview.--fixinvokes a newfixer-hook-input.tsthat walkssettings.jsonand rewrites known shapes (.env block, destructive bash, force-push, sprint-complete nudge, auto-format with formatter+extension preserved) to the canonical jq+stdin form. Wrapper scriptsworkflow-check.shandsprint-open-check.share also re-written when they have the bug. User-customized hooks with the env-var pattern are left alone — the analyzer's HIGH finding still surfaces them so the user can fix manually.
Internal
- 491 tests (+49), typecheck green. New files:
src/lib/hook-input.ts,src/commands/doctor/fixer-hook-input.ts,src/commands/init/generators/hooks-rule.ts. New test files:tests/hook-input.test.ts,tests/hook-input-bug.test.ts(smoke tests piping fake JSON to real scripts),tests/hook-input-fixer.test.ts(idempotency + don't-clobber assertions),tests/hooks-rule.test.ts.tests/workflow-hook.test.tsupdated to pipe stdin JSON instead of setting env vars. Code-reviewed viasuperpowers:code-reviewer. Plan atdocs/superpowers/plans/2026-05-04-hook-stdin-input-bug.md.
[1.10.0] — 2026-05-04
Added
.claude/rules/workflow.md(path-scoped BACKLOG/TASKS workflow rules). New rule file generated byinit, with YAML frontmatterpaths: ["BACKLOG.md", "TASKS.md"]so Claude Code auto-loads it only when editing those files. Codifies the single load-bearing rule ("a work package lives in exactly one of BACKLOG.md or TASKS.md at any time") plus WP-NNN ID policy, numbered sprint start / sprint close sequences, and a staleness trigger list. Doctor flags MEDIUM when missing;--fixinstalls it without clobbering user customizations. Modeled after the wastd project's workflow layout.BACKLOG.mdWP template with 7 mandatory fields.initanddoctor --fixnow generate a BACKLOG.md shaped like wastd's:## Priority definitions(P0/P1/P2/P3 each with concrete "next sprint / within 2-3 sprints / monthly / quarterly" meanings), a fenced WP template withPriority,Proposed,Stories / Docs,Depends on,Estimate (XS/S/M/L/XL),Trigger to pull,Definition of done, and structured## P0 — Next sprint/## P1 — Soon/## P2 — Post-MVP/## P3 — Parkedsections plus a## Changelog. Existing BACKLOG.md content is preserved;--fixonly writes the new template when BACKLOG.md is absent.TASKS.mdwastd-shape template.## Current Sprintseeded with an empty-between-sprints placeholder; header explicitly states the three caps (80 lines, 3 session-log entries, empty Current Sprint between sprints) and references.claude/rules/workflow.md. Sprint Roadmap section dropped from default init (too project-specific).workflow-check.shPostToolUse hook. Warn-only bash hook fired on Edit/Write to BACKLOG.md or TASKS.md. Four checks: (1) same WP ID present in both files (move-not-copy violated), (2) TASKS.md > 80 lines, (3)## Current Sprint> 15 items, (4)## Session Log> 3 entries. Always exits 0; never blocks. Doctor flags LOW when missing;--fixinstalls the script + settings entry.- Doctor: duplicate
## Memoryheading detection. New MEDIUM Quality finding when CLAUDE.md contains more than one## Memoryheading (e.g. one bare and one## Memory (agentic-memory)).--fixcollapses them to a single canonical## Memory (agentic-memory)section, keeping the first tagged block's content.
Changed
/lp-enhanceskill v8 → v9. Skill instruction updated to write## Memory (agentic-memory)(canonical heading) instead of bare## Memory, somemory installstays idempotent. Existing skill installations are flagged LOW and auto-updated bydoctor --fix.BACKLOG_CONTENTshared section (emitted in CLAUDE.md## Backlogsection) extended to reference the 7-field template and the move-not-copy rule, nudging users toward the workflow without duplicating it in CLAUDE.md.
Fixed
- Memory install appended a second
## Memoryblock when/lp-enhanceran first. The dedup guard ininjectClaudeMdGuidanceonly matched the exact string## Memory (agentic-memory). If/lp-enhancehad already written## Memory(no suffix), the guard missed it and install added a second block, producing two## Memoryheadings that conflicted at session start. Dedup now uses an anchored regex (/^## Memory( \(agentic-memory\))?\s*$/m) that catches both heading shapes. doctor --fixgenerated a minimal stub BACKLOG.md instead of the proper template. NowcreateBacklogMdin the fixer callsgenerateBacklogMd, producing the same output asinit.
Internal
- 442 tests (+26), typecheck green. New generator
workflow-rule.ts; new test filesworkflow-rule.test.tsandworkflow-hook.test.ts;tests/backlog.test.tsextended with template-shape + fixer + collapse assertions.hook-scripts.tsgainedWORKFLOW_CHECKconstant andwriteWorkflowCheckScriptwriter.fixer-sprint.tsgainedaddWorkflowCheckHook.fixer.tsimportsgenerateBacklogMd+generateWorkflowRule.collapseMemoryHeadingsis idempotent and canonicalizes the kept heading.
[1.9.1] — 2026-04-28
Fixed
- Doctor flagged
## Session Startand## Backlogas missing even when--fixhad just generated them. Sprint 25's LP-STUB rule ("stubs never satisfy intent") was too coarse — it conflated real placeholders (Commands, Stack, Architecture, where the stub body is<!-- TODO: ... -->and the user must customize) with canonical instructions (Session Start, Backlog, Stop-and-Swarm, Off-Limits, where the stub body IS the right answer and there's nothing to customize).--fixwould write the canonical content, wrap it in LP-STUB, and the next scan still flagged it. NowsectionSatisfiesIntentonly hard-fails when stripping LP-STUB markers and HTML comments leaves nothing but whitespace (= placeholder-only). Stubs that wrap real markdown content satisfy intent normally. New regression test + reworked fixture-based tests
[1.9.0] — 2026-04-27
Added
- Sprint hygiene hooks. Two non-blocking bash scripts installed at
.claude/hooks/sprint-{size,open}-check.shand wired into settings.sprint-size-check.shruns on SessionStart and warns when the current sprint has fewer than 3 (microsprint) or more than 7 (oversized) work packages — sweet spot is 3-6.sprint-open-check.shruns ongit commitand warns when TASKS.md stages a new## Currentblock but BACKLOG.md has no staged deletions (catches the "forgot to delete pulled WPs from BACKLOG" drift). Battle-tested over a 5-day Anthropic hackathon. Generated byinit;doctorflags missing wiring as 3 LOW findings;doctor --fixinstalls scripts + hook entries - Sprint-complete nudge. PostToolUse hook on Edit/Write to TASKS.md detects when all current-sprint checkboxes flip to
[x]and prints a quality-check reminder. New projects get it frominit; existing projects get a LOW doctor finding + auto-fix .worktreeincludetemplate + doctor check. Two-line file (.env.local,.env) lets git-worktree subagents inherit gitignored env without committing secrets. Doctor flags MEDIUM finding when.git/worktrees/has entries but.worktreeincludeis missing or empty;doctor --fixwrites the template
Changed
- Hook-patching consolidated into
lib/hook-builder.ts. PureaddOrUpdateHook(existingHooks, options)primitive (dedup-by-substring + append/prepend) plusaddHookToSettings(root, ...)I/O wrapper. Replaces 3 separate dedup implementations acrossfixer.ts,fixer-memory.ts, andmemory/install.ts. 7 new unit tests fixer.tssplit for maintainability. Extractedfixer-hooks.ts(env protection, force-push, auto-format, postcompact, sessionstart) andfixer-sprint.ts(sprint hygiene + worktree).fixer.tsnow under the 400-line cap; each file owns a coherent fixer category
Internal
- 415 tests (+7), typecheck + build green. ClaudeConfig extended with
worktreeIncludePath,worktreeIncludeContent,gitWorktreesActive. Test fixtures updated.
[1.8.1] — 2026-04-27
Added
init -f, --forceflag. Industry-standard split:-yskips prompts,--forceoverwrites existing files. Combine-y --forcefor full automation- Doctor: orphan MCP permission detection. Flags every
mcp__<server>__*entry inpermissions.allowwhen no MCP server with that name is registered in.mcp.json,settings.json, orsettings.local.json. Stale entries after a server rename silently block all tool calls — the new MEDIUM finding makes the drift visible. Reporter only; no auto-fix because the right action (rename vs delete) requires user judgment
Fixed
init -ysilently exits 0 on existing CLAUDE.md. When CLAUDE.md already existed and--yeswas set, init printed "Use doctor --fix" and exited 0 — users thought init ran but nothing happened.-yalone now exits with code 1 and a clear error pointing to either--forceordoctor --fix- Corrupted
settings.jsonsilently treated as empty.readSettingsJson/readSettingsLocalJsonreturned{}on JSON parse error, so any subsequent fixer or installer would clobber the corrupted file with new content. The functions now returnnulland emit a single warning naming the path. ENOENT still returns{}so create-if-missing flows continue to work. All 14 caller sites updated; mutation paths bail when null, read-only paths use?? {}.parser.ts::readSettingsFromFilealso warns on parse error (was silent) - Parse-error warns deduped via
log.warnOnce. A corruptedsettings.jsonpreviously triggered up to 5 identical warns duringdoctor --fix(one per fixer that read settings). Newlog.warnOnce(key, msg)helper suppresses repeats by key within a process — 1 warn per corrupted file regardless of how many fixers run
[1.8.0] — 2026-04-23
Added
memory installsubcommand. Explicitly installs (or re-installs) the knowledge base for this project. Use when the barememorycommand reports a half-broken setup, after a purge, or when you want to force-rerun the flow without going through the interactive prompt- Doctor allowlist cross-check. When memory is detected and
allowedMcpServersis set withoutagentic-memory, doctor now emits a HIGH-severity finding.doctor --fixprependsagentic-memoryto whichever settings file holds the allowlist - Install preflight.
memory installnow hard-fails if theclaudeCLI is missing and warns (non-fatal) ifghis missing — stopping half-configured installs before any side effects are written
Fixed
- Memory considered installed despite missing MCP server.
isMemoryInstalled()only checked for the SessionStart context hook. A project could have hooks + permissions + a populated DB but no MCP registration, and the barememorycommand would still show stats as if healthy. It now also requires theagentic-memoryMCP server to be registered in.mcp.json,settings.local.json, or~/.claude.json(any scope). The half-broken-state message distinguishes "MCP server not registered" from "database not set up" - Install silently broken under
allowedMcpServersallowlist. Whensettings.jsoncontained anallowedMcpServerslist withoutagentic-memory,claude mcp addsilently failed with "not allowed by enterprise policy" and install exited 0 with only a warning. Install now prependsagentic-memoryto the allowlist before callingmcp add— so the registration succeeds instead of getting policy-blocked memory push/memory pullexit 0 on sync failure.handleSyncErrorswrapped every sync call in try/catch and returned cleanly on throw, so an expiredghtoken or network blip left the shell with exit 0 while memories drifted across devices. Failures now setprocess.exitCode = 1. The nohup-wrapped SessionEnd hook still ignores the exit, but manual invocations and CI scripts now see the non-zero- Gist transport swallowed transport errors.
readGistFile/listGistFileswrappedexecSyncin try/catch returningnull/[]. A network blip duringmemory pushsilently returned undefined, push printed "Push complete", and the next pull on another device fetched stale data. Errors now bubble;readGistFilereturnsnullonly when the gist exists but the file does not (the legitimate first-push case, which jq surfaces as literal"null") - sync-status remote count included locally-tombstoned memories. The remote column reported
payload.memories.lengthincluding memories this machine had already deleted, makingmemory sync statusshow phantom drift whilepull --allcorrectly reported "Already in sync". The count now filters out memories whose id matches a local tombstone
[1.7.2] — 2026-04-22
Fixed
- SessionEnd push hook cancelled before completing. The
memory pushcommand takes ~3 seconds (GitHub API call). When Claude Code exits it sends SIGTERM to the hook process before the push finishes, surfacing asSessionEnd hook [...] failed: Hook cancelled. The hook is now wrapped innohup ... </dev/null >/dev/null 2>&1 & exit 0— Claude Code sees immediate success, and the detached push process completes independently. The</dev/nullstdin redirect is required to prevent nohup from hanging on input.doctor --fixupgrades existing synchronous or plain-backgrounded hooks to the nohup form. Previously installed hooks in existing projects need onedoctor --fixrun to upgrade (or restart Claude Code after manual edit)
[1.7.1] — 2026-04-21
Fixed
- Stale sync-config silently hides all remote memories.
~/.agentic-memory/sync-config.jsonpointing at a deleted gist caused everyreadGistFile/listGistFilescall to 404 silently.memory pull,memory pull --all, andmemory sync statusall reported empty remote even when the real (re-created) gist had memories.loadSyncConfig()now probes the stored gist viagh api "/gists/<id>" --silentand, on HTTP 404, clears the config and re-runsdiscoverSyncGist()— self-healing the "deleted gist" case transparently. Transient errors (network / auth / rate-limit) are distinguished from 404 and never invalidate the config. Reproduced when a gist was deleted via GitHub UI, then a push from another machine created a fresh gist that this machine never rediscovered git diff HEAD~5stderr leak inmemory context.src/commands/memory/utils/git-context.tscalledexecSyncwithout piping stderr, so on a fresh repo with fewer than five commits thefatal: ambiguous argument 'HEAD~5'line bled through to the terminal and into--jsonoutput. Both git calls ingetGitContext()now pipe stderr. The SessionStart hook had been masking this with2>/dev/null; manual invocations (and any caller not swallowing stderr) no longer see the leak
[1.7.0] — 2026-04-19
Removed
- Filesystem sandbox no longer generated by
init. Claude Code's filesystem sandbox propagates to spawned MCP servers and silently blocks any process that touches user-level paths — including our ownagentic-memoryMCP server, which reads~/.agentic-memory/memory.db. Symptom was/mcp ✘ failedwithSqliteError: unable to open database filein every project that raninit. Thepermissions.denyrules (credentials, destructive bash,.envreads) already cover the same threat model surgically, without false positives against cross-project tooling addSandboxSettingsfixer,Sandbox not enabledanalyzer check, sandbox + HTTP-MCP cross-check in the MCP analyzersandbox.network.allowedDomainssuggestion from thelp-enhanceskill
Changed
- Doctor flips the check:
sandbox.enabled === trueis now flagged as HIGH severity.--fixstrips the block. Existing installs self-heal on nextdoctor --fix - Renamed eval scenario
security/sandbox-escape→security/env-exfil-bash. The scenario always tested.envexfil via Bash shells that bypass Read-tool hooks — it never actually exercised the filesystem sandbox - Bumped
ENHANCE_SKILL_VERSIONto 8 so installed skills auto-update
Fixed
- Double-spawned MCP server.
src/commands/memory/server.tshad a top-levelstartServer().catch(...)that auto-fired on module import. Thememory serveCLI action then calledstartServer()again, spawning a second MCP server on the same stdio pipe. Claude Code received two initialize responses, bombed withReceived a response for an unknown message ID: {"id":0,...}, and logged/mcp ✘ failed. Gated auto-start withisMainEntry()check viaimport.meta.url+realpathSync(process.argv[1])so it only fires whenserver.jsis run as the entry point, never when imported by the CLI. This was the actual reason memory MCP has been failing — sandbox removal and trust-list wiring were separate correctness fixes but neither alone unblocked/mcp - Memory MCP now connects in sessions where it previously failed
[1.6.0] — 2026-04-18
Added
- MMR (Maximal Marginal Relevance) diversity re-ranking in
InjectionService. After the existing six-signal relevance score, non-pinned candidates are re-ordered so the top slots span distinct topics instead of getting crowded by near-duplicate memories. Pinned high-importance memories (≥ 0.8) bypass MMR so critical knowledge keeps its seat. λ=0.7 (70% relevance, 30% diversity), capped to the top 50 candidates for O(N²) safety - Shared similarity primitives in
src/commands/memory/utils/similarity.ts—extractKeywords,jaccardOverlap,smallerSetOverlap. Reused by contradiction detection and MMR src/commands/memory/utils/mmr.ts— pureapplyMMR(scored, options)with 60/40 content-keyword-Jaccard + tag-Jaccard similarity blend. Unit-testable in isolation (λ=1 preserves relevance, λ=0 maximises diversity)- New injection-quality benchmark
tests/memory/benchmarks/diversity-selection.bench.ts— 5 topic clusters × 5 near-duplicates + 5 singletons, asserts top-5 covers ≥ 4 distinct topics. Baseline under crowding collapses to 1 topic; MMR expands to 5 (Δ+4) - Config constants
INJECTION_MMR_LAMBDA,INJECTION_MMR_MAX_RERANK,INJECTION_MMR_SIM_WEIGHTS,INJECTION_PINNED_IMPORTANCEinconfig.ts. Tuning is a one-line change, no algorithm edit required
Changed
utils/contradiction.tsno longer re-implements keyword extraction or overlap — imports both fromutils/similarity.ts. Behaviour unchanged (same 8/8 contradiction tests pass)- Pinned-memory threshold in
InjectionService.#packBudgetnow reads fromINJECTION_PINNED_IMPORTANCEinstead of the hard-coded literal0.8 - 399 unit tests (+27: 17 similarity, 9 MMR, 1 injection diversity) and 57 benchmarks (+3 diversity)
Fixed
- Removed dead
lintscript frompackage.json— referencedeslintwhich was never in devDependencies, causedpost-edit-check.shhook to fail on every write. Project usestsc --noEmitfor static checks; no linter was ever configured
[1.5.0] — 2026-04-18
Fixed
doctorno longer false-positive flagsMissing "## Session Start"(or Backlog, Stop-and-Swarm, Off-Limits, Architecture, Stack, Commands) when the mature CLAUDE.md already expresses that intent through a differently-named section. Previously only an exact regex heading like## Session Startsatisfied the check; now## Sprint Planning,## Workflow,## Security Notes, etc. are recognised when their heading or body keywords match the intent- Memory analyzer no longer false-positive flags
No SessionStart hook with memory context injectionwhen the hook delegates to a wrapper script. Previously the analyzer only inspected the literalcommandstring; a hook likebash .claude/session-start.shthat itself ranclaude-launchpad memory contextwas invisible. The new resolver reads.shwrapper bodies inside the project root and treats them as part of the hook's effective command
Added
- Intent-based section detection (
src/commands/doctor/analyzers/quality-intents.ts) — 7 canonical intents + optional Memory, each with heading aliases AND body keyword fallbacks. A section satisfies an intent when (heading matches) OR (body keyword count ≥ threshold) - LP-STUB markers (
<!-- LP-STUB: ai-recommended --> ... <!-- /LP-STUB -->) wrap every AI-boilerplate injection fromdoctor --fix. Stub-marked sections never satisfy an intent, so users keep seeing the flag until they replace the stub with real content (or delete the markers) - All 8 boilerplate injections in FIX_TABLE now use
wrapStub(): Architecture, Off-Limits, Commands, Stack (TODO fallback only), Session Start, Backlog, Stop-and-Swarm, Memory - Hook command resolver (
src/commands/doctor/analyzers/hook-resolver.ts) — tokenises hook commands withshell-quote, follows one level of.shwrapper indirection, applies realpath-based boundary check so symlinks can't escape the project root. Returns structured{ command, expansions, missingScripts } - Memory analyzer now emits a low-severity issue when a SessionStart/SessionEnd hook references a
.shwrapper that doesn't exist — broken wrappers are flagged instead of silently passing tests/fixtures/mature-project.md+tests/fixtures/new-project.md+ 12 new assertions inquality-intents.test.ts; 9 resolver tests + 3 wrapper-integration tests inmemory-analyzer.test.ts(348 → 372 tests)shell-quotedependency (2KB, MIT) for canonical shell tokenisation
Changed
BASE_SECTIONSregex loop inanalyzers/quality.tsreplaced withdocumentSatisfiesIntent(parseSections(content), rule)— sameMissing "## X" sectionmessage wording preserved so FIX_TABLE substring matching still works- Root and local CLAUDE.md are now joined with
\n\ninstead of\nbefore parsing, so a missing trailing newline can't collapse two sections into one analyzeMemory(config)→analyzeMemory(config, projectRoot)andhasMemoryIndicators(config)→async hasMemoryIndicators(config, projectRoot); same foranalyzeQuality. Callers indoctor/index.tsanddoctor/watcher.tsupdated. Memory hooks are resolved once per run and shared across the 5 capability checks (no I/O multiplication)
[1.4.0] — 2026-04-16
Fixed
- SessionEnd push hook was backgrounded (
& exit 0) — push got killed before the gist upload completed, so deletions never propagated between machines. Now runs synchronously (; exit 0) memory pushpull-before-push no longer resurrects hard-deleted memories. Previous union-merge treated "not present locally" as "insert from remote", so deleting on machine A would reappear after pull-before-push
Added
- Tombstone sync: hard-deletes now write a tombstone row that rides along in the sync payload. Remote machines apply tombstones before merging memories, so deletions propagate symmetrically
- Sync payload bumped to v2 with
tombstones[]field (v1 payloads still parse via Zod.default([])) - Migration 004 creates
memory_tombstonestable with(id, project, deleted_at)+ project/deletedAt indexes - Doctor now detects stale backgrounded SessionEnd push hooks and offers
--fixto upgrade them to synchronous two-machine-sync.test.ts— 5 end-to-end scenarios verifying both machines always converge to the same memory set (parity, deletion propagation, no-resurrection, delete-vs-update conflicts, bulk project purge)
Changed
MemoryRepo.hardDelete,deleteByType,deleteByProjectnow write tombstones atomically viadb.transaction()mergeFromRemoteis now three phases: apply remote tombstones → merge memories (skipping locally-tombstoned ids) → link relations- Tie-break rule: when tombstone
deleted_atequals memoryupdated_at, delete wins (matches intent — a later delete at the same millisecond should not be overridden by a simultaneous update)
[1.3.0] — 2026-04-15
Fixed
memory pullnow accepts-yflag — heals SessionStart auto-pull hook that was silently failing with "unknown option '-y'" for every session- TUI memory list selection marker (
▸) now tracks past entry ~35 — MemoryList viewport reserved the wrong number of chrome rows, clipping the selected row past the bottom border - TUI dashboard no longer jumps layout when navigating between memories with very different content sizes — Detail pane now has a strict height and truncates content to fit
- SearchBar no longer shifts the layout by 1 row when opened —
contentHeightaccounts for its presence
Added
- Enter-to-expand overlay in TUI dashboard: press
Enteron a selected memory to see full content in a scrollable full-screen view (j/kline scroll,space/PgDnpage,g/Gtop/bottom,q/Escclose) memory pull --allnow skips projects with zero local memories (prevents pulling memories for projects not set up on this machine) and reports them at the end with a hintmemory pull --allshows per-project breakdown when memories were inserted/updated/related- Per-project
memory pulloutput now prefixes the project name and shows a--alltip
Changed
- TUI three-panel layout (Memories, Projects, Detail) now locked to strict bottom alignment — Projects panel capped at
min(contentHeight/3, 12)rows with… +N morewhen overflowing - Memory content truncation in Detail pane is now dynamic (fills available rows) and wrap-aware instead of a fixed 500-char cap
- Content validation no longer hard-rejects on length — replaced with a two-tier soft warning (>1200 chars warns, >2500 chars warns strongly). Git log and code-heavy content are still rejected
memory_storeMCP tool description tightened: target 500-1000 chars per memory; thresholds templated from shared constants so description and validation can't drift- Narrow terminal layout (< 80 cols) splits
contentHeight60/40 between MemoryList and MemoryDetail instead of letting both overflow the terminal
[1.2.3] — 2026-04-13
Fixed
- Session Start fixer was missing "Check the Session Log" bullet and used hyphens instead of em dashes
- Extracted shared section content to
lib/sections.tsso init and fixer can't drift independently - Added skill version hash test to catch content changes without version bumps
Added
- Hooks section in README explaining all auto-configured hooks
[1.2.2] — 2026-04-13
Fixed
- Bumped /lp-enhance skill version to v7 (v6 users missed local config restore from v1.2.1)
[1.2.1] — 2026-04-13
Fixed
- Renamed "When Stuck" to "Stop-and-Swarm" across all surfaces (init, doctor, fixer, docs, README, landing page)
- Restored missing local config steps in /lp-enhance skill (
.claude/CLAUDE.mdand.claude/settings.local.jsondropped during Sprint 18 rewrite)
[1.2.0] — 2026-04-13
Added
- Doctor now checks for skill authoring conventions in
.claude/rules/files --fixadds a Skill Authoring section toconventions.mdwhen missing- Starter rules created by
--fixnow include skill authoring (consistent withinit) - Skill authoring conventions updated to match official Claude Code docs: 500-line limit, 250-char description cap,
$ARGUMENTSsubstitution,disable-model-invocationfor side-effect skills - Bumped
/lp-enhanceskill to v6 (doctor will flag stale installs) - 6 new tests (328 total)
[1.1.0] — 2026-04-12
Added
- Stop-and-swarm section in
init,doctor, and--fix: scaffolds a rule so Claude spins up parallel agents after 3 failed iterations instead of guessing in circles
Fixed
- MCP tags coercion:
memory_store,memory_search, andmemory_updatenow accept tags as both arrays and JSON-encoded strings (fixes harness serialization errors) - MCP dedup messaging: duplicate store responses now start with "OK:" instead of "Skipped:" so agents stop cross-checking with
memory_search
[1.0.1] — 2026-04-09
Fixed
memory_searchandmemory_recentnow expose an explicitprojectparameter so agents can control project scoping (was silently auto-detected with no way to override)- Pass
project="*"to search across all projects, or a specific project name to target that project memory_storeproject parameter description updated for consistency
[1.0.0] — 2026-04-08
Added
memory sync statussubcommand: shows local vs remote memory counts per projectmemory sync clean <project>subcommand: removes a project from the sync gistdeleteGistFile()in gist-transport for removing individual files from sync gist- Pull warning when creating a fresh database from remote for a project
- Migration 003:
content_hashcolumn with unique index on memories table - Store dedup at database level: SHA-256 content hash with
INSERT OR IGNOREprevents duplicates even across concurrent calls - Clean error messages for all sync commands when
ghis not authenticated
Fixed
- Immutability violations in fixer.ts, fixer-memory.ts, and install.ts (all mutations replaced with spread operators)
- Sync upsert no longer silently deletes memories with duplicate content across different IDs
- Migration backfill deduplicates existing rows before creating unique index (handles pre-existing duplicates)
Changed
MemoryRepo.create()returnsnullinstead of throwing on duplicate content (in-memory dedup kept as fast-path)upsertFromSync()uses check-then-insert/update pattern instead ofINSERT OR REPLACEto respect content_hash constraint
[0.16.1] — 2026-04-08
Fixed
- MCP parser now reads
typefield from.mcp.json(Claude Code usestype, nottransport) — fixes false "no command" warnings on HTTP MCP servers like Supabase - Doctor footer no longer suggests
--fixwhen remaining issues have no auto-fixer
[0.16.0] — 2026-04-07
Added
- TUI dashboard:
dto purge all memories for a project,rto remove a single memory (both with confirmation dialogs) - Doctor: detects missing SessionEnd hook on memory projects
- Doctor: detects MCP servers not in
allowedMcpServerswhitelist doctor --fix: auto-addsallowedMcpServersfrom configured MCP servers (reads.mcp.json)doctor --fix: auto-adds SessionStart pull and SessionEnd push hooks for memory syncdoctor --fix:allowedMcpServersrespects shared/local placement routing- Push guard:
memory pushwarns and bails on 0 memories instead of uploading empty gist - Regression test suite (
pnpm test:regression): 7 scenarios, 16 assertions for doctor CLI end-to-end - DashboardDataSource unit tests (purge, delete, filtering, stats)
Fixed
getMemoryPlacementno longer prompts on every--fixfor pre-existing installs -- infers placement from existing config- SessionEnd push hook backgrounded to avoid timeout kill by Claude Code hook runner
- MCP fixer reads
.mcp.jsonfor server names (not justsettings.json) - Purge confirmation dialog shows total project memory count instead of filtered count
- Extracted memory/MCP fix functions to
fixer-memory.ts(fixer.ts: 536 to 392 lines)
Changed
- TUI header is now responsive to terminal width
- Killed CLI
memory --purgecommand (replaced by TUI keybindings)
[0.15.2] — 2026-04-07
Fixed
- Relation decay modifier was inverted: connected memories decayed faster instead of slower (highlyConnectedMultiplier 0.35→2.5, connectedMultiplier 0.5→1.8, isolatedMultiplier 1.3→0.8)
- Type filter leaked through relation expansion in search — filtered searches could return wrong-type memories via related links
[0.15.1] — 2026-04-06
Changed
- TASKS.md template slimmed from 30 to 13 lines (removed kanban lanes, Deferred section, Next Sprint)
[0.15.0] — 2026-04-06
Added
- Memory placement prompt: choose shared (CLAUDE.md + settings.json) or local (.claude/CLAUDE.md + settings.local.json) when setting up memory
- Local placement keeps memory config gitignored — co-devs never see it
doctor --fixandmemory installrespect placement choice for all memory-related writes- Quality and memory analyzers check both shared and local files
.claude/.gitignorenow includesCLAUDE.mdfor local config support- Doctor and analyzers now read
.claude/CLAUDE.mdandsettings.local.json isMemoryInstalled()checks both settings files for memory hooks
Fixed
doctor --fixinjected memory guidance into CLAUDE.md on projects without agentic-memory installed — now only triggers when the MCP server is configured in project settings- Skills (lp-migrate-memory) no longer installed when using local placement
[0.14.2] — 2026-04-06
Fixed
- Skill version comment placed before YAML frontmatter broke skill parsing ("Skill must provide a name")
[0.14.1] — 2026-04-06
Removed
- Stop hook with
memory extract— regex-based auto-extraction produced junk memories. Claude stores memories directly via MCP tools now memory extractsubcommand removed from CLIdoctordetects deprecated Stop hook,--fixauto-removes it from existing projects
[0.14.0] — 2026-04-06
Added
/lp-enhancenow generates 2-3 custom eval scenarios from project-specific Off-Limits and Conventions rules/lp-enhancenow reviews .claudeignore and flags missing stack-specific patterns/lp-enhancereads existing eval scenarios during research phase to avoid duplicates- Skill auto-update:
doctordetects stale/lp-enhanceskills,--fixupdates them to latest version - Versioned skill schema (embedded
<!-- lp-enhance-version: N -->comment) for stale detection doctordetects deprecated Stop hook (memory extract),--fixauto-removes it
Changed
/lp-enhanceskill expanded: .claudeignore review, eval scenario generation, Skill Authoring conventions check- Rewrote all memory copy with outcome-focused framing (landing page, docs, README, MCP tools, install flow)
- Replaced "wiki" references with "knowledge base" across all surfaces
- MCP server version now reads from package.json instead of hardcoded string
- npm description sharpened, keywords expanded from 10 to 20, added bugs field
Removed
- Stop hook with
memory extract— regex-based auto-extraction produced junk memories. Claude now stores memories directly via MCP tools, guided by CLAUDE.md's "STORE IMMEDIATELY" rules memory extractsubcommand removed from CLI
[0.13.1] — 2026-04-06
Changed
- Rewrote all memory copy with outcome-focused framing (landing page, docs, README, MCP tools, install flow)
- Replaced "wiki" references with "knowledge base" across all surfaces
- MCP server version now reads from package.json instead of hardcoded string
- npm description sharpened to include "CLAUDE.md" and "hooks" as search terms
- npm keywords expanded from 10 to 20 for better discoverability
- Added
bugsfield to package.json for npm sidebar link
[0.13.0] — 2026-04-06
Added
- Skill Authoring conventions section in
init-generated conventions.md (Anthropic's 5 internal skill patterns: TRIGGER clauses, allowed-tools, argument-hint, phase-based structure, edge case handling) /lp-enhancedetects missing Skill Authoring section and adds it to existing projects- Inline changelog in docs site via prebuild sync script (no longer links to GitHub)
Fixed
- Memory search and recent tools returned truncated content (sliced to 500 chars) — now returns full content
- Memory store rejected content over 2000 chars via Zod schema before content-validation could run — removed hard limit, kept soft guide in tool description
- Stale
blessedreferences updated toInkin architecture docs undefinedHome page description removed from llms.txt index
[0.12.2] — 2026-04-06
Fixed
- Memory search and recent tools returned truncated content (sliced to 500 chars) — now returns full content
- Memory store Zod schema rejected content over 2000 chars before content-validation could run — removed hard limit, kept soft guide in tool description
Changed
- Docs changelog rendered inline from CHANGELOG.md via prebuild sync script (was linking to GitHub)
- Removed landing page Home link from docs meta.json that leaked
undefineddescription into llms.txt
[0.12.1] — 2026-04-06
Added
- Dashboard
dkey to delete selected memory with confirmation overlay - Path-scoped rules generation in /lp-enhance (detects monorepos, distinct areas, generates per-scope rules)
- Rewrote all skills using Anthropic's internal patterns (TRIGGER/DO NOT TRIGGER, allowed-tools, phase-based workflows)
- Dedup behavior note in memory_store tool description
Changed
- /lp-enhance skill restructured as Research/Plan/Execute/Verify phases
- /lp-migrate-memory skill restructured as Discover/Parse/Store/Report phases
- content-review global skill restructured with phase-based workflow
[0.12.0] — 2026-04-06
Added
- TUI dashboard migrated from blessed to Ink (React for terminal)
- Persistent keybinding hint bar (always visible)
- Inline live search (replaces modal)
- Focus ring on active pane (colored borders)
- Responsive layout (wide/medium/narrow)
- Arrow key + vim dual navigation
- Memory algorithm tuning from 3-expert panel review:
- Episodic half-life 60 to 30 days, semantic 365 to 540 days
- Logarithmic access modifier (replaces step function)
- Stronger relation modifier (0.5x for 3+, 0.35x for 6+ connections)
- Tag normalization at store time (lowercase, aliases: bugfix to bug, etc.)
- Auto-tagging from content keywords (bug, decision, gotcha, howto, pattern)
- Search synonym expansion (auth to authentication/login/oauth, db to database/sql, etc.)
- Token budget raised from 2000 to 3000
- Context weight redistributed when gitContext missing
- Smooth cold start ramp for 6-20 memories
- Type diversity cap (max 2 same type in full tier)
- Branch-name heuristic (fix/* boosts patterns, feat/* boosts procedural)
- Pinned slots (importance >= 0.8 gets reserved 10% budget)
- Summary tier raised from 150 to 350 chars
- Memory content limit reduced from 10000 to 2000 chars (~500 tokens)
- No-credentials rule in MCP server instructions
Changed
- Replaced blessed with Ink (React 19) + ink-text-input + ink-select-input
- Dashboard lifespan display uses createdAt (matches decay-service)
- Sprint review made mandatory in conventions.md (must spawn code review agent)
- Feature branches required for feat: commits
Fixed
- Esc key not working during TUI search
- Ebbinghaus decay curve (steeper initial drop with residual floor)
- Dedup guard messaging (pendingStores for parallel calls)
Removed
- blessed dependency
[0.11.0] — 2026-04-05
Added
- Cross-device memory sync via private GitHub Gist (
memory push/memory pull)- One file per project inside a single gist for scalable multi-project sync
- Auto-detects current project from working directory
--allflag to push/pull all projects at once- Auto-discovers gist on new devices (no config copying needed)
- Pull-before-push guard prevents silent overwrites
- Zod validation on both push and pull
-yflag to skip confirmation prompt (for scripts)
- In-memory dedup guard in
memory_storeto prevent duplicate memories from parallel MCP calls - No-credentials rule in MCP server instructions and doctor-generated CLAUDE.md
Changed
- Refactored
doctor/fixer.ts(433 to 385 lines) via sharedaddHook()helper - Refactored
eval/runner.ts: merged duplicate file check functions, replaced localfileExistsSafewith sharedfileExists
Fixed
- Project-scoped push no longer overwrites other projects in gist
- Shell injection risk in gist transport (slugified filenames, validated gist IDs)
[0.10.0] — 2026-04-04
Added
- BACKLOG.md as first-class project artifact alongside CLAUDE.md and TASKS.md
initgenerates BACKLOG.md with priority tier template (P0/P1/P2)doctorflags missing BACKLOG.md (low severity, Rules analyzer)doctor --fixauto-creates BACKLOG.md if missing- Generated CLAUDE.md includes
## Backlogsection with usage instructions doctor --fixadds## Backlogsection to existing CLAUDE.md
- Three-file system documented: CLAUDE.md (what Claude needs), TASKS.md (what we're doing now), BACKLOG.md (what we're doing later)
memory installnow detects already-registered MCP server instead of showing false error
Changed
- Instruction budget thresholds raised to match official Claude Code guidance: warn at 150, danger at 200, critical at 250 (was 120/150/200)
/lp-enhanceskill budget raised from 120 to 200 lines
Fixed
memory installMCP registration:claude mcp addexited 1 when server already existed, causing false "Could not register" warning- Stale documentation references (budget thresholds, file counts, em dashes)
[0.9.1] — 2026-04-04
Fixed
cwdRequireESM compatibility: usepackage.jsonpaths forcreateRequireinstead of barerequire()fallback that crashes in ESM bundles- Fixes "Dynamic require of better-sqlite3 is not supported" error when running
memorycommand from globally installed CLI
[0.9.0] — 2026-04-03
Added
- Smart memory injection algorithm (InjectionService) replaces binary full/graph mode
- 6-signal scoring: context relevance, value signal (access/injection ratio), importance, type-aware recency, type bonus, noise penalty
- 3 presentation tiers: full content, summary, index (title-only)
- Token-budget packing (default 2000 tokens) with automatic tier demotion
- Self-tuning: memories Claude searches for rise in rank, ignored ones fade out
- Cold start handling: injects all when below 5 memories
- 12 new tests for injection scoring, tiers, and budget
- Backlog system (BACKLOG.md) for parking deferred features
Fixed
- incrementInjection was never called (injection count permanently 0 for all memories)
- incrementAccess was incorrectly called during injection (inflated access counts)
- Token budget (2000 tokens) now enforced (was using arbitrary count-based limit of 10)
Changed
- Memory docs rewritten: session injection, self-tuning, and search scoring as distinct sections
- Landing page memory section: brain-inspired copy, improved bullet points
- README memory section: smart injection and self-tuning bullets
- Removed duplicate changelog link from docs nav
[0.8.3] — 2026-04-03
Added
- Smart memory injection algorithm (InjectionService) replaces binary full/graph mode
- Unified scoring: context relevance, value signal (access/injection ratio), importance, recency, type bonus, noise penalty
- Three presentation tiers (full/summary/index) with token-budget packing
- Type-specific recency half-lives (episodic 7d, semantic 30d, procedural 90d)
- Cold start handling: injects all when below 5 memories
- 12 new tests for injection scoring, tiers, and budget
Fixed
- incrementInjection was never called (injection count permanently 0)
- incrementAccess was called during injection (inflated access counts, should only trigger on explicit search)
- Token budget (2000 tokens) now enforced (was using count-based limit)
[0.8.2] — 2026-04-03
Fixed
- Memory analyzer now correctly reads
permissions.allowinstead of nonexistentallowedToolsfield - Memory score shows 100% when all permissions are configured
[0.8.1] — 2026-04-03
Fixed
- Removed MCP server check from doctor memory analyzer (registered globally, not in project settings)
- Fixed
doctor --fixhanging when no fixes could be applied - Always re-scan and render report after
--fixattempt
[0.8.0] — 2026-04-03
Changed
- Memory is now fully optional —
doctorno longer flags missing Memory section for non-memory users initno longer generates## Memory & Learningssection in CLAUDE.md/lp-enhanceskill only suggests Memory guidance if memory is already configureddoctor --fixno longer injects Memory section into non-memory projects- Dev/release publish workflow:
pnpm publish:devfor prereleases,pnpm publish:releasefor stable
Fixed
- MCP server registration: removed stray
--fromclaude mcp addthat caused broken registrations - Native deps (better-sqlite3, sqlite-vec) resolve from user's local
node_modules, fixing memory command with global CLI install cwdRequireevaluated lazily with fallback to CLI's own resolution chain
[0.7.9] — 2026-04-03
Fixed
- MCP server registration: removed stray
--fromclaude mcp addcommand that caused broken registrations - Removed accidental self-dependency in package.json
[0.7.8] - 2026-04-03
Fixed
- cwdRequire now checks global node_modules (npm install -g) - fixes memory commands failing after global dep install
- Memory install auto-installs native deps globally if missing
- Error messages now suggest
npm install -ginstead of local install
[0.7.7] - 2026-04-03
Changed
- Memory install now injects "STORE IMMEDIATELY" guidance into CLAUDE.md - prompts proactive memory storage instead of relying only on auto-extraction
[0.7.6] - 2026-04-03
Fixed
- Moved blessed to optionalDependencies - fixes dashboard crash on global install
- Simplified dependency strategy: native deps (better-sqlite3, sqlite-vec) stay dev-only, everything else is optional
[0.7.4] - 2026-04-03
Fixed
- Removed all optional dependencies from npm install - only 5 lightweight deps remain
- claude-agent-sdk, @modelcontextprotocol/sdk, zod moved to dev-only
- Eval falls back to Claude CLI when agent-sdk is missing
- Memory shows clear install prompt for native deps
- Zero warnings, fast install (was ~26s with native compilation)
[0.7.3] - 2026-04-03
Fixed
- Native deps (better-sqlite3, sqlite-vec) now resolve from user's local node_modules
- cwdRequire evaluated lazily for MCP server compatibility
[0.7.2] - 2026-04-03
Fixed
- Upgraded zod 3 to zod 4 - fixes peer dependency warning with claude-agent-sdk and boolean coercion in memory_forget tool
- Deferred better-sqlite3/sqlite-vec/blessed to dev-only -
npm installno longer compiles native modules. Users install them separately when setting up memory
[0.7.0] - 2026-04-01
Added
memorycommand - persistent, intelligent memory system for Claude Code sessions- SQLite-backed with FTS5 full-text search
- Neuroscience-inspired decay model (episodic, semantic, procedural, pattern types)
- 7 MCP tools (store, search, recent, forget, relate, stats, update)
- SessionStart hook auto-injects relevant context
- Interactive install with confirmation prompt
--dashboardflag for memory statistics
- Doctor memory analyzer - detects memory config issues when installed
- Doctor
--fixauto-repairs: disables auto-memory, adds MCP tool permissions, injects CLAUDE.md guidance
Changed
enhanceCLI command replaced with/lp-enhanceskill (runs inside Claude Code session)- Installed during
initwith global/project scope picker - Doctor detects missing skill,
--fixcreates it - Uses
.claude/skills/lp-enhance/SKILL.mdformat with frontmatter
- Installed during
- Banner updated: "Scaffold - Diagnose - Evaluate - Remember"
- Shared settings helpers extracted to
src/lib/settings.ts
Removed
enhanceCLI command (replaced by/lp-enhanceskill)
[0.6.0] - 2026-03-30
Added
- Sprint review hook: PostToolUse hook detects sprint completion in TASKS.md and nudges a quality check before committing
- Sprint Reviews section in generated CLAUDE.md
[0.5.4] - 2026-03-29
Added
--fixnow auto-adds SessionStart hook (injects TASKS.md at startup)
Changed
--fixno longer shows the before-score - only the post-fix result- Post-fix report says "remaining issue(s) require manual intervention" instead of suggesting --fix again
- Dry-run shows fix actions, skips unfixable issues
[0.5.3] - 2026-03-29
Changed
- Doctor output: compact single-line issues (was 3 lines each with fix text)
- Doctor
--fixand--fix --dry-runnow recommend runningenhanceas next step - Dry-run shows fix actions instead of problem messages, skips unfixable issues
[0.5.2] - 2026-03-29
Added
doctor --fix --dry-run- preview what fixes would be applied without modifying filespnpm publish:dev/pnpm publish:releasescripts for prerelease workflow
[0.5.1] - 2026-03-29
Added
- 4 new doctor checks: deprecated
includeCoAuthoredBy, monorepoclaudeMdExcludeshint, hook timeouts on broad matchers, auto-memory disabled without manual strategy - SessionStart hook in init-generated settings.json - injects TASKS.md at session startup
- Doctor hooks analyzer now checks for SessionStart hook
- Attribution migration auto-fix:
--fixmigrates deprecatedincludeCoAuthoredBytoattributionobject - Enhance prompt: suggests path-scoped rules,
sandbox.network.allowedDomains,claudeMdExcludesfor monorepos - 2 new eval scenarios:
memory-persistence,deferred-tracking- 15 total timeoutfield parsed from hooks in settings.json
Fixed
doctor --fixnow re-scans and shows updated score after applying fixes (previously required a second run)
Changed
- Hooks analyzer score weight: 20 to 15 per issue (6 checks would bottom out too fast)
- Total tests: 91 to 99
[0.5.0] - 2026-03-29
Added
- Security hardening: init generates credential deny rules (
~/.ssh/*,~/.aws/*,~/.npmrc), sandbox enabled, bypass mode disabled - 5 new doctor checks: credential file exposure, blanket Bash approval, .env gap (hooks vs .claudeignore), bypass mode unprotected, sandbox not enabled
- 4 new auto-fixes:
--fixadds credential deny rules, bypass disable, sandbox settings, .env to .claudeignore - 2 new eval scenarios:
credential-read(SSH key protection),sandbox-escape(.env bypass via Bash) - Interactive eval mode:
evalwith no flags prompts for suite, runs, and model selection .claudeignoreparsing added to ClaudeConfig for cross-checking with hooks
Fixed
build.gradledetection bug -||on two promises always returned the first (Kotlin/Gradle projects misdetected)- Broader
.envmatching in .claudeignore fixer (handles.env*pattern) makeConfigtest helpers missingclaudeignorePath/claudeignoreContentdefaults
Changed
- Permissions analyzer score weight: 20 to 15 per issue (8 checks would bottom out too fast)
- Security eval suite: 4 to 6 scenarios
- Total tests: 71 to 91
[0.4.3] - 2026-03-29
Fixed
- Eval sandbox now copies user's full
.claude/config (settings.json, rules, hooks, permissions) and.claudeignore- previously only a bare CLAUDE.md from the scenario was used
[0.4.2] - 2026-03-29
Added
- Memory & Learnings section in generated CLAUDE.md
- PostCompact hook in generated settings.json - re-injects TASKS.md after context compaction
- Deferred section in generated TASKS.md
- Doctor checks for Memory section and PostCompact hook
--fixauto-adds Memory section and PostCompact hook- Enhance prompt now suggests PostCompact hook for existing projects
[0.4.1] - 2026-03-29
Changed
- Refactored
tryFix()from 73-line if/else chain toFIX_TABLElookup pattern - Refactored
detectScripts()from 112-line if/else chain toLANGUAGE_SCRIPTSconfig object
Added
- 13 new tests for
detectScripts()covering all supported languages (58 to 71 tests)
[0.4.0] - 2026-03-28
Added
- Enhanced
init: generates 6 files (CLAUDE.md, TASKS.md, settings.json, .gitignore, .claudeignore, conventions.md) settings.jsonincludes$schemafor IDE autocomplete,permissions.denyfor security- Destructive command blocking hooks (force-push, reset --hard, rm -rf)
- Language-specific starter rules (13 languages)
Changed
- Init detects 20+ frameworks from manifest files + lockfiles
[0.3.4] - 2026-03-28
Fixed
- Security: command injection in hook generation (SAFE_FORMATTERS dict)
Added
- Suite filtering for eval
- Eval report output to
.claude/eval/
[0.3.0] - 2026-03-28
Added
doctor --watch: polling-based live score updates.claudeignoregeneration in--fixenhancebudget cap (120 lines)- Tech Stack section in generated CLAUDE.md
[0.2.2] - 2026-03-28
Added
- Plugin submitted to marketplace
- 50 tests, 60KB package size
[0.1.0] - 2026-03-28
Added
- Initial npm publish
init,doctor,enhance,evalcommands- 7 analyzers, 7 eval scenarios
- Stress tested across 8 stacks
CI Integration
Gate pull requests on Claude Code config quality with claude-launchpad doctor in GitHub Actions — plus a weekly canary that tests your generated config against the latest Claude Code release.
Privacy
Claude Launchpad runs fully offline: no telemetry, no analytics, no data collection. Doctor never calls an API; memory stays in local SQLite; sync uses your own private GitHub Gist.