skilluse 0.1.10 → 0.2.0

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.
Files changed (2) hide show
  1. package/dist/cli.js +429 -411
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -50437,6 +50437,25 @@ var getInstance = (stdout, createInstance) => {
50437
50437
  };
50438
50438
  // node_modules/ink/build/components/Static.js
50439
50439
  var import_react14 = __toESM(require_react(), 1);
50440
+ function Static(props) {
50441
+ const { items, children: render2, style: customStyle } = props;
50442
+ const [index, setIndex] = import_react14.useState(0);
50443
+ const itemsToRender = import_react14.useMemo(() => {
50444
+ return items.slice(index);
50445
+ }, [items, index]);
50446
+ import_react14.useLayoutEffect(() => {
50447
+ setIndex(items.length);
50448
+ }, [items.length]);
50449
+ const children = itemsToRender.map((item, itemIndex) => {
50450
+ return render2(item, index + itemIndex);
50451
+ });
50452
+ const style = import_react14.useMemo(() => ({
50453
+ position: "absolute",
50454
+ flexDirection: "column",
50455
+ ...customStyle
50456
+ }), [customStyle]);
50457
+ return import_react14.default.createElement("ink-box", { internal_static: true, style }, children);
50458
+ }
50440
50459
  // node_modules/ink/build/components/Transform.js
50441
50460
  var import_react15 = __toESM(require_react(), 1);
50442
50461
  // node_modules/ink/build/components/Newline.js
@@ -66561,18 +66580,63 @@ function getSkillsPath(agentId, scope) {
66561
66580
  }
66562
66581
  return join(process.cwd(), agent.localPath);
66563
66582
  }
66583
+ // src/services/github.ts
66584
+ function buildGitHubHeaders(token) {
66585
+ const headers = {
66586
+ Accept: "application/vnd.github+json",
66587
+ "X-GitHub-Api-Version": "2022-11-28"
66588
+ };
66589
+ if (token) {
66590
+ headers.Authorization = `Bearer ${token}`;
66591
+ }
66592
+ return headers;
66593
+ }
66594
+ function buildGitHubRawHeaders(token) {
66595
+ const headers = {
66596
+ Accept: "application/vnd.github.raw+json",
66597
+ "X-GitHub-Api-Version": "2022-11-28"
66598
+ };
66599
+ if (token) {
66600
+ headers.Authorization = `Bearer ${token}`;
66601
+ }
66602
+ return headers;
66603
+ }
66604
+ function isAuthRequired(response) {
66605
+ return response.status === 401 || response.status === 403 && !isRateLimited(response);
66606
+ }
66607
+ function isRateLimited(response) {
66608
+ return response.headers.get("X-RateLimit-Remaining") === "0";
66609
+ }
66610
+ function getGitHubErrorMessage(response) {
66611
+ if (response.status === 401) {
66612
+ return "This repository requires authentication. Run 'skilluse login' to access private repos.";
66613
+ }
66614
+ if (response.status === 403) {
66615
+ if (isRateLimited(response)) {
66616
+ return "Rate limit exceeded. Run 'skilluse login' for higher rate limits (5000 req/hr vs 60 req/hr).";
66617
+ }
66618
+ return "This repository requires authentication. Run 'skilluse login' to access private repos.";
66619
+ }
66620
+ if (response.status === 404) {
66621
+ return "Repository not found or requires authentication.";
66622
+ }
66623
+ return `GitHub API error: ${response.status}`;
66624
+ }
66625
+
66564
66626
  // src/services/discovery.ts
66565
66627
  var GITHUB_API_URL2 = "https://api.github.com";
