diff --git a/get-shit-done/bin/lib/install-profiles.cjs b/get-shit-done/bin/lib/install-profiles.cjs index 0fffd83f5..8e6035c57 100644 --- a/get-shit-done/bin/lib/install-profiles.cjs +++ b/get-shit-done/bin/lib/install-profiles.cjs @@ -374,7 +374,30 @@ function stageAgentsForProfile(srcAgentsDir, resolvedProfile) { } function stageSkillsForRuntimeAsSkills(srcCommandsDir, resolvedProfile, converter, prefix) { - // stub + if (!fs.existsSync(srcCommandsDir)) return srcCommandsDir; + + const stageDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-profile-runtime-skills-')); + try { + const entries = fs.readdirSync(srcCommandsDir, { withFileTypes: true }); + for (const entry of entries) { + if (!entry.isFile()) continue; + if (!entry.name.endsWith('.md')) continue; + const stem = entry.name.slice(0, -3); + if (resolvedProfile.skills !== '*' && !resolvedProfile.skills.has(stem)) continue; + const content = fs.readFileSync(path.join(srcCommandsDir, entry.name), 'utf8'); + const skillName = `${prefix}${stem}`; + const converted = converter(content, skillName); + const destDir = path.join(stageDir, skillName); + fs.mkdirSync(destDir, { recursive: true }); + fs.writeFileSync(path.join(destDir, 'SKILL.md'), converted); + } + } catch (err) { + try { fs.rmSync(stageDir, { recursive: true, force: true }); } catch {} + throw err; + } + STAGED_DIRS.add(stageDir); + ensureExitCleanup(); + return stageDir; } // --------------------------------------------------------------------------- diff --git a/tests/install-profiles-stage.test.cjs b/tests/install-profiles-stage.test.cjs index 4594f259e..89d7fdb96 100644 --- a/tests/install-profiles-stage.test.cjs +++ b/tests/install-profiles-stage.test.cjs @@ -42,6 +42,27 @@ describe('stageSkillsForRuntimeAsSkills', () => { test('is exported as a function', () => { assert.strictEqual(typeof stageSkillsForRuntimeAsSkills, 'function'); }); + + test('skills === "*" stages all md files as /SKILL.md', () => { + const src = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-rta-src-')); + let stagedDir; + try { + for (const name of ['alpha', 'beta', 'gamma']) { + fs.writeFileSync(path.join(src, `${name}.md`), `# ${name}\n`); + } + const converter = (content, _skillName) => content; + stagedDir = stageSkillsForRuntimeAsSkills(src, { skills: '*' }, converter, 'gsd-'); + const entries = fs.readdirSync(stagedDir).sort(); + assert.deepStrictEqual(entries, ['gsd-alpha', 'gsd-beta', 'gsd-gamma']); + for (const name of ['alpha', 'beta', 'gamma']) { + const content = fs.readFileSync(path.join(stagedDir, `gsd-${name}`, 'SKILL.md'), 'utf8'); + assert.strictEqual(content, `# ${name}\n`); + } + } finally { + fs.rmSync(src, { recursive: true, force: true }); + if (stagedDir) cleanupStagedSkills(); + } + }); }); describe('stageSkillsForProfile', () => {