mirror of
https://github.com/thedotmack/claude-mem
synced 2026-04-25 17:15:04 +02:00
* docs: add investigation reports for 5 open GitHub issues Comprehensive analysis of issues #543, #544, #545, #555, and #557: - #557: settings.json not generated, module loader error (node/bun mismatch) - #555: Windows hooks not executing, hasIpc always false - #545: formatTool crashes on non-JSON tool_input strings - #544: mem-search skill hint shown incorrectly to Claude Code users - #543: /claude-mem slash command unavailable despite installation Each report includes root cause analysis, affected files, and proposed fixes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(logger): handle non-JSON tool_input in formatTool (#545) Wrap JSON.parse in try-catch to handle raw string inputs (e.g., Bash commands) that aren't valid JSON. Falls back to using the string as-is. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(context): update mem-search hint to reference MCP tools (#544) Update hint messages to reference MCP tools (search, get_observations) instead of the deprecated "mem-search skill" terminology. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(settings): auto-create settings.json on first load (#557, #543) When settings.json doesn't exist, create it with defaults instead of returning in-memory defaults. Creates parent directory if needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(hooks): use bun runtime for hooks except smart-install (#557) Change hook commands from node to bun since hooks use bun:sqlite. Keep smart-install.js on node since it bootstraps bun installation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: rebuild plugin scripts * docs: clarify that build artifacts must be committed * fix(docs): update build artifacts directory reference in CLAUDE.md * test: add test coverage for PR #558 fixes - Fix 2 failing tests: update "mem-search skill" → "MCP tools" expectations - Add 56 tests for formatTool() JSON.parse crash fix (Issue #545) - Add 27 tests for settings.json auto-creation (Issue #543) Test coverage includes: - formatTool: JSON parsing, raw strings, objects, null/undefined, all tool types - Settings: file creation, directory creation, schema migration, edge cases 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(tests): clean up flaky tests and fix circular dependency Phase 1 of test quality improvements: - Delete 6 harmful/worthless test files that used problematic mock.module() patterns or tested implementation details rather than behavior: - context-builder.test.ts (tested internal implementation) - export-types.test.ts (fragile mock patterns) - smart-install.test.ts (shell script testing antipattern) - session_id_refactor.test.ts (outdated, tested refactoring itself) - validate_sql_update.test.ts (one-time migration validation) - observation-broadcaster.test.ts (excessive mocking) - Fix circular dependency between logger.ts and SettingsDefaultsManager.ts by using late binding pattern - logger now lazily loads settings - Refactor mock.module() to spyOn() in several test files for more maintainable and less brittle tests: - observation-compiler.test.ts - gemini_agent.test.ts - error-handler.test.ts - server.test.ts - response-processor.test.ts All 649 tests pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(tests): phase 2 - reduce mock-heavy tests and improve focus - Remove mock-heavy query tests from observation-compiler.test.ts, keep real buildTimeline tests - Convert session_id_usage_validation.test.ts from 477 to 178 lines of focused smoke tests - Remove tests for language built-ins from worker-spawn.test.ts (JSON.parse, array indexing) - Rename logger-coverage.test.ts to logger-usage-standards.test.ts for clarity 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(tests): phase 3 - add JSDoc mock justification to test files Document mock usage rationale in 5 test files to improve maintainability: - error-handler.test.ts: Express req/res mocks, logger spies (~11%) - fallback-error-handler.test.ts: Zero mocks, pure function tests - session-cleanup-helper.test.ts: Session fixtures, worker mocks (~19%) - hook-constants.test.ts: process.platform mock for Windows tests (~12%) - session_store.test.ts: Zero mocks, real SQLite :memory: database Part of ongoing effort to document mock justifications per TESTING.md guidelines. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test(integration): phase 5 - add 72 tests for critical coverage gaps Add comprehensive test coverage for previously untested areas: - tests/integration/hook-execution-e2e.test.ts (10 tests) Tests lifecycle hooks execution flow and context propagation - tests/integration/worker-api-endpoints.test.ts (19 tests) Tests all worker service HTTP endpoints without heavy mocking - tests/integration/chroma-vector-sync.test.ts (16 tests) Tests vector embedding synchronization with ChromaDB - tests/utils/tag-stripping.test.ts (27 tests) Tests privacy tag stripping utilities for both <private> and <meta-observation> tags All tests use real implementations where feasible, following the project's testing philosophy of preferring integration-style tests over unit tests with extensive mocking. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * context update * docs: add comment linking DEFAULT_DATA_DIR locations Added NOTE comment in logger.ts pointing to the canonical DEFAULT_DATA_DIR in SettingsDefaultsManager.ts. This addresses PR reviewer feedback about the fragility of having the default defined in two places to avoid circular dependencies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
248
docs/reports/2026-01-05--issue-543-slash-command-unavailable.md
Normal file
248
docs/reports/2026-01-05--issue-543-slash-command-unavailable.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Issue #543 Analysis: /claude-mem Slash Command Not Available Despite Installation
|
||||
|
||||
**Date:** 2026-01-05
|
||||
**Version Analyzed:** 8.5.9
|
||||
**Status:** Expected Behavior - No such command exists
|
||||
**Related Issues:** #557 (if it exists), Windows initialization issues
|
||||
|
||||
## Issue Summary
|
||||
|
||||
A user reports that the `/claude-mem diagnostics` command returns "Unknown slash command: claude-mem" after installing claude-mem v8.5.9 on Windows.
|
||||
|
||||
### Reported Environment
|
||||
- Claude-mem version: 8.5.9
|
||||
- Claude Code version: 2.0.76
|
||||
- Node.js version: v22.21.0
|
||||
- Bun version: 1.3.5
|
||||
- OS: Windows 10.0.26200.7462 (x64)
|
||||
|
||||
### Reported Plugin Status
|
||||
- Worker Running: No
|
||||
- Database Exists: Yes (4.00 KB - minimal/empty database)
|
||||
- Settings Exist: No
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Finding 1: No `/claude-mem` Slash Command Exists
|
||||
|
||||
**Critical Discovery**: The `/claude-mem diagnostics` command does not exist in claude-mem. After extensive codebase analysis:
|
||||
|
||||
1. **No slash command registration found**: The `plugin/commands/` directory is empty. Claude-mem does not register any slash commands.
|
||||
|
||||
2. **Skills, not commands**: Claude-mem uses Claude Code's **skill system**, not the command system. Skills are defined in `plugin/skills/`:
|
||||
- `mem-search/` - Memory search functionality
|
||||
- `troubleshoot/` - Troubleshooting functionality
|
||||
- `search/` - Search operations
|
||||
- `claude-mem-settings/` - Settings management
|
||||
|
||||
3. **Empty skill directories**: All skill directories currently contain only empty subdirectories (`operations/`, `principles/`) with no SKILL.md files present in the built plugin. This suggests either:
|
||||
- Skills are dynamically loaded from the worker service
|
||||
- A build issue where skill files are not being bundled
|
||||
- Skills were removed or relocated in a recent refactor
|
||||
|
||||
### Finding 2: How Troubleshooting Actually Works
|
||||
|
||||
According to the documentation (`docs/public/troubleshooting.mdx`):
|
||||
|
||||
> "Describe any issues you're experiencing to Claude, and the troubleshoot skill will automatically activate to provide diagnosis and fixes."
|
||||
|
||||
The troubleshoot skill is designed to be **invoked naturally** - users describe their problem to Claude, and the skill auto-invokes. There is no `/claude-mem diagnostics` command.
|
||||
|
||||
### Finding 3: Settings.json Creation Flow
|
||||
|
||||
The `settings.json` file is **not created during installation**. It is created:
|
||||
|
||||
1. **On first worker API call**: The `ensureSettingsFile()` method in `SettingsRoutes.ts` (lines 400-413) creates the file with defaults when the settings API is first accessed.
|
||||
|
||||
2. **Worker must be running**: Since settings creation is triggered by API calls, the worker service must be running for settings to be created.
|
||||
|
||||
3. **Lazy initialization pattern**: This is intentional - settings are created on-demand with sensible defaults rather than during installation.
|
||||
|
||||
### Finding 4: Worker Service Not Running
|
||||
|
||||
The user reports "Worker Running: No". This is the core issue because:
|
||||
|
||||
1. **Worker auto-start on SessionStart**: The `hooks.json` shows the worker starts via:
|
||||
```json
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start",
|
||||
"timeout": 60
|
||||
}
|
||||
```
|
||||
|
||||
2. **Smart-install runs first**: Before worker start, `smart-install.js` runs to ensure Bun and uv are installed.
|
||||
|
||||
3. **Windows-specific issues**: The user is on Windows, which has known issues:
|
||||
- PowerShell escaping problems in `cleanupOrphanedProcesses()` (Issue #517)
|
||||
- PATH issues with freshly installed Bun
|
||||
- Process spawning differences
|
||||
|
||||
### Finding 5: Database Size Indicates No Data
|
||||
|
||||
The database is 4.00 KB, which is essentially an empty schema:
|
||||
- No observations recorded
|
||||
- No sessions created
|
||||
- Hooks may not have executed successfully
|
||||
|
||||
## Initialization Flow Analysis
|
||||
|
||||
```
|
||||
Installation
|
||||
|
|
||||
v
|
||||
First Session Start
|
||||
|
|
||||
+---> smart-install.js (ensure Bun + uv)
|
||||
| |
|
||||
| +---> May fail silently on Windows (PATH issues)
|
||||
|
|
||||
+---> worker-service.cjs start
|
||||
| |
|
||||
| +---> Likely failing (worker not running)
|
||||
|
|
||||
+---> context-hook.js (requires worker)
|
||||
| |
|
||||
| +---> Fails or returns empty (no worker)
|
||||
|
|
||||
+---> user-message-hook.js
|
||||
|
|
||||
+---> No context injected
|
||||
```
|
||||
|
||||
## Why Skills Directories Are Empty
|
||||
|
||||
After investigation, the skill directories in `plugin/skills/` are scaffolding structures but appear to have no SKILL.md files in the built plugin. The actual skill functionality may be:
|
||||
|
||||
1. **Served via HTTP API**: The Server.ts shows an `/api/instructions` endpoint that loads SKILL.md sections on-demand from `../skills/mem-search/`
|
||||
2. **Built differently**: The skills may be bundled into the worker service rather than standalone files
|
||||
3. **Documentation discrepancy**: The README and docs reference skills that may work differently than traditional Claude Code skill files
|
||||
|
||||
## Proposed Diagnosis
|
||||
|
||||
The user's issue is **not** that `/claude-mem diagnostics` doesn't work - that command never existed. The actual issues are:
|
||||
|
||||
1. **Misunderstanding of troubleshoot functionality**: The user expects a slash command but should describe issues naturally to Claude.
|
||||
|
||||
2. **Worker service failed to start**: Root cause for:
|
||||
- No settings.json created
|
||||
- Empty database (no observations)
|
||||
- No context injection working
|
||||
|
||||
3. **Possible Windows initialization failures**:
|
||||
- Bun may not be in PATH after smart-install
|
||||
- PowerShell execution policy issues
|
||||
- Worker spawn failures
|
||||
|
||||
## Recommended User Resolution
|
||||
|
||||
### Step 1: Verify Bun Installation
|
||||
```powershell
|
||||
bun --version
|
||||
```
|
||||
If not found, manually install:
|
||||
```powershell
|
||||
powershell -c "irm bun.sh/install.ps1 | iex"
|
||||
```
|
||||
Then restart terminal.
|
||||
|
||||
### Step 2: Manually Start Worker
|
||||
```powershell
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack
|
||||
bun plugin/scripts/worker-service.cjs start
|
||||
```
|
||||
|
||||
### Step 3: Verify Worker Health
|
||||
```powershell
|
||||
curl http://localhost:37777/health
|
||||
```
|
||||
|
||||
### Step 4: Create Settings Manually (if needed)
|
||||
```powershell
|
||||
curl http://localhost:37777/api/settings
|
||||
```
|
||||
This will create `~/.claude-mem/settings.json` with defaults.
|
||||
|
||||
### Step 5: For Diagnostics - Natural Language
|
||||
Instead of `/claude-mem diagnostics`, describe the issue to Claude:
|
||||
> "I'm having issues with claude-mem. Can you help troubleshoot?"
|
||||
|
||||
The troubleshoot skill should auto-invoke if the worker is running.
|
||||
|
||||
## Proposed Code Improvements
|
||||
|
||||
### 1. Add Diagnostic Slash Command
|
||||
|
||||
Create a `/claude-mem` command for diagnostics. File: `plugin/commands/claude-mem.json`:
|
||||
```json
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"description": "Claude-mem diagnostics and status",
|
||||
"handler": "scripts/diagnostic-command.js"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Eager Settings Creation
|
||||
|
||||
Modify `smart-install.js` to create settings.json during installation:
|
||||
```javascript
|
||||
const settingsPath = join(homedir(), '.claude-mem', 'settings.json');
|
||||
if (!existsSync(settingsPath)) {
|
||||
mkdirSync(join(homedir(), '.claude-mem'), { recursive: true });
|
||||
writeFileSync(settingsPath, JSON.stringify(getDefaults(), null, 2));
|
||||
console.log('Created settings.json with defaults');
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Better Windows Error Reporting
|
||||
|
||||
Add explicit error messages when worker fails to start on Windows:
|
||||
```javascript
|
||||
if (process.platform === 'win32' && !workerStarted) {
|
||||
console.error('Worker failed to start on Windows.');
|
||||
console.error('Please run manually: bun plugin/scripts/worker-service.cjs start');
|
||||
console.error('And check: https://docs.claude-mem.ai/troubleshooting');
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Health Check Command
|
||||
|
||||
Add a simple health check that works without the worker:
|
||||
```javascript
|
||||
// plugin/scripts/health-check.js
|
||||
const http = require('http');
|
||||
http.get('http://localhost:37777/health', (res) => {
|
||||
if (res.statusCode === 200) console.log('Worker: RUNNING');
|
||||
else console.log('Worker: NOT RESPONDING');
|
||||
}).on('error', () => console.log('Worker: NOT RUNNING'));
|
||||
```
|
||||
|
||||
## Relationship to Issue #557
|
||||
|
||||
If Issue #557 relates to initialization issues, this analysis confirms:
|
||||
- Settings.json creation is lazy (requires worker)
|
||||
- Worker auto-start can fail silently on Windows
|
||||
- Users may have incomplete installations without clear error messages
|
||||
|
||||
## Files Examined
|
||||
|
||||
- `/plugin/.claude-plugin/plugin.json` - Plugin manifest (no commands)
|
||||
- `/plugin/hooks/hooks.json` - Hook definitions
|
||||
- `/plugin/scripts/smart-install.js` - Installation script
|
||||
- `/plugin/scripts/worker-service.cjs` - Worker service
|
||||
- `/src/services/worker/http/routes/SettingsRoutes.ts` - Settings creation
|
||||
- `/src/shared/SettingsDefaultsManager.ts` - Default values
|
||||
- `/src/shared/paths.ts` - Path definitions
|
||||
- `/docs/public/troubleshooting.mdx` - User documentation
|
||||
- `/docs/public/usage/getting-started.mdx` - User guide
|
||||
|
||||
## Conclusion
|
||||
|
||||
The reported issue is a **user expectation mismatch** combined with a **Windows initialization failure**:
|
||||
|
||||
1. `/claude-mem diagnostics` does not exist - users should use natural language to invoke the troubleshoot skill
|
||||
2. The worker service failed to start, causing cascading issues (no settings, no context)
|
||||
3. Documentation could be clearer about available commands vs skills
|
||||
4. Windows-specific initialization issues are a known pattern
|
||||
|
||||
The fix should include both user documentation improvements and potentially adding a `/claude-mem` diagnostic command for discoverability.
|
||||
@@ -0,0 +1,444 @@
|
||||
# Investigation Report: Issue #544 - mem-search Skill Hint Shown to Claude Code Users
|
||||
|
||||
**Date:** 2026-01-05
|
||||
**Issue:** https://github.com/thedotmack/claude-mem/issues/544
|
||||
**Author:** m.woelk (@neifgmbh)
|
||||
**Status:** Open
|
||||
|
||||
---
|
||||
|
||||
## Issue Summary
|
||||
|
||||
The context footer displayed to users includes the message:
|
||||
|
||||
> "Use the mem-search skill to access memories by ID instead of re-reading files."
|
||||
|
||||
This hint is misleading because:
|
||||
1. **For Claude Code users**: The "mem-search skill" terminology is confusing. In Claude Code, memory search is available through **MCP tools** (`search`, `timeline`, `get_observations`), not a "skill"
|
||||
2. **For all users**: The skill directories in `plugin/skills/` are empty - no SKILL.md files exist
|
||||
|
||||
A second user (@niteeshm) confirmed the issue with "+1 the mem-search skill is missing."
|
||||
|
||||
---
|
||||
|
||||
## Code Location Verification
|
||||
|
||||
### Confirmed Locations
|
||||
|
||||
The message appears in **two formatters** and is rendered via **FooterRenderer.ts**:
|
||||
|
||||
#### 1. MarkdownFormatter.ts (line 228-234)
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/MarkdownFormatter.ts`
|
||||
|
||||
```typescript
|
||||
export function renderMarkdownFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
||||
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
||||
return [
|
||||
'',
|
||||
`Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use the mem-search skill to access memories by ID instead of re-reading files.`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. ColorFormatter.ts (line 225-231)
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/ColorFormatter.ts`
|
||||
|
||||
```typescript
|
||||
export function renderColorFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
||||
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
||||
return [
|
||||
'',
|
||||
`${colors.dim}Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use the mem-search skill to access memories by ID instead of re-reading files.${colors.reset}`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Additional References in Context Instructions
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/MarkdownFormatter.ts` (lines 70-79)
|
||||
|
||||
```typescript
|
||||
export function renderMarkdownContextIndex(): string[] {
|
||||
return [
|
||||
`**Context Index:** This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.`,
|
||||
'',
|
||||
`When you need implementation details, rationale, or debugging context:`,
|
||||
`- Use the mem-search skill to fetch full observations on-demand`,
|
||||
`- Critical types ( bugfix, decision) often need detailed fetching`,
|
||||
`- Trust this index over re-reading code for past decisions and learnings`,
|
||||
''
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/ColorFormatter.ts` (lines 72-81)
|
||||
|
||||
```typescript
|
||||
export function renderColorContextIndex(): string[] {
|
||||
return [
|
||||
`${colors.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${colors.reset}`,
|
||||
'',
|
||||
`${colors.dim}When you need implementation details, rationale, or debugging context:${colors.reset}`,
|
||||
`${colors.dim} - Use the mem-search skill to fetch full observations on-demand${colors.reset}`,
|
||||
...
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Footer Rendering Logic
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/sections/FooterRenderer.ts`
|
||||
|
||||
```typescript
|
||||
export function renderFooter(
|
||||
economics: TokenEconomics,
|
||||
config: ContextConfig,
|
||||
useColors: boolean
|
||||
): string[] {
|
||||
// Only show footer if we have savings to display
|
||||
if (!shouldShowContextEconomics(config) || economics.totalDiscoveryTokens <= 0 || economics.savings <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (useColors) {
|
||||
return Color.renderColorFooter(economics.totalDiscoveryTokens, economics.totalReadTokens);
|
||||
}
|
||||
return Markdown.renderMarkdownFooter(economics.totalDiscoveryTokens, economics.totalReadTokens);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Detection Analysis
|
||||
|
||||
### Current State: No Detection Exists
|
||||
|
||||
**Finding:** Claude-mem does **NOT** currently differentiate between Claude Code and Claude Desktop environments.
|
||||
|
||||
**Evidence:**
|
||||
1. Searched entire `src/` directory for environment detection patterns:
|
||||
- `claude.?code`, `claude.?desktop`, `isClaudeCode`, `isClaudeDesktop`, `environment`
|
||||
- Found 22 files, but none contain Claude Code vs Claude Desktop detection logic
|
||||
|
||||
2. Hook input analysis (`SessionStartInput` in `context-hook.ts`):
|
||||
```typescript
|
||||
export interface SessionStartInput {
|
||||
session_id: string;
|
||||
transcript_path: string;
|
||||
cwd: string;
|
||||
hook_event_name?: string;
|
||||
}
|
||||
```
|
||||
No environment identifier is passed to hooks.
|
||||
|
||||
3. The `ContextConfig` type has no environment field:
|
||||
```typescript
|
||||
export interface ContextConfig {
|
||||
totalObservationCount: number;
|
||||
fullObservationCount: number;
|
||||
sessionCount: number;
|
||||
showReadTokens: boolean;
|
||||
showWorkTokens: boolean;
|
||||
// ... no environment field
|
||||
}
|
||||
```
|
||||
|
||||
### Why Detection Would Be Difficult
|
||||
|
||||
Claude Code and Claude Desktop both:
|
||||
- Use the same plugin system (hooks)
|
||||
- Use the same MCP server configuration
|
||||
- Receive the same hook input structure
|
||||
|
||||
**Potential Detection Methods:**
|
||||
1. **Process name/parent** - Check if running under "claude-code" or "Claude Desktop" process
|
||||
2. **Environment variables** - Claude may set different env vars (needs research)
|
||||
3. **MCP config location** - Different config paths for each client
|
||||
4. **User agent/client header** - If available in MCP protocol
|
||||
|
||||
---
|
||||
|
||||
## Skill Availability Analysis
|
||||
|
||||
### What Actually Exists
|
||||
|
||||
#### Claude Code MCP Tools (via `.mcp.json`)
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/plugin/.mcp.json`
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"mcp-search": {
|
||||
"type": "stdio",
|
||||
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/mcp-server.cjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Available MCP Tools** (from `mcp-server.ts`):
|
||||
1. `search` - Step 1: Search memory index
|
||||
2. `timeline` - Step 2: Get context around results
|
||||
3. `get_observations` - Step 3: Fetch full details by IDs
|
||||
4. `__IMPORTANT` - Workflow documentation
|
||||
|
||||
**These tools ARE available in Claude Code** via MCP protocol.
|
||||
|
||||
#### Claude Desktop Setup (Manual)
|
||||
|
||||
From documentation (`docs/public/usage/claude-desktop.mdx`):
|
||||
- Requires manual MCP server configuration in `claude_desktop_config.json`
|
||||
- Uses the same MCP server and tools as Claude Code
|
||||
- Documentation refers to this as the "mem-search skill"
|
||||
|
||||
#### Plugin Skills Directory (Empty)
|
||||
|
||||
**Path:** `/Users/alexnewman/Scripts/claude-mem/plugin/skills/`
|
||||
|
||||
```
|
||||
skills/
|
||||
claude-mem-settings/ (empty)
|
||||
mem-search/
|
||||
operations/ (empty)
|
||||
principles/ (empty)
|
||||
search/
|
||||
operations/ (empty)
|
||||
troubleshoot/
|
||||
operations/ (empty)
|
||||
```
|
||||
|
||||
**Finding:** All skill directories are empty - no `SKILL.md` files exist.
|
||||
|
||||
### Terminology Confusion
|
||||
|
||||
| What Users See | What Actually Exists |
|
||||
|---------------|---------------------|
|
||||
| "mem-search skill" | MCP tools (`search`, `timeline`, `get_observations`) |
|
||||
| "skill" | Empty directory structures in `plugin/skills/` |
|
||||
| "skill to fetch observations" | `get_observations` MCP tool |
|
||||
|
||||
**The "skill" terminology is a legacy artifact** from an earlier architecture. The current system uses MCP tools, not skills.
|
||||
|
||||
---
|
||||
|
||||
## Root Cause
|
||||
|
||||
1. **Legacy Terminology**: The footer message uses "skill" language from a previous architecture
|
||||
2. **Architecture Evolution**: The search system migrated from skill-based to MCP-based (documented in `search-architecture.mdx`):
|
||||
> "Skill approach... was removed in favor of streamlined MCP architecture"
|
||||
3. **Incomplete Migration**: The message text was not updated when the architecture changed
|
||||
4. **No Skill Files**: The skill directories exist but contain no SKILL.md files
|
||||
|
||||
---
|
||||
|
||||
## Proposed Fix Options
|
||||
|
||||
### Option 1: Update Message to Reference MCP Tools (Recommended)
|
||||
|
||||
**Change the message to accurately describe the MCP tools:**
|
||||
|
||||
**Before:**
|
||||
> "Use the mem-search skill to access memories by ID instead of re-reading files."
|
||||
|
||||
**After:**
|
||||
> "Use MCP search tools (search, timeline, get_observations) to access memories by ID."
|
||||
|
||||
**Files to modify:**
|
||||
- `src/services/context/formatters/MarkdownFormatter.ts` (lines 75, 232)
|
||||
- `src/services/context/formatters/ColorFormatter.ts` (lines 77, 229)
|
||||
|
||||
**Pros:**
|
||||
- Accurate for both Claude Code and Claude Desktop
|
||||
- No environment detection needed
|
||||
- Simple change
|
||||
|
||||
**Cons:**
|
||||
- Longer message
|
||||
- Users need to know about MCP tools
|
||||
|
||||
### Option 2: Remove the Hint Entirely
|
||||
|
||||
**Simply remove the "Use the mem-search skill..." portion of the message.**
|
||||
|
||||
**Before:**
|
||||
> "Access 5k tokens of past research & decisions for just 1,234t. Use the mem-search skill to access memories by ID instead of re-reading files."
|
||||
|
||||
**After:**
|
||||
> "Access 5k tokens of past research & decisions for just 1,234t."
|
||||
|
||||
**Files to modify:**
|
||||
- `src/services/context/formatters/MarkdownFormatter.ts` (lines 75, 232)
|
||||
- `src/services/context/formatters/ColorFormatter.ts` (lines 77, 229)
|
||||
|
||||
**Pros:**
|
||||
- Simplest fix
|
||||
- No confusion about terminology
|
||||
- Cleaner footer
|
||||
|
||||
**Cons:**
|
||||
- Loses the helpful hint about memory search
|
||||
- Users may not know about MCP tools
|
||||
|
||||
### Option 3: Conditional Message Based on Environment Detection
|
||||
|
||||
**Implement environment detection and show different messages:**
|
||||
|
||||
```typescript
|
||||
export function renderFooter(economics: TokenEconomics, config: ContextConfig, useColors: boolean): string[] {
|
||||
const isClaudeCode = detectClaudeCodeEnvironment();
|
||||
const searchHint = isClaudeCode
|
||||
? "Use MCP search tools to access memories by ID."
|
||||
: "Use the mem-search skill to access memories by ID.";
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**Files to modify:**
|
||||
- Create new utility: `src/utils/environment-detection.ts`
|
||||
- `src/services/context/sections/FooterRenderer.ts`
|
||||
- `src/services/context/formatters/MarkdownFormatter.ts`
|
||||
- `src/services/context/formatters/ColorFormatter.ts`
|
||||
|
||||
**Pros:**
|
||||
- Context-appropriate messaging
|
||||
- Maintains helpful hint
|
||||
|
||||
**Cons:**
|
||||
- Complex to implement
|
||||
- May be fragile (environment detection methods could break)
|
||||
- More maintenance burden
|
||||
- Unclear how to reliably detect environment
|
||||
|
||||
### Option 4: Implement Actual Skills for Claude Code
|
||||
|
||||
**Create SKILL.md files in `plugin/skills/mem-search/`:**
|
||||
|
||||
**Path:** `plugin/skills/mem-search/SKILL.md`
|
||||
```markdown
|
||||
---
|
||||
name: mem-search
|
||||
description: Search claude-mem memory database using MCP tools
|
||||
---
|
||||
|
||||
# Memory Search
|
||||
|
||||
Use MCP tools to search your project memory...
|
||||
```
|
||||
|
||||
**Pros:**
|
||||
- Makes the message accurate
|
||||
- Provides better user guidance
|
||||
- Consistent with skill-based architecture
|
||||
|
||||
**Cons:**
|
||||
- Skills may be deprecated in favor of MCP
|
||||
- More files to maintain
|
||||
- May confuse the architecture (skills wrapping MCP tools)
|
||||
|
||||
---
|
||||
|
||||
## Implementation Recommendation
|
||||
|
||||
**Recommended: Option 1 (Update Message to Reference MCP Tools)**
|
||||
|
||||
### Rationale
|
||||
|
||||
1. **Accuracy**: MCP tools are the actual mechanism, not skills
|
||||
2. **Simplicity**: Single source of truth, no environment detection needed
|
||||
3. **Documentation Alignment**: Matches the architecture documentation
|
||||
4. **Low Risk**: Minimal code changes, no new systems
|
||||
|
||||
### Specific Changes
|
||||
|
||||
#### MarkdownFormatter.ts
|
||||
|
||||
**Line 75** (Context Index section):
|
||||
```typescript
|
||||
// Before:
|
||||
`- Use the mem-search skill to fetch full observations on-demand`,
|
||||
|
||||
// After:
|
||||
`- Use MCP tools (search, get_observations) to fetch full observations on-demand`,
|
||||
```
|
||||
|
||||
**Lines 228-234** (Footer):
|
||||
```typescript
|
||||
export function renderMarkdownFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
||||
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
||||
return [
|
||||
'',
|
||||
`Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use MCP search tools to access memories by ID.`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### ColorFormatter.ts
|
||||
|
||||
**Line 77** (Context Index section):
|
||||
```typescript
|
||||
// Before:
|
||||
`${colors.dim} - Use the mem-search skill to fetch full observations on-demand${colors.reset}`,
|
||||
|
||||
// After:
|
||||
`${colors.dim} - Use MCP tools (search, get_observations) to fetch full observations on-demand${colors.reset}`,
|
||||
```
|
||||
|
||||
**Lines 225-231** (Footer):
|
||||
```typescript
|
||||
export function renderColorFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
||||
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
||||
return [
|
||||
'',
|
||||
`${colors.dim}Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use MCP search tools to access memories by ID.${colors.reset}`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
1. Rebuild plugin: `npm run build-and-sync`
|
||||
2. Restart Claude Code
|
||||
3. Verify footer message appears correctly
|
||||
4. Verify context index instructions appear correctly
|
||||
|
||||
---
|
||||
|
||||
## Additional Considerations
|
||||
|
||||
### Empty Skill Directories
|
||||
|
||||
The empty `plugin/skills/` directories should be addressed separately:
|
||||
- Either remove them (if skills are deprecated)
|
||||
- Or populate them with SKILL.md files (if skills are still supported)
|
||||
|
||||
This is a **separate issue** from the message text.
|
||||
|
||||
### Documentation Updates
|
||||
|
||||
If Option 1 is implemented, documentation should also be reviewed:
|
||||
- `docs/public/usage/claude-desktop.mdx` references "mem-search skill"
|
||||
- `README.md` mentions "Skill-Based Search"
|
||||
- Various i18n README files
|
||||
|
||||
Consider creating a follow-up issue for documentation consistency.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Aspect | Finding |
|
||||
|--------|---------|
|
||||
| **Issue Valid?** | Yes - message is misleading |
|
||||
| **Location Verified?** | Yes - 4 locations in 2 formatters |
|
||||
| **Environment Detection?** | Does not exist |
|
||||
| **Skill Files?** | Empty directories, no SKILL.md |
|
||||
| **MCP Tools Available?** | Yes - in both Claude Code and Desktop |
|
||||
| **Recommended Fix** | Option 1: Update message to reference MCP tools |
|
||||
| **Complexity** | Low - 4 string changes |
|
||||
| **Risk** | Low - cosmetic text change |
|
||||
|
||||
---
|
||||
|
||||
*Report prepared for GitHub Issue #544*
|
||||
@@ -0,0 +1,241 @@
|
||||
# Issue #545: formatTool Crashes on Non-JSON Tool Input Strings
|
||||
|
||||
## Summary
|
||||
|
||||
**Issue**: `formatTool` method in `src/utils/logger.ts` crashes when `toolInput` is a string that is not valid JSON
|
||||
**Type**: Bug (Critical - Silent Data Loss)
|
||||
**Status**: Open
|
||||
**Author**: @Rob-van-B
|
||||
**Created**: January 4, 2026
|
||||
|
||||
The `formatTool` method unconditionally calls `JSON.parse()` on string inputs without error handling. When tool inputs are raw strings (not JSON), this throws an exception that propagates up the call stack, causing 400 errors for valid observation requests and silently stopping claude-mem from recording tool usage.
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Verified Issue Location
|
||||
|
||||
**File**: `/Users/alexnewman/Scripts/claude-mem/src/utils/logger.ts`
|
||||
**Line**: 139
|
||||
**Method**: `formatTool`
|
||||
|
||||
```typescript
|
||||
formatTool(toolName: string, toolInput?: any): string {
|
||||
if (!toolInput) return toolName;
|
||||
|
||||
const input = typeof toolInput === 'string' ? JSON.parse(toolInput) : toolInput;
|
||||
// ... rest of method
|
||||
}
|
||||
```
|
||||
|
||||
### The Problem
|
||||
|
||||
The code assumes that if `toolInput` is a string, it must be valid JSON. This assumption is incorrect. Tool inputs can be:
|
||||
|
||||
1. **Already-parsed objects** (no parsing needed)
|
||||
2. **JSON strings** (need parsing)
|
||||
3. **Raw strings that are not JSON** (will crash on parse)
|
||||
|
||||
When a raw string is passed (e.g., a Bash command like `ls -la`), `JSON.parse("ls -la")` throws:
|
||||
```
|
||||
SyntaxError: Unexpected token 'l', "ls -la" is not valid JSON
|
||||
```
|
||||
|
||||
### Existing Correct Pattern in Codebase
|
||||
|
||||
The issue is notable because the **correct pattern already exists** in `src/sdk/prompts.ts` (lines 96-102):
|
||||
|
||||
```typescript
|
||||
try {
|
||||
toolInput = typeof obs.tool_input === 'string' ? JSON.parse(obs.tool_input) : obs.tool_input;
|
||||
} catch (error) {
|
||||
logger.debug('SDK', 'Tool input is plain string, using as-is', {
|
||||
toolName: obs.tool_name
|
||||
}, error as Error);
|
||||
toolInput = obs.tool_input;
|
||||
}
|
||||
```
|
||||
|
||||
This demonstrates the correct defensive approach was implemented elsewhere but missed in `logger.ts`.
|
||||
|
||||
## Call Sites Affected
|
||||
|
||||
The `formatTool` method is called from 4 locations:
|
||||
|
||||
| File | Line | Context | Impact |
|
||||
|------|------|---------|--------|
|
||||
| `src/hooks/save-hook.ts` | 38 | PostToolUse hook logging | Hook crashes, observation lost |
|
||||
| `src/services/worker/http/middleware.ts` | 110 | HTTP request logging | 400 error returned to client |
|
||||
| `src/services/worker/SessionManager.ts` | 220 | Observation queue logging | Observation not queued |
|
||||
|
||||
All call sites pass `tool_input` directly from Claude Code's PostToolUse hook, which can be any type including raw strings.
|
||||
|
||||
## Impact Assessment
|
||||
|
||||
### Severity: High
|
||||
|
||||
1. **Silent Data Loss**: Observations fail to save without user notification
|
||||
2. **No Error Visibility**: Worker runs as background process - errors go unnoticed
|
||||
3. **Intermittent Failures**: Only affects certain tool types with string inputs
|
||||
4. **Cascading Effect**: One failed observation can disrupt session tracking
|
||||
|
||||
### Affected Tool Types
|
||||
|
||||
Tools most likely to trigger this bug:
|
||||
|
||||
- **Bash**: Command strings like `git status`, `npm install`
|
||||
- **Grep**: Search patterns
|
||||
- **Glob**: File patterns like `**/*.ts`
|
||||
- **Custom MCP tools**: May pass raw strings
|
||||
|
||||
### Data Flow Path
|
||||
|
||||
```
|
||||
Claude Code
|
||||
|
|
||||
v
|
||||
PostToolUse Hook (save-hook.ts:38)
|
||||
|-- logger.formatTool() <-- CRASH HERE
|
||||
|
|
||||
v [if crash, never reaches]
|
||||
Worker HTTP Endpoint
|
||||
|-- middleware.ts:110 logger.formatTool() <-- CRASH HERE TOO
|
||||
|
|
||||
v [if crash, 400 returned]
|
||||
SessionManager
|
||||
|-- SessionManager.ts:220 logger.formatTool() <-- CRASH HERE TOO
|
||||
|
|
||||
v [if crash, not queued]
|
||||
Database
|
||||
```
|
||||
|
||||
## Recommended Fix
|
||||
|
||||
### Option 1: User's Proposed Fix (Minimal)
|
||||
|
||||
```typescript
|
||||
let input = toolInput;
|
||||
if (typeof toolInput === 'string') {
|
||||
try {
|
||||
input = JSON.parse(toolInput);
|
||||
} catch {
|
||||
input = { raw: toolInput };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: Simple, encapsulates raw strings in an object
|
||||
**Cons**: Changes the shape of input for raw strings (may affect downstream logic)
|
||||
|
||||
### Option 2: Consistent with prompts.ts Pattern (Recommended)
|
||||
|
||||
```typescript
|
||||
formatTool(toolName: string, toolInput?: any): string {
|
||||
if (!toolInput) return toolName;
|
||||
|
||||
let input = toolInput;
|
||||
if (typeof toolInput === 'string') {
|
||||
try {
|
||||
input = JSON.parse(toolInput);
|
||||
} catch {
|
||||
// Input is a raw string, not JSON - use as-is
|
||||
input = toolInput;
|
||||
}
|
||||
}
|
||||
|
||||
// Bash: show full command
|
||||
if (toolName === 'Bash' && input.command) {
|
||||
return `${toolName}(${input.command})`;
|
||||
}
|
||||
|
||||
// Handle raw string inputs (e.g., from Bash commands passed as strings)
|
||||
if (typeof input === 'string') {
|
||||
return `${toolName}(${input.length > 50 ? input.slice(0, 50) + '...' : input})`;
|
||||
}
|
||||
|
||||
// ... rest of existing logic
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: Consistent with existing pattern, handles raw strings gracefully
|
||||
**Cons**: Requires additional check for string display formatting
|
||||
|
||||
### Option 3: Extract Shared Utility (Best Long-term)
|
||||
|
||||
Create a shared utility in `src/shared/json-utils.ts`:
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Safely parse JSON that might be a raw string
|
||||
* Returns the parsed object if valid JSON, otherwise the original value
|
||||
*/
|
||||
export function safeJsonParse<T>(value: T): T | object {
|
||||
if (typeof value !== 'string') return value;
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then use in both `logger.ts` and `prompts.ts` for consistency.
|
||||
|
||||
## Similar Patterns to Review
|
||||
|
||||
Other `JSON.parse` calls that may need similar protection:
|
||||
|
||||
| File | Line | Current Protection |
|
||||
|------|------|-------------------|
|
||||
| `src/sdk/prompts.ts` | 97, 106 | Has try-catch |
|
||||
| `src/services/sqlite/PendingMessageStore.ts` | 373-374 | No try-catch (lower risk - DB data should be valid) |
|
||||
| `src/utils/logger.ts` | 139 | **No try-catch (BUG)** |
|
||||
|
||||
## Testing Considerations
|
||||
|
||||
### Unit Tests Needed
|
||||
|
||||
1. `formatTool` with valid JSON string input
|
||||
2. `formatTool` with object input (already parsed)
|
||||
3. `formatTool` with raw string input (the bug case)
|
||||
4. `formatTool` with null/undefined input
|
||||
5. `formatTool` with empty string input
|
||||
|
||||
### Integration Tests Needed
|
||||
|
||||
1. PostToolUse hook with Bash command string
|
||||
2. Observation storage with raw string tool input
|
||||
3. Full pipeline from hook through worker to database
|
||||
|
||||
### Test Cases
|
||||
|
||||
```typescript
|
||||
// Should handle raw string input without crashing
|
||||
expect(logger.formatTool('Bash', 'ls -la')).toBe('Bash(ls -la)');
|
||||
|
||||
// Should handle JSON string input
|
||||
expect(logger.formatTool('Read', '{"file_path": "/foo"}'))
|
||||
.toBe('Read(/foo)');
|
||||
|
||||
// Should handle object input
|
||||
expect(logger.formatTool('Read', { file_path: '/foo' }))
|
||||
.toBe('Read(/foo)');
|
||||
|
||||
// Should handle empty/null input
|
||||
expect(logger.formatTool('Bash')).toBe('Bash');
|
||||
expect(logger.formatTool('Bash', null)).toBe('Bash');
|
||||
```
|
||||
|
||||
## Complexity
|
||||
|
||||
**Low** - 30 minutes to 1 hour
|
||||
|
||||
- Single file change (`src/utils/logger.ts`)
|
||||
- Clear fix pattern exists in codebase
|
||||
- No breaking API changes
|
||||
- Unit tests straightforward
|
||||
|
||||
## References
|
||||
|
||||
- GitHub Issue: #545
|
||||
- Related file with correct pattern: `src/sdk/prompts.ts` (lines 96-102)
|
||||
- Logger source: `src/utils/logger.ts` (lines 136-197)
|
||||
279
docs/reports/2026-01-05--issue-555-windows-hooks-ipc-false.md
Normal file
279
docs/reports/2026-01-05--issue-555-windows-hooks-ipc-false.md
Normal file
@@ -0,0 +1,279 @@
|
||||
# Issue #555 Analysis: Windows Hooks Not Executing - hasIpc Always False
|
||||
|
||||
**Date:** 2026-01-05
|
||||
**Version Analyzed:** 8.5.9
|
||||
**Claude Code Version:** 2.0.76
|
||||
**Platform:** Windows 11 (Build 26100), Git Bash (MINGW64)
|
||||
**Status:** INVESTIGATION COMPLETE - Root cause identified
|
||||
|
||||
## Issue Summary
|
||||
|
||||
On Windows 11 with Git Bash, Claude-mem plugin hooks are not executing at all. While the worker service starts successfully and responds to health checks, no observations are being saved and no hook-related logs appear.
|
||||
|
||||
### Reported Symptoms
|
||||
|
||||
```json
|
||||
// /api/health
|
||||
{
|
||||
"status": "ok",
|
||||
"build": "TEST-008-wrapper-ipc",
|
||||
"managed": false,
|
||||
"hasIpc": false,
|
||||
"platform": "win32",
|
||||
"pid": 3596,
|
||||
"initialized": true,
|
||||
"mcpReady": true
|
||||
}
|
||||
|
||||
// /api/stats
|
||||
{
|
||||
"observations": 0,
|
||||
"sessions": 1
|
||||
}
|
||||
```
|
||||
|
||||
### Key Observations
|
||||
|
||||
1. Worker starts and responds correctly to HTTP requests
|
||||
2. `hasIpc` is `false` (this is **expected behavior**, not a bug)
|
||||
3. `observations` remains at `0` - no data being captured
|
||||
4. No `[HOOK]` entries in worker logs - hooks never execute
|
||||
5. This differs from issue #517 which was about PowerShell escaping
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Primary Cause: Hook Commands Not Executing
|
||||
|
||||
The hooks defined in `plugin/hooks/hooks.json` are never being invoked by Claude Code on Windows.
|
||||
|
||||
### Understanding hasIpc
|
||||
|
||||
The `hasIpc` field is a **red herring** and is working as intended:
|
||||
|
||||
```typescript
|
||||
// src/services/server/Server.ts:152
|
||||
hasIpc: typeof process.send === 'function'
|
||||
```
|
||||
|
||||
This checks if the worker process was spawned with an IPC channel (via `fork()` or `spawn()` with `stdio: 'ipc'`). Plugin hooks execute as independent command-line processes, NOT as forked child processes with IPC channels. Therefore, `hasIpc: false` is the **expected, normal behavior** for all hook executions.
|
||||
|
||||
### Actual Problem: Hook Command Execution Failure
|
||||
|
||||
The hooks.json uses Unix-style environment variable syntax:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start"
|
||||
}
|
||||
```
|
||||
|
||||
**On Windows, this fails because:**
|
||||
|
||||
1. **Shell Interpreter Mismatch**: Claude Code on Windows likely uses `cmd.exe` or PowerShell to execute hook commands, not Git Bash. The `${VARIABLE}` syntax only works in Bash; cmd.exe uses `%VARIABLE%`.
|
||||
|
||||
2. **PATH Environment Differences**: The user runs Claude in Git Bash where `bun` and `node` are in PATH. However, Claude Code executes hooks in its own shell context (likely cmd.exe), which may not inherit Git Bash's PATH configuration.
|
||||
|
||||
3. **CLAUDE_PLUGIN_ROOT Resolution**: If Claude Code doesn't properly set or expand `CLAUDE_PLUGIN_ROOT` before executing the command, the entire path becomes invalid.
|
||||
|
||||
## Code Investigation Findings
|
||||
|
||||
### Affected Files
|
||||
|
||||
| File | Purpose | Issue |
|
||||
|------|---------|-------|
|
||||
| `plugin/hooks/hooks.json` | Hook command definitions | Uses `${CLAUDE_PLUGIN_ROOT}` Unix syntax |
|
||||
| `plugin/scripts/smart-install.js` | Dependency installer | Executed via hooks.json, never runs on Windows |
|
||||
| `plugin/scripts/worker-service.cjs` | Worker CLI | Executed via hooks.json, never runs on Windows |
|
||||
| `plugin/scripts/*.js` | Hook scripts | None execute because hooks.json commands fail |
|
||||
|
||||
### hooks.json Analysis
|
||||
|
||||
Current hooks.json commands:
|
||||
|
||||
```json
|
||||
{
|
||||
"SessionStart": [{
|
||||
"hooks": [
|
||||
{ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/smart-install.js\"" },
|
||||
{ "command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start" },
|
||||
{ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js\"" }
|
||||
]
|
||||
}],
|
||||
"PostToolUse": [{
|
||||
"hooks": [
|
||||
{ "command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start" },
|
||||
{ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/save-hook.js\"" }
|
||||
]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
**Problems identified:**
|
||||
|
||||
1. `${CLAUDE_PLUGIN_ROOT}` - Unix variable expansion, fails in cmd.exe
|
||||
2. `bun` command - May not be in system PATH on Windows
|
||||
3. `node` command - May not be in system PATH accessible to Claude Code
|
||||
|
||||
### Worker hasIpc Usage
|
||||
|
||||
The hasIpc field is used only for admin endpoint IPC messaging, which is a separate concern from hook execution:
|
||||
|
||||
```typescript
|
||||
// src/services/server/Server.ts:209-216
|
||||
const isWindowsManaged = process.platform === 'win32' &&
|
||||
process.env.CLAUDE_MEM_MANAGED === 'true' &&
|
||||
process.send;
|
||||
|
||||
if (isWindowsManaged) {
|
||||
process.send!({ type: 'restart' });
|
||||
}
|
||||
```
|
||||
|
||||
This IPC mechanism is for managed process scenarios and is unrelated to why hooks aren't executing.
|
||||
|
||||
## Relationship to Issue #517
|
||||
|
||||
| Aspect | Issue #517 | Issue #555 |
|
||||
|--------|------------|------------|
|
||||
| **Problem** | PowerShell `$_` variable misinterpreted by Bash | Hooks not executing at all |
|
||||
| **Location** | ProcessManager.ts (worker internals) | hooks.json execution by Claude Code |
|
||||
| **Fix Applied** | Replaced PowerShell with WMIC | N/A (new issue) |
|
||||
| **Scope** | Worker process management | Claude Code hook invocation |
|
||||
|
||||
Issue #517 fixed internal worker operations (orphaned process cleanup). Issue #555 is a completely different layer - it's about Claude Code's plugin system failing to invoke hooks on Windows.
|
||||
|
||||
## Proposed Fix
|
||||
|
||||
### Option 1: Cross-Platform Wrapper Script (Recommended)
|
||||
|
||||
Create a platform-aware wrapper that handles path resolution:
|
||||
|
||||
```javascript
|
||||
// plugin/scripts/hook-runner.js
|
||||
#!/usr/bin/env node
|
||||
const path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
// Resolve CLAUDE_PLUGIN_ROOT or compute from script location
|
||||
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT ||
|
||||
path.dirname(__dirname);
|
||||
|
||||
const hookScript = process.argv[2];
|
||||
const hookPath = path.join(pluginRoot, 'scripts', hookScript);
|
||||
|
||||
// Execute the actual hook
|
||||
require(hookPath);
|
||||
```
|
||||
|
||||
Update hooks.json to use relative paths:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "node ./scripts/hook-runner.js context-hook.js"
|
||||
}
|
||||
```
|
||||
|
||||
### Option 2: Windows-Specific hooks.json
|
||||
|
||||
Create a Windows-compatible version using `%CLAUDE_PLUGIN_ROOT%` syntax:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "node \"%CLAUDE_PLUGIN_ROOT%\\scripts\\smart-install.js\""
|
||||
}
|
||||
```
|
||||
|
||||
**Drawback:** Requires maintaining two hooks.json versions or using conditional logic.
|
||||
|
||||
### Option 3: Use Absolute Paths
|
||||
|
||||
Generate hooks.json at install time with resolved absolute paths:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "node \"C:\\Users\\username\\.claude\\plugins\\marketplaces\\thedotmack\\plugin\\scripts\\smart-install.js\""
|
||||
}
|
||||
```
|
||||
|
||||
**Drawback:** Less portable, requires install-time generation.
|
||||
|
||||
### Option 4: Ensure bun/node in System PATH
|
||||
|
||||
Add installation validation to ensure `bun` and `node` are in the system-wide PATH, not just Git Bash's PATH:
|
||||
|
||||
```powershell
|
||||
# In smart-install.js for Windows
|
||||
if (IS_WINDOWS) {
|
||||
// Add to system PATH if not present
|
||||
// Or use absolute paths to node/bun executables
|
||||
}
|
||||
```
|
||||
|
||||
## Debugging Steps for Users
|
||||
|
||||
1. **Verify plugin registration:**
|
||||
```powershell
|
||||
claude /status
|
||||
```
|
||||
|
||||
2. **Check plugin installation:**
|
||||
```powershell
|
||||
dir $env:USERPROFILE\.claude\plugins\marketplaces\thedotmack\plugin\hooks
|
||||
```
|
||||
|
||||
3. **Test environment variable:**
|
||||
```powershell
|
||||
$env:CLAUDE_PLUGIN_ROOT = "$env:USERPROFILE\.claude\plugins\marketplaces\thedotmack\plugin"
|
||||
node "$env:CLAUDE_PLUGIN_ROOT\scripts\smart-install.js"
|
||||
```
|
||||
|
||||
4. **Check if node/bun are in system PATH:**
|
||||
```powershell
|
||||
where.exe node
|
||||
where.exe bun
|
||||
```
|
||||
|
||||
5. **Enable Claude Code debug logging:**
|
||||
- Check Claude Code settings for debug/verbose mode
|
||||
- Look for hook execution errors in logs
|
||||
|
||||
## Impact Assessment
|
||||
|
||||
- **Severity:** High - Complete loss of memory functionality on Windows
|
||||
- **Scope:** All Windows users, especially those using Git Bash
|
||||
- **Workaround:** None currently - hooks must execute for memory to work
|
||||
- **Affected Versions:** Likely affects 8.5.x on Windows with Claude Code 2.0.76+
|
||||
|
||||
## Recommended Actions
|
||||
|
||||
1. **Immediate:** Document the issue and potential workarounds
|
||||
2. **Short-term:** Implement Option 1 (cross-platform wrapper script)
|
||||
3. **Long-term:** Request clarification from Anthropic on Windows hook execution behavior
|
||||
4. **Testing:** Add Windows CI/CD testing for hook execution
|
||||
|
||||
## Files to Modify
|
||||
|
||||
1. `plugin/hooks/hooks.json` - Update command syntax
|
||||
2. `plugin/scripts/hook-runner.js` - New cross-platform wrapper (create)
|
||||
3. `plugin/scripts/smart-install.js` - Add PATH validation for Windows
|
||||
4. `docs/public/troubleshooting.mdx` - Document Windows hook issues
|
||||
|
||||
## Appendix: Technical Details
|
||||
|
||||
### Environment Variable Expansion by Shell
|
||||
|
||||
| Shell | Syntax | Works in hooks.json |
|
||||
|-------|--------|---------------------|
|
||||
| Bash | `${VAR}` or `$VAR` | Yes (if Bash executes) |
|
||||
| cmd.exe | `%VAR%` | Yes (if cmd executes) |
|
||||
| PowerShell | `$env:VAR` | Yes (if PS executes) |
|
||||
|
||||
### Claude Code Hook Execution Flow
|
||||
|
||||
1. Claude Code loads hooks.json from plugin directory
|
||||
2. On hook event (SessionStart, PostToolUse, etc.), executes defined commands
|
||||
3. Commands are executed via system shell (platform-dependent)
|
||||
4. Hook process receives JSON via stdin, outputs response to stdout
|
||||
5. Claude Code processes hook output
|
||||
|
||||
The failure occurs at step 3 when the shell cannot resolve the command or environment variables.
|
||||
@@ -0,0 +1,343 @@
|
||||
# Investigation Report: Issue #557 - Plugin Fails to Start
|
||||
|
||||
**Date:** January 5, 2026
|
||||
**Issue:** [#557](https://github.com/thedotmack/claude-mem/issues/557) - Plugin fails to start: settings.json not generated, worker throws module loader error
|
||||
**Author:** Sheikh Abdur Raheem Ali (@sheikheddy)
|
||||
**Investigator:** Claude (Opus 4.5)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The plugin fails to start during the SessionStart hook with a Node.js module loader error. This investigation identifies two separate but related issues:
|
||||
|
||||
1. **Primary Issue:** Runtime mismatch - hooks are built for Bun but invoked with Node.js
|
||||
2. **Secondary Issue:** settings.json auto-creation only happens via HTTP API, not during initialization
|
||||
|
||||
The root cause appears to be that Claude Code 2.0.76 is invoking hooks with Node.js despite hooks having `#!/usr/bin/env bun` shebangs, and Node.js v25.2.1 cannot execute code with `bun:sqlite` imports (an external module reference that doesn't exist in Node.js).
|
||||
|
||||
---
|
||||
|
||||
## Environment Details
|
||||
|
||||
| Component | Version |
|
||||
|-----------|---------|
|
||||
| claude-mem | 8.1.0 |
|
||||
| Claude Code | 2.0.76 |
|
||||
| Node.js | v25.2.1 |
|
||||
| Bun | 1.3.5 |
|
||||
| OS | macOS 26.2 (arm64) |
|
||||
| Database Size | 17.9 MB (existing data) |
|
||||
|
||||
---
|
||||
|
||||
## Issue Analysis
|
||||
|
||||
### Error Location
|
||||
|
||||
The error occurs at:
|
||||
```
|
||||
node:internal/modules/cjs/loader:1423
|
||||
throw err;
|
||||
^
|
||||
```
|
||||
|
||||
This error signature indicates Node.js (not Bun) is attempting to load a CommonJS module that has unresolvable dependencies.
|
||||
|
||||
### Hook Configuration Analysis
|
||||
|
||||
From `/Users/alexnewman/Scripts/claude-mem/plugin/hooks/hooks.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "startup|clear|compact",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/smart-install.js\"",
|
||||
"timeout": 300
|
||||
},
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start",
|
||||
"timeout": 60
|
||||
},
|
||||
{
|
||||
"type": "command",
|
||||
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js\"",
|
||||
"timeout": 60
|
||||
},
|
||||
{
|
||||
"type": "command",
|
||||
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/user-message-hook.js\"",
|
||||
"timeout": 60
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Key Observation:** Hooks are explicitly invoked with `node` but are built as ESM bundles with Bun-specific features.
|
||||
|
||||
### Build Configuration Analysis
|
||||
|
||||
From `/Users/alexnewman/Scripts/claude-mem/scripts/build-hooks.js`:
|
||||
|
||||
1. **Hooks** are built with:
|
||||
- `format: 'esm'` (ES modules)
|
||||
- `external: ['bun:sqlite']` (Bun-specific SQLite binding)
|
||||
- Shebang: `#!/usr/bin/env bun`
|
||||
|
||||
2. **Worker Service** is built with:
|
||||
- `format: 'cjs'` (CommonJS)
|
||||
- `external: ['bun:sqlite']`
|
||||
- Shebang: `#!/usr/bin/env bun`
|
||||
|
||||
The `bun:sqlite` external dependency is the critical issue. When Node.js tries to load these files, it cannot resolve `bun:sqlite` as it's a Bun-specific built-in module.
|
||||
|
||||
### Settings.json Auto-Creation Analysis
|
||||
|
||||
From `/Users/alexnewman/Scripts/claude-mem/src/services/worker/http/routes/SettingsRoutes.ts`:
|
||||
|
||||
```typescript
|
||||
private ensureSettingsFile(settingsPath: string): void {
|
||||
if (!existsSync(settingsPath)) {
|
||||
const defaults = SettingsDefaultsManager.getAllDefaults();
|
||||
const dir = path.dirname(settingsPath);
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
writeFileSync(settingsPath, JSON.stringify(defaults, null, 2), 'utf-8');
|
||||
logger.info('SETTINGS', 'Created settings file with defaults', { settingsPath });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This method is only called when:
|
||||
1. `GET /api/settings` is requested
|
||||
2. `POST /api/settings` is requested
|
||||
|
||||
**Problem:** If the worker service fails to start (due to the module loader error), the HTTP API never becomes available, so `ensureSettingsFile` is never called.
|
||||
|
||||
### SettingsDefaultsManager Behavior
|
||||
|
||||
From `/Users/alexnewman/Scripts/claude-mem/src/shared/SettingsDefaultsManager.ts`:
|
||||
|
||||
```typescript
|
||||
static loadFromFile(settingsPath: string): SettingsDefaults {
|
||||
try {
|
||||
if (!existsSync(settingsPath)) {
|
||||
return this.getAllDefaults(); // Returns defaults, doesn't create file
|
||||
}
|
||||
// ... rest of loading logic
|
||||
} catch (error) {
|
||||
return this.getAllDefaults(); // Fallback to defaults on any error
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Behavior:** When settings.json doesn't exist, `loadFromFile` returns in-memory defaults but does NOT create the file. This is defensive programming (fail-safe) but means the file is never auto-created during worker startup.
|
||||
|
||||
---
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Primary Root Cause: Runtime Mismatch
|
||||
|
||||
The hooks are designed to run under Bun (as indicated by their shebangs and `bun:sqlite` dependency), but hooks.json explicitly invokes them with `node`:
|
||||
|
||||
```json
|
||||
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js\""
|
||||
```
|
||||
|
||||
When Node.js v25.2.1 attempts to load these ESM bundles:
|
||||
1. It parses the JavaScript successfully (ESM is valid)
|
||||
2. It encounters `import ... from 'bun:sqlite'`
|
||||
3. Node.js cannot resolve `bun:sqlite` (not a valid Node.js specifier)
|
||||
4. CJS loader throws the error at line 1423
|
||||
|
||||
### Why This Worked Before (Potential Regression Paths)
|
||||
|
||||
1. **Bun Availability:** The smart-install.js script auto-installs Bun, but the PATH may not be updated within the same shell session
|
||||
2. **Claude Code Change:** Claude Code 2.0.76 may have changed how it invokes hooks (not honoring shebangs, using explicit `node` command)
|
||||
3. **Node.js v25 Change:** Node.js v25 may handle ESM/CJS boundaries differently than earlier versions
|
||||
|
||||
### Secondary Root Cause: Settings Not Auto-Created at Startup
|
||||
|
||||
The worker service's background initialization (`initializeBackground()`) loads settings but doesn't create the file:
|
||||
|
||||
```typescript
|
||||
const settings = SettingsDefaultsManager.loadFromFile(USER_SETTINGS_PATH);
|
||||
const modeId = settings.CLAUDE_MEM_MODE;
|
||||
ModeManager.getInstance().loadMode(modeId);
|
||||
```
|
||||
|
||||
`loadFromFile` returns defaults when the file is missing but doesn't write them to disk.
|
||||
|
||||
---
|
||||
|
||||
## Affected Files
|
||||
|
||||
| File | Role | Issue |
|
||||
|------|------|-------|
|
||||
| `/plugin/hooks/hooks.json` | Hook configuration | Explicitly uses `node` instead of `bun` |
|
||||
| `/plugin/scripts/context-hook.js` | SessionStart hook | ESM with `bun:sqlite` dependency |
|
||||
| `/plugin/scripts/user-message-hook.js` | SessionStart hook | ESM with `bun:sqlite` dependency |
|
||||
| `/plugin/scripts/worker-service.cjs` | Worker service | CJS with `bun:sqlite` dependency |
|
||||
| `/src/shared/SettingsDefaultsManager.ts` | Settings manager | Doesn't auto-create file |
|
||||
| `/src/services/worker/http/routes/SettingsRoutes.ts` | HTTP routes | Only creates file on API access |
|
||||
| `/scripts/build-hooks.js` | Build script | Marks `bun:sqlite` as external |
|
||||
|
||||
---
|
||||
|
||||
## Proposed Fixes
|
||||
|
||||
### Fix 1: Update hooks.json to Use Bun (Recommended)
|
||||
|
||||
Change all hook commands from `node` to `bun`:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js\"",
|
||||
"timeout": 60
|
||||
}
|
||||
```
|
||||
|
||||
**Rationale:** Hooks depend on `bun:sqlite`, so they must run under Bun.
|
||||
|
||||
### Fix 2: Create Settings File During Startup
|
||||
|
||||
Add file creation to `SettingsDefaultsManager.loadFromFile`:
|
||||
|
||||
```typescript
|
||||
static loadFromFile(settingsPath: string): SettingsDefaults {
|
||||
try {
|
||||
if (!existsSync(settingsPath)) {
|
||||
const defaults = this.getAllDefaults();
|
||||
// Create directory if needed
|
||||
const dir = path.dirname(settingsPath);
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
// Write defaults to file
|
||||
writeFileSync(settingsPath, JSON.stringify(defaults, null, 2), 'utf-8');
|
||||
logger.info('SETTINGS', 'Created settings file with defaults', { settingsPath });
|
||||
return defaults;
|
||||
}
|
||||
// ... existing logic
|
||||
} catch (error) {
|
||||
logger.warn('SETTINGS', 'Failed to load/create settings, using defaults', { settingsPath }, error);
|
||||
return this.getAllDefaults();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Rationale:** This ensures settings.json always exists after first access, regardless of how the plugin starts.
|
||||
|
||||
### Fix 3: Build Hooks Without bun:sqlite Dependency (Alternative)
|
||||
|
||||
Modify the build to inline SQLite operations or use a Node.js-compatible SQLite library:
|
||||
|
||||
```javascript
|
||||
// In build-hooks.js
|
||||
external: [], // Remove bun:sqlite from externals
|
||||
```
|
||||
|
||||
This would require using `better-sqlite3` or similar, which has been deliberately avoided due to native module compilation issues.
|
||||
|
||||
### Fix 4: Add Fallback Logic in Hooks (Defensive)
|
||||
|
||||
Add runtime detection to hooks to provide better error messages:
|
||||
|
||||
```typescript
|
||||
if (typeof Bun === 'undefined') {
|
||||
console.error('This hook requires Bun runtime. Please ensure Bun is installed.');
|
||||
process.exit(1);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. **Confirm Bun is installed and in PATH:**
|
||||
```bash
|
||||
which bun
|
||||
bun --version
|
||||
```
|
||||
|
||||
2. **Manually test context-hook with Bun:**
|
||||
```bash
|
||||
bun ~/.claude/plugins/marketplaces/thedotmack/plugin/scripts/context-hook.js
|
||||
```
|
||||
|
||||
3. **Manually test context-hook with Node (should fail):**
|
||||
```bash
|
||||
node ~/.claude/plugins/marketplaces/thedotmack/plugin/scripts/context-hook.js
|
||||
```
|
||||
|
||||
4. **Check if settings.json exists:**
|
||||
```bash
|
||||
cat ~/.claude-mem/settings.json
|
||||
```
|
||||
|
||||
5. **Verify worker can start:**
|
||||
```bash
|
||||
bun ~/.claude/plugins/marketplaces/thedotmack/plugin/scripts/worker-service.cjs start
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Issues
|
||||
|
||||
- **Issue #290:** `refactor: simplify hook execution - use Node directly instead of Bun` - This commit changed hooks to use Node, potentially introducing this regression
|
||||
- **Issue #265:** `fix: add npm fallback when bun install fails with alias packages` - Related to Bun/npm installation issues
|
||||
- **Issue #527:** `uv-homebrew-analysis` - Related to dependency installation issues
|
||||
|
||||
---
|
||||
|
||||
## Workaround for Users
|
||||
|
||||
Until a fix is released, users can manually:
|
||||
|
||||
1. **Ensure Bun is installed:**
|
||||
```bash
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
source ~/.bashrc # or ~/.zshrc
|
||||
```
|
||||
|
||||
2. **Create settings.json manually:**
|
||||
```bash
|
||||
mkdir -p ~/.claude-mem
|
||||
cat > ~/.claude-mem/settings.json << 'EOF'
|
||||
{
|
||||
"CLAUDE_MEM_MODEL": "claude-sonnet-4-5",
|
||||
"CLAUDE_MEM_CONTEXT_OBSERVATIONS": "50",
|
||||
"CLAUDE_MEM_WORKER_PORT": "37777",
|
||||
"CLAUDE_MEM_WORKER_HOST": "127.0.0.1",
|
||||
"CLAUDE_MEM_PROVIDER": "claude",
|
||||
"CLAUDE_MEM_DATA_DIR": "$HOME/.claude-mem",
|
||||
"CLAUDE_MEM_LOG_LEVEL": "INFO",
|
||||
"CLAUDE_MEM_MODE": "code"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
3. **Start worker manually:**
|
||||
```bash
|
||||
bun ~/.claude/plugins/marketplaces/thedotmack/plugin/scripts/worker-service.cjs start
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
This issue is a **runtime mismatch regression** where hooks built for Bun are being invoked with Node.js. The fix requires updating `hooks.json` to use Bun for all hook commands that depend on `bun:sqlite`. The settings.json creation is a secondary issue that should be addressed by ensuring the file is created during first access in `SettingsDefaultsManager.loadFromFile`.
|
||||
|
||||
**Priority:** High (blocks plugin startup)
|
||||
**Severity:** Critical (plugin completely non-functional)
|
||||
**Effort:** Low (configuration change + minor code addition)
|
||||
Reference in New Issue
Block a user