mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-28 15:41:57 +02:00
v1.91.1.0 fix: harden Impeccable plugin discovery (#2978)
* fix(design-detect): find impeccable installed as a Claude Code plugin The design-detector probe only ever checked <root>/<SKILL_ROOTS>/skills/impeccable/, never the Claude Code plugin-cache layout (<root>/.claude/plugins/cache/<marketplace>/<plugin>/<version>/skills/impeccable/). A plugin-installed impeccable was therefore invisible: IMPECCABLE_SKILL stayed absent, the launcher was never found (so the NOT_CACHED run hint never fired), and its sibling engine was never considered. Add a plugin-cache walk alongside the existing SKILL_ROOTS walk, sharing the same presence/launcher/repo-local-exclusion/sibling-engine logic via an extracted checkSkillDir() helper so both paths stay behaviorally identical. Fixes #2838 * refactor(design-detect): consolidate newestSemverDir onto safeReaddir Both did the identical try/catch-around-readdirSync; newestSemverDir now reuses the new safeReaddir helper instead of duplicating it. * fix: harden Impeccable plugin discovery and regression fixtures * test: supply eval mode to the integrated detector callback adapter --------- Co-authored-by: Som Samantray <som.samantray@gmail.com>
This commit is contained in:
co-authored by
Som Samantray
parent
7b534d3e90
commit
2a113ae7e6
@@ -25,6 +25,17 @@ const BIN = path.join(ROOT, 'bin', 'gstack-gbrain-repo-policy');
|
||||
|
||||
let tmpHome: string;
|
||||
|
||||
function isolateGitRemote(repo: string, url: string): void {
|
||||
const git = (...args: string[]) => {
|
||||
const result = spawnSync('git', args, { cwd: repo, encoding: 'utf8', timeout: 10_000 });
|
||||
expect(result.status).toBe(0);
|
||||
return result.stdout.trim();
|
||||
};
|
||||
expect(git('config', '--get', 'remote.origin.url')).toBe(url);
|
||||
git('config', '--local', `url.${url}.insteadOf`, url);
|
||||
expect(git('remote', 'get-url', 'origin')).toBe(url);
|
||||
}
|
||||
|
||||
function run(args: string[], opts: { env?: Record<string, string> } = {}) {
|
||||
const res = spawnSync(BIN, args, {
|
||||
env: { ...process.env, GSTACK_HOME: tmpHome, ...(opts.env || {}) },
|
||||
@@ -54,6 +65,25 @@ afterEach(() => {
|
||||
fs.rmSync(tmpHome, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('fixture origin isolation overrides a controlled URL rewrite without changing the stored remote', () => {
|
||||
const repo = path.join(tmpHome, 'repo');
|
||||
fs.mkdirSync(repo);
|
||||
const git = (...args: string[]) => {
|
||||
const result = spawnSync('git', args, { cwd: repo, encoding: 'utf8', timeout: 10_000 });
|
||||
expect(result.status).toBe(0);
|
||||
return result.stdout.trim();
|
||||
};
|
||||
const url = 'https://fixture.invalid/org/repo.git';
|
||||
git('init', '-q');
|
||||
git('remote', 'add', 'origin', url);
|
||||
git('config', '--local', 'url.https://mirror.invalid/.insteadOf', 'https://fixture.invalid/');
|
||||
expect(git('config', '--get', 'remote.origin.url')).toBe(url);
|
||||
expect(git('remote', 'get-url', 'origin')).toBe('https://mirror.invalid/org/repo.git');
|
||||
isolateGitRemote(repo, url);
|
||||
expect(git('config', '--get', 'remote.origin.url')).toBe(url);
|
||||
expect(git('remote', 'get-url', 'origin')).toBe(url);
|
||||
});
|
||||
|
||||
describe('normalize', () => {
|
||||
test('strips https:// and .git', () => {
|
||||
const r = run(['normalize', 'https://github.com/foo/bar.git']);
|
||||
@@ -293,6 +323,7 @@ describe('gstack-gbrain-sync code stage honors the repo policy (#2140 sync path)
|
||||
spawnSync('git', args, { cwd: repoDir, encoding: 'utf-8', timeout: 30_000 });
|
||||
git('init', '-q', '.');
|
||||
git('remote', 'add', 'origin', REPO_URL);
|
||||
isolateGitRemote(repoDir, REPO_URL);
|
||||
fs.writeFileSync(path.join(repoDir, 'README.md'), 'fixture\n');
|
||||
git('add', '-A');
|
||||
git('-c', 'user.email=t@t', '-c', 'user.name=t', 'commit', '-qm', 'fixture');
|
||||
|
||||
Reference in New Issue
Block a user