66566
66628
  async function discoverSkillPaths(owner, repo, branch, token) {
66567
66629
  const url2 = `${GITHUB_API_URL2}/repos/${owner}/${repo}/git/trees/${branch}?recursive=1`;
66568
66630
  const response = await fetch(url2, {
66569
- headers: {
66570
- Accept: "application/vnd.github+json",
66571
- Authorization: `Bearer ${token}`,
66572
- "X-GitHub-Api-Version": "2022-11-28"
66573
- }
66631
+ headers: buildGitHubHeaders(token)
66574
66632
  });
66575
66633
  if (!response.ok) {
66634
+ if (isAuthRequired(response)) {
66635
+ return {
66636
+ authRequired: true,
66637
+ message: getGitHubErrorMessage(response)
66638
+ };
66639
+ }
66576
66640
  if (response.status === 404) {
66577
66641
  throw new Error(`Repository ${owner}/${repo} not found or branch '${branch}' doesn't exist`);
66578
66642
  }
@@ -66677,24 +66741,23 @@ async function getRemoteSkillInfo(token, skillName, repos) {
66677
66741
  try {
66678
66742
  const apiPath = basePath ? `https://api.github.com/repos/${repo}/contents/${basePath}?ref=${branch}` : `https://api.github.com/repos/${repo}/contents?ref=${branch}`;
66679
66743
  const response = await fetch(apiPath, {
66680
- headers: {
66681
- Authorization: `Bearer ${token}`,
66682
- Accept: "application/vnd.github+json",
66683
- "X-GitHub-Api-Version": "2022-11-28"
66684
- }
66744
+ headers: buildGitHubHeaders(token)
66685
66745
  });
66686
- if (!response.ok)
66746
+ if (!response.ok) {
66747
+ if (isAuthRequired(response)) {
66748
+ return {
66749
+ authRequired: true,
66750
+ message: getGitHubErrorMessage(response)
66751
+ };
66752
+ }
66687
66753
  continue;
66754
+ }
66688
66755
  const contents = await response.json();
66689
66756
  const dirs = contents.filter((item) => item.type === "dir" && item.name.toLowerCase() === skillName.toLowerCase());
66690
66757
  for (const dir of dirs) {
66691
66758
  const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${dir.path}/SKILL.md?ref=${branch}`;
66692
66759
  const skillResponse = await fetch(skillMdUrl, {
66693
- headers: {
66694
- Authorization: `Bearer ${token}`,
66695
- Accept: "application/vnd.github.raw+json",
66696
- "X-GitHub-Api-Version": "2022-11-28"
66697
- }
66760
+ headers: buildGitHubRawHeaders(token)
66698
66761
  });
66699
66762
  if (skillResponse.ok) {
66700
66763
  const content = await skillResponse.text();
@@ -66722,12 +66785,6 @@ function Info({ args: [skillName] }) {
66722
66785
  const [state, setState] = import_react31.useState({ phase: "checking" });
66723
66786
  import_react31.useEffect(() => {
66724
66787
  async function loadInfo() {
66725
- const credentials = await getCredentials();
66726
- if (!credentials) {
66727
- setState({ phase: "not_logged_in" });
66728
- exit();
66729
- return;
66730
- }
66731
66788
  setState({ phase: "loading" });
66732
66789
  const config2 = getConfig();
66733
66790
  const installedSkill = config2.installed.find((s) => s.name.toLowerCase() === skillName.toLowerCase());
@@ -66739,9 +66796,16 @@ function Info({ args: [skillName] }) {
66739
66796
  return;
66740
66797
  }
66741
66798
  }
66742
- const remoteInfo = await getRemoteSkillInfo(credentials.token, skillName, config2.repos);
66743
- if (remoteInfo) {
66744
- setState({ phase: "success", info: remoteInfo });
66799
+ const credentials = await getCredentials();
66800
+ const token = credentials?.token;
66801
+ const remoteResult = await getRemoteSkillInfo(token, skillName, config2.repos);
66802
+ if (remoteResult && "authRequired" in remoteResult) {
66803
+ setState({ phase: "auth_required", message: remoteResult.message });
66804
+ exit();
66805
+ return;
66806
+ }
66807
+ if (remoteResult) {
66808
+ setState({ phase: "success", info: remoteResult });
66745
66809
  } else {
66746
66810
  setState({ phase: "not_found", skillName });
66747
66811
  }
@@ -66760,20 +66824,14 @@ function Info({ args: [skillName] }) {
66760
66824
  return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Spinner2, {
66761
66825
  text: "Initializing..."
66762
66826
  }, undefined, false, undefined, this);
66763
- case "not_logged_in":
66827
+ case "auth_required":
66764
66828
  return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
66765
66829
  flexDirection: "column",
66766
- children: [
66767
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(StatusMessage, {
66768
- type: "error",
66769
- children: "Not authenticated"
66770
- }, undefined, false, undefined, this),
66771
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
66772
- dimColor: true,
66773
- children: "Run 'skilluse login' to authenticate with GitHub"
66774
- }, undefined, false, undefined, this)
66775
- ]
66776
- }, undefined, true, undefined, this);
66830
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(StatusMessage, {
66831
+ type: "error",
66832
+ children: state.message
66833
+ }, undefined, false, undefined, this)
66834
+ }, undefined, false, undefined, this);
66777
66835
  case "loading":
66778
66836
  return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Spinner2, {
66779
66837
  text: `Loading info for "${skillName}"...`
@@ -67004,35 +67062,30 @@ async function findSkill(token, repos, skillName) {
67004
67062
  try {
67005
67063
  const apiPath = basePath ? `https://api.github.com/repos/${repo}/contents/${basePath}?ref=${branch}` : `https://api.github.com/repos/${repo}/contents?ref=${branch}`;
67006
67064
  const response = await fetch(apiPath, {
67007
- headers: {
67008
- Authorization: `Bearer ${token}`,
67009
- Accept: "application/vnd.github+json",
67010
- "X-GitHub-Api-Version": "2022-11-28"
67011
- }
67065
+ headers: buildGitHubHeaders(token)
67012
67066
  });
67013
- if (!response.ok)
67067
+ if (!response.ok) {
67068
+ if (isAuthRequired(response)) {
67069
+ return {
67070
+ authRequired: true,
67071
+ message: getGitHubErrorMessage(response)
67072
+ };
67073
+ }
67014
67074
  continue;
67075
+ }
67015
67076
  const contents = await response.json();
67016
67077
  const dirs = contents.filter((item) => item.type === "dir" && item.name.toLowerCase() === skillName.toLowerCase());
67017
67078
  for (const dir of dirs) {
67018
67079
  const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${dir.path}/SKILL.md?ref=${branch}`;
67019
67080
  const skillResponse = await fetch(skillMdUrl, {
67020
- headers: {
67021
- Authorization: `Bearer ${token}`,
67022
- Accept: "application/vnd.github.raw+json",
67023
- "X-GitHub-Api-Version": "2022-11-28"
67024
- }
67081
+ headers: buildGitHubRawHeaders(token)
67025
67082
  });
67026
67083
  if (skillResponse.ok) {
67027
67084
  const content = await skillResponse.text();
67028
67085
  const frontmatter = parseFrontmatter2(content);
67029
67086
  const refUrl = `https://api.github.com/repos/${repo}/commits/${branch}`;
67030
67087
  const refResponse = await fetch(refUrl, {
67031
- headers: {
67032
- Authorization: `Bearer ${token}`,
67033
- Accept: "application/vnd.github+json",
67034
- "X-GitHub-Api-Version": "2022-11-28"
67035
- }
67088
+ headers: buildGitHubHeaders(token)
67036
67089
  });
67037
67090
  let commitSha = branch;
67038
67091
  if (refResponse.ok) {
@@ -67056,18 +67109,20 @@ async function findSkill(token, repos, skillName) {
67056
67109
  } catch {}
67057
67110
  }
67058
67111
  }
67059
- return results;
67112
+ return { results };
67060
67113
  }
67061
67114
  async function downloadSkillFiles(token, repo, skillPath, branch, targetDir, onProgress) {
67062
67115
  const treeUrl = `https://api.github.com/repos/${repo}/git/trees/${branch}?recursive=1`;
67063
67116
  const treeResponse = await fetch(treeUrl, {
67064
- headers: {
67065
- Authorization: `Bearer ${token}`,
67066
- Accept: "application/vnd.github+json",
67067
- "X-GitHub-Api-Version": "2022-11-28"
67068
- }
67117
+ headers: buildGitHubHeaders(token)
67069
67118
  });
67070
67119
  if (!treeResponse.ok) {
67120
+ if (isAuthRequired(treeResponse)) {
67121
+ return {
67122
+ authRequired: true,
67123
+ message: getGitHubErrorMessage(treeResponse)
67124
+ };
67125
+ }
67071
67126
  throw new Error(`Failed to fetch repository tree: ${treeResponse.status}`);
67072
67127
  }
67073
67128
  const treeData = await treeResponse.json();
@@ -67086,13 +67141,15 @@ async function downloadSkillFiles(token, repo, skillPath, branch, targetDir, onP
67086
67141
  }
67087
67142
  const fileUrl = `https://api.github.com/repos/${repo}/contents/${file2.path}?ref=${branch}`;
67088
67143
  const fileResponse = await fetch(fileUrl, {
67089
- headers: {
67090
- Authorization: `Bearer ${token}`,
67091
- Accept: "application/vnd.github.raw+json",
67092
- "X-GitHub-Api-Version": "2022-11-28"
67093
- }
67144
+ headers: buildGitHubRawHeaders(token)
67094
67145
  });
67095
67146
  if (!fileResponse.ok) {
67147
+ if (isAuthRequired(fileResponse)) {
67148
+ return {
67149
+ authRequired: true,
67150
+ message: getGitHubErrorMessage(fileResponse)
67151
+ };
67152
+ }
67096
67153
  throw new Error(`Failed to download file: ${file2.path}`);
67097
67154
  }
67098
67155
  const content = await fileResponse.text();
@@ -67109,13 +67166,15 @@ async function fetchGitHubSkill(token, owner, repo, path6, branch = "main") {
67109
67166
  try {
67110
67167
  const refUrl = `https://api.github.com/repos/${fullRepo}/commits/${branch}`;
67111
67168
  const refResponse = await fetch(refUrl, {
67112
- headers: {
67113
- Authorization: `Bearer ${token}`,
67114
- Accept: "application/vnd.github+json",
67115
- "X-GitHub-Api-Version": "2022-11-28"
67116
- }
67169
+ headers: buildGitHubHeaders(token)
67117
67170
  });
67118
67171
  if (!refResponse.ok) {
67172
+ if (isAuthRequired(refResponse)) {
67173
+ return {
67174
+ authRequired: true,
67175
+ message: getGitHubErrorMessage(refResponse)
67176
+ };
67177
+ }
67119
67178
  return null;
67120
67179
  }
67121
67180
  const refData = await refResponse.json();
@@ -67123,13 +67182,15 @@ async function fetchGitHubSkill(token, owner, repo, path6, branch = "main") {
67123
67182
  const skillMdPath = skillPath ? `${skillPath}/SKILL.md` : "SKILL.md";
67124
67183
  const skillMdUrl = `https://api.github.com/repos/${fullRepo}/contents/${skillMdPath}?ref=${branch}`;
67125
67184
  const skillResponse = await fetch(skillMdUrl, {
67126
- headers: {
67127
- Authorization: `Bearer ${token}`,
67128
- Accept: "application/vnd.github.raw+json",
67129
- "X-GitHub-Api-Version": "2022-11-28"
67130
- }
67185
+ headers: buildGitHubRawHeaders(token)
67131
67186
  });
67132
67187
  if (!skillResponse.ok) {
67188
+ if (isAuthRequired(skillResponse)) {
67189
+ return {
67190
+ authRequired: true,
67191
+ message: getGitHubErrorMessage(skillResponse)
67192
+ };
67193
+ }
67133
67194
  return null;
67134
67195
  }
67135
67196
  const content = await skillResponse.text();
@@ -67253,14 +67314,15 @@ function Install({ args: [skillName], options: opts }) {
67253
67314
  }
67254
67315
  }
67255
67316
  const credentials = await getCredentials();
67256
- if (!credentials) {
67257
- setState({ phase: "not_logged_in" });
67258
- exit();
67259
- return;
67260
- }
67317
+ const token = credentials?.token;
67261
67318
  if (source.type === "github") {
67262
67319
  setState({ phase: "searching", repo: `${source.owner}/${source.repo}` });
67263
- const result = await fetchGitHubSkill(credentials.token, source.owner, source.repo, source.path);
67320
+ const result = await fetchGitHubSkill(token, source.owner, source.repo, source.path);
67321
+ if (result && "authRequired" in result) {
67322
+ setState({ phase: "auth_required", message: result.message });
67323
+ exit();
67324
+ return;
67325
+ }
67264
67326
  if (!result) {
67265
67327
  setState({
67266
67328
  phase: "not_found",
@@ -67290,7 +67352,7 @@ function Install({ args: [skillName], options: opts }) {
67290
67352
  });
67291
67353
  try {
67292
67354
  const skillPath = source.path || "";
67293
- await downloadSkillFiles(credentials.token, `${source.owner}/${source.repo}`, skillPath, "main", installPath2, (downloaded, total) => {
67355
+ const downloadResult = await downloadSkillFiles(token, `${source.owner}/${source.repo}`, skillPath, "main", installPath2, (downloaded, total) => {
67294
67356
  const downloadProgress = 25 + downloaded / total * 50;
67295
67357
  setState((prev) => {
67296
67358
  if (prev.phase !== "installing")
@@ -67298,6 +67360,11 @@ function Install({ args: [skillName], options: opts }) {
67298
67360
  return { ...prev, progress: Math.round(downloadProgress) };
67299
67361
  });
67300
67362
  });
67363
+ if (downloadResult && "authRequired" in downloadResult) {
67364
+ setState({ phase: "auth_required", message: downloadResult.message });
67365
+ exit();
67366
+ return;
67367
+ }
67301
67368
  steps2[1].status = "done";
67302
67369
  steps2[2].status = "in_progress";
67303
67370
  setState((prev) => {
@@ -67342,7 +67409,13 @@ function Install({ args: [skillName], options: opts }) {
67342
67409
  for (const repo of allRepos) {
67343
67410
  setState({ phase: "searching", repo: repo.repo });
67344
67411
  }
67345
- const results = await findSkill(credentials.token, allRepos, source.name);
67412
+ const findResult = await findSkill(token, allRepos, source.name);
67413
+ if ("authRequired" in findResult) {
67414
+ setState({ phase: "auth_required", message: findResult.message });
67415
+ exit();
67416
+ return;
67417
+ }
67418
+ const { results } = findResult;
67346
67419
  if (results.length === 0) {
67347
67420
  setState({ phase: "not_found", skillName: source.name });
67348
67421
  exit();
@@ -67382,7 +67455,7 @@ function Install({ args: [skillName], options: opts }) {
67382
67455
  try {
67383
67456
  const repoConfig = config2.repos.find((r) => r.repo === skill.repo);
67384
67457
  const branch = repoConfig?.branch || "main";
67385
- await downloadSkillFiles(credentials.token, skill.repo, skill.path, branch, installPath, (downloaded, total) => {
67458
+ const downloadResult = await downloadSkillFiles(token, skill.repo, skill.path, branch, installPath, (downloaded, total) => {
67386
67459
  const downloadProgress = 25 + downloaded / total * 50;
67387
67460
  setState((prev) => {
67388
67461
  if (prev.phase !== "installing")
@@ -67390,6 +67463,11 @@ function Install({ args: [skillName], options: opts }) {
67390
67463
  return { ...prev, progress: Math.round(downloadProgress) };
67391
67464
  });
67392
67465
  });
67466
+ if (downloadResult && "authRequired" in downloadResult) {
67467
+ setState({ phase: "auth_required", message: downloadResult.message });
67468
+ exit();
67469
+ return;
67470
+ }
67393
67471
  steps[1].status = "done";
67394
67472
  steps[2].status = "in_progress";
67395
67473
  setState((prev) => {
@@ -67449,20 +67527,14 @@ function Install({ args: [skillName], options: opts }) {
67449
67527
  return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Spinner2, {
67450
67528
  text: "Initializing..."
67451
67529
  }, undefined, false, undefined, this);
67452
- case "not_logged_in":
67530
+ case "auth_required":
67453
67531
  return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
67454
67532
  flexDirection: "column",
67455
- children: [
67456
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(StatusMessage, {
67457
- type: "error",
67458
- children: "Not authenticated"
67459
- }, undefined, false, undefined, this),
67460
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
67461
- dimColor: true,
67462
- children: "Run 'skilluse login' to authenticate with GitHub"
67463
- }, undefined, false, undefined, this)
67464
- ]
67465
- }, undefined, true, undefined, this);
67533
+ children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(StatusMessage, {
67534
+ type: "error",
67535
+ children: state.message
67536
+ }, undefined, false, undefined, this)
67537
+ }, undefined, false, undefined, this);
67466
67538
  case "no_repos":
67467
67539
  return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
67468
67540
  flexDirection: "column",
@@ -67669,13 +67741,15 @@ async function checkForUpdate(token, skill, repoConfig) {
67669
67741
  try {
67670
67742
  const refUrl = `https://api.github.com/repos/${repo}/commits/${branch}`;
67671
67743
  const refResponse = await fetch(refUrl, {
67672
- headers: {
67673
- Authorization: `Bearer ${token}`,
67674
- Accept: "application/vnd.github+json",
67675
- "X-GitHub-Api-Version": "2022-11-28"
67676
- }
67744
+ headers: buildGitHubHeaders(token)
67677
67745
  });
67678
67746
  if (!refResponse.ok) {
67747
+ if (isAuthRequired(refResponse)) {
67748
+ return {
67749
+ authRequired: true,
67750
+ message: getGitHubErrorMessage(refResponse)
67751
+ };
67752
+ }
67679
67753
  return { ...skill, hasUpdate: false };
67680
67754
  }
67681
67755
  const refData = await refResponse.json();
@@ -67685,11 +67759,7 @@ async function checkForUpdate(token, skill, repoConfig) {
67685
67759
  }
67686
67760
  const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${skill.repoPath}/SKILL.md?ref=${branch}`;
67687
67761
  const skillResponse = await fetch(skillMdUrl, {
67688
- headers: {
67689
- Authorization: `Bearer ${token}`,
67690
- Accept: "application/vnd.github.raw+json",
67691
- "X-GitHub-Api-Version": "2022-11-28"
67692
- }
67762
+ headers: buildGitHubRawHeaders(token)
67693
67763
  });
67694
67764
  let latestVersion = skill.version;
67695
67765
  if (skillResponse.ok) {
@@ -67714,12 +67784,6 @@ function List({ options: opts }) {
67714
67784
  const [state, setState] = import_react33.useState({ phase: "checking" });
67715
67785
  import_react33.useEffect(() => {
67716
67786
  async function loadSkills() {
67717
- const credentials = await getCredentials();
67718
- if (!credentials) {
67719
- setState({ phase: "not_logged_in" });
67720
- exit();
67721
- return;
67722
- }
67723
67787
  const config2 = getConfig();
67724
67788
  const currentAgent = getCurrentAgent();
67725
67789
  const skills = opts.all ? config2.installed : config2.installed.filter((s) => s.agent === currentAgent || !s.agent);
@@ -67734,6 +67798,8 @@ function List({ options: opts }) {
67734
67798
  exit();
67735
67799
  return;
67736
67800
  }
67801
+ const credentials = await getCredentials();
67802
+ const token = credentials?.token;
67737
67803
  const skillsWithUpdates = [];
67738
67804
  for (let i = 0;i < skills.length; i++) {
67739
67805
  setState({
@@ -67744,9 +67810,17 @@ function List({ options: opts }) {
67744
67810
  const skill = skills[i];
67745
67811
  const repoConfig = config2.repos.find((r) => r.repo === skill.repo);
67746
67812
  if (repoConfig) {
67747
- const skillWithUpdate = await checkForUpdate(credentials.token, skill, repoConfig);
67748
- if (skillWithUpdate.hasUpdate) {
67749
- skillsWithUpdates.push(skillWithUpdate);
67813
+ const result = await checkForUpdate(token, skill, repoConfig);
67814
+ if ("authRequired" in result) {
67815
+ setState({
67816
+ phase: "auth_required",
67817
+ message: result.message
67818
+ });
67819
+ exit();
67820
+ return;
67821
+ }
67822
+ if (result.hasUpdate) {
67823
+ skillsWithUpdates.push(result);
67750
67824
  }
67751
67825
  }
67752
67826
  }
@@ -67766,20 +67840,14 @@ function List({ options: opts }) {
67766
67840
  return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Spinner2, {
67767
67841
  text: "Loading..."
67768
67842
  }, undefined, false, undefined, this);
67769
- case "not_logged_in":
67843
+ case "auth_required":
67770
67844
  return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
67771
67845
  flexDirection: "column",
67772
- children: [
67773
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(StatusMessage, {
67774
- type: "error",
67775
- children: "Not authenticated"
67776
- }, undefined, false, undefined, this),
67777
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
67778
- dimColor: true,
67779
- children: "Run 'skilluse login' to authenticate with GitHub"
67780
- }, undefined, false, undefined, this)
67781
- ]
67782
- }, undefined, true, undefined, this);
67846
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(StatusMessage, {
67847
+ type: "error",
67848
+ children: state.message
67849
+ }, undefined, false, undefined, this)
67850
+ }, undefined, false, undefined, this);
67783
67851
  case "checking_updates":
67784
67852
  return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Spinner2, {
67785
67853
  text: `Checking for updates (${state.current}/${state.total})...`
@@ -68331,12 +68399,6 @@ function RepoAdd({ args: [repoArg], options: opts }) {
68331
68399
  const [state, setState] = import_react36.useState({ phase: "checking" });
68332
68400
  import_react36.useEffect(() => {
68333
68401
  async function checkAndAdd() {
68334
- const credentials = await getCredentials();
68335
- if (!credentials) {
68336
- setState({ phase: "not_logged_in" });
68337
- exit();
68338
- return;
68339
- }
68340
68402
  if (!repoArg.match(/^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/)) {
68341
68403
  setState({ phase: "invalid_repo" });
68342
68404
  exit();
@@ -68371,15 +68433,22 @@ function RepoAdd({ args: [repoArg], options: opts }) {
68371
68433
  }
68372
68434
  setState({ phase: "discovering", repo: repoArg });
68373
68435
  try {
68436
+ const credentials = await getCredentials();
68437
+ const token = credentials?.token;
68374
68438
  const [owner, repo] = repoArg.split("/");
68375
- const discovery = await discoverSkillPaths(owner, repo, opts.branch, credentials.token);
68376
- if (discovery.totalSkills === 0) {
68439
+ const result = await discoverSkillPaths(owner, repo, opts.branch, token);
68440
+ if ("authRequired" in result) {
68441
+ setState({ phase: "auth_required", message: result.message });
68442
+ exit();
68443
+ return;
68444
+ }
68445
+ if (result.totalSkills === 0) {
68377
68446
  setState({ phase: "no_skills_found", repo: repoArg });
68378
68447
  } else {
68379
68448
  setState({
68380
68449
  phase: "select_paths",
68381
68450
  repo: repoArg,
68382
- discovery
68451
+ discovery: result
68383
68452
  });
68384
68453
  }
68385
68454
  } catch (error46) {
@@ -68485,20 +68554,14 @@ function RepoAdd({ args: [repoArg], options: opts }) {
68485
68554
  return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Spinner2, {
68486
68555
  text: "Checking..."
68487
68556
  }, undefined, false, undefined, this);
68488
- case "not_logged_in":
68557
+ case "auth_required":
68489
68558
  return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
68490
68559
  flexDirection: "column",
68491
- children: [
68492
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(StatusMessage, {
68493
- type: "error",
68494
- children: "Not authenticated"
68495
- }, undefined, false, undefined, this),
68496
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
68497
- dimColor: true,
68498
- children: "Run 'skilluse login' to authenticate with GitHub"
68499
- }, undefined, false, undefined, this)
68500
- ]
68501
- }, undefined, true, undefined, this);
68560
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(StatusMessage, {
68561
+ type: "error",
68562
+ children: state.message
68563
+ }, undefined, false, undefined, this)
68564
+ }, undefined, false, undefined, this);
68502
68565
  case "invalid_repo":
68503
68566
  return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
68504
68567
  flexDirection: "column",
@@ -68705,13 +68768,7 @@ function RepoEdit({ args: [repoArg], options: opts }) {
68705
68768
  const { exit } = use_app_default();
68706
68769
  const [state, setState] = import_react37.useState({ phase: "checking" });
68707
68770
  import_react37.useEffect(() => {
68708
- async function checkAndEdit() {
68709
- const credentials = await getCredentials();
68710
- if (!credentials) {
68711
- setState({ phase: "not_logged_in" });
68712
- exit();
68713
- return;
68714
- }
68771
+ function checkAndEdit() {
68715
68772
  const config2 = getConfig();
68716
68773
  const existingConfig = config2.repos.find((r) => r.repo === repoArg);
68717
68774
  if (!existingConfig) {
@@ -68784,20 +68841,6 @@ function RepoEdit({ args: [repoArg], options: opts }) {
68784
68841
  return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Spinner2, {
68785
68842
  text: "Checking..."
68786
68843
  }, undefined, false, undefined, this);
68787
- case "not_logged_in":
68788
- return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
68789
- flexDirection: "column",
68790
- children: [
68791
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(StatusMessage, {
68792
- type: "error",
68793
- children: "Not authenticated"
68794
- }, undefined, false, undefined, this),
68795
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
68796
- dimColor: true,
68797
- children: "Run 'skilluse login' to authenticate with GitHub"
68798
- }, undefined, false, undefined, this)
68799
- ]
68800
- }, undefined, true, undefined, this);
68801
68844
  case "not_found":
68802
68845
  return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
68803
68846
  flexDirection: "column",
@@ -69071,71 +69114,58 @@ var options9 = exports_external.object({});
69071
69114
  function RepoList(_props) {
69072
69115
  const { exit } = use_app_default();
69073
69116
  const [state, setState] = import_react39.useState({ phase: "checking" });
69117
+ const [outputItems, setOutputItems] = import_react39.useState([]);
69074
69118
  import_react39.useEffect(() => {
69075
- async function loadRepos() {
69076
- const credentials = await getCredentials();
69077
- if (!credentials) {
69078
- setState({ phase: "not_logged_in" });
69079
- exit();
69080
- return;
69081
- }
69082
- const config2 = getConfig();
69083
- setState({
69084
- phase: "success",
69085
- defaultRepo: config2.defaultRepo,
69086
- repos: config2.repos
69087
- });
69088
- exit();
69119
+ const config2 = getConfig();
69120
+ setState({
69121
+ phase: "success",
69122
+ defaultRepo: config2.defaultRepo,
69123
+ repos: config2.repos
69124
+ });
69125
+ }, []);
69126
+ import_react39.useEffect(() => {
69127
+ if (state.phase !== "checking" && outputItems.length === 0) {
69128
+ setOutputItems([{ id: "output" }]);
69089
69129
  }
69090
- loadRepos();
69091
- }, [exit]);
69092
- switch (state.phase) {
69093
- case "checking":
69094
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Spinner2, {
69095
- text: "Loading..."
69130
+ }, [state.phase, outputItems.length]);
69131
+ import_react39.useEffect(() => {
69132
+ if (outputItems.length > 0) {
69133
+ process.nextTick(() => exit());
69134
+ }
69135
+ }, [outputItems.length, exit]);
69136
+ const renderContent = () => {
69137
+ if (state.phase === "error") {
69138
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(StatusMessage, {
69139
+ type: "error",
69140
+ children: state.message
69096
69141
  }, undefined, false, undefined, this);
69097
- case "not_logged_in":
69098
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
69099
- flexDirection: "column",
69142
+ }
69143
+ if (state.phase === "success" && state.repos.length === 0) {
69144
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(jsx_dev_runtime16.Fragment, {
69100
69145
  children: [
69101
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(StatusMessage, {
69102
- type: "error",
69103
- children: "Not authenticated"
69104
- }, undefined, false, undefined, this),
69105
69146
  /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
69106
- dimColor: true,
69107
- children: "Run 'skilluse login' to authenticate with GitHub"
69147
+ bold: true,
69148
+ children: "Configured Repositories"
69149
+ }, undefined, false, undefined, this),
69150
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
69151
+ marginTop: 1,
69152
+ children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
69153
+ dimColor: true,
69154
+ children: "(no repositories configured)"
69155
+ }, undefined, false, undefined, this)
69156
+ }, undefined, false, undefined, this),
69157
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
69158
+ marginTop: 1,
69159
+ children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
69160
+ dimColor: true,
69161
+ children: "Run 'skilluse repo add owner/repo' to add one."
69162
+ }, undefined, false, undefined, this)
69108
69163
  }, undefined, false, undefined, this)
69109
69164
  ]
69110
69165
  }, undefined, true, undefined, this);
69111
- case "success":
69112
- if (state.repos.length === 0) {
69113
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
69114
- flexDirection: "column",
69115
- children: [
69116
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
69117
- bold: true,
69118
- children: "Configured Repositories"
69119
- }, undefined, false, undefined, this),
69120
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
69121
- marginTop: 1,
69122
- children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
69123
- dimColor: true,
69124
- children: "(no repositories configured)"
69125
- }, undefined, false, undefined, this)
69126
- }, undefined, false, undefined, this),
69127
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
69128
- marginTop: 1,
69129
- children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
69130
- dimColor: true,
69131
- children: "Run 'skilluse repo add owner/repo' to add one."
69132
- }, undefined, false, undefined, this)
69133
- }, undefined, false, undefined, this)
69134
- ]
69135
- }, undefined, true, undefined, this);
69136
- }
69137
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
69138
- flexDirection: "column",
69166
+ }
69167
+ if (state.phase === "success") {
69168
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(jsx_dev_runtime16.Fragment, {
69139
69169
  children: [
69140
69170
  /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Text, {
69141
69171
  bold: true,
@@ -69185,12 +69215,23 @@ function RepoList(_props) {
69185
69215
  })
69186
69216
  ]
69187
69217
  }, undefined, true, undefined, this);
69188
- case "error":
69189
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(StatusMessage, {
69190
- type: "error",
69191
- children: state.message
69192
- }, undefined, false, undefined, this);
69193
- }
69218
+ }
69219
+ return null;
69220
+ };
69221
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(jsx_dev_runtime16.Fragment, {
69222
+ children: [
69223
+ state.phase === "checking" && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Spinner2, {
69224
+ text: "Loading..."
69225
+ }, undefined, false, undefined, this),
69226
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Static, {
69227
+ items: outputItems,
69228
+ children: (item) => /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(Box_default, {
69229
+ flexDirection: "column",
69230
+ children: renderContent()
69231
+ }, item.id, false, undefined, this)
69232
+ }, undefined, false, undefined, this)
69233
+ ]
69234
+ }, undefined, true, undefined, this);
69194
69235
  }
69195
69236
 
69196
69237
  // src/commands/repo/remove.tsx
@@ -69206,13 +69247,7 @@ function RepoRemove({ args: [repoArg], options: opts }) {
69206
69247
  const { exit } = use_app_default();
69207
69248
  const [state, setState] = import_react40.useState({ phase: "checking" });
69208
69249
  import_react40.useEffect(() => {
69209
- async function checkAndRemove() {
69210
- const credentials = await getCredentials();
69211
- if (!credentials) {
69212
- setState({ phase: "not_logged_in" });
69213
- exit();
69214
- return;
69215
- }
69250
+ function checkAndRemove() {
69216
69251
  const config2 = getConfig();
69217
69252
  if (!config2.repos.find((r) => r.repo === repoArg)) {
69218
69253
  setState({ phase: "not_found", repo: repoArg });
@@ -69249,20 +69284,6 @@ function RepoRemove({ args: [repoArg], options: opts }) {
69249
69284
  return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Spinner2, {
69250
69285
  text: "Checking..."
69251
69286
  }, undefined, false, undefined, this);
69252
- case "not_logged_in":
69253
- return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
69254
- flexDirection: "column",
69255
- children: [
69256
- /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(StatusMessage, {
69257
- type: "error",
69258
- children: "Not authenticated"
69259
- }, undefined, false, undefined, this),
69260
- /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Text, {
69261
- dimColor: true,
69262
- children: "Run 'skilluse login' to authenticate with GitHub"
69263
- }, undefined, false, undefined, this)
69264
- ]
69265
- }, undefined, true, undefined, this);
69266
69287
  case "not_found":
69267
69288
  return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
69268
69289
  flexDirection: "column",
@@ -69335,94 +69356,92 @@ var options11 = exports_external.object({});
69335
69356
  function RepoUse({ args: [repoArg], options: _opts }) {
69336
69357
  const { exit } = use_app_default();
69337
69358
  const [state, setState] = import_react41.useState({ phase: "checking" });
69359
+ const [outputItems, setOutputItems] = import_react41.useState([]);
69338
69360
  import_react41.useEffect(() => {
69339
- async function setDefault() {
69340
- const credentials = await getCredentials();
69341
- if (!credentials) {
69342
- setState({ phase: "not_logged_in" });
69343
- exit();
69344
- return;
69345
- }
69346
- const config2 = getConfig();
69347
- if (!config2.repos.find((r) => r.repo === repoArg)) {
69348
- setState({ phase: "not_found", repo: repoArg });
69349
- exit();
69350
- return;
69351
- }
69352
- if (config2.defaultRepo === repoArg) {
69353
- setState({ phase: "already_default", repo: repoArg });
69354
- exit();
69355
- return;
69356
- }
69357
- setDefaultRepo(repoArg);
69358
- setState({ phase: "success", repo: repoArg });
69359
- exit();
69361
+ const config2 = getConfig();
69362
+ if (!config2.repos.find((r) => r.repo === repoArg)) {
69363
+ setState({ phase: "not_found", repo: repoArg });
69364
+ return;
69360
69365
  }
69361
- setDefault();
69362
- }, [repoArg, exit]);
69363
- switch (state.phase) {
69364
- case "checking":
69365
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Spinner2, {
69366
+ if (config2.defaultRepo === repoArg) {
69367
+ setState({ phase: "already_default", repo: repoArg });
69368
+ return;
69369
+ }
69370
+ setDefaultRepo(repoArg);
69371
+ setState({ phase: "success", repo: repoArg });
69372
+ }, [repoArg]);
69373
+ import_react41.useEffect(() => {
69374
+ if (state.phase !== "checking" && outputItems.length === 0) {
69375
+ setOutputItems([{ id: "output" }]);
69376
+ }
69377
+ }, [state.phase, outputItems.length]);
69378
+ import_react41.useEffect(() => {
69379
+ if (outputItems.length > 0) {
69380
+ process.nextTick(() => exit());
69381
+ }
69382
+ }, [outputItems.length, exit]);
69383
+ const renderContent = () => {
69384
+ switch (state.phase) {
69385
+ case "not_found":
69386
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
69387
+ children: [
69388
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69389
+ type: "error",
69390
+ children: [
69391
+ "Repository ",
69392
+ state.repo,
69393
+ " not found in config"
69394
+ ]
69395
+ }, undefined, true, undefined, this),
69396
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
69397
+ dimColor: true,
69398
+ children: [
69399
+ "Run 'skilluse repo add ",
69400
+ state.repo,
69401
+ "' to add it first."
69402
+ ]
69403
+ }, undefined, true, undefined, this)
69404
+ ]
69405
+ }, undefined, true, undefined, this);
69406
+ case "already_default":
69407
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69408
+ type: "success",
69409
+ children: [
69410
+ state.repo,
69411
+ " is already the default"
69412
+ ]
69413
+ }, undefined, true, undefined, this);
69414
+ case "success":
69415
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69416
+ type: "success",
69417
+ children: [
69418
+ "Default repo set to ",
69419
+ state.repo
69420
+ ]
69421
+ }, undefined, true, undefined, this);
69422
+ case "error":
69423
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69424
+ type: "error",
69425
+ children: state.message
69426
+ }, undefined, false, undefined, this);
69427
+ default:
69428
+ return null;
69429
+ }
69430
+ };
69431
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
69432
+ children: [
69433
+ state.phase === "checking" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Spinner2, {
69366
69434
  text: "Setting default..."
69367
- }, undefined, false, undefined, this);
69368
- case "not_logged_in":
69369
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
69370
- flexDirection: "column",
69371
- children: [
69372
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69373
- type: "error",
69374
- children: "Not authenticated"
69375
- }, undefined, false, undefined, this),
69376
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
69377
- dimColor: true,
69378
- children: "Run 'skilluse login' to authenticate with GitHub"
69379
- }, undefined, false, undefined, this)
69380
- ]
69381
- }, undefined, true, undefined, this);
69382
- case "not_found":
69383
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
69384
- flexDirection: "column",
69385
- children: [
69386
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69387
- type: "error",
69388
- children: [
69389
- "Repository ",
69390
- state.repo,
69391
- " not found in config"
69392
- ]
69393
- }, undefined, true, undefined, this),
69394
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
69395
- dimColor: true,
69396
- children: [
69397
- "Run 'skilluse repo add ",
69398
- state.repo,
69399
- "' to add it first."
69400
- ]
69401
- }, undefined, true, undefined, this)
69402
- ]
69403
- }, undefined, true, undefined, this);
69404
- case "already_default":
69405
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69406
- type: "success",
69407
- children: [
69408
- state.repo,
69409
- " is already the default"
69410
- ]
69411
- }, undefined, true, undefined, this);
69412
- case "success":
69413
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69414
- type: "success",
69415
- children: [
69416
- "Default repo set to ",
69417
- state.repo
69418
- ]
69419
- }, undefined, true, undefined, this);
69420
- case "error":
69421
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(StatusMessage, {
69422
- type: "error",
69423
- children: state.message
69424
- }, undefined, false, undefined, this);
69425
- }
69435
+ }, undefined, false, undefined, this),
69436
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Static, {
69437
+ items: outputItems,
69438
+ children: (item) => /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
69439
+ flexDirection: "column",
69440
+ children: renderContent()
69441
+ }, item.id, false, undefined, this)
69442
+ }, undefined, false, undefined, this)
69443
+ ]
69444
+ }, undefined, true, undefined, this);
69426
69445
  }
69427
69446
 
69428
69447
  // src/commands/agent/index.tsx
@@ -69633,13 +69652,15 @@ async function fetchSkillsFromRepo(token, repoConfig) {
69633
69652
  try {
69634
69653
  const apiPath = basePath ? `https://api.github.com/repos/${repo}/contents/${basePath}?ref=${branch}` : `https://api.github.com/repos/${repo}/contents?ref=${branch}`;
69635
69654
  const response = await fetch(apiPath, {
69636
- headers: {
69637
- Authorization: `Bearer ${token}`,
69638
- Accept: "application/vnd.github+json",
69639
- "X-GitHub-Api-Version": "2022-11-28"
69640
- }
69655
+ headers: buildGitHubHeaders(token)
69641
69656
  });
69642
69657
  if (!response.ok) {
69658
+ if (isAuthRequired(response)) {
69659
+ return {
69660
+ authRequired: true,
69661
+ message: getGitHubErrorMessage(response)
69662
+ };
69663
+ }
69643
69664
  continue;
69644
69665
  }
69645
69666
  const contents = await response.json();
@@ -69647,11 +69668,7 @@ async function fetchSkillsFromRepo(token, repoConfig) {
69647
69668
  for (const dir of dirs) {
69648
69669
  const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${dir.path}/SKILL.md?ref=${branch}`;
69649
69670
  const skillResponse = await fetch(skillMdUrl, {
69650
- headers: {
69651
- Authorization: `Bearer ${token}`,
69652
- Accept: "application/vnd.github.raw+json",
69653
- "X-GitHub-Api-Version": "2022-11-28"
69654
- }
69671
+ headers: buildGitHubRawHeaders(token)
69655
69672
  });
69656
69673
  if (skillResponse.ok) {
69657
69674
  const content = await skillResponse.text();
@@ -69693,12 +69710,6 @@ function Search({ args: [keyword], options: opts }) {
69693
69710
  const [state, setState] = import_react44.useState({ phase: "checking" });
69694
69711
  import_react44.useEffect(() => {
69695
69712
  async function search() {
69696
- const credentials = await getCredentials();
69697
- if (!credentials) {
69698
- setState({ phase: "not_logged_in" });
69699
- exit();
69700
- return;
69701
- }
69702
69713
  const config2 = getConfig();
69703
69714
  let reposToSearch = [];
69704
69715
  if (opts.all) {
@@ -69716,11 +69727,18 @@ function Search({ args: [keyword], options: opts }) {
69716
69727
  exit();
69717
69728
  return;
69718
69729
  }
69730
+ const credentials = await getCredentials();
69731
+ const token = credentials?.token;
69719
69732
  const allSkills = [];
69720
69733
  for (const repoConfig of reposToSearch) {
69721
69734
  setState({ phase: "searching", repo: repoConfig.repo });
69722
- const skills = await fetchSkillsFromRepo(credentials.token, repoConfig);
69723
- allSkills.push(...skills);
69735
+ const result = await fetchSkillsFromRepo(token, repoConfig);
69736
+ if ("authRequired" in result) {
69737
+ setState({ phase: "auth_required", message: result.message });
69738
+ exit();
69739
+ return;
69740
+ }
69741
+ allSkills.push(...result);
69724
69742
  }
69725
69743
  const matchingSkills = filterSkills(allSkills, keyword);
69726
69744
  setState({ phase: "success", skills: matchingSkills, keyword });
@@ -69739,20 +69757,14 @@ function Search({ args: [keyword], options: opts }) {
69739
69757
  return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Spinner2, {
69740
69758
  text: "Initializing..."
69741
69759
  }, undefined, false, undefined, this);
69742
- case "not_logged_in":
69760
+ case "auth_required":
69743
69761
  return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
69744
69762
  flexDirection: "column",
69745
- children: [
69746
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(StatusMessage, {
69747
- type: "error",
69748
- children: "Not authenticated"
69749
- }, undefined, false, undefined, this),
69750
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
69751
- dimColor: true,
69752
- children: "Run 'skilluse login' to authenticate with GitHub"
69753
- }, undefined, false, undefined, this)
69754
- ]
69755
- }, undefined, true, undefined, this);
69763
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(StatusMessage, {
69764
+ type: "error",
69765
+ children: state.message
69766
+ }, undefined, false, undefined, this)
69767
+ }, undefined, false, undefined, this);
69756
69768
  case "no_repos":
69757
69769
  return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
69758
69770
  flexDirection: "column",
@@ -70104,14 +70116,17 @@ async function checkForUpdate2(token, skill, repoConfig) {
70104
70116
  try {
70105
70117
  const refUrl = `https://api.github.com/repos/${repo}/commits/${branch}`;
70106
70118
  const refResponse = await fetch(refUrl, {
70107
- headers: {
70108
- Authorization: `Bearer ${token}`,
70109
- Accept: "application/vnd.github+json",
70110
- "X-GitHub-Api-Version": "2022-11-28"
70111
- }
70119
+ headers: buildGitHubHeaders(token)
70112
70120
  });
70113
- if (!refResponse.ok)
70121
+ if (!refResponse.ok) {
70122
+ if (isAuthRequired(refResponse)) {
70123
+ return {
70124
+ authRequired: true,
70125
+ message: getGitHubErrorMessage(refResponse)
70126
+ };
70127
+ }
70114
70128
  return null;
70129
+ }
70115
70130
  const refData = await refResponse.json();
70116
70131
  const latestSha = refData.sha;
70117
70132
  if (latestSha === skill.commitSha) {
@@ -70119,11 +70134,7 @@ async function checkForUpdate2(token, skill, repoConfig) {
70119
70134
  }
70120
70135
  const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${skill.repoPath}/SKILL.md?ref=${branch}`;
70121
70136
  const skillResponse = await fetch(skillMdUrl, {
70122
- headers: {
70123
- Authorization: `Bearer ${token}`,
70124
- Accept: "application/vnd.github.raw+json",
70125
- "X-GitHub-Api-Version": "2022-11-28"
70126
- }
70137
+ headers: buildGitHubRawHeaders(token)
70127
70138
  });
70128
70139
  let latestVersion = skill.version;
70129
70140
  if (skillResponse.ok) {
@@ -70146,13 +70157,15 @@ async function checkForUpdate2(token, skill, repoConfig) {
70146
70157
  async function downloadSkillFiles2(token, repo, skillPath, branch, targetDir) {
70147
70158
  const treeUrl = `https://api.github.com/repos/${repo}/git/trees/${branch}?recursive=1`;
70148
70159
  const treeResponse = await fetch(treeUrl, {
70149
- headers: {
70150
- Authorization: `Bearer ${token}`,
70151
- Accept: "application/vnd.github+json",
70152
- "X-GitHub-Api-Version": "2022-11-28"
70153
- }
70160
+ headers: buildGitHubHeaders(token)
70154
70161
  });
70155
70162
  if (!treeResponse.ok) {
70163
+ if (isAuthRequired(treeResponse)) {
70164
+ return {
70165
+ authRequired: true,
70166
+ message: getGitHubErrorMessage(treeResponse)
70167
+ };
70168
+ }
70156
70169
  throw new Error(`Failed to fetch repository tree: ${treeResponse.status}`);
70157
70170
  }
70158
70171
  const treeData = await treeResponse.json();
@@ -70171,13 +70184,15 @@ async function downloadSkillFiles2(token, repo, skillPath, branch, targetDir) {
70171
70184
  }
70172
70185
  const fileUrl = `https://api.github.com/repos/${repo}/contents/${file2.path}?ref=${branch}`;
70173
70186
  const fileResponse = await fetch(fileUrl, {
70174
- headers: {
70175
- Authorization: `Bearer ${token}`,
70176
- Accept: "application/vnd.github.raw+json",
70177
- "X-GitHub-Api-Version": "2022-11-28"
70178
- }
70187
+ headers: buildGitHubRawHeaders(token)
70179
70188
  });
70180
70189
  if (!fileResponse.ok) {
70190
+ if (isAuthRequired(fileResponse)) {
70191
+ return {
70192
+ authRequired: true,
70193
+ message: getGitHubErrorMessage(fileResponse)
70194
+ };
70195
+ }
70181
70196
  throw new Error(`Failed to download file: ${file2.path}`);
70182
70197
  }
70183
70198
  const content = await fileResponse.text();
@@ -70189,12 +70204,6 @@ function Upgrade({ args: [skillName] }) {
70189
70204
  const [state, setState] = import_react46.useState({ phase: "checking" });
70190
70205
  import_react46.useEffect(() => {
70191
70206
  async function upgrade() {
70192
- const credentials = await getCredentials();
70193
- if (!credentials) {
70194
- setState({ phase: "not_logged_in" });
70195
- exit();
70196
- return;
70197
- }
70198
70207
  const config2 = getConfig();
70199
70208
  let skillsToCheck = [];
70200
70209
  if (skillName) {
@@ -70213,6 +70222,8 @@ function Upgrade({ args: [skillName] }) {
70213
70222
  exit();
70214
70223
  return;
70215
70224
  }
70225
+ const credentials = await getCredentials();
70226
+ const token = credentials?.token;
70216
70227
  const upgrades = [];
70217
70228
  for (let i = 0;i < skillsToCheck.length; i++) {
70218
70229
  setState({
@@ -70224,9 +70235,14 @@ function Upgrade({ args: [skillName] }) {
70224
70235
  const repoConfig = config2.repos.find((r) => r.repo === skill.repo);
70225
70236
  if (!repoConfig)
70226
70237
  continue;
70227
- const update = await checkForUpdate2(credentials.token, skill, repoConfig);
70228
- if (update) {
70229
- upgrades.push(update);
70238
+ const result = await checkForUpdate2(token, skill, repoConfig);
70239
+ if (result && "authRequired" in result) {
70240
+ setState({ phase: "auth_required", message: result.message });
70241
+ exit();
70242
+ return;
70243
+ }
70244
+ if (result) {
70245
+ upgrades.push(result);
70230
70246
  }
70231
70247
  }
70232
70248
  if (upgrades.length === 0) {
@@ -70247,7 +70263,15 @@ function Upgrade({ args: [skillName] }) {
70247
70263
  const repoConfig = config2.repos.find((r) => r.repo === skill.repo);
70248
70264
  if (!repoConfig)
70249
70265
  continue;
70250
- await downloadSkillFiles2(credentials.token, skill.repo, skill.repoPath, repoConfig.branch, skill.installedPath);
70266
+ const downloadResult = await downloadSkillFiles2(token, skill.repo, skill.repoPath, repoConfig.branch, skill.installedPath);
70267
+ if (downloadResult && "authRequired" in downloadResult) {
70268
+ setState({
70269
+ phase: "auth_required",
70270
+ message: downloadResult.message
70271
+ });
70272
+ exit();
70273
+ return;
70274
+ }
70251
70275
  const updatedSkill = {
70252
70276
  ...skill,
70253
70277
  commitSha: latestSha,
@@ -70277,20 +70301,14 @@ function Upgrade({ args: [skillName] }) {
70277
70301
  return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Spinner2, {
70278
70302
  text: "Initializing..."
70279
70303
  }, undefined, false, undefined, this);
70280
- case "not_logged_in":
70304
+ case "auth_required":
70281
70305
  return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
70282
70306
  flexDirection: "column",
70283
- children: [
70284
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(StatusMessage, {
70285
- type: "error",
70286
- children: "Not authenticated"
70287
- }, undefined, false, undefined, this),
70288
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70289
- dimColor: true,
70290
- children: "Run 'skilluse login' to authenticate with GitHub"
70291
- }, undefined, false, undefined, this)
70292
- ]
70293
- }, undefined, true, undefined, this);
70307
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(StatusMessage, {
70308
+ type: "error",
70309
+ children: state.message
70310
+ }, undefined, false, undefined, this)
70311
+ }, undefined, false, undefined, this);
70294
70312
  case "not_found":
70295
70313
  return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
70296
70314
  flexDirection: "column",
@@ -70409,7 +70427,7 @@ function Upgrade({ args: [skillName] }) {
70409
70427
  // package.json
70410
70428
  var package_default = {
70411
70429
  name: "skilluse",
70412
- version: "0.1.10",
70430
+ version: "0.2.0",
70413
70431
  description: "CLI tool for managing and installing AI Coding Agent Skills",
70414
70432
  main: "dist/cli.js",
70415
70433
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skilluse",
3
- "version": "0.1.10",
3
+ "version": "0.2.0",
4
4
  "description": "CLI tool for managing and installing AI Coding Agent Skills",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {