Agent Skills: Extension Support & Security Disclosure (#15834)

This commit is contained in:
N. Taylor Mullen
2026-01-04 14:45:07 -08:00
committed by GitHub
parent 12c7c9cc42
commit bdb349e7f6
9 changed files with 476 additions and 31 deletions
+25 -4
View File
@@ -38,6 +38,7 @@ import {
logExtensionInstallEvent,
logExtensionUninstall,
logExtensionUpdateEvent,
loadSkillsFromDir,
type ExtensionEvents,
type MCPServerConfig,
type ExtensionInstallMetadata,
@@ -262,10 +263,17 @@ Would you like to attempt to install via "git clone" instead?`,
const newHasHooks = fs.existsSync(
path.join(localSourcePath, 'hooks', 'hooks.json'),
);
let previousHasHooks = false;
if (isUpdate && previous && previous.hooks) {
previousHasHooks = Object.keys(previous.hooks).length > 0;
}
const previousHasHooks = !!(
isUpdate &&
previous &&
previous.hooks &&
Object.keys(previous.hooks).length > 0
);
const newSkills = await loadSkillsFromDir(
path.join(localSourcePath, 'skills'),
);
const previousSkills = previous?.skills ?? [];
await maybeRequestConsentOrFail(
newExtensionConfig,
@@ -273,6 +281,8 @@ Would you like to attempt to install via "git clone" instead?`,
newHasHooks,
previousExtensionConfig,
previousHasHooks,
newSkills,
previousSkills,
);
const extensionId = getExtensionId(newExtensionConfig, installMetadata);
const destinationPath = new ExtensionStorage(
@@ -551,6 +561,10 @@ Would you like to attempt to install via "git clone" instead?`,
});
}
const skills = await loadSkillsFromDir(
path.join(effectiveExtensionPath, 'skills'),
);
const extension: GeminiCLIExtension = {
name: config.name,
version: config.version,
@@ -567,6 +581,7 @@ Would you like to attempt to install via "git clone" instead?`,
id: getExtensionId(config, installMetadata),
settings: config.settings,
resolvedSettings,
skills,
};
this.loadedExtensions = [...this.loadedExtensions, extension];
@@ -721,6 +736,12 @@ Would you like to attempt to install via "git clone" instead?`,
output += `\n ${tool}`;
});
}
if (extension.skills && extension.skills.length > 0) {
output += `\n Agent skills:`;
extension.skills.forEach((skill) => {
output += `\n ${skill.name}: ${skill.description}`;
});
}
const resolvedSettings = extension.resolvedSettings;
if (resolvedSettings && resolvedSettings.length > 0) {
output += `\n Settings:`;