MCPcopy
hub / github.com/upstash/context7 / installCommand

Function installCommand

packages/cli/src/commands/skill.ts:233–478  ·  view source on GitHub ↗
(
  input: string,
  skillName: string | undefined,
  options: AddOptions
)

Source from the content-addressed store, hash-verified

231}
232
233async function installCommand(
234 input: string,
235 skillName: string | undefined,
236 options: AddOptions
237): Promise<void> {
238 trackEvent("command", { name: "install" });
239 const parsed = parseSkillInput(input);
240 if (!parsed) {
241 log.error(`Invalid input format: ${input}`);
242 log.info(`Expected: /owner/repo or full GitHub URL`);
243 log.info(`Example: ctx7 skills install /anthropics/skills pdf`);
244 log.blank();
245 return;
246 }
247 const repo = `/${parsed.owner}/${parsed.repo}`;
248
249 log.blank();
250 const spinner = ora(`Fetching skills from ${repo}...`).start();
251
252 let selectedSkills: (Skill & { project: string })[];
253
254 // When a specific skill name is provided, fetch only that skill
255 if (skillName) {
256 spinner.text = `Fetching skill: ${skillName}...`;
257 const skillData = await getSkill(repo, skillName);
258
259 if (skillData.error || !skillData.name) {
260 if (skillData.error === "prompt_injection_detected") {
261 spinner.fail(pc.red(`Prompt injection detected in skill: ${skillName}`));
262 log.warn("This skill contains potentially malicious content and cannot be installed.");
263 return;
264 }
265
266 spinner.text = `Fetching skill from GitHub: ${skillName}...`;
267 const ghResult = await getSkillFromGitHub(repo, skillName);
268 if (ghResult.status === "repo_not_found") {
269 spinner.fail(pc.red(`Repository not found: ${repo}`));
270 return;
271 }
272 if (ghResult.status !== "ok" || !ghResult.skill) {
273 spinner.fail(pc.red(`Skill not found: ${skillName}`));
274 return;
275 }
276
277 spinner.succeed(`Found skill: ${skillName}`);
278 selectedSkills = [ghResult.skill];
279 } else {
280 spinner.succeed(`Found skill: ${skillName}`);
281 selectedSkills = [
282 {
283 name: skillData.name,
284 description: skillData.description,
285 url: skillData.url,
286 project: repo,
287 },
288 ];
289 }
290 } else {

Callers 2

registerSkillCommandsFunction · 0.85
registerSkillAliasesFunction · 0.85

Calls 15

trackEventFunction · 0.85
parseSkillInputFunction · 0.85
getSkillFunction · 0.85
getSkillFromGitHubFunction · 0.85
listProjectSkillsFunction · 0.85
listSkillsFromGitHubFunction · 0.85
formatPopularityFunction · 0.85
formatTrustFunction · 0.85
terminalLinkFunction · 0.85
formatInstallRangeFunction · 0.85
checkboxWithHoverFunction · 0.85
promptForInstallTargetsFunction · 0.85

Tested by

no test coverage detected