mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-02 15:04:37 +01:00
C1: skillify finds the browse SDK under its own host's install root
The template hardcoded ~/.claude/skills/gstack for the canonical browse-client.ts, so external hosts read another host's install or nothing. A new INSTALLED_ROOT resolver (sibling of INSTALLED_BIN_DIR) names the host's global root, or the per-install root when setup renders for one.
This commit is contained in:
1 parent
ea0b4841ba
commit
424214ace7
3 files changed
+31
-2
No files matched your search
@@ -143,6 +143,7 @@ export const RESOLVERS: Record<string, ResolverFn> = {
|
||||
// Literal bin dir for skills that skip the shared preamble, where
|
||||
// $GSTACK_BIN is never set (#2906): the per-install root when rendering for
|
||||
// one, else the host's default global root.
|
||||
INSTALLED_ROOT: (ctx) => ctx.installRoot ? ctx.installRoot.replace(/\/+$/, '') : `~/${getHostConfig(ctx.host).globalRoot}`,
|
||||
INSTALLED_BIN_DIR: (ctx) => ctx.installRoot ? `${ctx.installRoot.replace(/\/+$/, '')}/bin` : `~/${getHostConfig(ctx.host).globalRoot}/bin`,
|
||||
FOREGROUND_DISPATCH_NOTE: () => FOREGROUND_DISPATCH_NOTE,
|
||||
GBRAIN_CONTEXT_LOAD: generateGBrainContextLoad,
|
||||
|
||||
@@ -220,7 +220,7 @@ Resolve the gstack install dir. Two reliable signals (in order):
|
||||
`$B skill list` (the `bundled` row). The skill dir is
|
||||
`<gstack-install>/browser-skills/hackernews-frontpage/`, so the install
|
||||
dir is two `dirname` calls above its `_lib/browse-client.ts`.
|
||||
2. The active gstack skills install at `~/.claude/skills/gstack/`. Read
|
||||
2. The active gstack skills install at `{{INSTALLED_ROOT}}/`. Read
|
||||
the symlink target if it's a symlink, otherwise use the path directly.
|
||||
|
||||
Example (run as Bun, not bash, to avoid shell-redirect parsing issues):
|
||||
@@ -232,7 +232,7 @@ import * as path from 'path';
|
||||
|
||||
function resolveSdkPath(): string {
|
||||
const candidates = [
|
||||
path.join(os.homedir(), '.claude', 'skills', 'gstack', 'browse', 'src', 'browse-client.ts'),
|
||||
'{{INSTALLED_ROOT}}/browse/src/browse-client.ts'.replace(/^~(?=\/)/, os.homedir()),
|
||||
// Add other install-dir candidates if your environment differs.
|
||||
];
|
||||
for (const c of candidates) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* /skillify resolved the browse SDK at ~/.claude/skills/gstack on every host,
|
||||
* so on Codex and the other external hosts it read another host's install (or
|
||||
* nothing). The install root now comes from the host config (INSTALLED_ROOT).
|
||||
*/
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { ALL_HOST_CONFIGS } from '../hosts';
|
||||
import { runGeneration } from '../scripts/gen-skill-docs';
|
||||
|
||||
const out = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-skillify-paths-'));
|
||||
beforeAll(async () => { expect((await runGeneration({ host: 'all', outputRoot: out })).exitCode).toBe(0); });
|
||||
afterAll(() => fs.rmSync(out, { recursive: true, force: true }));
|
||||
|
||||
describe('skillify resolves the browse SDK from its own host install', () => {
|
||||
for (const host of ALL_HOST_CONFIGS) {
|
||||
test(host.name, () => {
|
||||
const file = host.name === 'claude' ? path.join(out, 'skillify/SKILL.md') : path.join(out, host.hostSubdir, 'skills/gstack-skillify/SKILL.md');
|
||||
if (!fs.existsSync(file)) return;
|
||||
const text = fs.readFileSync(file, 'utf8');
|
||||
const sdk = text.split('\n').filter(l => l.includes('browse-client.ts') && /homedir|replace/.test(l));
|
||||
expect(sdk).toEqual([` '~/${host.globalRoot}/browse/src/browse-client.ts'.replace(/^~(?=\\/)/, os.homedir()),`]);
|
||||
expect(text).toContain(`The active gstack skills install at \`~/${host.globalRoot}/\``);
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user