mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-17 23:28:04 +02:00
install-plan.js and install-apply.js both require ./lib/install/config at load time, and that module required ajv unconditionally at the top of the file even though ajv is only actually used when validating an ecc-install.json. When ECC is installed via the Claude Code plugin marketplace, the marketplace directory is a bare git clone with no node_modules, so requiring ajv crashes commands like --list-profiles that never touch install-config validation at all. Same root cause in scripts/lib/control-pane/state.js: sql.js and @iarna/toml were required at module scope even though they are only used inside openSqlDatabase() and readTomlConfig(), so control-pane.js --help crashed too. Make both requires lazy so they only load when the feature that actually needs them runs. For the case where ajv/sql.js/js-yaml/@iarna-toml is genuinely needed and still missing, add a small helper that turns the raw MODULE_NOT_FOUND into an actionable message naming the package and the install command, instead of a stack trace (install-apply.js) or, worse, an unhandled crash with a usage banner tacked on that reads like a bad argument (install-plan.js, control-pane.js). Applied the same helper to memory-mcp.mjs, where ajv is genuinely load-bearing (it compiles every MCP tool's JSON schema up front) so it can't be made lazy the same way. Added a regression test that copies just scripts/, schemas/, and manifests/ into a directory with no node_modules anywhere above it in the filesystem, which reproduces the plugin-marketplace install exactly, and asserts install-plan.js and control-pane.js still work.
39 lines
1.2 KiB
JavaScript
39 lines
1.2 KiB
JavaScript
'use strict';
|
|
|
|
// Production dependencies declared in package.json's "dependencies" field.
|
|
// `npm install` never runs when ECC is installed via the Claude Code plugin
|
|
// marketplace (a plain git clone), so these can be missing at runtime even
|
|
// though the code that needs them is fine.
|
|
const RUNTIME_DEPENDENCY_VERSIONS = {
|
|
ajv: '8.20.0',
|
|
'sql.js': '1.14.2',
|
|
'js-yaml': '4.3.1',
|
|
'@iarna/toml': '2.2.5',
|
|
};
|
|
|
|
function describeMissingDependencyError(error) {
|
|
if (!error || error.code !== 'MODULE_NOT_FOUND') {
|
|
return null;
|
|
}
|
|
|
|
const match = /Cannot find module '([^']+)'/.exec(error.message || '');
|
|
const moduleName = match && match[1];
|
|
const pinnedVersion = moduleName && RUNTIME_DEPENDENCY_VERSIONS[moduleName];
|
|
|
|
if (!pinnedVersion) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
`Missing dependency '${moduleName}'. ECC's production dependencies aren't installed ` +
|
|
'(this happens when ECC was installed via the Claude Code plugin marketplace, which ' +
|
|
'clones the repo but never runs npm install). Run "npm install" from the ECC repo ' +
|
|
`root, or install just this package with "npm install --no-save ${moduleName}@${pinnedVersion}".`
|
|
);
|
|
}
|
|
|
|
module.exports = {
|
|
RUNTIME_DEPENDENCY_VERSIONS,
|
|
describeMissingDependencyError,
|
|
};
|