Commit Graph

299 Commits

Author SHA1 Message Date
Alex Newman df36ce68df chore: bump version to 10.2.1
Publish to npm / publish (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:08:33 -05:00
Alex Newman f24251118e fix: bun install, node-addon-api for sharp, consolidate PendingMessageStore (#1140)
* fix: use bun install in sync, add node-addon-api for sharp, consolidate PendingMessageStore

- Switch sync-marketplace from npm to bun install
- Add node-addon-api as dev dep so sharp builds under bun
- Consolidate duplicate PendingMessageStore instantiation in worker-service finally block

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

* build assets

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:05:42 -05:00
Alex Newman 854bf922a4 chore: bump version to 10.2.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:40:10 -05:00
Alex Newman 327dd44992 chore: bump version to 10.1.0
Publish to npm / publish (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 00:17:34 -05:00
Alex Newman 676a3d175e fix: make context and colored timeline fetches truly parallel
Address PR #1125 review feedback - both fetches now start simultaneously
via Promise.all instead of sequential-then-parallel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 00:11:25 -05:00
Alex Newman 34358ab33d feat: add systemMessage support for SessionStart hook and tune defaults
Add systemMessage field to HookResult so SessionStart can display a
colored timeline directly to the user in the CLI. The handler now
parallel-fetches both markdown (for Claude context) and ANSI-colored
(for user display) timelines, appending a viewer URL link.

Also update default settings to hide verbose token columns (read/work
tokens, savings amount) and disable full observation expansion, keeping
the cleaner index-only view by default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 00:05:13 -05:00
Alex Newman 51abe5d1ff chore: bump version to 10.0.8
Publish to npm / publish (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 23:33:20 -05:00
Alex Newman 055888e181 fix: address PR review feedback for subprocess cleanup and binary resolution
Wrap SDK query loop in try/finally so subprocess cleanup runs on error paths.
Swap Chroma binary check order to try project-level .bin first (common case).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 23:24:00 -05:00
Alex Newman 67ba17cc8a fix: use WASM backend for Chroma embeddings to fix cross-platform issues
Chroma requires client-side embeddings — the server is storage only.
The previous commit incorrectly removed @chroma-core/default-embed.

Uses DefaultEmbeddingFunction({ wasm: true }) which forces the WASM
backend instead of native ONNX binaries. Same model (all-MiniLM-L6-v2),
same embeddings, but works on all platforms without segfaults or
ENOENT errors (#1104, #1105, #1110).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 23:14:21 -05:00
Alex Newman e1ef14dbcc fix: resolve orphaned subprocesses and Chroma HTTP regressions
- Add subprocess cleanup after SDK query loop completes, using existing
  ProcessRegistry infrastructure (getProcessBySession + ensureProcessExit)
- Replace npx-based Chroma binary spawning with absolute path resolution
  via require.resolve, falling back to npx with explicit cwd (#1120)
- Remove @chroma-core/default-embed client-side dependency; let Chroma
  HTTP server handle embeddings server-side (#1104, #1105, #1110)

Closes #1010, #1089, #1090, #1068, #1120, #1104, #1105, #1110

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:04:52 -05:00
Alex Newman 0ac4c7b8a9 chore: bump version to 10.0.7
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 16:52:11 -05:00
Alex Newman c27314f896 fix: address PR review comments for chroma server lifecycle 2026-02-13 23:39:30 -05:00
Alex Newman 1b68c55763 fix: resolve SDK spawn failures and sharp native binary crashes
- Strip CLAUDECODE env var from SDK subprocesses to prevent "cannot be
  launched inside another Claude Code session" error (Claude Code 2.1.42+)
- Lazy-load @chroma-core/default-embed to avoid eagerly pulling in
  sharp native binaries at bundle startup (fixes ERR_DLOPEN_FAILED)
- Add stderr capture to SDK spawn for diagnosing future process failures
- Exclude lockfiles from marketplace rsync and delete stale lockfiles
  before npm install to prevent native dep version mismatches

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:47:27 -05:00
Alex Newman 5de728612e chore: bump version to 10.0.6
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 00:02:37 -05:00
Alex Newman 31514d1943 chore: bump version to 10.0.5
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:26:36 -05:00
Alex Newman 05e904e613 feat: enhance /api/health with version, uptime, workerPath, and AI status
Replace hardcoded TEST-008 build ID with real package version. Add worker
filesystem path, uptime counter, and AI provider status (including last
interaction success/failure tracking) to the health endpoint response.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 21:16:22 -05:00
Alex Newman 1bfb473c19 chore: bump version to 10.0.3 2026-02-11 15:44:45 -05:00
Alex Newman 0b214a59a1 chore: bump version to 10.0.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 15:25:50 -05:00
Alex Newman cb0933a908 fix: resolve merge conflict in isWorkerUnavailableError
Missing return statement and closing brace in the programming errors
check caused a build failure after merging main.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:47:46 -05:00
Rod Boev 418e38ee46 fix: hook resilience and worker lifecycle improvements (#957, #923, #984, #987, #1042)
Reduce timeouts to eliminate 10-30s startup delay when worker is dead
(common on WSL2 after hibernate). Add stale PID detection, graceful
error handling across all handlers, and error classification that
distinguishes worker unavailability from handler bugs.

- HEALTH_CHECK 30s→3s, new POST_SPAWN_WAIT (5s), PORT_IN_USE_WAIT (3s)
- isProcessAlive() with EPERM handling, cleanStalePidFile()
- getPluginVersion() try-catch for shutdown race (#1042)
- isWorkerUnavailableError: transport+5xx+429→exit 0, 4xx→exit 2
- No-op handler for unknown event types (#984)
- Wrap all handler fetch calls in try-catch for graceful degradation
- CLAUDE_MEM_HEALTH_TIMEOUT_MS env var override with validation
2026-02-10 15:34:35 -05:00
Alex Newman 5969d670d0 chore: bump version to 9.1.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 02:18:44 -05:00
Alex Newman 8dfcb5e612 chore: bump version to 9.1.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:05:38 -05:00
Alex Newman ff503d08a7 MAESTRO: Merge PR #657 - Add generate/clean CLI commands for CLAUDE.md management
Cherry-picked source changes from PR #657 (224 commits behind main).
Adds `claude-mem generate` and `claude-mem clean` CLI commands:
- New src/cli/claude-md-commands.ts with generateClaudeMd() and cleanClaudeMd()
- Worker service generate/clean case handlers with --dry-run support
- CLAUDE_MD logger component type
- Uses shared isDirectChild from path-utils.ts (DRY improvement over PR original)

Skipped from PR: 91 CLAUDE.md file deletions (stale), build artifacts,
.claude/plans/ dev artifact, smart-install.js shell alias auto-injection
(aggressive profile modification without consent).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 05:52:54 -05:00
Alex Newman 3ad53733e8 MAESTRO: Merge PR #884 adding Zscaler SSL certificate support for ChromaDB vector search
Adds automatic detection and handling of Zscaler enterprise security certificates
on macOS. Combines standard certifi CA certificates with Zscaler certificates into
a single bundle, passed via SSL_CERT_FILE/REQUESTS_CA_BUNDLE/CURL_CA_BUNDLE env vars
to the chroma-mcp subprocess. Certificate bundle is cached for 24 hours. Falls back
gracefully when Zscaler is not present, with no impact on non-Zscaler environments.

Co-Authored-By: RClark4958 <rickdclark48@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 02:15:19 -05:00
Alex Newman 403913a0fc MAESTRO: Merge PR #769 fixing chroma-mcp zombie processes, rebuild compiled output
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 02:11:32 -05:00
Alex Newman e19617a065 build: rebuild compiled output after PR #887 merge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 02:07:22 -05:00
Alex Newman 711f5455df fix: generate synthetic memorySessionId for stateless providers (PR #615)
Gemini and OpenRouter are stateless APIs that never return session IDs.
Without synthetic IDs, PR #693's defensive memorySessionId checks throw
errors on every observation processing call for these providers.

Generates provider-prefixed IDs (gemini-/openrouter-{contentSessionId}-
{timestamp}) before the first API call, persisted to the database via
updateMemorySessionId(). Applied from PR #615 (closed due to staleness).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 02:04:49 -05:00
Alex Newman 228a006953 build: rebuild compiled output after PR #741 merge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:58:08 -05:00
Alex Newman e2de295c41 build: rebuild compiled output after PR #627 merge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:53:44 -05:00
Alex Newman e8097caed7 build: rebuild compiled output after PR #937 merge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:48:04 -05:00
Alex Newman 6382d6f9c7 MAESTRO: Merge PR #693 - prevent infinite restart loop that causes runaway API costs
Add restart limit (max 3 consecutive restarts) with exponential backoff
to prevent infinite generator restart loops. Also add defensive
memorySessionId checks in GeminiAgent and OpenRouterAgent before
expensive LLM calls to fail fast when session ID hasn't been captured.

Based on PR #693 by @ajbmachon (applied to current main).

Co-Authored-By: Andre Machon <ajbmachon2@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:43:12 -05:00
Alex Newman 9c68a3ba3d MAESTRO: Merge PR #913 - respect CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED setting
Folder CLAUDE.md generation is now gated behind the CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED
setting (default: false). The setting is exposed via the settings API and handles both
string and boolean JSON values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:38:01 -05:00
Alex Newman ab3d4ca865 MAESTRO: Prevent CLAUDE.md generation in unsafe directories (PR #929 concept)
Add exclusion list for directories where CLAUDE.md generation breaks
toolchains: res/ (Android aapt2), .git/, build/, node_modules/,
__pycache__/. Closes issue #912. Credit to @jayvenn21.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:35:31 -05:00
Alex Newman e5a133b3da MAESTRO: Prevent nested duplicate directory creation in CLAUDE.md paths (PR #836 concept)
Add hasConsecutiveDuplicateSegments() check to isValidPathForClaudeMd() to reject paths
like frontend/frontend/ or src/src/ that occur when cwd already includes the directory name.
3 new tests added (46 total for claude-md-utils). Fixes #814. Credit to @Glucksberg.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:03:03 -05:00
Alex Newman 15e9473533 MAESTRO: Fix CLAUDE.md race condition from PR #974 - skip folders with active CLAUDE.md edits
Prevents "file modified since read" errors when Claude Code is actively editing
a CLAUDE.md file by detecting CLAUDE.md paths in observation file lists and
skipping those folders during updates. Closes #859. Credit: @cheapsteak.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 23:57:32 -05:00
Alex Newman d333c7dc08 MAESTRO: Expand startup orphan cleanup to target mcp-server and worker-service processes
The startup cleanupOrphanedProcesses() only targeted chroma-mcp, leaving
orphaned mcp-server.cjs and worker-service.cjs processes undetected after
daemon crashes. Expanded to target all claude-mem process types with
30-minute age filtering and current PID exclusion. Closes PR #687 (which
had a spawnDaemon regression removing Windows WMIC support).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 22:06:46 -05:00
Alex Newman d0b4c7ee59 MAESTRO: Add DOMPurify XSS defense-in-depth to TerminalPreview (closes PR #896)
PR #896 identified a valid XSS concern in TerminalPreview.tsx but was
broken (missing DOMPurify import and dependency). The existing
escapeXML:true on AnsiToHtml already mitigates the vector, but
DOMPurify adds defense-in-depth sanitization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 18:14:46 -05:00
Alex Newman ebed56674e chore: bump version to 9.0.17
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 15:56:04 -05:00
Alex Newman 094f5ab1b4 chore: bump version to 9.0.16
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 01:43:27 -05:00
Alex Newman 8f1a260d96 chore: bump version to 9.0.15
Includes PR #745 isolated credentials fix - prevents API key hijacking
from random project .env files by using centralized credentials from
~/.claude-mem/.env

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:21:01 -05:00
Alex Newman 6ee6e21eb5 chore: bump version to 9.0.14
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 19:58:02 -05:00
Alex Newman add5d62cec build assets
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 19:51:39 -05:00
Alex Newman 57a60c1309 chore: bump version to 9.0.13
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 19:41:07 -05:00
Alex Newman bef825c0d8 build assets 2026-02-04 19:39:06 -05:00
Alex Newman 7566b8c650 fix: add idle timeout to prevent zombie observer processes (#856)
* fix: add idle timeout to prevent zombie observer processes

Root cause fix for zombie observer accumulation. The SessionQueueProcessor
iterator now exits gracefully after 3 minutes of inactivity instead of
waiting forever for messages.

Changes:
- Add IDLE_TIMEOUT_MS constant (3 minutes)
- waitForMessage() now returns boolean and accepts timeout parameter
- createIterator() tracks lastActivityTime and exits on idle timeout
- Graceful exit via return (not throw) allows SDK to complete cleanly

This addresses the root cause that PR #848 worked around with pattern
matching. Observer processes now self-terminate, preventing accumulation
when session-complete hooks don't fire.

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

* fix: trigger abort on idle timeout to actually kill subprocess

The previous implementation only returned from the iterator on idle timeout,
but this doesn't terminate the Claude subprocess - it just stops yielding
messages. The subprocess stays alive as a zombie because:

1. Returning from createIterator() ends the generator
2. The SDK closes stdin via transport.endInput()
3. But the subprocess may not exit on stdin EOF
4. No abort signal is sent to kill it

Fix: Add onIdleTimeout callback that SessionManager uses to call
session.abortController.abort(). This sends SIGTERM to the subprocess
via the SDK's ProcessTransport abort handler.

Verified by Codex analysis of the SDK internals:
- abort() triggers ProcessTransport abort handler → SIGTERM
- transport.close() sends SIGTERM → escalates to SIGKILL after 5s
- Just closing stdin is NOT sufficient to guarantee subprocess exit

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

* fix: add idle timeout to prevent zombie observer processes

Also cleaned up hooks.json to remove redundant start commands.
The hook command handler now auto-starts the worker if not running,
which is how it should have been since we changed to auto-start.

This maintenance change was done manually.

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

* fix: resolve race condition in session queue idle timeout detection

- Reset timer on spurious wakeup when queue is empty but duration check fails
- Use optional chaining for onIdleTimeout callback
- Include threshold value in idle timeout log message for better diagnostics
- Add comprehensive unit tests for SessionQueueProcessor

Fixes PR #856 review feedback.

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

* feat: migrate installer to Setup hook

- Add plugin/scripts/setup.sh for one-time dependency setup
- Add Setup hook to hooks.json (triggers via claude --init)
- Remove smart-install.js from SessionStart hook
- Keep smart-install.js as manual fallback for Windows/auto-install

Setup hook handles:
- Bun detection with fallback locations
- uv detection (optional, for Chroma)
- Version marker to skip redundant installs
- Clear error messages with install instructions

* feat: add np for one-command npm releases

- Add np as dev dependency
- Add release, release:patch, release:minor, release:major scripts
- Add prepublishOnly hook to run build before publish
- Configure np (no yarn, include all contents, run tests)

* fix: reduce PostToolUse hook timeout to 30s

PostToolUse runs on every tool call, 120s was excessive and could cause
hangs. Reduced to 30s for responsive behavior.

* docs: add PR shipping report

Analyzed 6 PRs for shipping readiness:
- #856: Ready to merge (idle timeout fix)
- #700, #722, #657: Have conflicts, need rebase
- #464: Contributor PR, too large (15K+ lines)
- #863: Needs manual review

Includes shipping strategy and conflict resolution order.

* MAESTRO: Verify PR #856 test suite passes

All 797 tests pass (3 skipped, 0 failures). The 11 SessionQueueProcessor
idle timeout tests all pass with 20 expect() assertions verified.

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

* MAESTRO: Verify PR #856 build passes

- Ran npm run build successfully with no TypeScript errors
- All artifacts generated (worker-service, mcp-server, context-generator, viewer UI)

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

* MAESTRO: Code review PR #856 implementation verified

Verified all requirements in SessionQueueProcessor.ts:
- IDLE_TIMEOUT_MS = 180000ms (3 minutes)
- waitForMessage() accepts timeout parameter
- lastActivityTime reset on spurious wakeup (race condition fix)
- Graceful exit logs include thresholdMs parameter
- 11 comprehensive test cases in SessionQueueProcessor.test.ts

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: bigph00t <166455923+bigph00t@users.noreply.github.com>
Co-authored-by: root <root@srv1317155.hstgr.cloud>
2026-02-04 19:31:24 -05:00
Alex Newman a16b25275e chore: bump version to 9.0.12 2026-01-28 16:19:40 -05:00
Alex Newman abffce6424 fix: use cwd instead of CLAUDE_CONFIG_DIR for observer session isolation (#845)
The previous approach (PR #837) set CLAUDE_CONFIG_DIR to isolate observer
sessions from `claude --resume`. However, this broke authentication because
Claude Code stores credentials in the config directory.

This fix uses the SDK's `cwd` option instead:
- Observer sessions run with cwd=~/.claude-mem/observer-sessions/
- Project name = path.basename(cwd) = "observer-sessions"
- Sessions won't appear when running `claude --resume` from actual projects
- Authentication works because ~/.claude/ config is preserved

Changes:
- ProcessRegistry.ts: Remove CLAUDE_CONFIG_DIR override from spawn
- SDKAgent.ts: Add cwd option to query() pointing to observer dir
- paths.ts: Rename OBSERVER_CONFIG_DIR to OBSERVER_SESSIONS_DIR

Fixes regression from #837

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 16:18:15 -05:00
Alex Newman bd1fe5995f chore: bump version to 9.0.11
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 13:50:21 -05:00
Alex Newman bd619229b2 chore: bump version to 9.0.10
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 15:51:43 -05:00
Alex Newman da01e4bba0 chore: bump version to 9.0.9 2026-01-25 23:59:26 -05:00