feat(skills): validate manifest installer specs
This commit is contained in:
@@ -11,6 +11,48 @@ import { execSync } from 'child_process';
|
||||
import { platform } from 'os';
|
||||
import type { Skill, SkillManifest, SkillRequirements, SkillTier } from './types.js';
|
||||
|
||||
function isStringArray(value: unknown): value is string[] {
|
||||
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
||||
}
|
||||
|
||||
function hasValidInstallers(manifest: unknown): boolean {
|
||||
if (!manifest || typeof manifest !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const candidate = manifest as { installers?: unknown };
|
||||
if (candidate.installers === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Array.isArray(candidate.installers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return candidate.installers.every((installer) => {
|
||||
if (!installer || typeof installer !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const typedInstaller = installer as { type?: unknown; packages?: unknown; url?: unknown; destination?: unknown };
|
||||
if (typedInstaller.type === 'brew' || typedInstaller.type === 'node' || typedInstaller.type === 'go') {
|
||||
return isStringArray(typedInstaller.packages);
|
||||
}
|
||||
|
||||
if (typedInstaller.type === 'download') {
|
||||
if (typeof typedInstaller.url !== 'string') {
|
||||
return false;
|
||||
}
|
||||
if (typedInstaller.destination !== undefined && typeof typedInstaller.destination !== 'string') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a skill's system requirements are met.
|
||||
*
|
||||
@@ -90,6 +132,10 @@ export function loadSkill(directory: string, tier: SkillTier): Skill | null {
|
||||
console.warn(`Skill manifest at ${manifestPath} missing required fields (name, description, version)`);
|
||||
return null;
|
||||
}
|
||||
if (!hasValidInstallers(raw)) {
|
||||
console.warn(`Skill manifest at ${manifestPath} has invalid installers specification`);
|
||||
return null;
|
||||
}
|
||||
|
||||
manifest = {
|
||||
...raw,
|
||||
|
||||
Reference in New Issue
Block a user