diff --git a/src/server/__tests__/skill-market.test.ts b/src/server/__tests__/skill-market.test.ts index 57dd29ae..2bf857f1 100644 --- a/src/server/__tests__/skill-market.test.ts +++ b/src/server/__tests__/skill-market.test.ts @@ -715,6 +715,20 @@ describe('skill market risk analysis', () => { expect(risk).toEqual(['requires-api-key']) }) + it('does not treat similarly named fields as allowed tools or hooks', () => { + const risk = analyzeSkillRisk({ + entryContent: [ + '---', + 'disallowed-tools: Bash', + 'webhooks: https://example.com/callback', + '---', + ].join('\n'), + files: [], + }) + + expect(risk).toEqual(['external-network']) + }) + it('returns an empty array when no conservative risks are detected', () => { const risk = analyzeSkillRisk({ entryContent: 'A local-only skill with no special permissions.', diff --git a/src/server/services/skillMarket/risk.ts b/src/server/services/skillMarket/risk.ts index c895329c..3f1c8959 100644 --- a/src/server/services/skillMarket/risk.ts +++ b/src/server/services/skillMarket/risk.ts @@ -11,6 +11,8 @@ const RISK_LABEL_ORDER: SkillMarketRiskLabel[] = [ const EXECUTABLE_EXTENSION = /\.(sh|bash|zsh|fish|ps1|cmd|bat|py|js|ts)$/i const API_KEYWORD = /api[\s_-]?key|token|secret/i +const ALLOWED_TOOLS_KEY = /^\s*allowed-tools\s*:/m +const HOOKS_KEY = /^\s*hooks\s*:/m export function analyzeSkillRisk(input: { entryContent?: string @@ -19,13 +21,12 @@ export function analyzeSkillRisk(input: { }): SkillMarketRiskLabel[] { const labels = new Set() const entryContent = input.entryContent ?? '' - const entryLines = entryContent.split(/\r?\n/) - if (entryLines.some((line) => line.includes('allowed-tools:'))) { + if (ALLOWED_TOOLS_KEY.test(entryContent)) { labels.add('allowed-tools') } - if (entryLines.some((line) => line.includes('hooks:'))) { + if (HOOKS_KEY.test(entryContent)) { labels.add('hooks') }