mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 22:14:25 +01:00
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:
1 parent
424214ace7
commit
ac8e30cce6
2 files changed
+6
-5
No files matched your search
@@ -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);
|
||||
|
||||
@@ -83,11 +83,11 @@ describe('C4: ship and plan-ceo-review are carved on every external host', () =>
|
||||
});
|
||||
}
|
||||
|
||||
test('no external render points at $GSTACK_ROOT/<skill>/sections/ (runtime roots have no section trees)', () => {
|
||||
test('no external render points at <root>/<skill>/sections/ (runtime roots have no section trees)', () => {
|
||||
const offenders: string[] = [];
|
||||
for (const config of EXTERNAL) {
|
||||
for (const file of skillFiles(path.join(renders.all, config.hostSubdir))) {
|
||||
const hits = fs.readFileSync(file, 'utf8').match(/\$GSTACK_ROOT\/[a-z0-9-]+\/sections\/[\w.-]+/g) ?? [];
|
||||
const hits = fs.readFileSync(file, 'utf8').match(/(?:\$GSTACK_ROOT|~\/[\w./-]*skills\/gstack)\/[a-z0-9-]+\/sections\/[\w.-]+/g) ?? [];
|
||||
offenders.push(...hits.map(hit => `${path.relative(renders.all, file)}: ${hit}`));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user