mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-26 19:45:03 +02:00
fix(install): ship ajv/sql.js with the plugin install bundle (#2822)
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.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
'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,
|
||||
};
|
||||
Reference in New Issue
Block a user