mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 22:14:25 +01:00
C4: external hosts point at carved sections relative to the installed skill
Publishes the pointer form setup matches: on every non-Claude host a carved section is `sections/<file>` relative to the installed gstack-<skill> SKILL.md directory (QA's existing form), never $GSTACK_ROOT/<skill>/sections/, which does not exist in external runtime roots. No render changes yet: only QA is carved on external hosts today.
This commit is contained in:
1 parent
a0c0668b3b
commit
b141b101e9
2 files changed
+36
-2
No files matched your search
@@ -54,11 +54,17 @@ function findSection(skill: string, id: string): SectionEntry {
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pointer to a carved section file. Claude keeps its global-root path; QA and
|
||||
* every external host point relative to the installed skill directory, because
|
||||
* external runtime roots (`$GSTACK_ROOT`) carry no `<skill>/sections/` tree
|
||||
* while setup links or copies whole skill directories.
|
||||
*/
|
||||
export function sectionPath(ctx: TemplateContext, skill: string, id: string): string {
|
||||
const entry = findSection(skill, id);
|
||||
if (skill === 'qa' || skill === 'qa-only') {
|
||||
if (ctx.host !== 'claude' || skill === 'qa' || skill === 'qa-only') {
|
||||
fs.accessSync(path.join(ROOT, skill, 'sections', `${entry.file}.tmpl`), fs.constants.R_OK);
|
||||
const installedName = ctx.host === 'claude' ? `\`${skill}\`/\`gstack-${skill}\`` : `\`gstack-${skill}\``;
|
||||
const installedName = ctx.host === 'claude' ? `\`${skill}\`/\`gstack-${skill}\`` : `\`${skill.startsWith('gstack-') ? skill : `gstack-${skill}`}\``;
|
||||
return `\`sections/${entry.file}\` relative to the installed ${installedName} SKILL.md directory`;
|
||||
}
|
||||
return `\`${ctx.paths.skillRoot}/${skill}/sections/${entry.file}\``;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* C4: carved skills on external hosts point at sections relative to the
|
||||
* installed skill directory. `$GSTACK_ROOT/<skill>/sections/...` does not exist
|
||||
* in external runtime roots (Codex's holds bin, lib, browse, review only), so a
|
||||
* root-relative pointer would 404 and the model would work from memory.
|
||||
*/
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import { ALL_HOST_CONFIGS } from '../hosts';
|
||||
import { sectionPath } from '../scripts/resolvers/sections';
|
||||
import { HOST_PATHS, type TemplateContext } from '../scripts/resolvers/types';
|
||||
|
||||
const context = (host: string, skillName: string): TemplateContext => ({ host, skillName, tmplPath: '', paths: HOST_PATHS[host] });
|
||||
|
||||
describe('C4: external section pointers', () => {
|
||||
for (const config of ALL_HOST_CONFIGS.filter(c => c.name !== 'claude')) {
|
||||
test(`${config.name}: ship and plan-ceo-review point relative to the installed skill directory`, () => {
|
||||
expect(sectionPath(context(config.name, 'ship'), 'ship', 'tests'))
|
||||
.toBe('`sections/tests.md` relative to the installed `gstack-ship` SKILL.md directory');
|
||||
expect(sectionPath(context(config.name, 'plan-ceo-review'), 'plan-ceo-review', 'review-sections'))
|
||||
.toBe('`sections/review-sections.md` relative to the installed `gstack-plan-ceo-review` SKILL.md directory');
|
||||
expect(sectionPath(context(config.name, 'ship'), 'ship', 'tests')).not.toContain('$GSTACK_ROOT');
|
||||
});
|
||||
}
|
||||
|
||||
test('claude keeps its global-root pointer (bytes unchanged)', () => {
|
||||
expect(sectionPath(context('claude', 'ship'), 'ship', 'tests')).toBe('`~/.claude/skills/gstack/ship/sections/tests.md`');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user