Commit Graph

27 Commits

Author SHA1 Message Date
Alex Newman 9e2973059a UX redesign: installer + provider rename + /learn-codebase + welcome card + SessionStart hint (#2255)
* feat(ux): claude-mem UX improvements with installer enhancements

Squashed PR #2156 commits for clean rebase onto main:
- feat(installer): add provider selection, model prompt, worker auto-start
- refactor: rename *Agent provider classes to *Provider
- feat: add /learn-codebase skill and viewer welcome card
- feat(worker): inject welcome hint when project has zero observations
- fix(pr-2156): address greptile review comments
- fix(pr-2156): address coderabbit review comments
- fix(pr-2156): persist CLAUDE_MEM_PROVIDER for non-claude in non-TTY mode
- fix(pr-2156): file-backed settings reads in installer + env-first SKILL doc

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* build: rebuild plugin artifacts after rebase onto v12.4.7

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(skills): strip claude-mem internals from learn-codebase

The learn-codebase skill, install next-step copy, WelcomeCard, and
welcome-hint previously walked the primary agent through worker endpoints
and synthetic observation payloads. The PostToolUse hook already captures
every Read/Edit the agent makes — the agent should have no awareness that
the memory layer exists. Collapse the skill to one instruction ("read every
source file in full") and rephrase touchpoints to describe only what the
user observes (Claude reading files), not what happens behind the scenes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(sync): preflight version mismatch + settings-aware port resolution

Two related fixes for build-and-sync's worker restart step:

1. Read CLAUDE_MEM_WORKER_PORT from ~/.claude-mem/settings.json the same
   way the worker does, instead of computing the default port from the
   uid alone. Previously, users with a custom port saw a misleading
   "Worker not running" message because the restart POST hit the wrong
   port and got ECONNREFUSED.

2. Add a preflight check that aborts the sync when the running worker's
   reported version does not match the version we are about to build.
   Claude Code's plugin loader pins the worker to a specific cache
   version per session, so syncing into a newer cache directory has no
   effect until the user runs `claude plugin update thedotmack/claude-mem`
   to bump the pin. The preflight surfaces this explicitly with the exact
   command to run; --force bypasses it for intentional cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(learn-codebase): note sed for partial reads of large files

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor: strip comments codebase-wide

Removed prose comments from all tracked source. Preserved directives
(@ts-ignore, eslint-disable, biome-ignore, prettier-ignore, triple-slash
references, webpack magic, shebangs). Deleted two tests that asserted
on comment text rather than runtime behavior.

Net: 401 files, -14,587 / +389 lines, -10.4% bytes.

Verified: typecheck passes, build passes, test count unchanged from
baseline (22 pre-existing fails, all unrelated).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(installer): move runtime setup into npx, eliminate hook dead air

Smart-install ran 3 times during a fresh install — the worst run was silent,
fired by Claude Code's Setup hook after `claude plugin install`, producing
~30s of dead air that looked like the plugin was hung.

This change makes `npx claude-mem install` the single place heavy work
happens, with a visible spinner. Hooks become runtime-only.

- New `src/npx-cli/install/setup-runtime.ts` module: ensureBun, ensureUv,
  installPluginDependencies, read/writeInstallMarker, isInstallCurrent.
  Marker schema preserved exactly ({version, bun, uv, installedAt}) so
  ContextBuilder and BranchManager readers keep working.
- `npx claude-mem install`: ungated copy/register/enable for every IDE,
  inserts a "Setting up runtime" task with honest "first install can take
  ~30s" spinner. The claude-code shell-out to `claude plugin install` is
  removed — npx already populated everything Claude reads.
- New `npx claude-mem repair` command for post-`claude plugin update`
  recovery, force-reinstalls runtime.
- Setup hook now runs `plugin/scripts/version-check.js` (29ms wall) instead
  of smart-install. Mismatch prints "run: npx claude-mem repair" on stderr.
  Always exits 0 (non-blocking, per CLAUDE.md exit-code strategy).
- SessionStart loses the smart-install entry; 2 hooks remain (worker start,
  context fetch).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(installer): delete smart-install sources, retarget tests

- Delete scripts/smart-install.js + plugin/scripts/smart-install.js (both
  are source files kept in sync manually; both must go).
- Delete tests/smart-install.test.ts (covered surface is gone).
- tests/plugin-scripts-line-endings: drop smart-install.js entry.
- tests/infrastructure/plugin-distribution: retarget two assertions at
  version-check.js (the new Setup hook script).
- New tests/setup-runtime.test.ts: 9 tests covering marker read/write,
  isInstallCurrent semantics. Marker schema invariant verified.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(installer): describe npx-driven setup + version-check Setup hook

Sweep public docs and architecture notes to reflect the new flow:
npx installer does Bun/uv setup with a visible spinner; Setup hook runs
sub-100ms version-check.js; users hit `npx claude-mem repair` after a
`claude plugin update`.

- docs/architecture-overview.md: hook lifecycle table + npx flow paragraph
- docs/public/configuration.mdx: tree + hook config example
- docs/public/development.mdx: build output line
- docs/public/hooks-architecture.mdx: full rewrite of pre-hook section,
  timing table, performance table
- docs/public/architecture/{overview,hooks,worker-service}.mdx: tree
  comments, JSON config example, Bun requirement section

docs/reports/* untouched (historical incident reports).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(install): mergeSettings writes via USER_SETTINGS_PATH

Greptile P1 (#2156): `settingsFilePath()` only resolved
`process.env.CLAUDE_MEM_DATA_DIR`, while `getSetting()` reads via
`USER_SETTINGS_PATH` which `resolveDataDir()` populates from BOTH the env
var AND a `CLAUDE_MEM_DATA_DIR` entry persisted in
`~/.claude-mem/settings.json`. Result: a user with the data dir saved in
settings.json but not exported in their shell would have provider/model
settings silently written to `~/.claude-mem/settings.json` while
`getSetting()` read from `/custom/path/settings.json` — read/write split.

Drop `settingsFilePath()` and the now-unused `homedir` import; reuse the
already-imported `USER_SETTINGS_PATH` constant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(cli): parse --provider, --model, --no-auto-start install flags

Greptile P1 (#2156): InstallOptions has fields `provider`, `model`,
`noAutoStart`, but the install case in the npx-cli switch only parsed
`--ide`. The other three flags were silently dropped — `npx claude-mem
install --provider gemini` was a no-op.

Extract a `parseInstallOptions(argv)` helper, share it between the bare
`npx claude-mem` and `npx claude-mem install` paths, and validate
`--provider` against the allowed set. Update help text accordingly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(install): pipe runtime-setup output, always show IDE multiselect

Two issues caught in a docker test of the installer:

1. The bun.sh installer, uv installer, and `bun install` were using
   stdio: 'inherit', dumping their stdout/stderr through clack's spinner
   region — visible as raw "downloading uv 0.11.8…" / "Checked 58
   installs across 38 packages…" text streaming under the spinner. Switch
   to stdio: 'pipe' and surface captured stderr only on failure (via a
   shared describeExecError() helper that includes stdout when stderr is
   empty). Spinner stays clean on the happy path.

2. promptForIDESelection() silently picked claude-code when no IDEs were
   detected, never showing the user the multiselect. On a fresh machine
   with no IDEs present yet (e.g. our docker test container), the user
   never got to choose. Now: always show the full IDE list when
   interactive; mark detected ones with [detected] hints and pre-select
   them; show a warn line if zero are detected explaining they should pick
   what they plan to use. Non-TTY callers still get the silent
   claude-code default at the call site (unchanged).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(install): skip marketplace work for claude-code-only, offer to install Claude Code

Two related UX fixes from a docker test:

**Delay between "Saved Claude model=…" and "Plugin files copied OK"**

After dropping the needsManualInstall gate, every install was unconditionally
running `copyPluginToMarketplace` (which copied the entire root node_modules
tree — thousands of files, dozens of seconds) and `runNpmInstallInMarketplace`
(npm install --production) even when only claude-code was selected. Neither
is needed for claude-code: that path uses the plugin cache dir + the
installed_plugins.json + enabledPlugins flag, all of which we already write.

- Drop `node_modules` from `copyPluginToMarketplace`'s allowed-entries list;
  the dependency-install task populates it on the destination side anyway.
- Re-introduce `needsMarketplace = selectedIDEs.some(id => id !== 'claude-code')`
  scoped *only* to `copyPluginToMarketplace`, `runNpmInstallInMarketplace`,
  and the pre-install `shutdownWorkerAndWait` (also pointless for claude-code-
  only flows since we're not overwriting the worker's running cache dir
  source). All other tasks (cache copy, register, enable, runtime setup) stay
  unconditional.

**Claude Code missing → silent install of an IDE that isn't there**

When the user picked claude-code on a machine without it (e.g. a fresh
container), the install completed but `claude` was unavailable and the only
hint was a generic warn line. Replace with an explicit pre-flight prompt:

  Claude Code is not installed. Claude-mem works best in Claude Code, but
  also works with the IDEs below.
  ? Install Claude Code now?
    ◆ Yes — install Claude Code (recommended)
    ◯ No — pick another IDE below
    ◯ Cancel installation

If the user picks "Yes", run `curl -fsSL https://claude.ai/install.sh | bash`
(or the PowerShell equivalent on Windows), then re-detect IDEs and proceed
with claude-code pre-selected. If the install fails or the user picks "No",
the multiselect still appears with claude-code visible (just unmarked
[detected]), so they can opt in or pick another IDE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(install): detect Claude Code via `claude` CLI, not ~/.claude dir

The directory `~/.claude` can exist (e.g. mounted in Docker, or created
by tooling) without Claude Code actually being installed. Detect the
`claude` command in PATH instead so the installer correctly offers to
install Claude Code when missing.

* docs(learn-codebase): add reviewer note explaining the cost tradeoff

The skill intentionally reads every file in full to build a cognitive
cache that pays off across the rest of the project. Add a brief note
so reviewers (human or bot) understand the tradeoff before flagging
the unbounded read as a cost issue.

* fix: address Greptile P1 feedback on welcome hint and learn-codebase

- SearchRoutes: skip welcome hint when caller passes ?full=true so
  explicit full-context requests aren't intercepted by the hint.
- learn-codebase: replace `sed` instruction with the Read tool's
  offset/limit parameters, since Bash is gated in Claude Code by
  default.

* feat(install): ASCII-animated logo splash on interactive install

Plays a ~1s bloom animation of the claude-mem sunburst logomark when
the installer starts in an interactive terminal — geometrically rendered
via 12 ray curves around a center disc, in the brand orange. The
wordmark and tagline type on alongside the final frame.

Auto-skipped on non-TTY, in CI, when NO_COLOR or CLAUDE_MEM_NO_BANNER
is set, or when the terminal is too narrow.

Inspired by ghostty +boo.

* feat(banner): replace rotation frames with angular-sector bloom generator

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(banner): replace rotation frames with angular-sector bloom generator

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(banner): three-act choreography renderer with radial gradient and diff redraw

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(banner): update preview script to support small/medium/hero tier selection

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(docker): add COLORTERM=truecolor to test-installer sandbox

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(install): auto-apply PATH for Claude Code with spinner UX

The Claude Code install.sh prints a Setup notes block telling users to
manually edit "your shell config file" to add ~/.local/bin to PATH —
which left fresh installs unable to launch claude from the command line.

After a successful install, detect ~/.local/bin/claude on disk and, if
the dir is missing from PATH, append the right export line to .zshrc /
.bash_profile / .bashrc / fish config (idempotent, marked with a
comment). Also updates process.env.PATH for the current install run.

Wraps the curl|bash install in a clack spinner (interactive only) so the
~4 minute native-build download doesn't look frozen — output is captured
silently and dumped on failure for debuggability. Non-interactive mode
keeps inherited stdio for CI logs.

Verified end-to-end in the test-installer docker sandbox: spinner
animates, .bashrc gets the export, fresh login shell resolves claude.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(banner): video-frame ASCII renderer with three-act choreography

Generator switched from a single Jimp-rendered logo to pre-extracted
video frames concatenated with \x01 separators and gzip-deflated, ported
from ghostty's boo wire format. Renderer rewritten around three acts
(ignite → stagger bloom → text reveal + breathe) with adaptive sizing,
radial gradient, and diff-based redraw.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(onboarding): unify install / SessionStart / viewer around one first-success moment

Three surfaces now point at the same north-star moment — open the viewer, do
anything in Claude Code, watch an observation appear within seconds — with the
same verbatim timing and privacy lines, and a single canonical "how it works"
explainer instead of three diverging copies.

- Canonical explainer at src/services/worker/onboarding-explainer.md served via
  GET /api/onboarding/explainer; mirrored into plugin/skills/how-it-works/SKILL.md
- SessionStart welcome hint rewritten as third-person status (no imperatives
  Claude tries to execute), pinned with a default-value regression test
- Post-install Next Steps reframed as "two paths": passive default + optional
  /learn-codebase front-load; drops /mem-search and /knowledge-agent from this
  surface; adds verbatim timing + privacy lines and /how-it-works link
- /api/stats response gains firstObservationAt for the viewer stat row
- Viewer WelcomeCard branches on observationCount === 0: empty state shows live
  worker-connection dot + "waiting for activity"; has-data state shows
  observations · projects · since [date] and two example prompts. v2 dismiss key
- jimp added to package.json to fix pre-existing banner-frame build break

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(banner): play unconditionally; only honor CLAUDE_MEM_NO_BANNER

The 128-col / TTY / CI / NO_COLOR gates silently swallowed the banner in
narrower terminals, CI logs, and any non-TTY pipe — including Docker runs
where -it should preserve the experience but column width was the wrong
gate. Remove the implicit gates; keep the explicit opt-out only.

If a frame wraps in a narrow terminal, that's better than the banner
not playing at all.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* revert(banner): restore 15:33 gating logic per user request

Reverts eb6fc157. Restores isBannerEnabled to the state at commit
8e448015 (2026-04-30 15:33): TTY check, !CI, !NO_COLOR, !CLAUDE_MEM_NO_BANNER,
and cols >= BANNER.width.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(install): wrap remaining slow steps with spinners

Each IDE installer (Cursor, Gemini CLI, OpenCode, Windsurf, OpenClaw,
Codex CLI, MCP integrations) now runs inside a clack task spinner with
per-step progress messages instead of silent dynamic-import + cpSync.
Pre-overwrite worker shutdown (up to 10s) and the post-install health
probe (up to 3s) also get spinners.

Internal console.log/error/warn from each IDE installer is buffered
during the spinner; if the install fails, captured output is replayed
afterward via log.warn so users can see what broke.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(review): observation count + IDE pre-selection regressions

WelcomeCard's "no observations yet" empty state was triggered when a
project filter narrowed the feed to zero rows, even with thousands of
observations elsewhere. Source the count from global stats.database
to match firstObservationAt's scope.

Restore initialValues: [] in the IDE multiselect — pre-selecting every
detected IDE was the exact regression #2106 was filed for.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(install): trichotomy worker state + cache fallback for script path

ensureWorkerStarted now returns 'ready' | 'warming' | 'dead' instead of
boolean. The spawned-but-still-warming case (common in Docker cold
starts and slow first-time inits) was being misreported as 'did not
start', which contradicted the next-steps panel saying 'still starting
up'. Install task message and Next Steps headline now agree on the
actual state.

Also fixes the actual root cause of 'Worker did not start' on
claude-code-only installs: the worker script path was hardcoded to the
marketplace dir, which is left empty when no non-claude-code IDE is
selected. Now falls back to pluginCacheDirectory(version) when the
marketplace copy isn't present.

Verified end-to-end in docker/claude-mem with --ide claude-code,
--ide cursor, and a fresh container — install task and headline
agree on 'Worker ready at http://localhost:<port>' in all cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: align CLAUDE.md and public docs with current code

Sweep across CLAUDE.md and 10 high-traffic docs/public/ MDX files to
remove point-in-time references and align with the actual current
shape of the codebase. Highlights:

- Hardcoded port 37777 → per-user formula (37700 + uid % 100) on the
  front-door pages (introduction, installation, configuration,
  architecture/overview, architecture/worker-service, troubleshooting,
  hooks-architecture, platform-integration).
- Default model 'sonnet' → 'claude-haiku-4-5-20251001' (matches
  SettingsDefaultsManager).
- Node 18 → 20 (matches package.json engines).
- Lifecycle hook count corrected (5 events).
- Removed the nonexistent 'Smart Install' component and pre-built
  directory tree referencing files that no longer exist
  (context-hook.ts, save-hook.ts, cleanup-hook.ts, etc.); replaced
  with the real worker dispatcher shape.
- Removed CLAUDE.md '#2101' issue tag (kept the design rationale).
- Replaced obsolete hooks.json example with a description of the real
  bun-runner.js / worker-service.cjs hook event shape.

Lower-traffic doc pages still hardcode 37777 — left for a separate
global pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(scripts): land strip-comments around real parsers (postcss, remark, parse5)

Each language gets a real parser to locate comments, then we splice ranges
out of the original source. The library never serializes — that's how
remark-stringify produced 243 reformat-noise diffs in the first attempt
versus the 21 real strip targets here.

  JS/TS/JSX  -> ts.createSourceFile + getLeadingCommentRanges
  CSS/SCSS   -> postcss.parse + walkComments + node.source offsets
  MD/MDX     -> remark-parse (+ remark-mdx) + AST html / mdx-expression nodes
  HTML       -> parse5 with sourceCodeLocationInfo
  shell/py   -> kept hand-rolled hash stripper (no library worth the dep)

Preserves: shebangs, @ts-* directives, eslint-disable, biome-ignore,
prettier-ignore, triple-slash refs, webpack magic, /*! license keep,
@strip-comments-keep file marker. JS/TS handler runs a parse-roundtrip
check and refuses to write if syntax errors increased (catches the
worker-utils.ts breakage class from the 2026-04-29 attempt).

npm scripts:
  strip-comments         (apply)
  strip-comments:check   (CI-style, exits non-zero if changes needed)
  strip-comments:dry-run (list, no writes)

Verified --check on this repo: 21 changes, -4.0% bytes, no parse-error
regressions, no reformat-suspect false positives.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor: strip comments codebase-wide via parser-backed tool

21 files changed, -17,550 bytes (-4.0%) of narrative comments removed
across .ts / .tsx / .js / .mjs and the .gitignore. JS/TS comments stripped
via ts.createSourceFile + getLeadingCommentRanges — same canonical lexer,
same behavior as the 2026-04-29 strip, no reformat noise.

Preexisting baseline (unchanged):
  typecheck: 16 errors at HEAD, 16 errors after strip (line numbers shift,
             no new error classes — verified via diff of sorted error lists)
  build:     fails at HEAD with CrushHooksInstaller.js unresolved import
             (preexisting, unrelated to this strip)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(install): drop Crush integration references after extract

The Crush integration was extracted to its own branch on May 1, but the
import at install.ts:280 (and the case block + ide-detection entry +
McpIntegrations config + npx-cli help text) still referenced the now-
removed CrushHooksInstaller.js, breaking the build.

Removes:
- case 'crush' block in install.ts
- crush entry in ide-detection.ts
- CRUSH_CONFIG and registration in McpIntegrations.ts
- 'crush' from the IDE Identifiers help line in index.ts

Rebuilds worker-service.cjs to match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(banner): mark generated banner-frames.ts with @strip-comments-keep

Without this, every build/strip cycle ping-pongs five lines of doc
comments in and out of the auto-generated output. The keep-marker tells
strip-comments.ts to skip the file entirely.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(build): drop banner-frame regen from build script

generate-banner-frames.mjs requires PNG frames in /tmp/cmem-banner-frames
that only exist after the maintainer runs ffmpeg locally on the source
video. CI has neither the video nor the frames, so the build broke on
Windows. The output (src/npx-cli/banner-frames.ts) is committed, so the
regen is a one-shot dev step — not a build step. Run the script directly
when the video changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(worker): unstick the spinner — kill claim-self-lock, wake on fail, auto-broadcast

Three surgical changes that cure the stuck-spinner bug at the source.

Phase 1.1 (L9): claimNextMessage no longer self-excludes its own worker_pid.
A single UPDATE-RETURNING grabs the oldest pending row by id. Removes the
LiveWorkerPidsProvider plumbing that was never injected — Supervisor enforces
single-worker via PID file, so the multi-worker SQL was defending against a
configuration the project does not support.

Phase 1.2 (L19): SessionManager.markMessageFailed wraps PendingMessageStore.markFailed
and emits 'message' on the per-session EventEmitter. The iterator's waitForMessage
now wakes immediately on re-pend instead of parking for 3 minutes. ResponseProcessor
and SessionRoutes routed through the new wrapper.

Phase 1.3 (L24): PendingMessageStore takes an optional onMutate callback fired
from every mutator (enqueue, claimNextMessage, confirmProcessed, markFailed,
transitionMessagesTo, clearFailedOlderThan). SessionManager wires it; WorkerService
passes broadcastProcessingStatus. Ten manual broadcast calls deleted across
SessionCleanupHelper, SessionEventBroadcaster, SessionRoutes, DataRoutes, and
worker-service. Caller discipline becomes structurally impossible to forget.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(worker): delete dead code — legacy routes, processPendingQueues, decorative guards

Pure deletions. Phase 2 of kill-the-asshole-gates.

- Legacy /sessions/:sessionDbId/* routes (handleSessionInit, handleObservations,
  handleSummarize, handleSessionStatus, handleSessionDelete, handleSessionComplete)
  bypassed all five ingest gates and were a parallel write path. Folded the
  initializeSession + broadcastNewPrompt + syncUserPrompt + ensureGeneratorRunning
  + broadcastSessionStarted work into the canonical /api/sessions/init handler so
  the hook makes one round trip instead of two.
- processPendingQueues (~104 lines, zero callers) — replaced in Phase 6 by a
  one-statement startup sweep.
- spawnInProgress Map and crashRecoveryScheduled Set — decorative dedupe over
  generatorPromise and stillExists checks that already provide the real safety.
- STALE_GENERATOR_THRESHOLD_MS — pre-empted live generators and raced with the
  finally block; the 3min idle timeout already kills zombies.
- MAX_SESSION_WALL_CLOCK_MS — ran a SELECT on every observation to enforce 24h.
  Runaway-spend protection lives in the API key, not in claude-mem.
- Missing-id 400 in shared.ts ingestObservation — Zod already enforces min(1)
  on contentSessionId and toolName at the route schema.
- SessionCompletionHandler import + completionHandler field on SessionRoutes
  (orphaned after handler deletions).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(worker): SQL-backed getTotalQueueDepth — single source of truth

Was: iterate this.sessions.values() and sum getPendingCount per session.
Now: SELECT COUNT(*) FROM pending_messages WHERE status IN ('pending','processing').

The in-memory sessions Map drifted from the DB rows whenever a generator exited
without confirm/fail, leading to false-positive isProcessing in the UI. Phase 1.3's
auto-broadcast fires on every mutation, but it broadcast a stale Map count.
Reading from the DB makes the UI's spinner state match what the queue actually holds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(worker): typed abortReason replaces wasAborted boolean

Was: a boolean wasAborted that lumped every abort together. The finally block
branched on !wasAborted, so any abort skipped restart — including idle aborts
with pending work, which is exactly the case where we DO want to restart.

Now: ActiveSession.abortReason is a typed enum 'idle' | 'shutdown' | 'overflow'
| 'restart-guard'. The finally block consumes the reason and only skips restart
for 'shutdown' and 'restart-guard'. Idle and overflow aborts fall through, so
if pending work exists they trigger restart correctly.

Dropped 'stale' and 'wall-clock' from the union — Phase 2 deleted those paths.
Natural-completion abort (post-success) intentionally has no reason; it's not
gating restart logic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(worker): unify the two generator-exit finally blocks

Was: worker-service.ts:startSessionProcessor and SessionRoutes:ensureGeneratorRunning
each had their own ~70-line finally block with divergent restart-guard handling.
The worker-service path called terminateSession on RestartGuard trip and orphaned
pending rows (the L16 bug); the SessionRoutes path drained them. Two places to
update when rules changed.

Now: handleGeneratorExit in src/services/worker/session/GeneratorExitHandler.ts
owns the contract:
  1. Always kill the SDK subprocess if alive.
  2. Always drain processingMessageIds via sessionManager.markMessageFailed
     (which wakes the iterator — Phase 1.2).
  3. shutdown / restart-guard reasons: drain pending rows via
     transitionMessagesTo('failed'), finalize, remove from Map. Fixes L16.
  4. pendingCount=0: finalize normally and remove from Map.
  5. pendingCount>0: backoff respawn via per-session respawnTimer (no global Set;
     Phase 2.4 deleted that). RestartGuard trip drains to 'abandoned'.

Both finally blocks are now ~10-line wrappers that translate local state into the
canonical abortReason and delegate. Restored completionHandler injection into
SessionRoutes (was dropped in Phase 2 cleanup; needed by the unified helper for
finalizeSession).

Behavior change: SessionRoutes' previous "keep idle session in memory" was
deliberately replaced by the plan's "remove from Map on natural completion" —
next observation reinitializes via getMessageIterator → initializeSession.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(worker): startup orphan sweep — reset 'processing' rows at boot

When the worker dies (crash, kill, restart), any pending_messages rows it left
in 'processing' state are by definition orphans (the only worker is dead).
Single SQL UPDATE at boot resets them to 'pending' so the iterator can claim
them again. Replaces the deleted processPendingQueues function (Phase 2.2).

Runs in initializeBackground after dbManager.initialize() and before the
initializationComplete middleware releases blocked HTTP requests, so no
in-flight request can race the sweep. NOT on a periodic timer — after boot,
every 'processing' row has a live consumer and a periodic sweep would race.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(worker): simplify enqueue catch, replace memorySessionId throw with re-pend

7.1: queueObservation's catch was logging two ERROR-level messages and rethrowing.
The rethrow is correct (FK violations / disk full / schema drift should crash
loudly), but the verbose ERROR logging pretended the error was recoverable.
Reduced to one INFO line + rethrow.

7.2: ResponseProcessor's memorySessionId guard was throwing if the SDK hadn't
included session_id on the first user-yield, terminal-failing the entire batch.
Now warns and re-pends in-flight messages via sessionManager.markMessageFailed
(which wakes the iterator — Phase 1.2). The next iteration tries again with
memorySessionId hopefully captured.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(sync): mirror builds to installed-version cache for hot reload

When package.json bumps past Claude Code's installed pin, sync-marketplace
wrote new code to cache/<buildVersion>/ but the worker loaded from
cache/<installedVersion>/, so worker:restart reloaded the same old code.

Replace the exit-on-mismatch preflight with a mirror step: when versions
differ, also rsync plugin/ into cache/<installedVersion>/ so worker:restart
hot-reloads new code without a Claude Code session restart. The
build-version cache still gets written for the eventual
`claude plugin update`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: delete dead barrel files and orphan utilities

- src/sdk/index.ts (re-exports parser+prompts; nothing imported the barrel)
- src/services/Context.ts (re-exports ./context/index.js; no importers)
- src/services/integrations/index.ts (no importers)
- src/services/worker/Search.ts (3-line barrel of ./search/index.js)
- src/services/infrastructure/index.ts: drop CleanupV12_4_3 re-export
- src/utils/error-messages.ts (getWorkerRestartInstructions never imported)
- src/types/transcript.ts (170 LoC of types, zero importers)
- src/npx-cli/_preview.ts (banner dev preview, no script wires it)

Build + tests still pass; observations still flowing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(parser): drop unused detectLanguage

Only the user-grammar-aware variant detectLanguageWithUserGrammars()
is actually called.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(types): drop unused SdkSessionRecord + ObservationWithContext

Both interfaces in src/types/database.ts had zero importers anywhere
in src or tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(npx-cli): drop unused getDetectedIDEs + claudeMemDataDirectory

getDetectedIDEs has no callers — install.ts uses detectInstalledIDEs
directly. claudeMemDataDirectory has no callers either.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(ProcessManager): drop dead orphan-reaper + signal-handler helpers

Each had zero callers in src/ or tests/:
  - cleanupOrphanedProcesses + enumerateOrphanedProcesses
  - ORPHAN_PROCESS_PATTERNS + ORPHAN_MAX_AGE_MINUTES
  - forceKillProcess
  - waitForProcessesExit
  - createSignalHandler
  - resetWorkerRuntimePathCache

The orphan reaper was retired in PATHFINDER Plan 02 ("OS process groups
replace hand-rolled reapers", commit 94d592f2) — these were the leftover
pieces. shutdown.ts uses the supervisor's own kill-pgid path instead.

parseElapsedTime kept (covered by tests/infrastructure/process-manager.test.ts).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(scripts): delete 11 unreferenced DX/forensic scripts

None of these are referenced by package.json npm scripts or docs/.
All last touched on Apr 29 only as part of the comment-stripping
pass — the feature code itself is older and orphaned:

  analyze-transformations-smart.js
  debug-transcript-structure.ts
  dump-transcript-readable.ts
  endless-mode-token-calculator.js
  extract-prompts-to-yaml.cjs
  extract-rich-context-examples.ts
  find-silent-failures.sh
  fix-all-timestamps.ts
  format-transcript-context.ts
  test-transcript-parser.ts
  transcript-to-markdown.ts

These are standalone tools — runtime behavior unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(scripts): delete unused extraction/ and types/ subdirs

- scripts/extraction/{extract-all-xml.py, filter-actual-xml.py, README.md}
  point at ~/Scripts/claude-mem/ — the user's pre-relocation path that no
  longer exists. Zero references in package.json, src/, or tests/.
- scripts/types/export.ts duplicates ObservationRecord etc. and has no
  importers (CodexCliInstaller imports transcripts/types, not this).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(BranchManager): drop dead getInstalledPluginPath

OpenCodeInstaller has its own (used) getInstalledPluginPath; the
BranchManager copy never had any external callers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(ChromaSyncState): unexport DocKind (used internally only)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(gemini): drop stale earliestPendingTimestamp / processingMessageIds

Both fields were removed from ActiveSession in earlier queue-engine
cleanup. Tests had been silently keeping them because the mock sessions
use 'as any' to bypass strict typing, so the dead fields rode along
without complaint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: drop 3 unused module-level constants

- src/npx-cli/banner.ts: CURSOR_HOME, CLEAR_DOWN (banner uses
  CLEAR_SCREEN which combines clear-down + cursor-home into a single
  CSI sequence; the standalone constants were leftovers).
- src/services/worker/BranchManager.ts: DEFAULT_SHELL_TIMEOUT_MS
  (BranchManager only uses GIT_COMMAND_TIMEOUT_MS / NPM_INSTALL_TIMEOUT_MS).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(opencode-plugin): drop dead workerPost helper

Only the fire-and-forget variant (workerPostFireAndForget) is actually
called. workerPost was the await-result version with no remaining caller.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: drop 8 truly-unused interface fields

Verified each by grepping for `.field`, `"field"`, `'field'`, and
`field:` patterns across src/ + tests/ + plugin/scripts. Where the
only remaining usage was the assignment site, removed the assignments too.

- GitHubStarsData: watchers_count, forks_count (only stargazers_count read)
- TableColumnInfo: dflt_value (PRAGMA returns it but no caller reads it)
- IndexInfo: seq (PRAGMA returns it but no caller reads it)
- ObservationRecord: source_files (legacy field, no readers)
- HookResult.hookSpecificOutput: permissionDecisionReason
- WatchTarget: rescanIntervalMs (set in config, never read)
- ShutdownResult: confirmedStopped (write-only — assigned but no
  reader; updated all 3 return sites to drop it)
- ModePrompts: language_instruction (multilingual support never wired)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(npx-cli): reuse InstallOptions type instead of inline duplicate

parseInstallOptions had its return type written out inline as an
anonymous duplicate of InstallOptions. Use the canonical type
(import type — zero bundle cost).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(integrations): drop unused Platform type alias

The detectPlatform() function that returned this type was deleted earlier
in the branch (along with getScriptExtension that consumed it). The type
itself outlived its consumer; only string literals "Platform:" survive in
console.log diagnostics, which don't reference the alias.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(worker): broadcast processing_status when summarize is queued

broadcastSummarizeQueued was an empty no-op even though
handleSummarizeByClaudeId calls it after enqueueing. The PendingMessageStore
onMutate callback already fires broadcastProcessingStatus on enqueue, but
calling it explicitly from broadcastSummarizeQueued ensures the spinner
ticks on the moment a summary is requested even if the onMutate chain has
any timing race.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(worker): keep spinner on while summary generates

ClaudeProvider's SDK can pull multiple synthetic prompts (e.g.
observation + summarize) before producing responses. Each pull pushed
an ID to session.processingMessageIds. When the SDK's first
observation response came back, ResponseProcessor.confirmProcessed
deleted ALL pending message rows — including the still-in-flight
summary — so getTotalQueueDepth dropped to 0 and the spinner turned
off, even though the summary took another ~22s to actually generate.

Tag each in-flight message with its type ({id, type}) so the response
processor can pop only the FIFO message of the matching type
(observation vs summarize). The summary row stays in 'processing'
until its own response arrives, keeping the spinner lit through the
entire summary window.

Also updates Gemini/OpenRouter providers and GeneratorExitHandler for
the new shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(worker): clear summary from queue on any SDK response

Switch ResponseProcessor from type-aware FIFO matching to strict FIFO
popping (each SDK response → 1 in-flight message consumed). This way
the summary always clears when the SDK responds, even when the
response is unparseable or the summary doesn't actually generate
content — preventing stuck spinner / queue-depth-stuck-at-1.

Spinner behavior is preserved: messages enqueued after the summary
keep the queue depth elevated, and only when the SDK has responded
to every prompt does the queue drain to zero.

Also: when the consumed message is a 'summarize' and parsing fails,
treat it as best-effort and confirmProcessed (no retry) — summaries
that can't be parsed shouldn't keep retrying.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(viewer): redesign welcome card and remove source filters

The first-start welcome card now explains the three feed card types
(observation/summary/prompt) with color-coded badges, points users at
the gear icon for settings and the project dropdown for filtering, and
plugs /mem-search for recall — replacing the old two-line "ask:" prompts.

Source filter tabs (Claude/Codex/etc.) are removed from the header.
Filtering by AI provider was nonsense from a user POV; the project
dropdown is the only header filter now. Source tracking is also
stripped from useSSE, usePagination, App state, and CSS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(viewer): keep welcome card in feed column, swap rows for 3 squares

Two visible problems in the previous design: the card stretched
edge-to-edge while feed cards sit in a centered 650px column, and
the body was a stack of long horizontal rows that scanned line-by-line.

Both fixed: Feed now accepts a pinnedTop slot so the welcome card
renders inside the same .feed-content column as observation cards.
Body is now a 3-column grid of square feature blocks — Live feed,
Tune it, Recall it — each with a custom inline SVG illustration
(stacked cards with color-coded stripes, gear+sliders, magnifier
over cards). Old text-row sections (welcome-card-types,
welcome-card-tips, welcome-card-section, welcome-card-tip-icon)
are removed. Squares stack to one column under 600px.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(viewer): convert welcome card to glassy modal with stylized logo

Card now opens as a centered modal with a frosted/glass backdrop
(blur + saturate) so it doubles as a proper help dialog when reopened
from the header's question-mark button. Removed the observation count,
project count, and "since" date — those don't make sense for a
first-launch surface and felt out of place in a help context.

Header art swapped from the small webp logomark to the new
high-resolution sun/sunburst PNG (claude-mem-logo-stylized.png),
shipped as a checked-in asset in src/ui and plugin/ui.

Bigger throughout: 28px h2, 16px tagline, 88px illustrations,
26px feature padding, 1:1 aspect-ratio squares. Backdrop click and
Esc both close. Mobile collapses the grid to one column and drops
the aspect-ratio constraint.

Reverted the unused pinnedTop slot on Feed.tsx since the welcome
card is now a true overlay rather than an in-feed pinned card.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(viewer): make welcome modal actually glassy

Previous version had a 55%-opacity black backdrop that almost fully
blocked the underlying UI — the "glass" was just a dark plate.

Now the backdrop is fully transparent (no darkening at all), the
panel itself drops to 55% bg-card opacity with its existing
backdrop-filter blur(28px) saturate(170%), and the feature squares
drop to 35% bg-tertiary so they layer as glass-on-glass over the
already-blurred panel. The header and feed below now read clearly
through the modal's frosted blur.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(viewer): bulletproof square features via padding-bottom + clamp() fluid type

Squares were rendering taller than wide because aspect-ratio is treated
as a minimum — content can push the box past 1:1. Switched to the
classic padding-bottom: 100% trick: percentage padding resolves against
the parent's width, so the box is ALWAYS W × W regardless of content.
Inner content sits in an absolutely-positioned flex column that can't
push the shell taller.

Whole modal is now desktop-first and fluid via clamp() — no media-query
stair-steps for type, padding, gaps, border-radius, illustration size,
or modal width. Single mobile breakpoint at <600px collapses the grid
to one column and reverts the padding-bottom trick so each feature can
grow to natural content height.

Tightened the three feature descriptions so they fit comfortably inside
the square at the desktop size.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(viewer): 15% black overlay + heavier modal shadow for elevation

Backdrop goes from transparent to rgba(0,0,0,0.15) — just enough
darkening to push the modal visually forward without burying the
underlying UI. Modal shadow stacked: 40px/120px ambient + 16px/48px
contact, both deeper, plus the existing inset 1px highlight.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(build): clear pending_messages queue on build-and-sync

Rewrites scripts/clear-failed-queue.ts to talk directly to SQLite via
bun:sqlite — the previous HTTP endpoints (/api/pending-queue/*) were
removed during the queue engine rewrite, so the script was orphaned.
Wires `npm run queue:clear` into `build-and-sync` so each rebuild
starts with a clean queue.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(worker): collapse parser to binary valid/invalid + clearPendingForSession model

- Parser: { valid: true, observations, summary } | { valid: false } — drops kind/skipped enum dispatch
- ResponseProcessor: two branches only (parseable → store + clearPendingForSession; else → no-op)
- Drop processingMessageIds + per-message claim/confirm/markFailed lifecycle across 3 providers
- PendingMessageStore: 226 → 140 lines; remove markFailed/transitionMessagesTo/confirmProcessed/clearFailedOlderThan/getAllPending/peekPendingTypes... wait keep peekPendingTypes
- Schema migration v31+v32: drop retry_count, failed_at_epoch, completed_at_epoch, worker_pid columns
- SessionQueueProcessor: delete two 1s recovery sleeps (let iterator end on error)
- Server.ts/SettingsRoutes.ts: replace four magic-number setTimeout exit-flush patterns with flushResponseThen helper
- GeneratorExitHandler: 183 → 117 lines (drain in-flight loop gone)

Net: -181 lines. No more silent data loss via maxRetries=3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(pr-2255): address review comments batch 1

- install.ts: needsMarketplace true when claude-code selected (P1, was no-op)
- install.ts: throw on invalid --model so CLI exits non-zero
- install.ts: skip worker health checks + adapt next-step copy when --no-auto-start
- install.ts: repair regenerates plugin cache when missing
- index.ts: readFlag rejects missing/flag-shaped values
- index.ts: route flag-first invocations (e.g. `--provider claude`) to install
- banner.ts: fail-open if frame payload decode throws
- SearchRoutes.ts: 5s TTL cache for settings reads on hot hook path (P2)
- detect-error-handling-antipatterns.ts: trailing-brace strip whitespace-tolerant
- investigate-timestamps.ts: compute Dec 2025 epochs at runtime (was Dec 2024)
- regenerate-claude-md.ts: include workingDir in fallback walker so root is covered
- sync-marketplace.cjs: parseWorkerPort validates 1..65535 before http.request
- sync-to-marketplace.sh: resolve SOURCE_DIR from script location, not cwd
- Dockerfile.test-installer: bash --login sources .bashrc via .bash_profile
- docs/configuration.mdx: drop nonexistent .worker.port file refs, use settings.json
- docs/architecture-overview.md: dynamic port + queue model after parser collapse
- docs/architecture/worker-service.mdx: dynamic port example + drop port-file claim
- docs/platform-integration.mdx: WORKER_BASE_URL pattern, drop hardcoded 37777
- install/public/install.sh: Node 20 floor (was 18) to match docs

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(pr-2255): reset claimed messages to pending on early-return paths

ResponseProcessor returns early in two cases:
- parser invalid (unparseable response)
- memorySessionId not yet captured

Both paths previously left the just-claimed message in `status='processing'`,
which counts toward `getPendingCount`. The generator-exit handler then sees
`pendingCount > 0` and respawns the generator, looping until the restart
guard trips and `clearPendingForSession` deletes the message — silent data
loss.

Calling `resetProcessingToPending` on these paths lets the next generator
pass re-claim the message and try again, instead of burning the restart
budget on no-op respawns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(pr-2255): swebench fallback row + troubleshooting port path

- evals/swebench/run-batch.py: append fallback prediction row when
  orchestrator future raises, preserving "never drop an instance" guarantee
- docs/troubleshooting.mdx: drop nonexistent .worker.port / worker.port file
  references; use settings.json + /api/health for port discovery

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(pr-2255): memoize per-project observation count for welcome-hint hot path

handleContextInject runs on every PostToolUse hook (after every Read/Edit).
The welcome-hint block ran a COUNT(*) on observations for every call once
CLAUDE_MEM_WELCOME_HINT_ENABLED was true. Observation counts are
monotonically increasing — once a project has any observations it always
will — so cache the positive result in a Set and skip the COUNT(*) on
subsequent requests.

Combined with the 5s settings TTL added earlier, the steady-state cost on
the hook hot path drops to a Set lookup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(pr-2255): use clearProcessingForSession on AI-success path

clearPendingForSession deletes ALL rows for the session. On the success
path of processAgentResponse, that's wrong: messages that arrived as
'pending' during the (1-5s) AI response latency get deleted along with
the 'processing' row we just consumed. In a hook burst (three quick
PostToolUse hooks), B and C land while A is in flight; A's success then
nukes B and C — silent data loss.

Add a status-scoped clearProcessingForSession to PendingMessageStore +
SessionManager, and use it in ResponseProcessor's success path. The
unconditional clearPendingForSession remains correct in
GeneratorExitHandler for hard-stop / restart-guard-trip paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Revert "fix(pr-2255): use clearProcessingForSession on AI-success path"

This reverts commit a08995299c30cbad36bddc3e5bddda7af8604b35.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:05:56 -07:00
Ousama Ben Younes b81281fd6c fix: update default model from claude-sonnet-4-5 to claude-sonnet-4-6 (#1390)
CLAUDE_MEM_MODEL defaulted to the deprecated claude-sonnet-4-5 across source,
installer, tests, and documentation. Updated all references to claude-sonnet-4-6.

Closes #1390

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-31 22:42:23 +00:00
Alex Newman 4df9f61347 refactor: implement in-process worker architecture for hooks (#722)
* fix: stop generating empty CLAUDE.md files

- Return empty string instead of "No recent activity" when no observations exist
- Skip writing CLAUDE.md files when formatted content is empty
- Remove redundant "auto-generated by claude-mem" HTML comment
- Clean up 98 existing empty CLAUDE.md files across the codebase
- Update tests to expect empty string for empty input

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* build assets

* refactor: implement in-process worker architecture for hooks

Replaces spawn-based worker startup with in-process architecture:
- Hook processes now become the worker when port 37777 is free
- Eliminates Windows spawn issues (NO SPAWN rule)
- SessionStart chains: smart-install && stop && context

Key changes:
- worker-service.ts: hook case starts WorkerService in-process
- hook-command.ts: skipExit option prevents process.exit() when hosting worker
- hooks.json: single chained command replaces separate start/hook commands
- worker-utils.ts: ensureWorkerRunning() returns boolean, doesn't block
- handlers: graceful fallback when worker unavailable

All 761 tests pass. Manual verification confirms hook stays alive as worker.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* context

* a

* MAESTRO: Mark PR #722 test verification task complete

All 797 tests passed (3 skipped, 0 failed) after merge conflict resolution.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* MAESTRO: Mark PR #722 build verification task complete

* MAESTRO: Mark PR #722 code review task complete

Code review verified:
- worker-service.ts hook case starts WorkerService in-process
- hook-command.ts has skipExit option
- hooks.json uses single chained command
- worker-utils.ts ensureWorkerRunning() returns boolean

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* MAESTRO: Mark PR #722 conflict resolution push task complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 19:49:15 -05:00
Alex Newman 2659ec3231 fix: Claude Code 2.1.1 compatibility + log-level audit + path validation fixes (#614)
* Refactor CLAUDE.md and related files for December 2025 updates

- Updated CLAUDE.md in src/services/worker with new entries for December 2025, including changes to Search.ts, GeminiAgent.ts, SDKAgent.ts, and SessionManager.ts.
- Revised CLAUDE.md in src/shared to reflect updates and new entries for December 2025, including paths.ts and worker-utils.ts.
- Modified hook-constants.ts to clarify exit codes and their behaviors.
- Added comprehensive hooks reference documentation for Claude Code, detailing usage, events, and examples.
- Created initial CLAUDE.md files in various directories to track recent activity.

* fix: Merge user-message-hook output into context-hook hookSpecificOutput

- Add footer message to additionalContext in context-hook.ts
- Remove user-message-hook from SessionStart hooks array
- Fixes issue where stderr+exit(1) approach was silently discarded

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update logs and documentation for recent plugin and worker service changes

- Added detailed logs for worker service activities from Dec 10, 2025 to Jan 7, 2026, including initialization patterns, cleanup confirmations, and diagnostic logging.
- Updated plugin documentation with recent activities, including plugin synchronization and configuration changes from Dec 3, 2025 to Jan 7, 2026.
- Enhanced the context hook and worker service logs to reflect improvements and fixes in the plugin architecture.
- Documented the migration and verification processes for the Claude memory system and its integration with the marketplace.

* Refactor hooks architecture and remove deprecated user-message-hook

- Updated hook configurations in CLAUDE.md and hooks.json to reflect changes in session start behavior.
- Removed user-message-hook functionality as it is no longer utilized in Claude Code 2.1.0; context is now injected silently.
- Enhanced context-hook to handle session context injection without user-visible messages.
- Cleaned up documentation across multiple files to align with the new hook structure and removed references to obsolete hooks.
- Adjusted timing and command execution for hooks to improve performance and reliability.

* fix: Address PR #610 review issues

- Replace USER_MESSAGE_ONLY test with BLOCKING_ERROR test in hook-constants.test.ts
- Standardize Claude Code 2.1.0 note wording across all three documentation files
- Exclude deprecated user-message-hook.ts from logger-usage-standards test

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Remove hardcoded fake token counts from context injection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Address PR #610 review issues by fixing test files, standardizing documentation notes, and verifying code quality improvements.

* fix: Add path validation to CLAUDE.md distribution to prevent invalid directory creation

- Add isValidPathForClaudeMd() function to reject invalid paths:
  - Tilde paths (~) that Node.js doesn't expand
  - URLs (http://, https://)
  - Paths with spaces (likely command text or PR references)
  - Paths with # (GitHub issue/PR references)
  - Relative paths that escape project boundary

- Integrate validation in updateFolderClaudeMdFiles loop
- Add 6 unit tests for path validation
- Update .gitignore to prevent accidental commit of malformed directories
- Clean up existing invalid directories (~/, PR #610..., git diff..., https:)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: Implement path validation in CLAUDE.md generation to prevent invalid directory creation

- Added `isValidPathForClaudeMd()` function to validate file paths in `src/utils/claude-md-utils.ts`.
- Integrated path validation in `updateFolderClaudeMdFiles` to skip invalid paths.
- Added 6 new unit tests in `tests/utils/claude-md-utils.test.ts` to cover various rejection cases.
- Updated `.gitignore` to prevent tracking of invalid directories.
- Cleaned up existing invalid directories in the repository.

* feat: Promote critical WARN logs to ERROR level across codebase

Comprehensive log-level audit promoting 38+ WARN messages to ERROR for
improved debugging and incident response:

- Parser: observation type errors, data contamination
- SDK/Agents: empty init responses (Gemini, OpenRouter)
- Worker/Queue: session recovery, auto-recovery failures
- Chroma: sync failures, search failures (now treated as critical)
- SQLite: search failures (primary data store)
- Session/Generator: failures, missing context
- Infrastructure: shutdown, process management failures
- File Operations: CLAUDE.md updates, config reads
- Branch Management: recovery checkout failures

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: Address PR #614 review issues

- Remove incorrectly tracked tilde-prefixed files from git
- Fix absolute path validation to check projectRoot boundaries
- Add test coverage for absolute path validation edge cases

Closes review issues:
- Issue 1: ~/ prefixed files removed from tracking
- Issue 3: Absolute paths now validated against projectRoot
- Issue 4: Added 3 new test cases for absolute path scenarios

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* build assets and context

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 23:34:20 -05:00
Alex Newman a3d6bfc7dd feat: Update CLAUDE.md files with recent test activities and improvements
- Added detailed entries for test activities across various modules including `export-types.test.ts`, `server.test.ts`, `smart-install.test.ts`, and others.
- Documented significant changes in test coverage, cleanup efforts, and regression tests.
- Enhanced the `plans` documentation with recent implementation strategies and PR follow-ups.
- Introduced a comprehensive report on Windows platform challenges and solutions, detailing issues like zombie ports, console popups, and process management.
- Established a new `ProcessManager` architecture to address Windows-specific issues and improve reliability.
- Updated integration tests to reflect recent changes and ensure comprehensive coverage.
2026-01-07 16:53:02 -05:00
Alex Newman e1ab73decc feat: Live Context System with Distributed CLAUDE.md Generation (#556)
* docs: add folder index generator plan

RFC for auto-generating folder-level CLAUDE.md files with observation
timelines. Includes IDE symlink support and root CLAUDE.md integration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: implement folder index generator (Phase 1)

Add automatic CLAUDE.md generation for folders containing observed files.
This enables IDE context providers to access relevant memory observations.

Core modules:
- FolderDiscovery: Extract folders from observation file paths
- FolderTimelineCompiler: Compile chronological timeline per folder
- ClaudeMdGenerator: Write CLAUDE.md with tag-based content replacement
- FolderIndexOrchestrator: Coordinate regeneration on observation save

Integration:
- Event-driven regeneration after observation save in ResponseProcessor
- HTTP endpoints for folder discovery, timeline, and manual generation
- Settings for enabling/configuring folder index behavior

The <claude-mem-context> tag wrapping ensures:
- Manual CLAUDE.md content is preserved
- Auto-generated content won't be recursively observed
- Clean separation between user and system content

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add updateFolderClaudeMd function to CursorHooksInstaller

Adds function to update CLAUDE.md files for folders touched by observations.
Uses existing /api/search/by-file endpoint, preserves content outside
<claude-mem-context> tags, and writes atomically via temp file + rename.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: hook updateFolderClaudeMd into ResponseProcessor

Calls updateFolderClaudeMd after observation save to update folder-level
CLAUDE.md files. Uses fire-and-forget pattern with error logging.
Extracts file paths from saved observations and workspace path from registry.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add timeline formatting for folder CLAUDE.md files

Implements formatTimelineForClaudeMd function that transforms API response
into compact markdown table format. Converts emojis to text labels,
handles ditto marks for timestamps, and groups under "Recent" header.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: remove old folder-index implementation

Deletes redundant folder-index services that were replaced by the simpler
updateFolderClaudeMd approach in CursorHooksInstaller.ts.

Removed:
- src/services/folder-index/ directory (5 files)
- FolderIndexRoutes.ts
- folder-index settings from SettingsDefaultsManager
- folder-index route registration from worker-service

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add worktree-aware project filtering for unified timelines

Detect git worktrees and show both parent repo and worktree observations
in the session start timeline. When running in a worktree, the context
now includes observations from both projects, interleaved chronologically.

- Add detectWorktree() utility to identify worktree directories
- Add getProjectContext() to return parent + worktree projects
- Update context hook to pass multi-project queries
- Add queryObservationsMulti() and querySummariesMulti() for IN clauses
- Maintain backward compatibility with single-project queries

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* fix: restructure logging to prove session correctness and reduce noise

Add critical logging at each stage of the session lifecycle to prove the session ID chain (contentSessionId → sessionDbId → memorySessionId) stays aligned. New logs include CREATED, ENQUEUED, CLAIMED, MEMORY_ID_CAPTURED, STORING, and STORED. Move intermediate migration and backfill progress logs to DEBUG level to reduce noise, keeping only essential initialization and completion logs at INFO level.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* refactor: extract folder CLAUDE.md utils to shared location

Moves folder CLAUDE.md utilities from CursorHooksInstaller to a new
shared utils file. Removes Cursor registry dependency - file paths
from observations are already absolute, no workspace lookup needed.

New file: src/utils/claude-md-utils.ts
- replaceTaggedContent() - preserves user content outside tags
- writeClaudeMdToFolder() - atomic writes with tag preservation
- formatTimelineForClaudeMd() - API response to compact markdown
- updateFolderClaudeMdFiles() - orchestrates folder updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: trigger folder CLAUDE.md updates when observations are saved

The folder CLAUDE.md update was previously only triggered in
syncAndBroadcastSummary, but summaries run with observationCount=0
(observations are saved separately). Moved the update logic to
syncAndBroadcastObservations where file paths are available.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* all the claudes

* test: add unit tests for claude-md-utils pure functions

Add 11 tests covering replaceTaggedContent and formatTimelineForClaudeMd:
- replaceTaggedContent: empty content, tag replacement, appending, partial tags
- formatTimelineForClaudeMd: empty input, parsing, ditto marks, session IDs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add integration tests for file operation functions

Add 9 tests for writeClaudeMdToFolder and updateFolderClaudeMdFiles:
- writeClaudeMdToFolder: folder creation, content preservation, nested dirs, atomic writes
- updateFolderClaudeMdFiles: empty skip, fetch/write, deduplication, error handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add unit tests for timeline-formatting utilities

Add 14 tests for extractFirstFile and groupByDate functions:
- extractFirstFile: relative paths, fallback to files_read, null handling, invalid JSON
- groupByDate: empty arrays, date grouping, chronological sorting, item preservation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: rebuild plugin scripts with merged features

* docs: add project-specific CLAUDE.md with architecture and development notes

* fix: exclude project root from auto-generated CLAUDE.md updates

Skip folders containing .git directory when auto-updating subfolder
CLAUDE.md files. This ensures:

1. Root CLAUDE.md remains user-managed and untouched by the system
2. SessionStart context injection stays pristine throughout the session
3. Subfolder CLAUDE.md files continue to receive live context updates
4. Cleaner separation between user-authored root docs and auto-generated folder indexes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: prevent crash from resuming stale SDK sessions on worker restart

When the worker restarts, it was incorrectly passing the `resume` parameter
to INIT prompts (lastPromptNumber=1) when a memorySessionId existed from a
previous SDK session. This caused "Claude Code process exited with code 1"
crashes because the SDK tried to resume into a session that no longer exists.

Root cause: The resume condition only checked `hasRealMemorySessionId` but
did not verify that this was a CONTINUATION prompt (lastPromptNumber > 1).

Fix: Add `session.lastPromptNumber > 1` check to the resume condition:
- Before: `...(hasRealMemorySessionId && { resume: session.memorySessionId })`
- After: `...(hasRealMemorySessionId && session.lastPromptNumber > 1 && { resume: ... })`

Also added:
- Enhanced debug logging that warns when skipping resume for INIT prompts
- Unit tests in tests/sdk-agent-resume.test.ts (9 test cases)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: properly handle Chroma MCP connection errors

Previously, ensureCollection() caught ALL errors from chroma_get_collection_info
and assumed they meant "collection doesn't exist", triggering unnecessary
collection creation attempts. Connection errors like "Not connected" or
"MCP error -32000: Connection closed" would cascade into failed creation attempts.

Similarly, queryChroma() would silently return empty results when the MCP call
failed, masking the underlying connection problem.

Changes:
- ensureCollection(): Detect connection errors and re-throw immediately instead
  of attempting collection creation
- queryChroma(): Wrap MCP call in try-catch and throw connection errors instead
  of returning empty results
- Both methods reset connection state (connected=false, client=null) on
  connection errors so subsequent operations can attempt to reconnect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* pushed

* fix: scope regenerate-claude-md.ts to current working directory

Critical bug fix: The script was querying ALL observations from the database
across ALL projects ever recorded (1396+ folders), then attempting to write
CLAUDE.md files everywhere including other projects, non-existent paths, and
ignored directories.

Changes:
- Use git ls-files to discover folders (respects .gitignore automatically)
- Filter database query to current project only (by folder name)
- Use relative paths for database queries (matches storage format)
- Add --clean flag to remove auto-generated CLAUDE.md files
- Add fallback directory walker for non-git repos

Now correctly scopes to 26 folders with observations instead of 1396+.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs and adjustments

* fix: cleanup mode strips tags instead of deleting files blindly

The cleanup mode was incorrectly deleting entire files that contained
<claude-mem-context> tags. The correct behavior (per original design):

1. Strip the <claude-mem-context>...</claude-mem-context> section
2. If empty after stripping → delete the file
3. If has remaining content → save the stripped version

Now properly preserves user content in CLAUDE.md files while removing
only the auto-generated sections.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* deleted some files

* chore: regenerate folder CLAUDE.md files with fixed script

Regenerated 23 folder CLAUDE.md files using the corrected script that:
- Scopes to current working directory only
- Uses git ls-files to respect .gitignore
- Filters by project name

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update CLAUDE.md files for January 5, 2026

- Regenerated and staged 23 CLAUDE.md files with a mix of new and modified content.
- Fixed cleanup mode to properly strip tags instead of deleting files blindly.
- Cleaned up empty CLAUDE.md files from various directories, including ~/.claude and ~/Scripts.
- Conducted dry-run cleanup that identified a significant reduction in auto-generated CLAUDE.md files.
- Removed the isAutoGeneratedClaudeMd function due to incorrect file deletion behavior.

* feat: use settings for observation limit in batch regeneration script

Replace hard-coded limit of 10 with configurable CLAUDE_MEM_CONTEXT_OBSERVATIONS
setting (default: 50). This allows users to control how many observations appear
in folder CLAUDE.md files.

Changes:
- Import SettingsDefaultsManager and load settings at script startup
- Use OBSERVATION_LIMIT constant derived from settings at both call sites
- Remove stale default parameter from findObservationsByFolder function

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: use settings for observation limit in event-driven updates

Replace hard-coded limit of 10 in updateFolderClaudeMdFiles with
configurable CLAUDE_MEM_CONTEXT_OBSERVATIONS setting (default: 50).

Changes:
- Import SettingsDefaultsManager and os module
- Load settings at function start (once, not in loop)
- Use limit from settings in API call

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Implement configurable observation limits and enhance search functionality

- Added configurable observation limits to batch regeneration scripts.
- Enhanced SearchManager to handle folder queries and normalize parameters.
- Introduced methods to check for direct child files in observations and sessions.
- Updated SearchOptions interface to include isFolder flag for filtering.
- Improved code quality with comprehensive reviews and anti-pattern checks.
- Cleaned up auto-generated CLAUDE.md files across various directories.
- Documented recent changes and improvements in CLAUDE.md files.

* build asset

* Project Context from Claude-Mem auto-added (can be auto removed at any time)

* CLAUDE.md updates

* fix: resolve CLAUDE.md files to correct directory in worktree setups

When using git worktrees, CLAUDE.md files were being written relative to
the worker's process.cwd() instead of the actual project directory. This
fix threads the project's cwd from message processing through to the file
writing utilities, ensuring CLAUDE.md files are created in the correct
project directory regardless of where the worker was started.

Changes:
- Add projectRoot parameter to updateFolderClaudeMdFiles for path resolution
- Thread projectRoot through ResponseProcessor call chain
- Track lastCwd from messages in SDKAgent, GeminiAgent, OpenRouterAgent
- Add tests for relative/absolute path handling with projectRoot

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* more project context updates

* context updates

* fix: preserve actual dates in folder CLAUDE.md generation

Previously, formatTimelineForClaudeMd used today's date for all
observations because the API only returned time (e.g., "4:30 PM")
without date information. This caused all historical observations
to appear as if they happened today.

Changes:
- SearchManager.findByFile now groups results by date with headers
  (e.g., "### Jan 4, 2026") matching formatSearchResults behavior
- formatTimelineForClaudeMd now parses these date headers and uses
  the correct date when constructing epochs for date grouping

The timeline dates are critical for claude-mem context - LLMs need
accurate temporal context to understand when work happened.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* build: update worker assets with date parsing fix

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* claude-mem context: Fixed critical date parsing bug in PR #556

* fix: address PR #556 review items

- Use getWorkerHost() instead of hard-coded 127.0.0.1 in claude-md-utils
- Add error message and stack details to FOLDER_INDEX logging
- Add 5 new tests for worktree/projectRoot path resolution

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Refactor CLAUDE documentation across multiple components and tests

- Updated CLAUDE.md files in src/ui/viewer, src/ui/viewer/constants, src/ui/viewer/hooks, tests/server, tests/worker/agents, and plans to reflect recent changes and improvements.
- Removed outdated entries and consolidated recent activities for clarity.
- Enhanced documentation for hooks, settings, and pagination implementations.
- Streamlined test suite documentation for server and worker agents, indicating recent test audits and cleanup efforts.
- Adjusted plans to remove obsolete entries and focus on current implementation strategies.

* docs: comprehensive v9.0 documentation audit and updates

- Add usage/folder-context to docs.json navigation (was documented but hidden!)
- Update introduction.mdx with v9.0 release notes (Live Context, Worktree Support, Windows Fixes)
- Add CLAUDE_MEM_WORKER_HOST setting to configuration.mdx
- Add Folder Context Files section with link to detailed docs
- Document worktree support in folder-context.mdx
- Update terminology from "mem-search skill" to "MCP tools" throughout active docs
- Update Search Pipeline in architecture/overview.mdx
- Update usage/getting-started.mdx with MCP tools terminology
- Update usage/claude-desktop.mdx title and terminology
- Update hooks-architecture.mdx reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add recent activity log for worker CLI with detailed entries

* chore: update CLAUDE.md context files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add brainstorming report for CLAUDE.md distribution architecture

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 22:41:42 -05:00
Alex Newman fef332d213 feat: add examples for Claude Agent SDK V2 including basic, multi-turn, one-shot, and session resume functionalities 2025-12-31 16:37:49 -05:00
Alex Newman 8d485890b9 feat(cursor): Add Claude-Mem Cursor hooks installation and management
- Introduced functionality for installing, uninstalling, and checking the status of Cursor hooks.
- Added a new command structure for managing hooks with detailed usage instructions.
- Implemented a method to locate the cursor-hooks directory across different environments.
- Updated build-hooks script to inform users about the location of Cursor hooks.

This enhancement streamlines the integration of Claude-Mem with Cursor, improving user experience and accessibility of hooks.
2025-12-29 20:14:23 -05:00
Alex Newman 78cb5c38dc Remove outdated documentation files related to Claude-Mem hooks cleanup, PR #335 review summary, and Windows worker struggles. These files contained obsolete information and action items that are no longer relevant to the current project state. 2025-12-16 17:19:23 -05:00
Alex Newman 426fbdd38d Merge main into fix/windows-console-popups
Resolved conflicts in built files by rebuilding

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 17:04:48 -05:00
Alex Newman 282345f379 backup: Phase 1 agent work (security, persistence, batch endpoint)
This is a backup of all work done by the 3 Phase 1 agents:

Agent A - Command Injection Fix (Issue #354):
- Fixed command injection in BranchManager.ts
- Fixed unnecessary shell usage in bun-path.ts
- Added comprehensive security test suite
- Created SECURITY.md and SECURITY_AUDIT_REPORT.md

Agent B - Observation Persistence Fix (Issue #353):
- Added PendingMessageStore from PR #335
- Integrated persistent queue into SessionManager
- Modified SDKAgent to mark messages complete
- Updated SessionStore with pending_messages migration
- Updated worker-types.ts with new interfaces

Agent C - Batch Endpoint Verification (Issue #348):
- Created batch-observations.test.ts
- Updated worker-service.mdx documentation

Also includes:
- Documentation context files (biomimetic, windows struggles)
- Build artifacts from agent testing

This work will be re-evaluated after v7.3.0 release.
2025-12-16 15:44:06 -05:00
Alex Newman 23591db589 fix: Windows console popup issue using PowerShell workaround
Fixes blank console windows appearing on Windows 11 when spawning the worker process.

## Problem

On Windows, `windowsHide: true` doesn't work when combined with `detached: true` in child_process.spawn().
This is a Node.js limitation (nodejs/node#21825) that **Bun also inherits** because Bun uses Node.js process spawning semantics.

Result: Blank console windows with "claude" title appear during claude-mem operations.

## Solution

Use PowerShell's `Start-Process -WindowStyle Hidden` on Windows to properly hide console windows.
Unix platforms continue using standard `spawn()` with `detached: true`.

## Testing

Validated by ToxMox on Windows 11 in PR #315:
- windowsHide approach:  Still shows blank consoles
- PowerShell approach:  Properly hides windows

## Implementation

```typescript
// Windows: PowerShell workaround
Start-Process -FilePath 'bun' -ArgumentList '${script}' -WindowStyle Hidden

// Unix: Standard spawn (works fine)
spawn(bunPath, [script], { detached: true })
```

## Notes

- Affects BOTH Bun and Node.js runtimes on Windows
- This is a **high-priority fix** for Windows users
- Keeps Bun runtime (doesn't address zombie socket issue)
- Zombie socket issue is separate and requires different solution

## References

- Issue: #304 (Multiple visible console windows on Windows 11)
- Testing: PR #315 (ToxMox's detailed analysis)
- Node.js bug: nodejs/node#21825
- Extracted from: PR #335

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 23:13:21 -05:00
Alex Newman 61488042d8 Mem-search enhancements: table output, simplified API, Sonnet default, and removed fake URIs (#317)
* feat: Add batch fetching for observations and update documentation

- Implemented a new endpoint for fetching multiple observations by IDs in a single request.
- Updated the DataRoutes to include a POST /api/observations/batch endpoint.
- Enhanced SKILL.md documentation to reflect changes in the search process and batch fetching capabilities.
- Increased the default limit for search results from 5 to 40 for better usability.

* feat!: Fix timeline parameter passing with SearchManager alignment

BREAKING CHANGE: Timeline MCP tools now use standardized parameter names
- anchor_id → anchor
- before → depth_before
- after → depth_after
- obs_type → type (timeline tool only)

Fixes timeline endpoint failures caused by parameter name mismatch between
MCP layer and SearchManager. Adds new SessionStore methods for fetching
prompts and session summaries by ID.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: reframe timeline parameter fix as bug fix, not breaking change

The timeline tools were completely broken due to parameter name mismatch.
There's nothing to migrate from since the old parameters never worked.

Co-authored-by: Alex Newman <thedotmack@users.noreply.github.com>

* Refactor mem-search documentation and optimize API tool definitions

- Updated SKILL.md to emphasize batch fetching for observations, clarifying usage and efficiency.
- Removed deprecated tools from mcp-server.ts and streamlined tool definitions for clarity.
- Enhanced formatting in FormattingService.ts for better output readability.
- Adjusted SearchManager.ts to improve result headers and removed unnecessary search tips from combined text.

* Refactor FormattingService and SearchManager for table-based output

- Updated FormattingService to format search results as tables, including methods for formatting observations, sessions, and user prompts.
- Removed JSON format handling from SearchManager and streamlined result formatting to consistently use table format.
- Enhanced readability and consistency in search tips and formatting logic.
- Introduced token estimation for observations and improved time formatting.

* refactor: update documentation and API references for version bump and search functionalities

* Refactor code structure for improved readability and maintainability

* chore: change default model from haiku to sonnet

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: unify timeline formatting across search and context services

Extract shared timeline formatting utilities into reusable module to align
MCP search output format with context-generator's date/file-grouped format.

Changes:
- Create src/shared/timeline-formatting.ts with reusable utilities
  (parseJsonArray, formatDateTime, formatTime, formatDate, toRelativePath,
  extractFirstFile, groupByDate)
- Refactor context-generator.ts to use shared utilities
- Update SearchManager.search() to use date/file grouping
- Add search-specific row formatters to FormattingService
- Fix timeline methods to extract actual file paths from metadata
  instead of hardcoding 'General'
- Remove Work column from search output (kept in context output)

Result: Consistent date/file-grouped markdown formatting across both
systems while maintaining their different column requirements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: remove redundant legend from search output

Remove legend from search/timeline results since it's already shown
in SessionStart context. Saves ~30 tokens per search result.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Refactor session summary rendering to remove links

- Removed link generation for session summaries in context generation and search manager.
- Updated output formatting to exclude links while maintaining the session summary structure.
- Adjusted related components in TimelineService to ensure consistency across the application.

* fix: move skillPath declaration outside try block to fix scoping bug

The skillPath variable was declared inside the try block but referenced
in the catch block for error logging. Since const is block-scoped, this
would cause a ReferenceError when the error handler executes.

Moved skillPath declaration before the try block so it's accessible in
both try and catch scopes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: address PR #317 code review feedback

**Critical Fixes:**
- Replace happy_path_error__with_fallback debug calls with proper logger methods in mcp-server.ts
- All HTTP API calls now use logger.debug/error for consistent logging

**Code Quality Improvements:**
- Extract 90-day recency window magic numbers to named constants
- Added RECENCY_WINDOW_DAYS and RECENCY_WINDOW_MS constants in SearchManager

**Documentation:**
- Document model cost implications of Haiku → Sonnet upgrade in CHANGELOG
- Provide clear migration path for users who want to revert to Haiku

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: simplify CHANGELOG - remove cost documentation

Removed model cost comparison documentation per user feedback.
Kept only the technical code quality improvements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Alex Newman <thedotmack@users.noreply.github.com>
2025-12-14 21:58:11 -05:00
Alex Newman 52d2f72a82 Standardize and enhance error handling across hooks and worker service (#295)
* Enhance error logging in hooks

- Added detailed error logging in context-hook, new-hook, save-hook, and summary-hook to capture status, project, port, and relevant session information on failures.
- Improved error messages thrown in save-hook and summary-hook to include specific context about the failure.

* Refactor migration logging to use console.log instead of console.error

- Updated SessionSearch and SessionStore classes to replace console.error with console.log for migration-related messages.
- Added notes in the documentation to clarify the use of console.log for migration messages due to the unavailability of the structured logger during constructor execution.

* Refactor SDKAgent and silent-debug utility to simplify error handling

- Updated SDKAgent to use direct defaults instead of happy_path_error__with_fallback for non-critical fields such as last_user_message, last_assistant_message, title, filesRead, filesModified, concepts, and summary.request.
- Enhanced silent-debug documentation to clarify appropriate use cases for happy_path_error__with_fallback, emphasizing its role in handling unexpected null/undefined values while discouraging its use for nullable fields with valid defaults.

* fix: correct happy_path_error__with_fallback usage to prevent false errors

Fixes false "Missing cwd" and "Missing transcript_path" errors that were
flooding silent.log even when values were present.

Root cause: happy_path_error__with_fallback was being called unconditionally
instead of only when the value was actually missing.

Pattern changed from:
  value: happy_path_error__with_fallback('Missing', {}, value || '')

To correct usage:
  value: value || happy_path_error__with_fallback('Missing', {}, '')

Fixed in:
- src/hooks/save-hook.ts (PostToolUse hook)
- src/hooks/summary-hook.ts (Stop hook)
- src/services/worker/http/routes/SessionRoutes.ts (2 instances)

Impact: Eliminates false error noise, making actual errors visible.

Addresses issue #260 - users were seeing "Missing cwd" errors despite
Claude Code correctly passing all required fields.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Enhance error logging and handling across services

- Improved error messages in SessionStore to include project context when fetching boundary observations and timestamps.
- Updated ChromaSync error handling to provide more informative messages regarding client initialization failures, including the project context.
- Enhanced error logging in WorkerService to include the package path when reading version fails.
- Added detailed error logging in worker-utils to capture expected and running versions during health checks.
- Extended WorkerErrorMessageOptions to include actualError for more informative restart instructions.

* Refactor error handling in hooks to use standardized fetch error handler

- Introduced a new error handler `handleFetchError` in `shared/error-handler.ts` to standardize logging and user-facing error messages for fetch failures across hooks.
- Updated `context-hook.ts`, `new-hook.ts`, `save-hook.ts`, and `summary-hook.ts` to utilize the new error handler, improving consistency and maintainability.
- Removed redundant imports and error handling logic related to worker restart instructions from the hooks.

* feat: add comprehensive error handling tests for hooks and ChromaSync client

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-13 23:25:43 -05:00
Alex Newman 1491123706 feat(ProcessManager): add Bun availability check and improve PID file validation
- Implemented a method to check if Bun is available in the system PATH.
- Updated the startWithBun method to return an error if Bun is not found.
- Enhanced PID file parsing to validate required fields and their types.
- Cleaned up stale PID files if the process is no longer alive.

fix(SettingsRoutes): clear port cache after updating settings

- Added a call to clearPortCache after writing updated settings to ensure the application uses the latest configuration.
2025-12-12 17:48:41 -05:00
Alex Newman eaba21329c Refactor hooks codebase: reduce complexity and improve maintainability (#204)
* refactor: Clean up hook-response and new-hook files

- Removed 'PreCompact' hook type and associated logic from hook-response.ts for improved type safety.
- Deleted extensive architecture comments in new-hook.ts to streamline code readability.
- Simplified debug logging in new-hook.ts to reduce verbosity.
- Enhanced ensureWorkerRunning function in worker-utils.ts with a final health check before throwing errors.
- Added a new documentation file outlining the hooks cleanup process and future improvements.

* Refactor cleanup and user message hooks

- Updated cleanup-hook.js to improve error handling and remove unnecessary input checks.
- Simplified user-message-hook.js by removing time-sensitive announcements and streamlining output.
- Enhanced logging functionality in both hooks for better debugging and clarity.

* Refactor error handling in hooks to use centralized error handler

- Introduced `handleWorkerError` function in `src/shared/hook-error-handler.ts` to manage worker-related errors.
- Updated `context-hook.ts`, `new-hook.ts`, `save-hook.ts`, and `summary-hook.ts` to utilize the new error handler, simplifying error management and improving code readability.
- Removed repetitive error handling logic from individual hooks, ensuring consistent user-friendly messages for connection issues.

* Refactor user-message and summary hooks to utilize shared transcript parser; introduce hook exit codes

- Moved user message extraction logic to a new shared module `transcript-parser.ts` for better code reuse.
- Updated `summary-hook.ts` to use the new `extractLastMessage` function for retrieving user and assistant messages.
- Replaced direct exit code usage in `user-message-hook.ts` with constants from `hook-constants.ts` for improved readability and maintainability.
- Added `HOOK_EXIT_CODES` to `hook-constants.ts` to standardize exit codes across hooks.

* Refactor hook input interfaces to enforce required fields

- Updated `SessionStartInput`, `UserPromptSubmitInput`, `PostToolUseInput`, and `StopInput` interfaces to require `session_id`, `transcript_path`, and `cwd` fields, ensuring better type safety and clarity in hook inputs.
- Removed optional index signatures from these interfaces to prevent unintended properties and improve code maintainability.
- Adjusted related hook implementations to align with the new interface definitions.

* Refactor save-hook to remove tool skipping logic; enhance summary-hook to handle spinner stopping with error logging; update SessionRoutes to load skip tools from settings; add CLAUDE_MEM_SKIP_TOOLS to SettingsDefaultsManager for configurable tool exclusion.

* Document CLAUDE_MEM_SKIP_TOOLS setting in public docs

Added documentation for the new CLAUDE_MEM_SKIP_TOOLS configuration
setting in response to PR review feedback. Users can now discover and
customize which tools are excluded from observations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-09 22:45:22 -05:00
Alex Newman c3761a2204 Refactor silent debugging to happy path error handling
- Replaced instances of silentDebug with happy_path_error__with_fallback across multiple files to improve error logging and handling.
- Updated the utility function to provide clearer semantics for error handling when expected values are missing.
- Introduced a script to find potential silent failures in the codebase that may need to be addressed with the new error handling approach.
2025-12-09 15:09:44 -05:00
Alex Newman 577cac8831 Add Platform Integration Guide for claude-mem worker service
- Introduced comprehensive documentation for integrating claude-mem into VSCode extensions, IDE plugins, and CLI tools.
- Detailed worker service basics, including environment variables and build commands.
- Provided an overview of worker architecture and request flow.
- Documented API reference for session lifecycle, data retrieval, search operations, and settings configuration.
- Included integration patterns, error handling strategies, and development workflow guidelines.
- Added critical implementation notes and additional resources for developers.
2025-12-08 22:36:00 -05:00
Alex Newman 2b223b7cd9 feat: Add dual-tag system for meta-observation control (#153)
* feat: Add dual-tag system for meta-observation control

Implements <private> and <claude-mem-context> tag stripping at hook layer
to give users fine-grained control over what gets persisted in observations
and enable future real-time context injection without recursive storage.

**Features:**
- stripMemoryTags() function in save-hook.ts
- Strips both <private> and <claude-mem-context> tags before sending to worker
- Always active (no configuration needed)
- Comprehensive test suite (19 tests, all passing)
- User documentation for <private> tag
- Technical architecture documentation

**Architecture:**
- Edge processing pattern (filter at hook, not worker)
- Defensive type handling with silentDebug
- Supports multiline, nested, and multiple tags
- Enables strategic orchestration for internal tools

**User-Facing:**
- <private> tag for manual privacy control (documented)
- Prevents sensitive data from persisting in observations

**Infrastructure:**
- <claude-mem-context> tag ready for real-time context feature
- Prevents recursive storage when context injection ships

**Files:**
- src/hooks/save-hook.ts: Core implementation
- tests/strip-memory-tags.test.ts: Test suite (19/19 passing)
- docs/public/usage/private-tags.mdx: User guide
- docs/public/docs.json: Navigation update
- docs/context/dual-tag-system-architecture.md: Technical docs
- plugin/scripts/save-hook.js: Built hook

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Strip private tags from user prompts and skip memory ops for fully private prompts

Fixes critical privacy bug where <private> tags were not being stripped from
user prompts before storage in user_prompts table, making private content
searchable via mem-search.

Changes:

1. new-hook.ts: Skip memory operations for fully private prompts
   - If cleaned prompt is empty after stripping tags, skip saveUserPrompt
   - Skip worker init to avoid wasting resources on empty prompts
   - Logs: "(fully private - skipped)"

2. save-hook.ts: Skip observations for fully private prompts
   - Check if user prompt was entirely private before creating observations
   - Respects user intent: fully private prompt = no observations at all
   - Prevents "thoughts pop up" issue where private prompts create public observations

3. SessionStore.ts: Add getUserPrompt() method
   - Retrieves prompt text by session_id and prompt_number
   - Used by save-hook to check if prompt was private

4. Tests: Added 4 new tests for fully private prompt detection (16 total, all passing)

5. Docs: Updated private-tags.mdx to reflect correct behavior
   - User prompts ARE now filtered before storage
   - Private content never reaches database or search indices

Privacy Protection:
- Fully private prompts: No user_prompt saved, no worker init, no observations
- Partially private prompts: Tags stripped, content sanitized before storage
- Zero leaks: Private content never indexed or searchable

Addresses reviewer feedback on PR #153 about user prompt filtering.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Enhance memory tag handling and indexing in user prompts

- Added a new index `idx_user_prompts_lookup` on `user_prompts` for improved query performance based on `claude_session_id` and `prompt_number`.
- Refactored memory tag stripping functionality into dedicated utility functions: `stripMemoryTagsFromJson` and `stripMemoryTagsFromPrompt` for better separation of concerns and reusability.
- Updated hooks (`new-hook.ts` and `save-hook.ts`) to utilize the new tag stripping functions, ensuring private content is not stored or searchable.
- Removed redundant inline tag stripping functions from hooks to streamline code.
- Added tests for the new tag stripping utilities to ensure functionality and prevent regressions.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-30 22:57:26 -05:00
Alex Newman 01be3156fb fix: context hook updates and cleanup (#150)
* fix(context-hook): update savings message to reference mem-search skill

Changed "Use claude-mem search" to "Use the mem-search skill" for clarity.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: delete outdated docs, experiments, and test results

Removed:
- docs/context/ (moved to private/)
- experiment/ (obsolete)
- test-results/ (stale)
- tests/ (outdated)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(user-message-hook): update support link to Discord community

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-28 20:17:44 -05:00
Alex Newman 4e5913611a feat(search-server): enhance decision search with optional semantic query support
- Updated the 'decisions' tool to accept an optional 'query' parameter for semantic filtering.
- Implemented logic to handle semantic search using Chroma when a query is provided.
- Preserved ranking order of results based on Chroma's output.
- Added fallback to metadata-first search when no query is present.
2025-11-25 16:37:08 -05:00
Alex Newman 9285826547 feat: implement Endless Mode for real-time context compression in Claude sessions 2025-11-16 23:19:43 -05:00
Alex Newman c0778bef00 docs: Align search documentation with hybrid ChromaDB architecture (#116)
* feat: Add discovery_tokens for ROI tracking in observations and session summaries

- Introduced `discovery_tokens` column in `observations` and `session_summaries` tables to track token costs associated with discovering and creating each observation and summary.
- Updated relevant services and hooks to calculate and display ROI metrics based on discovery tokens.
- Enhanced context economics reporting to include savings from reusing previous observations.
- Implemented migration to ensure the new column is added to existing tables.
- Adjusted data models and sync processes to accommodate the new `discovery_tokens` field.

* refactor: streamline context hook by removing unused functions and updating terminology

- Removed the estimateTokens and getObservations helper functions as they were not utilized.
- Updated the legend and output messages to replace "discovery" with "work" for clarity.
- Changed the emoji representation for different observation types to better reflect their purpose.
- Enhanced output formatting for improved readability and understanding of token usage.

* Refactor user-message-hook and context-hook for improved clarity and functionality

- Updated user-message-hook.js to enhance error messaging and improve variable naming for clarity.
- Modified context-hook.ts to include a new column key section, improved context index instructions, and added emoji icons for observation types.
- Adjusted footer messages in context-hook.ts to emphasize token savings and access to past research.
- Changed user-message-hook.ts to update the feedback and support message for clarity.

* fix: Critical ROI tracking fixes from PR review

Addresses critical findings from PR #111 review:

1. **Fixed incorrect discovery token calculation** (src/services/worker/SDKAgent.ts)
   - Changed from passing cumulative total to per-response delta
   - Now correctly tracks token cost for each observation/summary
   - Captures token state before/after response processing
   - Prevents all observations getting inflated cumulative values

2. **Fixed schema version mismatch** (src/services/sqlite/SessionStore.ts)
   - Changed ensureDiscoveryTokensColumn() from version 11 to version 7
   - Now matches migration007 definition in migrations.ts
   - Ensures consistent version tracking across migration system

These fixes ensure ROI metrics accurately reflect token costs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Update search documentation to reflect hybrid ChromaDB architecture

The backend correctly implements ChromaDB-first semantic search with SQLite
temporal ordering and FTS5 fallback, but documentation incorrectly described
it as "FTS5 full-text search". This fix aligns all skill guides and tool
descriptions with the actual implementation.

Changes:
- Update SKILL.md to describe hybrid architecture with ChromaDB primary
- Update observations.md title and query parameter descriptions
- Update all three search tool descriptions in search-server.ts:
  * search_observations
  * search_sessions
  * search_user_prompts

All tools now correctly document:
- ChromaDB semantic search (primary ranking)
- 90-day recency filter
- SQLite temporal ordering
- FTS5 fallback (when ChromaDB unavailable)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Add discovery_tokens column to observations and session_summaries tables

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-16 13:36:17 -05:00
Alex Newman 68290a9121 Performance improvements: Token reduction and enhanced summaries (#101)
* refactor: Reduce continuation prompt token usage by 95 lines

Removed redundant instructions from continuation prompt that were originally
added to mitigate a session continuity issue. That issue has since been
resolved, making these detailed instructions unnecessary on every continuation.

Changes:
- Reduced continuation prompt from ~106 lines to ~11 lines (~95 line reduction)
- Changed "User's Goal:" to "Next Prompt in Session:" (more accurate framing)
- Removed redundant WHAT TO RECORD, WHEN TO SKIP, and OUTPUT FORMAT sections
- Kept concise reminder: "Continue generating observations and progress summaries..."
- Initial prompt still contains all detailed instructions

Impact:
- Significant token savings on every continuation prompt
- Faster context injection with no loss of functionality
- Instructions remain comprehensive in initial prompt

Files modified:
- src/sdk/prompts.ts (buildContinuationPrompt function)
- plugin/scripts/worker-service.cjs (compiled output)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: Enhance observation and summary prompts for clarity and token efficiency

* Enhance prompt clarity and instructions in prompts.ts

- Added a reminder to think about instructions before starting work.
- Simplified the continuation prompt instruction by removing "for this ongoing session."

* feat: Enhance settings.json with permissions and deny access to sensitive files

refactor: Remove PLAN-full-observation-display.md and PR_SUMMARY.md as they are no longer needed

chore: Delete SECURITY_SUMMARY.md since it is redundant after recent changes

fix: Update worker-service.cjs to streamline observation generation instructions

cleanup: Remove src-analysis.md and src-tree.md for a cleaner codebase

refactor: Modify prompts.ts to clarify instructions for memory processing

* refactor: Remove legacy worker service implementation

* feat: Enhance summary hook to extract last assistant message and improve logging

- Added function to extract the last assistant message from the transcript.
- Updated summary hook to include last assistant message in the summary request.
- Modified SDKSession interface to store last assistant message.
- Adjusted buildSummaryPrompt to utilize last assistant message for generating summaries.
- Updated worker service and session manager to handle last assistant message in summarize requests.
- Introduced silentDebug utility for improved logging and diagnostics throughout the summary process.

* docs: Add comprehensive implementation plan for ROI metrics feature

Added detailed implementation plan covering:
- Token usage capture from Agent SDK
- Database schema changes (migration #8)
- Discovery cost tracking per observation
- Context hook display with ROI metrics
- Testing and rollout strategy

Timeline: ~20 hours over 4 days
Goal: Empirical data for YC application amendment

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Add transcript processing scripts for analysis and formatting

- Implemented `dump-transcript-readable.ts` to generate a readable markdown dump of transcripts, excluding certain entry types.
- Created `extract-rich-context-examples.ts` to extract and showcase rich context examples from transcripts, highlighting user requests and assistant reasoning.
- Developed `format-transcript-context.ts` to format transcript context into a structured markdown format for improved observation generation.
- Added `test-transcript-parser.ts` for validating data extraction from transcript JSONL files, including statistics and error reporting.
- Introduced `transcript-to-markdown.ts` for a complete representation of transcript data in markdown format, showing all context data.
- Enhanced type definitions in `transcript.ts` to support new features and ensure type safety.
- Built `transcript-parser.ts` to handle parsing of transcript JSONL files, including error handling and data extraction methods.

* Refactor hooks and SDKAgent for improved observation handling

- Updated `new-hook.ts` to clean user prompts by stripping leading slashes for better semantic clarity.
- Enhanced `save-hook.ts` to include additional tools in the SKIP_TOOLS set, preventing unnecessary observations from certain command invocations.
- Modified `prompts.ts` to change the structure of observation prompts, emphasizing the observational role and providing a detailed XML output format for observations.
- Adjusted `SDKAgent.ts` to enforce stricter tool usage restrictions, ensuring the memory agent operates solely as an observer without any tool access.

* feat: Enhance session initialization to accept user prompts and prompt numbers

- Updated `handleSessionInit` in `worker-service.ts` to extract `userPrompt` and `promptNumber` from the request body and pass them to `initializeSession`.
- Modified `initializeSession` in `SessionManager.ts` to handle optional `currentUserPrompt` and `promptNumber` parameters.
- Added logic to update the existing session's `userPrompt` and `lastPromptNumber` if a `currentUserPrompt` is provided.
- Implemented debug logging for session initialization and updates to track user prompts and prompt numbers.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-13 18:22:44 -05:00
Alex Newman cb4aea57a8 feat: Add comprehensive documentation for Language Model Tool API and related resources 2025-11-12 15:58:44 -05:00
Alex Newman 1c9da73d5f feat: Add VSCode Language Model Tool API documentation 2025-11-12 13:39:46 -05:00
basher83 97d565e3cd Replace search skill with mem-search (#91)
* feat: add mem-search skill with progressive disclosure architecture

Add comprehensive mem-search skill for accessing claude-mem's persistent
cross-session memory database. Implements progressive disclosure workflow
and token-efficient search patterns.

Features:
- 12 search operations (observations, sessions, prompts, by-type, by-concept, by-file, timelines, etc.)
- Progressive disclosure principles to minimize token usage
- Anti-patterns documentation to guide LLM behavior
- HTTP API integration for all search functionality
- Common workflows with composition examples

Structure:
- SKILL.md: Entry point with temporal trigger patterns
- principles/: Progressive disclosure + anti-patterns
- operations/: 12 search operation files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: add CHANGELOG entry for mem-search skill

Document mem-search skill addition in Unreleased section with:
- 100% effectiveness compliance metrics
- Comparison to previous search skill implementation
- Progressive disclosure architecture details
- Reference to audit report documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: add mem-search skill audit report

Add comprehensive audit report validating mem-search skill against
Anthropic's official skill-creator documentation.

Report includes:
- Effectiveness metrics comparison (search vs mem-search)
- Critical issues analysis for production readiness
- Compliance validation across 6 key dimensions
- Reference implementation guidance

Result: mem-search achieves 100% compliance vs search's 67%

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Add comprehensive search architecture analysis document

- Document current state of dual search architectures (HTTP API and MCP)
- Analyze HTTP endpoints and MCP search server architectures
- Identify DRY violations across search implementations
- Evaluate the use of curl as the optimal approach for search
- Provide architectural recommendations for immediate and long-term improvements
- Outline action plan for cleanup, feature parity, DRY refactoring

* refactor: Remove deprecated search skill documentation and operations

* refactor: Reorganize documentation into public and context directories

Changes:
- Created docs/public/ for Mintlify documentation (.mdx files)
- Created docs/context/ for internal planning and implementation docs
- Moved all .mdx files and assets to docs/public/
- Moved all internal .md files to docs/context/
- Added CLAUDE.md to both directories explaining their purpose
- Updated docs.json paths to work with new structure

Benefits:
- Clear separation between user-facing and internal documentation
- Easier to maintain Mintlify docs in dedicated directory
- Internal context files organized separately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Enhance session management and continuity in hooks

- Updated new-hook.ts to clarify session_id threading and idempotent session creation.
- Modified prompts.ts to require claudeSessionId for continuation prompts, ensuring session context is maintained.
- Improved SessionStore.ts documentation on createSDKSession to emphasize idempotent behavior and session connection.
- Refined SDKAgent.ts to detail continuation prompt logic and its reliance on session.claudeSessionId for unified session handling.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alex Newman <thedotmack@gmail.com>
2025-11-11 16:15:07 -05:00