C4: rewrite section refs on hosts whose root stays a literal ~/<globalRoot>

Kiro, OpenCode, Cursor and Copilot render ~/.claude/skills/gstack as their own
literal root, not $GSTACK_ROOT, so plan-eng-review's self-check pointer
escaped the rewrite (found by the setup lane's installed-pointer check).
This commit is contained in:
garrytan committed 2026-10-03 21:51:27 +00:00
1 parent 424214ace7
commit ac8e30cce6
2 files changed
+6 -5

No files matched your search

+4 -3
View File
@@ -38,13 +38,14 @@ export function usesLazySections(host: Host, skill: string): boolean {
/**
* External hosts: a template's literal `~/.claude/skills/gstack/<skill>/sections/<file>`
* reference arrives here as `$GSTACK_ROOT/<skill>/sections/<file>`, which external
* runtime roots do not have. For a carved skill, point it at the installed copy;
* reference arrives here as `$GSTACK_ROOT/...` or `~/<globalRoot>/...`, and external
* runtime roots have no section trees. For a carved skill, point it at the installed copy;
* for this skill's own section inlined by {{SECTION}}, point at the inlined text.
*/
export function rewriteCarvedSectionRefs(content: string, ctx: TemplateContext): string {
if (ctx.host === 'claude') return content;
return content.replace(/`\$GSTACK_ROOT\/([a-z0-9-]+)\/sections\/([A-Za-z0-9._-]+)`/g, (match, skill: string, file: string) => {
// The root arrives as $GSTACK_ROOT or as the host's literal ~/<globalRoot> (path rewrites).
return content.replace(/`(?:\$GSTACK_ROOT|~\/[\w./-]*?skills\/gstack)\/([a-z0-9-]+)\/sections\/([A-Za-z0-9._-]+)`/g, (match, skill: string, file: string) => {
if (!fs.existsSync(path.join(ROOT, skill, 'sections', `${file}.tmpl`))) return match;
if (usesLazySections(ctx.host, skill)) return `\`sections/${file}\` relative to the installed \`gstack-${skill}\` SKILL.md directory`;
const entry = loadManifest(skill).sections.find(e => e.file === file);