fix: exclude non-wiped dirs from custom-file scan; warn on non-Claude model profiles (#2511)
* fix(detect-custom-files): exclude skills and command dirs not wiped by installer (closes #2505) GSD_MANAGED_DIRS included 'skills' and 'command' directories, but the installer never wipes those paths. Users with third-party skills installed (40+ files, none in GSD's manifest) had every skill flagged as a "custom file" requiring backup, producing noisy false-positive reports on every /gsd-update run. Removes 'skills' and 'command' from both gsd-tools.cjs and the SDK's detect-custom-files.ts. Adds two regression tests confirming neither directory is scanned. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(settings): warn that model profiles are no-ops on non-Claude runtimes (closes #2506) settings.md presented Quality/Balanced/Budget model profiles without any indication that these tiers map to Claude models (Opus/Sonnet/Haiku) and have no effect on non-Claude runtimes (Codex, Gemini CLI, OpenRouter). Users on Codex saw the profile chooser as if it would meaningfully select models, but all agents silently used the runtime default regardless. Adds a non-Claude runtime note before the profile question (shown in TEXT_MODE, the path all non-Claude runtimes take) explaining the profiles are no-ops and directing users to either choose Inherit or configure model_overrides manually. Also updates the Inherit option description to explicitly name the runtimes where it is the correct choice. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -225,4 +225,58 @@ describe('detect-custom-files — update workflow backup detection (#1997)', ()
|
||||
`should detect custom reference; got: ${JSON.stringify(json.custom_files)}`
|
||||
);
|
||||
});
|
||||
|
||||
// #2505 — installer does NOT wipe skills/ or command/; scanning them produces
|
||||
// false-positive "custom file" reports for every skill the user has installed
|
||||
// from other packages.
|
||||
test('does not scan skills/ directory (installer does not wipe it)', () => {
|
||||
writeManifest(tmpDir, {
|
||||
'get-shit-done/workflows/execute-phase.md': '# Execute Phase\n',
|
||||
});
|
||||
|
||||
// Simulate user having third-party skills installed — none in manifest
|
||||
const skillsDir = path.join(tmpDir, 'skills');
|
||||
fs.mkdirSync(skillsDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(skillsDir, 'my-custom-skill.md'), '# My Skill\n');
|
||||
fs.writeFileSync(path.join(skillsDir, 'another-plugin-skill.md'), '# Another\n');
|
||||
|
||||
const result = runGsdTools(
|
||||
['detect-custom-files', '--config-dir', tmpDir],
|
||||
tmpDir
|
||||
);
|
||||
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const json = JSON.parse(result.output);
|
||||
const skillFiles = json.custom_files.filter(f => f.startsWith('skills/'));
|
||||
assert.strictEqual(
|
||||
skillFiles.length, 0,
|
||||
`skills/ should not be scanned; got false positives: ${JSON.stringify(skillFiles)}`
|
||||
);
|
||||
});
|
||||
|
||||
test('does not scan command/ directory (installer does not wipe it)', () => {
|
||||
writeManifest(tmpDir, {
|
||||
'get-shit-done/workflows/execute-phase.md': '# Execute Phase\n',
|
||||
});
|
||||
|
||||
// Simulate files in command/ dir not wiped by installer
|
||||
const commandDir = path.join(tmpDir, 'command');
|
||||
fs.mkdirSync(commandDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(commandDir, 'user-command.md'), '# User Command\n');
|
||||
|
||||
const result = runGsdTools(
|
||||
['detect-custom-files', '--config-dir', tmpDir],
|
||||
tmpDir
|
||||
);
|
||||
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const json = JSON.parse(result.output);
|
||||
const commandFiles = json.custom_files.filter(f => f.startsWith('command/'));
|
||||
assert.strictEqual(
|
||||
commandFiles.length, 0,
|
||||
`command/ should not be scanned; got false positives: ${JSON.stringify(commandFiles)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user