mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 22:26:38 +03:00
Give plugin agent files the plugin-root variable, not the skill token
A spawned agent never loads SKILL.md, so the <skill-base-dir> token
Setup defines is undefined in the one context that must act on it
(review finding). Claude Code substitutes ${CLAUDE_PLUGIN_ROOT} inline
anywhere in plugin agent content, so the agents directory now gets its
own rewrite emitting the quoted variable form; the skill and reference
files keep the token, which the main thread's base-directory report
resolves.
Drafted with AI assistance, reviewed by a maintainer.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -44,6 +44,15 @@ const SETUP_FALLBACK_TEXT =
|
||||
const SETUP_PLUGIN_TEXT =
|
||||
'Every `node "<skill-base-dir>/scripts/..."` command in this skill and its references resolves against that base directory.';
|
||||
|
||||
// Agent files are subagent system prompts: a spawned agent never loads
|
||||
// SKILL.md, so Setup's <skill-base-dir> token is undefined in the one
|
||||
// context that must act on it (review finding). Claude Code substitutes
|
||||
// ${CLAUDE_PLUGIN_ROOT} inline anywhere in plugin skill and agent content
|
||||
// (code.claude.com/docs/en/plugins-reference), so agent instructions carry
|
||||
// the variable form; where a harness leaves it unsubstituted, the variable
|
||||
// still names the plugin install directory for the agent to locate.
|
||||
export const PLUGIN_AGENT_SCRIPTS_PATH = '${CLAUDE_PLUGIN_ROOT}/skills/impeccable/scripts';
|
||||
|
||||
/**
|
||||
* Rewrite one markdown file's content for the plugin subtree. Pure, so the
|
||||
* unit suite can pin every rewrite without a build.
|
||||
@@ -64,6 +73,21 @@ export function rewritePluginMarkdown(content) {
|
||||
.replace(/node <skill-base-dir>\/scripts\/([^\s`"]+)/g, 'node "<skill-base-dir>/scripts/$1"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite one agent file's content for the plugin subtree. Same quoting
|
||||
* discipline as the skill rewrite, but the path is the plugin-root
|
||||
* variable rather than the skill-base-dir token SKILL.md defines,
|
||||
* because no SKILL.md travels with a spawned agent.
|
||||
*/
|
||||
export function rewritePluginAgentMarkdown(content) {
|
||||
return content
|
||||
.replaceAll(CLAUDE_PROJECT_SCRIPTS_PATH, PLUGIN_AGENT_SCRIPTS_PATH)
|
||||
.replace(
|
||||
/node \$\{CLAUDE_PLUGIN_ROOT\}\/skills\/impeccable\/scripts\/([^\s`"]+)/g,
|
||||
'node "${CLAUDE_PLUGIN_ROOT}/skills/impeccable/scripts/$1"',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fail the build when the copied SKILL.md no longer matches the rewrite.
|
||||
* The fallback-sentence replacement keys on the exact Setup step 1 text; if
|
||||
@@ -98,20 +122,21 @@ export function verifyPluginSkillRewrite(skillMdPath) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply rewritePluginMarkdown to every .md file under dir, recursively.
|
||||
* Apply a rewrite to every .md file under dir, recursively. Defaults to
|
||||
* the skill rewrite; the agents directory passes rewritePluginAgentMarkdown.
|
||||
* Script files are left alone: the only project-relative paths in them
|
||||
* (hook-admin.mjs) install project-scoped hooks via ${CLAUDE_PROJECT_DIR},
|
||||
* which is that command's actual job.
|
||||
*/
|
||||
export function rewritePluginMarkdownTree(dir) {
|
||||
export function rewritePluginMarkdownTree(dir, rewrite = rewritePluginMarkdown) {
|
||||
if (!fs.existsSync(dir)) return;
|
||||
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
const entryPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
rewritePluginMarkdownTree(entryPath);
|
||||
rewritePluginMarkdownTree(entryPath, rewrite);
|
||||
} else if (entry.name.endsWith('.md')) {
|
||||
const original = fs.readFileSync(entryPath, 'utf-8');
|
||||
const rewritten = rewritePluginMarkdown(original);
|
||||
const rewritten = rewrite(original);
|
||||
if (rewritten !== original) fs.writeFileSync(entryPath, rewritten);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user