fix: preserve gstack env var resolver paths

This commit is contained in:
Brown 2026-05-26 09:15:58 +09:00
parent 64f9aafa1e
commit 34802c60ef
3 changed files with 53 additions and 5 deletions

View File

@ -100,13 +100,17 @@ export function generateSnapshotFlags(_ctx: TemplateContext): string {
} }
export function generateBrowseSetup(ctx: TemplateContext): string { export function generateBrowseSetup(ctx: TemplateContext): string {
const globalBrowse = ctx.paths.browseDir.startsWith('~')
? `$HOME${ctx.paths.browseDir.slice(1)}/browse`
: `${ctx.paths.browseDir}/browse`;
return `## SETUP (run this check BEFORE any browse command) return `## SETUP (run this check BEFORE any browse command)
\`\`\`bash \`\`\`bash
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) _ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
B="" B=""
[ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" ] && B="$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" [ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" ] && B="$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse"
[ -z "$B" ] && B="$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse" [ -z "$B" ] && B="${globalBrowse}"
if [ -x "$B" ]; then if [ -x "$B" ]; then
echo "READY: $B" echo "READY: $B"
else else

View File

@ -786,13 +786,20 @@ Source: [OpenAI "Designing Delightful Frontends with GPT-5.4"](https://developer
} }
export function generateDesignSetup(ctx: TemplateContext): string { export function generateDesignSetup(ctx: TemplateContext): string {
const globalDesign = ctx.paths.designDir.startsWith('~')
? `$HOME${ctx.paths.designDir.slice(1)}/design`
: `${ctx.paths.designDir}/design`;
const globalBrowse = ctx.paths.browseDir.startsWith('~')
? `$HOME${ctx.paths.browseDir.slice(1)}/browse`
: `${ctx.paths.browseDir}/browse`;
return `## DESIGN SETUP (run this check BEFORE any design mockup command) return `## DESIGN SETUP (run this check BEFORE any design mockup command)
\`\`\`bash \`\`\`bash
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) _ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
D="" D=""
[ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" ] && D="$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" [ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" ] && D="$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design"
[ -z "$D" ] && D="$HOME${ctx.paths.designDir.replace(/^~/, '')}/design" [ -z "$D" ] && D="${globalDesign}"
if [ -x "$D" ]; then if [ -x "$D" ]; then
echo "DESIGN_READY: $D" echo "DESIGN_READY: $D"
else else
@ -800,7 +807,7 @@ else
fi fi
B="" B=""
[ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" ] && B="$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" [ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" ] && B="$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse"
[ -z "$B" ] && B="$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse" [ -z "$B" ] && B="${globalBrowse}"
if [ -x "$B" ]; then if [ -x "$B" ]; then
echo "BROWSE_READY: $B" echo "BROWSE_READY: $B"
else else
@ -831,13 +838,17 @@ data, not project files. They persist across branches, conversations, and worksp
} }
export function generateDesignMockup(ctx: TemplateContext): string { export function generateDesignMockup(ctx: TemplateContext): string {
const globalDesign = ctx.paths.designDir.startsWith('~')
? `$HOME${ctx.paths.designDir.slice(1)}/design`
: `${ctx.paths.designDir}/design`;
return `## Visual Design Exploration return `## Visual Design Exploration
\`\`\`bash \`\`\`bash
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) _ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
D="" D=""
[ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" ] && D="$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" [ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" ] && D="$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design"
[ -z "$D" ] && D="$HOME${ctx.paths.designDir.replace(/^~/, '')}/design" [ -z "$D" ] && D="${globalDesign}"
[ -x "$D" ] && echo "DESIGN_READY" || echo "DESIGN_NOT_AVAILABLE" [ -x "$D" ] && echo "DESIGN_READY" || echo "DESIGN_NOT_AVAILABLE"
\`\`\` \`\`\`

View File

@ -23,7 +23,9 @@ import {
cursor, cursor,
openclaw, openclaw,
} from '../hosts/index'; } from '../hosts/index';
import { HOST_PATHS } from '../scripts/resolvers/types'; import { HOST_PATHS, type TemplateContext } from '../scripts/resolvers/types';
import { generateBrowseSetup } from '../scripts/resolvers/browse';
import { generateDesignSetup, generateDesignMockup } from '../scripts/resolvers/design';
const ROOT = path.resolve(import.meta.dir, '..'); const ROOT = path.resolve(import.meta.dir, '..');
@ -288,6 +290,37 @@ describe('HOST_PATHS derivation from configs', () => {
}); });
}); });
// ─── Env-var path resolver regression ───────────────────────
describe('env-var path resolver regression', () => {
const hermesCtx: TemplateContext = {
skillName: 'gstack',
tmplPath: 'gstack/SKILL.md.tmpl',
host: 'hermes',
paths: HOST_PATHS.hermes,
};
test('browse setup preserves Hermes GSTACK_BROWSE env var path', () => {
const setup = generateBrowseSetup(hermesCtx);
expect(setup).toContain('B="$GSTACK_BROWSE/browse"');
expect(setup).not.toContain('$HOME$GSTACK_BROWSE');
});
test('design setup preserves Hermes GSTACK_DESIGN and GSTACK_BROWSE env var paths', () => {
const setup = generateDesignSetup(hermesCtx);
expect(setup).toContain('D="$GSTACK_DESIGN/design"');
expect(setup).toContain('B="$GSTACK_BROWSE/browse"');
expect(setup).not.toContain('$HOME$GSTACK_DESIGN');
expect(setup).not.toContain('$HOME$GSTACK_BROWSE');
});
test('design mockup preserves Hermes GSTACK_DESIGN env var path', () => {
const mockup = generateDesignMockup(hermesCtx);
expect(mockup).toContain('D="$GSTACK_DESIGN/design"');
expect(mockup).not.toContain('$HOME$GSTACK_DESIGN');
});
});
// ─── host-config-export.ts CLI ────────────────────────────── // ─── host-config-export.ts CLI ──────────────────────────────
describe('host-config-export.ts CLI', () => { describe('host-config-export.ts CLI', () => {