Files
msd-core/sdk/src/sdk-package-compatibility.test.ts
Tom Boucher 5c35eceb41 feat(sdk): deepen package seam for legacy query compatibility (#3419)
* feat(sdk): deepen compatibility seam for legacy profile path

* chore(changeset): set PR number for #3419

* test(sdk): make query seam wiring assertion behavioral
2026-05-11 21:12:29 -04:00

98 lines
3.8 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import { join } from 'node:path';
import {
BUNDLED_CORE_CJS_PATH,
BUNDLED_GSD_AGENTS_DIR,
BUNDLED_GSD_TEMPLATES_DIR,
BUNDLED_GSD_TOOLS_PATH,
loadLegacyCoreConfig,
probeLegacySdkAsset,
resolveBundledAgentsDir,
resolveBundledTemplatesDir,
resolveGsdToolsPath,
resolveLegacyInstallDir,
resolveLegacyUserProfilePath,
resolveLegacyTemplatesDir,
resolveLegacyWorkflowsDir,
} from './sdk-package-compatibility.js';
import { GSDError } from './errors.js';
describe('SDK Package Seam Module', () => {
const projectDir = '/work/project';
const homeDir = '/users/tester';
it('resolves legacy install-relative directories through one seam', () => {
expect(resolveLegacyInstallDir(homeDir)).toBe(join(homeDir, '.claude', 'get-shit-done'));
expect(resolveLegacyTemplatesDir(homeDir)).toBe(join(homeDir, '.claude', 'get-shit-done', 'templates'));
expect(resolveLegacyWorkflowsDir(homeDir)).toBe(join(homeDir, '.claude', 'get-shit-done', 'workflows'));
expect(resolveLegacyUserProfilePath(homeDir)).toBe(join(homeDir, '.claude', 'get-shit-done', 'USER-PROFILE.md'));
expect(resolveBundledTemplatesDir()).toBe(BUNDLED_GSD_TEMPLATES_DIR);
expect(resolveBundledAgentsDir()).toBe(BUNDLED_GSD_AGENTS_DIR);
});
it('probes legacy gsd-tools locations in bundled -> project -> home order', () => {
const resolution = probeLegacySdkAsset('gsd-tools', projectDir, {
homeDir,
existsSync: path => path === join(projectDir, '.claude', 'get-shit-done', 'bin', 'gsd-tools.cjs'),
});
expect(resolution.probes).toEqual([
BUNDLED_GSD_TOOLS_PATH,
join(projectDir, '.claude', 'get-shit-done', 'bin', 'gsd-tools.cjs'),
join(homeDir, '.claude', 'get-shit-done', 'bin', 'gsd-tools.cjs'),
]);
expect(resolution.path).toBe(join(projectDir, '.claude', 'get-shit-done', 'bin', 'gsd-tools.cjs'));
expect(resolution.fallbackPath).toBe(join(homeDir, '.claude', 'get-shit-done', 'bin', 'gsd-tools.cjs'));
});
it('returns concrete fallback gsd-tools path when no legacy probe exists', () => {
const path = resolveGsdToolsPath(projectDir, {
homeDir,
existsSync: () => false,
});
expect(path).toBe(join(homeDir, '.claude', 'get-shit-done', 'bin', 'gsd-tools.cjs'));
});
it('loads legacy core.cjs through one compatibility adapter', () => {
const loadConfig = vi.fn((cwd: string) => ({ cwd, source: 'legacy-core' }));
const requireFn = vi.fn(() => ({ loadConfig }));
const createRequire = vi.fn(() => requireFn as unknown as NodeJS.Require);
const result = loadLegacyCoreConfig(projectDir, {
homeDir,
existsSync: path => path === BUNDLED_CORE_CJS_PATH,
createRequire,
});
expect(createRequire).toHaveBeenCalledOnce();
expect(requireFn).toHaveBeenCalledWith(BUNDLED_CORE_CJS_PATH);
expect(loadConfig).toHaveBeenCalledWith(projectDir);
expect(result).toEqual({ cwd: projectDir, source: 'legacy-core' });
});
it('reports checked core.cjs probes when legacy asset missing', () => {
expect(() => loadLegacyCoreConfig(projectDir, {
homeDir,
existsSync: () => false,
})).toThrow(GSDError);
try {
loadLegacyCoreConfig(projectDir, {
homeDir,
existsSync: () => false,
});
expect.fail('expected GSDError');
} catch (error) {
expect(error).toBeInstanceOf(GSDError);
const message = (error as Error).message;
expect(message).toContain('state load: get-shit-done/bin/lib/core.cjs not found.');
expect(message).toContain('Checked:');
expect(message).toContain(BUNDLED_CORE_CJS_PATH);
expect(message).toContain(join(projectDir, '.claude', 'get-shit-done', 'bin', 'lib', 'core.cjs'));
expect(message).toContain(join(homeDir, '.claude', 'get-shit-done', 'bin', 'lib', 'core.cjs'));
}
});
});