ctx7 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -152,15 +152,24 @@ function getGitHubHeaders() {
152
152
  ...ghToken && { Authorization: `token ${ghToken}` }
153
153
  };
154
154
  }
155
+ async function extractGitHubError(response) {
156
+ let detail = `HTTP ${response.status}`;
157
+ try {
158
+ const body = await response.json();
159
+ if (body.message) detail += `: ${body.message}`;
160
+ } catch {
161
+ }
162
+ return detail;
163
+ }
155
164
  async function fetchRepoTree(owner, repo, branch, headers) {
156
165
  const treeUrl = `${GITHUB_API}/repos/${owner}/${repo}/git/trees/${branch}?recursive=1`;
157
166
  const response = await fetch(treeUrl, { headers });
158
- if (!response.ok) return null;
167
+ if (!response.ok) return { error: await extractGitHubError(response) };
159
168
  return await response.json();
160
169
  }
161
170
  async function fetchDefaultBranch(owner, repo, headers) {
162
171
  const response = await fetch(`${GITHUB_API}/repos/${owner}/${repo}`, { headers });
163
- if (!response.ok) return { status: response.status };
172
+ if (!response.ok) return { error: await extractGitHubError(response), status: response.status };
164
173
  const data = await response.json();
165
174
  return { branch: data.default_branch };
166
175
  }
@@ -171,9 +180,12 @@ async function listSkillsFromGitHub(project) {
171
180
  const [owner, repo] = parts;
172
181
  const headers = getGitHubHeaders();
173
182
  const branchResult = await fetchDefaultBranch(owner, repo, headers);
174
- if ("status" in branchResult) return { status: "repo_not_found" };
183
+ if ("error" in branchResult) {
184
+ if (branchResult.status === 404) return { status: "repo_not_found" };
185
+ return { status: "error", error: branchResult.error };
186
+ }
175
187
  const treeData = await fetchRepoTree(owner, repo, branchResult.branch, headers);
176
- if (!treeData) return { status: "error", error: "Could not fetch repository tree" };
188
+ if ("error" in treeData) return { status: "error", error: treeData.error };
177
189
  const skillMdFiles = treeData.tree.filter(
178
190
  (item) => item.type === "blob" && item.path.toLowerCase().endsWith("skill.md")
179
191
  );
@@ -214,8 +226,9 @@ async function downloadSkillFromGitHub(skill) {
214
226
  const { owner, repo, branch, path: skillPath } = parsed;
215
227
  const ghHeaders = getGitHubHeaders();
216
228
  const treeData = await fetchRepoTree(owner, repo, branch, ghHeaders);
217
- if (!treeData) {
218
- return { files: [], error: `GitHub API error` };
229
+ if ("error" in treeData) {
230
+ const hint = !ghHeaders["Authorization"] && /403|429|rate/.test(treeData.error) ? " \u2014 run `gh auth login` or set the GITHUB_TOKEN env var to increase rate limits" : "";
231
+ return { files: [], error: `GitHub API error: ${treeData.error}${hint}` };
219
232
  }
220
233
  const skillFiles = treeData.tree.filter(
221
234
  (item) => item.type === "blob" && item.path.startsWith(skillPath + "/")
@@ -3516,6 +3529,20 @@ async function setupAgent(agentName, auth, transport, scope) {
3516
3529
  skillPath
3517
3530
  };
3518
3531
  }
3532
+ function logSkillStatus(skillStatus, skillPath) {
3533
+ const skillFailed = skillStatus.startsWith("failed:");
3534
+ const skillIcon = skillStatus === "installed" ? pc8.green("+") : skillFailed ? pc8.red("\u2716") : pc8.dim("~");
3535
+ log.plain(` ${skillIcon} Skill ${skillFailed ? "failed" : skillStatus}`);
3536
+ log.plain(` ${pc8.dim(skillPath)}`);
3537
+ if (skillFailed) {
3538
+ log.plain(` ${pc8.red(skillStatus.slice("failed: ".length))}`);
3539
+ if (skillStatus.includes("EACCES")) {
3540
+ log.plain(
3541
+ ` ${pc8.yellow("tip:")} fix permissions with: ${pc8.cyan(`sudo chown -R $(whoami) ${dirname7(dirname7(skillPath))}`)}`
3542
+ );
3543
+ }
3544
+ }
3545
+ }
3519
3546
  async function setupMcp(agents2, options, scope) {
3520
3547
  const transport = resolveTransport(options);
3521
3548
  if (transport === "stdio" && options.oauth) {
@@ -3544,14 +3571,7 @@ async function setupMcp(agents2, options, scope) {
3544
3571
  const ruleIcon = r.ruleStatus === "installed" ? pc8.green("+") : pc8.dim("~");
3545
3572
  log.plain(` ${ruleIcon} Rule ${r.ruleStatus}`);
3546
3573
  log.plain(` ${pc8.dim(r.rulePath)}`);
3547
- const skillIcon = r.skillStatus === "installed" ? pc8.green("+") : pc8.dim("~");
3548
- log.plain(` ${skillIcon} Skill ${r.skillStatus}`);
3549
- log.plain(` ${pc8.dim(r.skillPath)}`);
3550
- if (r.skillStatus.includes("EACCES")) {
3551
- log.plain(
3552
- ` ${pc8.yellow("tip:")} fix permissions with: ${pc8.cyan(`sudo chown -R $(whoami) ${dirname7(dirname7(r.skillPath))}`)}`
3553
- );
3554
- }
3574
+ logSkillStatus(r.skillStatus, r.skillPath);
3555
3575
  }
3556
3576
  log.blank();
3557
3577
  trackEvent("setup", { agents: agents2, scope, authMode: auth.mode });
@@ -3597,22 +3617,16 @@ async function setupCli(options) {
3597
3617
  const installSpinner = ora4("Installing...").start();
3598
3618
  const results = [];
3599
3619
  for (const agentName of agents2) {
3600
- installSpinner.text = `Setting up ${getAgent(agentName).displayName}...`;
3620
+ const agentDef = getAgent(agentName);
3621
+ installSpinner.text = `Setting up ${agentDef.displayName}...`;
3601
3622
  const r = await setupCliAgent(agentName, scope, downloadData);
3602
- results.push({ agent: getAgent(agentName).displayName, ...r });
3623
+ results.push({ agent: agentDef.displayName, ...r });
3603
3624
  }
3604
3625
  installSpinner.succeed("Context7 CLI setup complete");
3605
3626
  log.blank();
3606
3627
  for (const r of results) {
3607
3628
  log.plain(` ${pc8.bold(r.agent)}`);
3608
- const skillIcon = r.skillStatus === "installed" ? pc8.green("+") : pc8.dim("~");
3609
- log.plain(` ${skillIcon} Skill ${r.skillStatus}`);
3610
- log.plain(` ${pc8.dim(r.skillPath)}`);
3611
- if (r.skillStatus.includes("EACCES")) {
3612
- log.plain(
3613
- ` ${pc8.yellow("tip:")} fix permissions with: ${pc8.cyan(`sudo chown -R $(whoami) ${dirname7(dirname7(r.skillPath))}`)}`
3614
- );
3615
- }
3629
+ logSkillStatus(r.skillStatus, r.skillPath);
3616
3630
  const ruleIcon = r.ruleStatus === "installed" || r.ruleStatus === "updated" ? pc8.green("+") : pc8.dim("~");
3617
3631
  log.plain(` ${ruleIcon} Rule ${r.ruleStatus}`);
3618
3632
  log.plain(` ${pc8.dim(r.rulePath)}`);