Skip to content

Commit 1b89a6a

Browse files
committed
fix: restrict portable update detection
1 parent 5b33031 commit 1b89a6a

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

bin/lib/init-flow.mjs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync, cpSync } from 'fs';
1+
import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync, cpSync } from 'fs';
22
import { dirname, join, isAbsolute } from 'path';
33
import { buildPlanningCliHelperEntries, renderSkillContent } from './rendering.mjs';
44
import { buildManifest, readManifest, writeManifest } from './manifest.mjs';
@@ -147,7 +147,7 @@ export function createCmdUpdate(ctx) {
147147
updated = true;
148148
}
149149

150-
if (platforms.length > 0 || existsSync(ctx.planningDir) || existsSync(join(ctx.cwd, '.agents', 'skills'))) {
150+
if (platforms.length > 0 || existsSync(ctx.planningDir) || hasGeneratedOpenStandardSkills(ctx.cwd)) {
151151
if (isDry) {
152152
console.log(' - would update open-standard skills (.agents/skills/gsdd-*)');
153153
} else {
@@ -199,6 +199,21 @@ export function createCmdUpdate(ctx) {
199199
};
200200
}
201201

202+
function hasGeneratedOpenStandardSkills(cwd) {
203+
const skillsDir = join(cwd, '.agents', 'skills');
204+
if (!existsSync(skillsDir)) return false;
205+
206+
try {
207+
return readdirSync(skillsDir, { withFileTypes: true }).some((entry) =>
208+
entry.isDirectory() &&
209+
entry.name.startsWith('gsdd-') &&
210+
existsSync(join(skillsDir, entry.name, 'SKILL.md'))
211+
);
212+
} catch {
213+
return false;
214+
}
215+
}
216+
202217
function generateOpenStandardSkills(cwd, workflows) {
203218
for (const workflow of workflows) {
204219
const dir = join(cwd, '.agents', 'skills', workflow.name);

tests/gsdd.manifest.test.cjs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,20 @@ describe('generation manifest', () => {
175175
assert.strictEqual(afterContent, beforeContent);
176176
});
177177

178+
test('update does not generate GSDD skills for unrelated .agents/skills directories', async () => {
179+
const unrelatedSkillDir = path.join(tmpDir, '.agents', 'skills', 'custom-agent');
180+
fs.mkdirSync(unrelatedSkillDir, { recursive: true });
181+
fs.writeFileSync(path.join(unrelatedSkillDir, 'SKILL.md'), '# Custom Agent\n');
182+
183+
const result = await runCliAsMain(tmpDir, ['update']);
184+
assert.strictEqual(result.exitCode, 0, result.output);
185+
assert.match(result.output, /no adapters found to update/);
186+
assert.ok(!fs.existsSync(path.join(tmpDir, '.agents', 'skills', 'gsdd-plan')),
187+
'unrelated .agents/skills must not trigger GSDD skill generation');
188+
assert.ok(!fs.existsSync(path.join(tmpDir, '.planning')),
189+
'update must not bootstrap planning state for an unrelated .agents/skills directory');
190+
});
191+
178192
test('update repairs open-standard skills when only the .planning/bin helper remains', async () => {
179193
await initProject();
180194

0 commit comments

Comments
 (0)