mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-16 21:25:42 +02:00
fix(install): strip ecc: plugin namespace from manual Claude installs
The ecc@ecc plugin namespaces agents, commands and skills as `ecc:<name>`. A manual install (install-apply --target claude|claude-project) places the same files at bare names under ~/.claude, so plugin-prefixed references in copied markdown point at agents and commands that do not exist in that layout (e.g. subagent_type "ecc:planner", frontmatter agent: ecc:...). - Add plugin-namespace.js with stripPluginNamespace(), which removes the `ecc:` prefix before an identifier and leaves `ecc@ecc`, URLs and words ending in "ecc" alone. - Apply it to markdown copy operations when the target is claude or claude-project. Non-markdown files and other targets are unchanged. - Reword the agents rule so it describes both install modes instead of stating that agents only ship with the plugin. - Cover the transform with tests/lib/install-plugin-namespace.test.js.
This commit is contained in:
@@ -51,6 +51,11 @@ const {
|
||||
prepareExcludedPathsReconciliation,
|
||||
} = require('./excluded-paths-reconciliation');
|
||||
const { buildInstallIndex, rewriteRelativeLinks } = require('./link-rewrite');
|
||||
const { stripPluginNamespace } = require('./plugin-namespace');
|
||||
|
||||
// Manual installs place agents, commands and skills at bare names; the
|
||||
// ecc@ecc plugin namespaces them as `ecc:<name>`.
|
||||
const MANUAL_CLAUDE_TARGETS = new Set(['claude', 'claude-project']);
|
||||
const { adaptAntigravityAgent } = require('./antigravity-agent');
|
||||
|
||||
function isMarkdownPath(filePath) {
|
||||
@@ -874,13 +879,16 @@ function applyInstallPlanLocked(plan, dependencies = {}, settingsLockHeld = fals
|
||||
&& operation.sourceRelativePath
|
||||
&& isMarkdownPath(operation.destinationPath)
|
||||
);
|
||||
if (operation.kind === 'copy-file' && (operation.contentTransform || needsLinkRewrite)) {
|
||||
const stripNamespace = MANUAL_CLAUDE_TARGETS.has(plan.adapter?.target)
|
||||
&& isMarkdownPath(operation.destinationPath);
|
||||
if (operation.kind === 'copy-file' && (operation.contentTransform || needsLinkRewrite || stripNamespace)) {
|
||||
const transformed = transformInstallContent(
|
||||
operation,
|
||||
fs.readFileSync(operation.sourcePath, 'utf8')
|
||||
);
|
||||
const namespaced = stripNamespace ? stripPluginNamespace(transformed) : transformed;
|
||||
const installedContent = needsLinkRewrite
|
||||
? rewriteRelativeLinks(transformed, {
|
||||
? rewriteRelativeLinks(namespaced, {
|
||||
sourceRel: operation.sourceRelativePath,
|
||||
index: linkIndex,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
// The ecc@ecc plugin exposes agents, commands and skills under an `ecc:`
|
||||
// namespace (`ecc:planner`, `/ecc:plan`). A manual install
|
||||
// (install-apply --target claude|claude-project) places the same files at bare
|
||||
// names, so plugin-prefixed references in copied markdown must drop the prefix
|
||||
// or they point at agents and commands that do not exist in that layout.
|
||||
//
|
||||
// The leading guard keeps `ecc@ecc` and words that merely end in "ecc" (e.g.
|
||||
// "decc:") untouched; the lookahead requires a real identifier after the colon.
|
||||
const PLUGIN_NAMESPACE_PREFIX = /(^|[^A-Za-z0-9_@.-])ecc:(?=[a-z][a-z0-9-]*)/gm;
|
||||
|
||||
function stripPluginNamespace(content) {
|
||||
return String(content).replace(PLUGIN_NAMESPACE_PREFIX, '$1');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
stripPluginNamespace,
|
||||
};
|
||||
Reference in New Issue
Block a user