.maestro/playbooks/2026-02-23-Issue-Triage/2026-02-23-Root-Cause-Fixes/TRIAGE-07-Installation-Distribution.md
New users hit install failures: missing node_modules in cache installs, skills/ directory not copied, and np (a publish tool) incorrectly listed as a runtime dependency. These prevent the plugin from working at all.
Issues resolved: #1128, #1166 (missing node_modules), #1187 (missing skills/), #1156 (np runtime dep), #979 (migration failure), #1041 (marketplace not found)
Audit and fix plugin/package.json dependencies:
plugin/package.json and compare against actual runtime imports in plugin/scripts/*.jsrequire('chromadb') in plugin scriptspackage.json — move np to devDependencies if it's in dependenciesVerified 2026-02-23: All dependencies are correct.
plugin/package.jsonhas only@chroma-core/default-embed(needed by bundled worker-service.cjs for ONNX embeddings). Nochromadbreferences exist in any plugin scripts or error messages.npis already in rootdevDependencies. No changes required.
Fix missing node_modules in cache-based installs:
scripts/smart-install.js or similar)npm install --production runsFixed 2026-02-23: Root cause was
plugin/scripts/smart-install.jshad a hardcoded path to~/.claude/plugins/marketplaces/thedotmackthat doesn't work for cache-based installs. Replaced withresolveRoot()that usesCLAUDE_PLUGIN_ROOTenv var (set by Claude Code for all hooks), falls back to script location viaimport.meta.url, then XDG and legacy paths. Also fixed incorrectinstallCLI()path (ROOT/plugin/scripts/→ROOT/scripts/). AddedverifyCriticalModules()post-install check that verifies allpackage.jsondependencies exist innode_modules/before declaring success, with npm fallback on failure. Updated bothplugin/scripts/smart-install.js(distributed) andscripts/smart-install.js(dev) to use identical resolution logic. Tests added intests/smart-install.test.ts(8 tests passing).
Fix missing skills/ directory after install:
plugin/skills/ to the outputplugin/skills/mem-search/SKILL.md is included in the distributionFixed 2026-02-23:
plugin/skills/mem-search/SKILL.mdis already committed to git and correctly located in theplugin/distribution directory. The build script (scripts/build-hooks.js) doesn't need to copy it — skills are source files, not build outputs. Distribution is covered by: (1)sync-marketplace.cjssyncs entireplugin/to both marketplace and cache paths, (2) rootpackage.json"files"field includes"plugin"for npm publishes, (3)plugin.jsondoesn't reference skills because Claude Code discovers them by convention (skills/*/SKILL.md). Added build-time verification inscripts/build-hooks.jsthat fails the build ifplugin/skills/mem-search/SKILL.md,plugin/hooks/hooks.json, orplugin/.claude-plugin/plugin.jsonare missing. Added 10 regression tests intests/infrastructure/plugin-distribution.test.tscovering: skill file existence, YAML frontmatter validity, 3-layer workflow documentation, required distribution files, hooks.json integrity with CLAUDE_PLUGIN_ROOT references, package.json files field, and build script verification step.
Fix MigrationRunner schema initialization (#979):
src/services/sqlite/MigrationRunner.tsCREATE TABLE IF NOT EXISTS for all core tablesFixed 2026-02-23: Root cause was two parallel migration systems (old
DatabaseManagermigrations 1-7 and newMigrationRunnermigrations 4-22) sharing the sameschema_versionstable. Version numbers 5, 6, 7 conflicted — old system's version 5 drops orphaned tables, new system's version 5 addsworker_portcolumn. When old versions were pre-recorded,initializeSchema()skipped core table creation (maxApplied > 0gate) and migrations 5-7 were incorrectly considered "already applied". Fixes applied: (1) RemovedmaxApplied === 0gate ininitializeSchema()— core tables now always created viaCREATE TABLE IF NOT EXISTSregardless of version state. (2) Migrations 5-7 now check actual database state (column/constraint existence) rather than trusting version tracking alone. (3) Added crash-safety: temp table rebuild migrations (7, 9, 21) nowDROP TABLE IF EXISTS xxx_newbefore creating temp tables, preventing failures from previously-crashed runs. (4) Added missing migration 21 (addOnUpdateCascadeToForeignKeys) toMigrationRunner— was only inSessionStore. (5) AddedON UPDATE CASCADEto FK definitions ininitializeSchema(). All changes applied to bothrunner.tsandSessionStore.ts. Added 13 regression tests intests/services/sqlite/migration-runner.test.tscovering: fresh database initialization, idempotency (run twice), version conflict scenario (old versions 1-7 pre-recorded), crash recovery (leftover temp tables), FK cascade constraints, and data integrity preservation.
Run npm test and fix any failures
Fixed 2026-02-23: 21 test failures across 8 test files. Root causes and fixes:
- Server health endpoint (12 tests):
ServerOptionsinterface addedworkerPathandgetAiStatusproperties but 3 test files (server.test.ts,hook-execution-e2e.test.ts,worker-api-endpoints.test.ts) weren't updated. Added missing properties to all mock/inlineServerOptionsobjects.- Logger usage standards (1 test):
src/services/transcripts/cli.tsusesconsole.logfor user-facing CLI output but was flagged as a background service. Added exclusion pattern.- MarkdownFormatter (2 tests): Tests expected "MCP tools" and "MCP" strings but source was refactored to reference "mem-search skill" and "claude-mem skill" instead. Updated test expectations.
- SettingsDefaultsManager (1 test):
getBooltest usedCLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS(default changed to'false'). Updated to useCLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT(default'true').- ChromaSync (3 tests): Tests checked internal
client,transport,connectedproperties that no longer exist after refactor toChromaMcpManagersingleton. Updated tests to verify transport cleanup inChromaMcpManager.tssource instead.- OpenClaw (2 tests): Tests expected
memory_tool skipping and response truncation but source code lacked these features. Addedmemory_prefix check to skip recursive observation loops andMAX_TOOL_RESPONSE_LENGTH = 1000truncation toopenclaw/src/index.ts. Final result: 1008 pass, 0 fail, 3 skip across 57 files.