skilluse 0.7.0 → 0.9.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 (3) hide show
  1. package/README.md +7 -3
  2. package/dist/cli.js +945 -414
  3. package/package.json +1 -2
package/dist/cli.js CHANGED
@@ -66638,6 +66638,87 @@ function extractParentPaths(skillMdPaths) {
66638
66638
  const result = Array.from(parentCounts.entries()).map(([path6, skillCount]) => ({ path: path6, skillCount })).sort((a, b) => b.skillCount - a.skillCount);
66639
66639
  return result;
66640
66640
  }
66641
+ // src/services/skills.ts
66642
+ function parseFrontmatter(content) {
66643
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
66644
+ if (!frontmatterMatch) {
66645
+ return {};
66646
+ }
66647
+ const yaml = frontmatterMatch[1];
66648
+ const result = {};
66649
+ const lines = yaml.split(`
66650
+ `);
66651
+ for (const line of lines) {
66652
+ const colonIndex = line.indexOf(":");
66653
+ if (colonIndex === -1)
66654
+ continue;
66655
+ const key = line.substring(0, colonIndex).trim();
66656
+ let value = line.substring(colonIndex + 1).trim();
66657
+ if (typeof value === "string" && value.startsWith("[") && value.endsWith("]")) {
66658
+ value = value.slice(1, -1).split(",").map((s) => s.trim());
66659
+ }
66660
+ if (key) {
66661
+ result[key] = value;
66662
+ }
66663
+ }
66664
+ return result;
66665
+ }
66666
+ async function fetchSkillMetadata(token, repo, branch, dirPath) {
66667
+ try {
66668
+ const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${dirPath}/SKILL.md?ref=${branch}`;
66669
+ const skillResponse = await fetch(skillMdUrl, {
66670
+ headers: buildGitHubRawHeaders(token)
66671
+ });
66672
+ if (!skillResponse.ok) {
66673
+ return null;
66674
+ }
66675
+ const content = await skillResponse.text();
66676
+ const frontmatter = parseFrontmatter(content);
66677
+ if (!frontmatter.name) {
66678
+ return null;
66679
+ }
66680
+ return {
66681
+ name: String(frontmatter.name),
66682
+ description: String(frontmatter.description || ""),
66683
+ type: frontmatter.type ? String(frontmatter.type) : undefined,
66684
+ version: frontmatter.version ? String(frontmatter.version) : undefined,
66685
+ tags: Array.isArray(frontmatter.tags) ? frontmatter.tags.map(String) : undefined,
66686
+ repo,
66687
+ path: dirPath
66688
+ };
66689
+ } catch {
66690
+ return null;
66691
+ }
66692
+ }
66693
+ async function fetchSkillsFromRepo(token, repoConfig) {
66694
+ const { repo, branch, paths: paths2 } = repoConfig;
66695
+ const allSkills = [];
66696
+ const searchPaths = paths2.length > 0 ? paths2 : [""];
66697
+ for (const basePath of searchPaths) {
66698
+ try {
66699
+ const apiPath = basePath ? `https://api.github.com/repos/${repo}/contents/${basePath}?ref=${branch}` : `https://api.github.com/repos/${repo}/contents?ref=${branch}`;
66700
+ const response = await fetch(apiPath, {
66701
+ headers: buildGitHubHeaders(token)
66702
+ });
66703
+ if (!response.ok) {
66704
+ if (isAuthRequired(response)) {
66705
+ return {
66706
+ authRequired: true,
66707
+ message: getGitHubErrorMessage(response)
66708
+ };
66709
+ }
66710
+ continue;
66711
+ }
66712
+ const contents = await response.json();
66713
+ const dirs = contents.filter((item) => item.type === "dir");
66714
+ const skillPromises = dirs.map((dir) => fetchSkillMetadata(token, repo, branch, dir.path));
66715
+ const results = await Promise.all(skillPromises);
66716
+ const skills = results.filter((s) => s !== null);
66717
+ allSkills.push(...skills);
66718
+ } catch {}
66719
+ }
66720
+ return allSkills;
66721
+ }
66641
66722
  // src/commands/index.tsx
66642
66723
  var jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
66643
66724
  var options = exports_external.object({});
@@ -66859,6 +66940,7 @@ function Index(_props) {
66859
66940
  /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
66860
66941
  flexDirection: "column",
66861
66942
  marginLeft: 2,
66943
+ marginBottom: 1,
66862
66944
  children: state.skills.length === 0 ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
66863
66945
  dimColor: true,
66864
66946
  children: "(no skills installed)"
@@ -66877,7 +66959,24 @@ function Index(_props) {
66877
66959
  ]
66878
66960
  }, undefined, true, undefined, this)
66879
66961
  }, skill.name, false, undefined, this))
66880
- }, undefined, false, undefined, this)
66962
+ }, undefined, false, undefined, this),
66963
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
66964
+ marginTop: 0,
66965
+ children: [
66966
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
66967
+ dimColor: true,
66968
+ children: "Run "
66969
+ }, undefined, false, undefined, this),
66970
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
66971
+ color: "cyan",
66972
+ children: "skilluse --help"
66973
+ }, undefined, false, undefined, this),
66974
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
66975
+ dimColor: true,
66976
+ children: " for all commands"
66977
+ }, undefined, false, undefined, this)
66978
+ ]
66979
+ }, undefined, true, undefined, this)
66881
66980
  ]
66882
66981
  }, undefined, true, undefined, this);
66883
66982
  }
@@ -66908,7 +67007,7 @@ var args = exports_external.tuple([
66908
67007
  exports_external.string().describe("Skill name to show info for")
66909
67008
  ]);
66910
67009
  var options2 = exports_external.object({});
66911
- function parseFrontmatter(content) {
67010
+ function parseFrontmatter2(content) {
66912
67011
  const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
66913
67012
  if (!frontmatterMatch)
66914
67013
  return {};
@@ -66933,11 +67032,11 @@ async function getLocalSkillInfo(skill) {
66933
67032
  try {
66934
67033
  const skillMdPath = join2(skill.installedPath, "SKILL.md");
66935
67034
  const content = await readFile(skillMdPath, "utf-8");
66936
- const frontmatter = parseFrontmatter(content);
67035
+ const frontmatter = parseFrontmatter2(content);
66937
67036
  return {
66938
67037
  name: String(frontmatter.name || skill.name),
66939
67038
  description: String(frontmatter.description || ""),
66940
- version: String(frontmatter.version || skill.version),
67039
+ version: frontmatter.version ? String(frontmatter.version) : "",
66941
67040
  type: frontmatter.type ? String(frontmatter.type) : skill.type,
66942
67041
  author: frontmatter.author ? String(frontmatter.author) : undefined,
66943
67042
  tags: Array.isArray(frontmatter.tags) ? frontmatter.tags.map(String) : undefined,
@@ -66952,7 +67051,7 @@ async function getLocalSkillInfo(skill) {
66952
67051
  return {
66953
67052
  name: skill.name,
66954
67053
  description: "",
66955
- version: skill.version,
67054
+ version: "",
66956
67055
  type: skill.type,
66957
67056
  repo: skill.repo,
66958
67057
  repoPath: skill.repoPath,
@@ -66991,7 +67090,7 @@ async function getRemoteSkillInfo(token, skillName, repos) {
66991
67090
  });
66992
67091
  if (skillResponse.ok) {
66993
67092
  const content = await skillResponse.text();
66994
- const frontmatter = parseFrontmatter(content);
67093
+ const frontmatter = parseFrontmatter2(content);
66995
67094
  return {
66996
67095
  name: String(frontmatter.name || dir.name),
66997
67096
  description: String(frontmatter.description || ""),
@@ -67384,7 +67483,7 @@ function SecurityWarningPrompt({
67384
67483
  ]
67385
67484
  }, undefined, true, undefined, this);
67386
67485
  }
67387
- function parseFrontmatter2(content) {
67486
+ function parseFrontmatter3(content) {
67388
67487
  const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
67389
67488
  if (!frontmatterMatch) {
67390
67489
  return {};
@@ -67458,7 +67557,7 @@ async function findSkill(token, repos, skillName) {
67458
67557
  });
67459
67558
  if (skillResponse.ok) {
67460
67559
  const content = await skillResponse.text();
67461
- const frontmatter = parseFrontmatter2(content);
67560
+ const frontmatter = parseFrontmatter3(content);
67462
67561
  const refUrl = `https://api.github.com/repos/${repo}/commits/${branch}`;
67463
67562
  const refResponse = await fetch(refUrl, {
67464
67563
  headers: buildGitHubHeaders(token)
@@ -67473,7 +67572,6 @@ async function findSkill(token, repos, skillName) {
67473
67572
  name: String(frontmatter.name || dir.name),
67474
67573
  description: String(frontmatter.description || ""),
67475
67574
  type: frontmatter.type ? String(frontmatter.type) : undefined,
67476
- version: frontmatter.version ? String(frontmatter.version) : "1.0.0",
67477
67575
  author: frontmatter.author ? String(frontmatter.author) : undefined,
67478
67576
  repo,
67479
67577
  path: dir.path
@@ -67570,14 +67668,13 @@ async function fetchGitHubSkill(token, owner, repo, path6, branch = "main") {
67570
67668
  return null;
67571
67669
  }
67572
67670
  const content = await skillResponse.text();
67573
- const frontmatter = parseFrontmatter2(content);
67671
+ const frontmatter = parseFrontmatter3(content);
67574
67672
  const skillName = path6 ? basename(path6) : repo;
67575
67673
  return {
67576
67674
  skill: {
67577
67675
  name: String(frontmatter.name || skillName),
67578
67676
  description: String(frontmatter.description || ""),
67579
67677
  type: frontmatter.type ? String(frontmatter.type) : undefined,
67580
- version: frontmatter.version ? String(frontmatter.version) : "1.0.0",
67581
67678
  author: frontmatter.author ? String(frontmatter.author) : undefined,
67582
67679
  repo: fullRepo,
67583
67680
  path: skillPath
@@ -67680,7 +67777,6 @@ function Install({ args: [skillName], options: opts }) {
67680
67777
  repo: skill2.repo,
67681
67778
  repoPath: skill2.path,
67682
67779
  commitSha: commitSha2,
67683
- version: skill2.version || "1.0.0",
67684
67780
  type: skill2.type || "skill",
67685
67781
  installedPath: installPath2,
67686
67782
  scope,
@@ -67791,7 +67887,6 @@ function Install({ args: [skillName], options: opts }) {
67791
67887
  repo: skill.repo,
67792
67888
  repoPath: skill.path,
67793
67889
  commitSha,
67794
- version: skill.version || "1.0.0",
67795
67890
  type: skill.type || "skill",
67796
67891
  installedPath: installPath,
67797
67892
  scope,
@@ -67887,7 +67982,6 @@ function Install({ args: [skillName], options: opts }) {
67887
67982
  repo: skill.repo,
67888
67983
  repoPath: skill.path,
67889
67984
  commitSha,
67890
- version: skill.version || "1.0.0",
67891
67985
  type: skill.type || "skill",
67892
67986
  installedPath: installPath,
67893
67987
  scope,
@@ -68092,8 +68186,7 @@ function Install({ args: [skillName], options: opts }) {
68092
68186
  children: [
68093
68187
  'Installed "',
68094
68188
  state.skill.name,
68095
- '" v',
68096
- state.skill.version
68189
+ '"'
68097
68190
  ]
68098
68191
  }, undefined, true, undefined, this),
68099
68192
  /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
@@ -68139,24 +68232,6 @@ var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
68139
68232
  var options4 = exports_external.object({
68140
68233
  outdated: exports_external.boolean().default(false).describe("Show only outdated skills")
68141
68234
  });
68142
- function parseFrontmatter3(content) {
68143
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
68144
- if (!frontmatterMatch)
68145
- return {};
68146
- const yaml = frontmatterMatch[1];
68147
- const result = {};
68148
- for (const line of yaml.split(`
68149
- `)) {
68150
- const colonIndex = line.indexOf(":");
68151
- if (colonIndex === -1)
68152
- continue;
68153
- const key = line.substring(0, colonIndex).trim();
68154
- const value = line.substring(colonIndex + 1).trim();
68155
- if (key)
68156
- result[key] = value;
68157
- }
68158
- return result;
68159
- }
68160
68235
  async function checkForUpdate(token, skill, repoConfig) {
68161
68236
  const { repo, branch } = repoConfig;
68162
68237
  try {
@@ -68178,21 +68253,8 @@ async function checkForUpdate(token, skill, repoConfig) {
68178
68253
  if (latestSha === skill.commitSha) {
68179
68254
  return { ...skill, hasUpdate: false };
68180
68255
  }
68181
- const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${skill.repoPath}/SKILL.md?ref=${branch}`;
68182
- const skillResponse = await fetch(skillMdUrl, {
68183
- headers: buildGitHubRawHeaders(token)
68184
- });
68185
- let latestVersion = skill.version;
68186
- if (skillResponse.ok) {
68187
- const content = await skillResponse.text();
68188
- const frontmatter = parseFrontmatter3(content);
68189
- if (frontmatter.version) {
68190
- latestVersion = String(frontmatter.version);
68191
- }
68192
- }
68193
68256
  return {
68194
68257
  ...skill,
68195
- latestVersion,
68196
68258
  latestSha,
68197
68259
  hasUpdate: true
68198
68260
  };
@@ -68369,15 +68431,9 @@ function List({ options: opts }) {
68369
68431
  /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
68370
68432
  dimColor: true,
68371
68433
  children: [
68372
- " v",
68373
- skill.version
68374
- ]
68375
- }, undefined, true, undefined, this),
68376
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
68377
- color: "green",
68378
- children: [
68379
- " → v",
68380
- skill.latestVersion
68434
+ " (",
68435
+ skill.scope,
68436
+ ")"
68381
68437
  ]
68382
68438
  }, undefined, true, undefined, this)
68383
68439
  ]
@@ -68388,9 +68444,7 @@ function List({ options: opts }) {
68388
68444
  dimColor: true,
68389
68445
  children: [
68390
68446
  "From: ",
68391
- skill.repo,
68392
- " | Scope: ",
68393
- skill.scope
68447
+ skill.repo
68394
68448
  ]
68395
68449
  }, undefined, true, undefined, this)
68396
68450
  }, undefined, false, undefined, this)
@@ -68438,13 +68492,6 @@ function List({ options: opts }) {
68438
68492
  bold: true,
68439
68493
  children: skill.name
68440
68494
  }, undefined, false, undefined, this),
68441
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
68442
- dimColor: true,
68443
- children: [
68444
- " v",
68445
- skill.version
68446
- ]
68447
- }, undefined, true, undefined, this),
68448
68495
  /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
68449
68496
  dimColor: true,
68450
68497
  children: [
@@ -68562,7 +68609,6 @@ function Login(_props) {
68562
68609
  phase: "no_installation",
68563
68610
  installUrl: "https://github.com/apps/skilluse/installations/new"
68564
68611
  });
68565
- exit();
68566
68612
  return;
68567
68613
  }
68568
68614
  if (installations.length === 0) {
@@ -68570,7 +68616,6 @@ function Login(_props) {
68570
68616
  phase: "no_installation",
68571
68617
  installUrl: "https://github.com/apps/skilluse/installations/new"
68572
68618
  });
68573
- exit();
68574
68619
  return;
68575
68620
  }
68576
68621
  const storedInstallations = installations.map((inst) => ({
@@ -68588,10 +68633,14 @@ function Login(_props) {
68588
68633
  username,
68589
68634
  installations: storedInstallations
68590
68635
  });
68591
- exit();
68592
68636
  }
68593
68637
  runLogin();
68594
68638
  }, [exit]);
68639
+ import_react35.useEffect(() => {
68640
+ if (state.phase === "success" || state.phase === "no_installation") {
68641
+ exit();
68642
+ }
68643
+ }, [state.phase, exit]);
68595
68644
  switch (state.phase) {
68596
68645
  case "requesting_code":
68597
68646
  return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Spinner2, {
@@ -68680,25 +68729,51 @@ function Login(_props) {
68680
68729
  flexDirection: "column",
68681
68730
  children: [
68682
68731
  /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
68683
- dimColor: true,
68684
- children: [
68685
- state.installations.length,
68686
- " installation",
68687
- state.installations.length > 1 ? "s" : "",
68688
- " found:"
68689
- ]
68690
- }, undefined, true, undefined, this),
68691
- state.installations.map((inst) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
68692
- dimColor: true,
68732
+ children: "App installed on:"
68733
+ }, undefined, false, undefined, this),
68734
+ state.installations.map((inst) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
68735
+ marginLeft: 2,
68693
68736
  children: [
68694
- "• ",
68695
- inst.account,
68696
- " (",
68697
- inst.accountType.toLowerCase(),
68698
- ")"
68737
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
68738
+ color: "green",
68739
+ children: "*"
68740
+ }, undefined, false, undefined, this),
68741
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
68742
+ children: [
68743
+ " ",
68744
+ inst.account
68745
+ ]
68746
+ }, undefined, true, undefined, this),
68747
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
68748
+ dimColor: true,
68749
+ children: [
68750
+ " ",
68751
+ "(",
68752
+ inst.accountType.toLowerCase(),
68753
+ ",",
68754
+ " ",
68755
+ inst.repositorySelection === "all" ? "all repos" : "selected repos",
68756
+ ")"
68757
+ ]
68758
+ }, undefined, true, undefined, this)
68699
68759
  ]
68700
68760
  }, inst.id, true, undefined, this))
68701
68761
  ]
68762
+ }, undefined, true, undefined, this),
68763
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
68764
+ marginTop: 1,
68765
+ flexDirection: "column",
68766
+ children: [
68767
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
68768
+ dimColor: true,
68769
+ children: "To publish skills to other orgs, install the App there first:"
68770
+ }, undefined, false, undefined, this),
68771
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
68772
+ color: "cyan",
68773
+ dimColor: true,
68774
+ children: "https://github.com/apps/skilluse/installations/new"
68775
+ }, undefined, false, undefined, this)
68776
+ ]
68702
68777
  }, undefined, true, undefined, this)
68703
68778
  ]
68704
68779
  }, undefined, true, undefined, this);
@@ -69728,82 +69803,6 @@ function RepoList(_props) {
69728
69803
  var import_react41 = __toESM(require_react(), 1);
69729
69804
  var jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
69730
69805
  var options11 = exports_external.object({});
69731
- function parseFrontmatter4(content) {
69732
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
69733
- if (!frontmatterMatch) {
69734
- return {};
69735
- }
69736
- const yaml = frontmatterMatch[1];
69737
- const result = {};
69738
- for (const line of yaml.split(`
69739
- `)) {
69740
- const colonIndex = line.indexOf(":");
69741
- if (colonIndex === -1)
69742
- continue;
69743
- const key = line.substring(0, colonIndex).trim();
69744
- let value = line.substring(colonIndex + 1).trim();
69745
- if (typeof value === "string" && value.startsWith("[") && value.endsWith("]")) {
69746
- value = value.slice(1, -1).split(",").map((s) => s.trim());
69747
- }
69748
- if (key) {
69749
- result[key] = value;
69750
- }
69751
- }
69752
- return result;
69753
- }
69754
- async function fetchSkillsFromRepo(token, repoConfig, installedSkillNames) {
69755
- const { repo, branch, paths: paths2 } = repoConfig;
69756
- const skills = [];
69757
- const searchPaths = paths2.length > 0 ? paths2 : [""];
69758
- for (const basePath of searchPaths) {
69759
- try {
69760
- const apiPath = basePath ? `https://api.github.com/repos/${repo}/contents/${basePath}?ref=${branch}` : `https://api.github.com/repos/${repo}/contents?ref=${branch}`;
69761
- const response = await fetch(apiPath, {
69762
- headers: buildGitHubHeaders(token)
69763
- });
69764
- if (!response.ok) {
69765
- if (isAuthRequired(response)) {
69766
- return {
69767
- authRequired: true,
69768
- message: getGitHubErrorMessage(response)
69769
- };
69770
- }
69771
- continue;
69772
- }
69773
- const contents = await response.json();
69774
- const dirs = contents.filter((item) => item.type === "dir");
69775
- for (const dir of dirs) {
69776
- const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${dir.path}/SKILL.md?ref=${branch}`;
69777
- const skillResponse = await fetch(skillMdUrl, {
69778
- headers: buildGitHubRawHeaders(token)
69779
- });
69780
- if (skillResponse.ok) {
69781
- const content = await skillResponse.text();
69782
- const frontmatter = parseFrontmatter4(content);
69783
- if (frontmatter.name) {
69784
- const skillName = String(frontmatter.name);
69785
- skills.push({
69786
- name: skillName,
69787
- description: String(frontmatter.description || ""),
69788
- type: frontmatter.type ? String(frontmatter.type) : undefined,
69789
- version: frontmatter.version ? String(frontmatter.version) : undefined,
69790
- repo,
69791
- path: dir.path,
69792
- installed: installedSkillNames.has(skillName)
69793
- });
69794
- }
69795
- }
69796
- }
69797
- } catch {}
69798
- }
69799
- skills.sort((a, b) => {
69800
- if (a.installed !== b.installed) {
69801
- return a.installed ? -1 : 1;
69802
- }
69803
- return a.name.localeCompare(b.name);
69804
- });
69805
- return skills;
69806
- }
69807
69806
  function RepoSkills(_props) {
69808
69807
  const { exit } = use_app_default();
69809
69808
  const [state, setState] = import_react41.useState({ phase: "checking" });
@@ -69826,14 +69825,23 @@ function RepoSkills(_props) {
69826
69825
  const installedSkillNames = new Set(config2.installed.filter((s) => s.agent === currentAgent || !s.agent).map((s) => s.name));
69827
69826
  const credentials = await getCredentials();
69828
69827
  const token = credentials?.token;
69829
- const result = await fetchSkillsFromRepo(token, repoConfig, installedSkillNames);
69828
+ const result = await fetchSkillsFromRepo(token, repoConfig);
69830
69829
  if ("authRequired" in result) {
69831
69830
  setState({ phase: "auth_required", message: result.message });
69832
69831
  return;
69833
69832
  }
69833
+ const skillsWithInstalled = result.map((skill) => ({
69834
+ ...skill,
69835
+ installed: installedSkillNames.has(skill.name)
69836
+ })).sort((a, b) => {
69837
+ if (a.installed !== b.installed) {
69838
+ return a.installed ? -1 : 1;
69839
+ }
69840
+ return a.name.localeCompare(b.name);
69841
+ });
69834
69842
  setState({
69835
69843
  phase: "success",
69836
- skills: result,
69844
+ skills: skillsWithInstalled,
69837
69845
  repoName: repoConfig.repo
69838
69846
  });
69839
69847
  }
@@ -70400,129 +70408,48 @@ function Agent({ args: [agentIdArg] }) {
70400
70408
  var import_react45 = __toESM(require_react(), 1);
70401
70409
  var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
70402
70410
  var args8 = exports_external.tuple([exports_external.string().describe("Search keyword")]);
70403
- var options15 = exports_external.object({
70404
- all: exports_external.boolean().default(false).describe("Search in all configured repos (not just default)")
70405
- });
70406
- function parseFrontmatter5(content) {
70407
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
70408
- if (!frontmatterMatch) {
70409
- return {};
70410
- }
70411
- const yaml = frontmatterMatch[1];
70412
- const result = {};
70413
- const lines = yaml.split(`
70414
- `);
70415
- for (const line of lines) {
70416
- const colonIndex = line.indexOf(":");
70417
- if (colonIndex === -1)
70418
- continue;
70419
- const key = line.substring(0, colonIndex).trim();
70420
- let value = line.substring(colonIndex + 1).trim();
70421
- if (typeof value === "string" && value.startsWith("[") && value.endsWith("]")) {
70422
- value = value.slice(1, -1).split(",").map((s) => s.trim());
70411
+ var options15 = exports_external.object({});
70412
+ function filterSkills(skills, keyword) {
70413
+ const lowerKeyword = keyword.toLowerCase();
70414
+ return skills.filter((skill) => {
70415
+ if (skill.name.toLowerCase().includes(lowerKeyword)) {
70416
+ return true;
70423
70417
  }
70424
- if (key) {
70425
- result[key] = value;
70418
+ if (skill.description.toLowerCase().includes(lowerKeyword)) {
70419
+ return true;
70426
70420
  }
70427
- }
70428
- return result;
70421
+ if (skill.tags?.some((tag) => tag.toLowerCase().includes(lowerKeyword))) {
70422
+ return true;
70423
+ }
70424
+ return false;
70425
+ });
70429
70426
  }
70430
- async function fetchSkillsFromRepo2(token, repoConfig) {
70431
- const { repo, branch, paths: paths2 } = repoConfig;
70432
- const skills = [];
70433
- const searchPaths = paths2.length > 0 ? paths2 : [""];
70434
- for (const basePath of searchPaths) {
70435
- try {
70436
- const apiPath = basePath ? `https://api.github.com/repos/${repo}/contents/${basePath}?ref=${branch}` : `https://api.github.com/repos/${repo}/contents?ref=${branch}`;
70437
- const response = await fetch(apiPath, {
70438
- headers: buildGitHubHeaders(token)
70439
- });
70440
- if (!response.ok) {
70441
- if (isAuthRequired(response)) {
70442
- return {
70443
- authRequired: true,
70444
- message: getGitHubErrorMessage(response)
70445
- };
70446
- }
70447
- continue;
70448
- }
70449
- const contents = await response.json();
70450
- const dirs = contents.filter((item) => item.type === "dir");
70451
- for (const dir of dirs) {
70452
- const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${dir.path}/SKILL.md?ref=${branch}`;
70453
- const skillResponse = await fetch(skillMdUrl, {
70454
- headers: buildGitHubRawHeaders(token)
70455
- });
70456
- if (skillResponse.ok) {
70457
- const content = await skillResponse.text();
70458
- const frontmatter = parseFrontmatter5(content);
70459
- if (frontmatter.name) {
70460
- skills.push({
70461
- name: String(frontmatter.name),
70462
- description: String(frontmatter.description || ""),
70463
- type: frontmatter.type ? String(frontmatter.type) : undefined,
70464
- version: frontmatter.version ? String(frontmatter.version) : undefined,
70465
- tags: Array.isArray(frontmatter.tags) ? frontmatter.tags.map(String) : undefined,
70466
- repo,
70467
- path: dir.path
70468
- });
70469
- }
70470
- }
70471
- }
70472
- } catch {}
70473
- }
70474
- return skills;
70475
- }
70476
- function filterSkills(skills, keyword) {
70477
- const lowerKeyword = keyword.toLowerCase();
70478
- return skills.filter((skill) => {
70479
- if (skill.name.toLowerCase().includes(lowerKeyword)) {
70480
- return true;
70481
- }
70482
- if (skill.description.toLowerCase().includes(lowerKeyword)) {
70483
- return true;
70484
- }
70485
- if (skill.tags?.some((tag) => tag.toLowerCase().includes(lowerKeyword))) {
70486
- return true;
70487
- }
70488
- return false;
70489
- });
70490
- }
70491
- function Search({ args: [keyword], options: opts }) {
70427
+ function Search({ args: [keyword] }) {
70492
70428
  const { exit } = use_app_default();
70493
70429
  const [state, setState] = import_react45.useState({ phase: "checking" });
70494
70430
  const [outputItems, setOutputItems] = import_react45.useState([]);
70495
70431
  import_react45.useEffect(() => {
70496
70432
  async function search() {
70497
70433
  const config2 = getConfig();
70498
- let reposToSearch = [];
70499
- if (opts.all) {
70500
- reposToSearch = config2.repos;
70501
- } else if (config2.defaultRepo) {
70502
- const defaultRepoConfig = config2.repos.find((r) => r.repo === config2.defaultRepo);
70503
- if (defaultRepoConfig) {
70504
- reposToSearch = [defaultRepoConfig];
70505
- }
70434
+ let repoConfig;
70435
+ if (config2.defaultRepo) {
70436
+ repoConfig = config2.repos.find((r) => r.repo === config2.defaultRepo);
70506
70437
  } else if (config2.repos.length > 0) {
70507
- reposToSearch = [config2.repos[0]];
70438
+ repoConfig = config2.repos[0];
70508
70439
  }
70509
- if (reposToSearch.length === 0) {
70440
+ if (!repoConfig) {
70510
70441
  setState({ phase: "no_repos" });
70511
70442
  return;
70512
70443
  }
70444
+ setState({ phase: "searching", repo: repoConfig.repo });
70513
70445
  const credentials = await getCredentials();
70514
70446
  const token = credentials?.token;
70515
- const allSkills = [];
70516
- for (const repoConfig of reposToSearch) {
70517
- setState({ phase: "searching", repo: repoConfig.repo });
70518
- const result = await fetchSkillsFromRepo2(token, repoConfig);
70519
- if ("authRequired" in result) {
70520
- setState({ phase: "auth_required", message: result.message });
70521
- return;
70522
- }
70523
- allSkills.push(...result);
70447
+ const result = await fetchSkillsFromRepo(token, repoConfig);
70448
+ if ("authRequired" in result) {
70449
+ setState({ phase: "auth_required", message: result.message });
70450
+ return;
70524
70451
  }
70525
- const matchingSkills = filterSkills(allSkills, keyword);
70452
+ const matchingSkills = filterSkills(result, keyword);
70526
70453
  setState({ phase: "success", skills: matchingSkills, keyword });
70527
70454
  }
70528
70455
  search().catch((err) => {
@@ -70531,7 +70458,7 @@ function Search({ args: [keyword], options: opts }) {
70531
70458
  message: err instanceof Error ? err.message : "Search failed"
70532
70459
  });
70533
70460
  });
70534
- }, [keyword, opts.all]);
70461
+ }, [keyword]);
70535
70462
  import_react45.useEffect(() => {
70536
70463
  const isFinalState = state.phase === "no_repos" || state.phase === "success" || state.phase === "auth_required" || state.phase === "error";
70537
70464
  if (isFinalState && outputItems.length === 0) {
@@ -70731,12 +70658,8 @@ function ConfirmPrompt({
70731
70658
  children: skill.name
70732
70659
  }, undefined, false, undefined, this),
70733
70660
  /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70734
- children: [
70735
- " v",
70736
- skill.version,
70737
- "?"
70738
- ]
70739
- }, undefined, true, undefined, this)
70661
+ children: "?"
70662
+ }, undefined, false, undefined, this)
70740
70663
  ]
70741
70664
  }, undefined, true, undefined, this),
70742
70665
  /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
@@ -70908,25 +70831,9 @@ var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
70908
70831
  var args10 = exports_external.tuple([
70909
70832
  exports_external.string().optional().describe("Skill name to upgrade (optional, upgrades all if omitted)")
70910
70833
  ]);
70911
- var options17 = exports_external.object({});
70912
- function parseFrontmatter6(content) {
70913
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
70914
- if (!frontmatterMatch)
70915
- return {};
70916
- const yaml = frontmatterMatch[1];
70917
- const result = {};
70918
- for (const line of yaml.split(`
70919
- `)) {
70920
- const colonIndex = line.indexOf(":");
70921
- if (colonIndex === -1)
70922
- continue;
70923
- const key = line.substring(0, colonIndex).trim();
70924
- const value = line.substring(colonIndex + 1).trim();
70925
- if (key)
70926
- result[key] = value;
70927
- }
70928
- return result;
70929
- }
70834
+ var options17 = exports_external.object({
70835
+ yes: exports_external.boolean().default(false).describe("Skip selection and upgrade all")
70836
+ });
70930
70837
  async function checkForUpdate2(token, skill, repoConfig) {
70931
70838
  const { repo, branch } = repoConfig;
70932
70839
  try {
@@ -70948,23 +70855,10 @@ async function checkForUpdate2(token, skill, repoConfig) {
70948
70855
  if (latestSha === skill.commitSha) {
70949
70856
  return null;
70950
70857
  }
70951
- const skillMdUrl = `https://api.github.com/repos/${repo}/contents/${skill.repoPath}/SKILL.md?ref=${branch}`;
70952
- const skillResponse = await fetch(skillMdUrl, {
70953
- headers: buildGitHubRawHeaders(token)
70954
- });
70955
- let latestVersion = skill.version;
70956
- if (skillResponse.ok) {
70957
- const content = await skillResponse.text();
70958
- const frontmatter = parseFrontmatter6(content);
70959
- if (frontmatter.version) {
70960
- latestVersion = String(frontmatter.version);
70961
- }
70962
- }
70963
70858
  return {
70964
70859
  skill,
70965
70860
  currentSha: skill.commitSha,
70966
- latestSha,
70967
- latestVersion
70861
+ latestSha
70968
70862
  };
70969
70863
  } catch {
70970
70864
  return null;
@@ -71015,12 +70909,69 @@ async function downloadSkillFiles2(token, repo, skillPath, branch, targetDir) {
71015
70909
  await writeFile2(targetPath, content, "utf-8");
71016
70910
  }
71017
70911
  }
71018
- function Upgrade({ args: [skillName] }) {
70912
+ function Upgrade({ args: [skillName], options: options18 }) {
71019
70913
  const { exit } = use_app_default();
71020
70914
  const [state, setState] = import_react47.useState({ phase: "checking" });
71021
70915
  const [outputItems, setOutputItems] = import_react47.useState([]);
70916
+ const performUpgrades = import_react47.useCallback(async (upgradesToPerform) => {
70917
+ const config2 = getConfig();
70918
+ const credentials = await getCredentials();
70919
+ const token = credentials?.token;
70920
+ const upgraded = [];
70921
+ for (let i = 0;i < upgradesToPerform.length; i++) {
70922
+ const { skill, latestSha } = upgradesToPerform[i];
70923
+ setState({
70924
+ phase: "upgrading",
70925
+ upgrades: upgradesToPerform,
70926
+ current: i,
70927
+ progress: Math.round(i / upgradesToPerform.length * 100)
70928
+ });
70929
+ try {
70930
+ const repoConfig = config2.repos.find((r) => r.repo === skill.repo);
70931
+ if (!repoConfig)
70932
+ continue;
70933
+ const downloadResult = await downloadSkillFiles2(token, skill.repo, skill.repoPath, repoConfig.branch, skill.installedPath);
70934
+ if (downloadResult && "authRequired" in downloadResult) {
70935
+ setState({
70936
+ phase: "auth_required",
70937
+ message: downloadResult.message
70938
+ });
70939
+ return;
70940
+ }
70941
+ const updatedSkill = {
70942
+ ...skill,
70943
+ commitSha: latestSha
70944
+ };
70945
+ addInstalledSkill(updatedSkill);
70946
+ upgraded.push(skill.name);
70947
+ } catch {}
70948
+ }
70949
+ if (upgraded.length > 0) {
70950
+ setState({ phase: "success", upgraded });
70951
+ } else {
70952
+ setState({ phase: "error", message: "All upgrades failed" });
70953
+ }
70954
+ }, []);
70955
+ const handleSelectConfirm = (selectedValues) => {
70956
+ if (state.phase !== "select")
70957
+ return;
70958
+ if (selectedValues.length === 0) {
70959
+ setState({ phase: "cancelled" });
70960
+ return;
70961
+ }
70962
+ const selectedUpgrades = state.upgrades.filter((u) => selectedValues.includes(u.skill.name));
70963
+ performUpgrades(selectedUpgrades).catch((err) => {
70964
+ setState({
70965
+ phase: "error",
70966
+ message: err instanceof Error ? err.message : "Upgrade failed"
70967
+ });
70968
+ });
70969
+ };
70970
+ const handleSelectCancel = () => {
70971
+ setState({ phase: "cancelled" });
70972
+ };
71022
70973
  import_react47.useEffect(() => {
71023
- async function upgrade() {
70974
+ async function checkUpdates() {
71024
70975
  const config2 = getConfig();
71025
70976
  let skillsToCheck = [];
71026
70977
  if (skillName) {
@@ -71063,51 +71014,21 @@ function Upgrade({ args: [skillName] }) {
71063
71014
  setState({ phase: "no_updates" });
71064
71015
  return;
71065
71016
  }
71066
- const upgraded = [];
71067
- for (let i = 0;i < upgrades.length; i++) {
71068
- const { skill, latestSha, latestVersion } = upgrades[i];
71069
- setState({
71070
- phase: "upgrading",
71071
- upgrades,
71072
- current: i,
71073
- progress: Math.round(i / upgrades.length * 100)
71074
- });
71075
- try {
71076
- const repoConfig = config2.repos.find((r) => r.repo === skill.repo);
71077
- if (!repoConfig)
71078
- continue;
71079
- const downloadResult = await downloadSkillFiles2(token, skill.repo, skill.repoPath, repoConfig.branch, skill.installedPath);
71080
- if (downloadResult && "authRequired" in downloadResult) {
71081
- setState({
71082
- phase: "auth_required",
71083
- message: downloadResult.message
71084
- });
71085
- return;
71086
- }
71087
- const updatedSkill = {
71088
- ...skill,
71089
- commitSha: latestSha,
71090
- version: latestVersion
71091
- };
71092
- addInstalledSkill(updatedSkill);
71093
- upgraded.push(`${skill.name} → v${latestVersion}`);
71094
- } catch {}
71095
- }
71096
- if (upgraded.length > 0) {
71097
- setState({ phase: "success", upgraded });
71098
- } else {
71099
- setState({ phase: "error", message: "All upgrades failed" });
71017
+ if (skillName || options18.yes) {
71018
+ await performUpgrades(upgrades);
71019
+ return;
71100
71020
  }
71021
+ setState({ phase: "select", upgrades });
71101
71022
  }
71102
- upgrade().catch((err) => {
71023
+ checkUpdates().catch((err) => {
71103
71024
  setState({
71104
71025
  phase: "error",
71105
71026
  message: err instanceof Error ? err.message : "Upgrade failed"
71106
71027
  });
71107
71028
  });
71108
- }, [skillName]);
71029
+ }, [skillName, options18.yes, performUpgrades]);
71109
71030
  import_react47.useEffect(() => {
71110
- const isFinalState = state.phase === "not_found" || state.phase === "no_updates" || state.phase === "success" || state.phase === "auth_required" || state.phase === "error";
71031
+ const isFinalState = state.phase === "not_found" || state.phase === "no_updates" || state.phase === "success" || state.phase === "auth_required" || state.phase === "cancelled" || state.phase === "error";
71111
71032
  if (isFinalState && outputItems.length === 0) {
71112
71033
  setOutputItems([{ id: "output" }]);
71113
71034
  }
@@ -71175,6 +71096,11 @@ function Upgrade({ args: [skillName] }) {
71175
71096
  }, undefined, false, undefined, this)
71176
71097
  ]
71177
71098
  }, undefined, true, undefined, this);
71099
+ case "cancelled":
71100
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(StatusMessage, {
71101
+ type: "info",
71102
+ children: "Upgrade cancelled"
71103
+ }, undefined, false, undefined, this);
71178
71104
  case "error":
71179
71105
  return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(StatusMessage, {
71180
71106
  type: "error",
@@ -71192,6 +71118,32 @@ function Upgrade({ args: [skillName] }) {
71192
71118
  state.phase === "checking_updates" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Spinner2, {
71193
71119
  text: `Checking for updates (${state.current}/${state.total})...`
71194
71120
  }, undefined, false, undefined, this),
71121
+ state.phase === "select" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
71122
+ flexDirection: "column",
71123
+ children: [
71124
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
71125
+ marginBottom: 1,
71126
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
71127
+ bold: true,
71128
+ children: [
71129
+ "Found ",
71130
+ state.upgrades.length,
71131
+ " skill(s) with updates available:"
71132
+ ]
71133
+ }, undefined, true, undefined, this)
71134
+ }, undefined, false, undefined, this),
71135
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(MultiSelect, {
71136
+ items: state.upgrades.map((u) => ({
71137
+ label: u.skill.name,
71138
+ value: u.skill.name,
71139
+ hint: `${u.currentSha.slice(0, 7)} → ${u.latestSha.slice(0, 7)}`
71140
+ })),
71141
+ initialSelected: state.upgrades.map((u) => u.skill.name),
71142
+ onSubmit: handleSelectConfirm,
71143
+ onCancel: handleSelectCancel
71144
+ }, undefined, false, undefined, this)
71145
+ ]
71146
+ }, undefined, true, undefined, this),
71195
71147
  state.phase === "upgrading" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
71196
71148
  flexDirection: "column",
71197
71149
  children: [
@@ -71225,16 +71177,6 @@ function Upgrade({ args: [skillName] }) {
71225
71177
  " ",
71226
71178
  upgrade.skill.name
71227
71179
  ]
71228
- }, undefined, true, undefined, this),
71229
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
71230
- dimColor: true,
71231
- children: [
71232
- " ",
71233
- "v",
71234
- upgrade.skill.version,
71235
- " → v",
71236
- upgrade.latestVersion
71237
- ]
71238
71180
  }, undefined, true, undefined, this)
71239
71181
  ]
71240
71182
  }, upgrade.skill.name, true, undefined, this)),
@@ -71257,10 +71199,593 @@ function Upgrade({ args: [skillName] }) {
71257
71199
  ]
71258
71200
  }, undefined, true, undefined, this);
71259
71201
  }
71202
+
71203
+ // src/commands/publish.tsx
71204
+ import { readdir, readFile as readFile2 } from "node:fs/promises";
71205
+ import { existsSync as existsSync4 } from "node:fs";
71206
+ import { join as join5 } from "node:path";
71207
+ var import_react48 = __toESM(require_react(), 1);
71208
+ var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
71209
+ var args11 = exports_external.tuple([exports_external.string().describe("Skill name to publish")]);
71210
+ var options18 = exports_external.object({});
71211
+ var FINAL_PHASES2 = [
71212
+ "success",
71213
+ "error",
71214
+ "no_default_repo",
71215
+ "skill_not_found",
71216
+ "missing_skill_md",
71217
+ "invalid_frontmatter",
71218
+ "auth_required",
71219
+ "no_write_access",
71220
+ "repo_not_found",
71221
+ "cancelled"
71222
+ ];
71223
+ function parseFrontmatter4(content) {
71224
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
71225
+ if (!frontmatterMatch) {
71226
+ return {};
71227
+ }
71228
+ const yaml = frontmatterMatch[1];
71229
+ const result = {};
71230
+ const lines = yaml.split(`
71231
+ `);
71232
+ for (const line of lines) {
71233
+ const colonIndex = line.indexOf(":");
71234
+ if (colonIndex === -1)
71235
+ continue;
71236
+ const key = line.substring(0, colonIndex).trim();
71237
+ let value = line.substring(colonIndex + 1).trim();
71238
+ if (key) {
71239
+ result[key] = value;
71240
+ }
71241
+ }
71242
+ return result;
71243
+ }
71244
+ async function getFilesRecursively(dir) {
71245
+ const files = [];
71246
+ const entries = await readdir(dir, { withFileTypes: true });
71247
+ for (const entry of entries) {
71248
+ const fullPath = join5(dir, entry.name);
71249
+ if (entry.isDirectory()) {
71250
+ const subFiles = await getFilesRecursively(fullPath);
71251
+ files.push(...subFiles);
71252
+ } else {
71253
+ files.push(fullPath);
71254
+ }
71255
+ }
71256
+ return files;
71257
+ }
71258
+ async function checkSkillExists(token, repo, skillPath, branch) {
71259
+ try {
71260
+ const response = await fetch(`https://api.github.com/repos/${repo}/contents/${skillPath}?ref=${branch}`, { headers: buildGitHubHeaders(token) });
71261
+ return response.ok;
71262
+ } catch {
71263
+ return false;
71264
+ }
71265
+ }
71266
+ async function uploadFile(token, repo, path6, content, branch, existingSha) {
71267
+ const url2 = `https://api.github.com/repos/${repo}/contents/${path6}`;
71268
+ const body = {
71269
+ message: `Add ${path6} via skilluse`,
71270
+ content: Buffer.from(content).toString("base64"),
71271
+ branch
71272
+ };
71273
+ if (existingSha) {
71274
+ body.sha = existingSha;
71275
+ }
71276
+ try {
71277
+ const response = await fetch(url2, {
71278
+ method: "PUT",
71279
+ headers: {
71280
+ ...buildGitHubHeaders(token),
71281
+ "Content-Type": "application/json"
71282
+ },
71283
+ body: JSON.stringify(body)
71284
+ });
71285
+ if (response.status === 403 || response.status === 401) {
71286
+ return { success: false, noAccess: true };
71287
+ }
71288
+ if (response.status === 404) {
71289
+ return { success: false, notFound: true };
71290
+ }
71291
+ if (!response.ok) {
71292
+ const data = await response.json();
71293
+ return { success: false, message: data.message || `HTTP ${response.status}` };
71294
+ }
71295
+ return { success: true };
71296
+ } catch (err) {
71297
+ return {
71298
+ success: false,
71299
+ message: err instanceof Error ? err.message : "Upload failed"
71300
+ };
71301
+ }
71302
+ }
71303
+ async function getFileSha(token, repo, path6, branch) {
71304
+ try {
71305
+ const response = await fetch(`https://api.github.com/repos/${repo}/contents/${path6}?ref=${branch}`, { headers: buildGitHubHeaders(token) });
71306
+ if (response.ok) {
71307
+ const data = await response.json();
71308
+ return data.sha;
71309
+ }
71310
+ } catch {}
71311
+ return;
71312
+ }
71313
+ function OverwritePrompt({
71314
+ skillName,
71315
+ repo,
71316
+ onConfirm,
71317
+ onCancel
71318
+ }) {
71319
+ use_input_default((input, key) => {
71320
+ if (input.toLowerCase() === "y" || key.return) {
71321
+ onConfirm();
71322
+ } else if (input.toLowerCase() === "n" || key.escape) {
71323
+ onCancel();
71324
+ }
71325
+ });
71326
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71327
+ flexDirection: "column",
71328
+ borderStyle: "round",
71329
+ paddingX: 1,
71330
+ children: [
71331
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71332
+ marginBottom: 1,
71333
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71334
+ color: "yellow",
71335
+ bold: true,
71336
+ children: "Skill Already Exists"
71337
+ }, undefined, false, undefined, this)
71338
+ }, undefined, false, undefined, this),
71339
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71340
+ flexDirection: "column",
71341
+ marginBottom: 1,
71342
+ children: [
71343
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71344
+ children: [
71345
+ "Skill",
71346
+ " ",
71347
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71348
+ color: "cyan",
71349
+ bold: true,
71350
+ children: skillName
71351
+ }, undefined, false, undefined, this),
71352
+ " ",
71353
+ "already exists in repository:"
71354
+ ]
71355
+ }, undefined, true, undefined, this),
71356
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71357
+ marginLeft: 2,
71358
+ marginTop: 1,
71359
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71360
+ dimColor: true,
71361
+ children: repo
71362
+ }, undefined, false, undefined, this)
71363
+ }, undefined, false, undefined, this)
71364
+ ]
71365
+ }, undefined, true, undefined, this),
71366
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71367
+ children: [
71368
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71369
+ dimColor: true,
71370
+ children: "Press "
71371
+ }, undefined, false, undefined, this),
71372
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71373
+ color: "green",
71374
+ children: "Y"
71375
+ }, undefined, false, undefined, this),
71376
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71377
+ dimColor: true,
71378
+ children: " to overwrite, "
71379
+ }, undefined, false, undefined, this),
71380
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71381
+ color: "red",
71382
+ children: "N"
71383
+ }, undefined, false, undefined, this),
71384
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71385
+ dimColor: true,
71386
+ children: " to cancel"
71387
+ }, undefined, false, undefined, this)
71388
+ ]
71389
+ }, undefined, true, undefined, this)
71390
+ ]
71391
+ }, undefined, true, undefined, this);
71392
+ }
71393
+ function Publish({ args: [skillName] }) {
71394
+ const { exit } = use_app_default();
71395
+ const [state, setState] = import_react48.useState({ phase: "checking" });
71396
+ const [outputItems, setOutputItems] = import_react48.useState([]);
71397
+ const [publishContext, setPublishContext] = import_react48.useState(null);
71398
+ import_react48.useEffect(() => {
71399
+ async function validate2() {
71400
+ const credentials = await getCredentials();
71401
+ if (!credentials?.token) {
71402
+ setState({ phase: "auth_required" });
71403
+ return;
71404
+ }
71405
+ const config2 = getConfig();
71406
+ if (!config2.defaultRepo) {
71407
+ setState({ phase: "no_default_repo" });
71408
+ return;
71409
+ }
71410
+ const repoConfig = config2.repos.find((r) => r.repo === config2.defaultRepo);
71411
+ if (!repoConfig) {
71412
+ setState({ phase: "no_default_repo" });
71413
+ return;
71414
+ }
71415
+ const agentId = getCurrentAgent();
71416
+ const agent = getAgent(agentId);
71417
+ if (!agent) {
71418
+ setState({ phase: "error", message: `Unknown agent: ${agentId}` });
71419
+ return;
71420
+ }
71421
+ const skillsDir = getSkillsPath(agentId, "local");
71422
+ const skillPath = join5(skillsDir, skillName);
71423
+ if (!existsSync4(skillPath)) {
71424
+ setState({
71425
+ phase: "skill_not_found",
71426
+ skillName,
71427
+ searchPath: skillsDir
71428
+ });
71429
+ return;
71430
+ }
71431
+ const skillMdPath = join5(skillPath, "SKILL.md");
71432
+ if (!existsSync4(skillMdPath)) {
71433
+ setState({ phase: "missing_skill_md", skillPath });
71434
+ return;
71435
+ }
71436
+ const skillMdContent = await readFile2(skillMdPath, "utf-8");
71437
+ const frontmatter = parseFrontmatter4(skillMdContent);
71438
+ if (!frontmatter.name) {
71439
+ setState({ phase: "invalid_frontmatter", field: "name" });
71440
+ return;
71441
+ }
71442
+ if (!frontmatter.description) {
71443
+ setState({ phase: "invalid_frontmatter", field: "description" });
71444
+ return;
71445
+ }
71446
+ setPublishContext({
71447
+ skillPath,
71448
+ repoConfig,
71449
+ token: credentials.token
71450
+ });
71451
+ const basePath = repoConfig.paths.length > 0 ? repoConfig.paths[0] : "";
71452
+ const targetPath = basePath && basePath !== "." ? `${basePath}/${skillName}` : skillName;
71453
+ const exists = await checkSkillExists(credentials.token, repoConfig.repo, targetPath, repoConfig.branch);
71454
+ if (exists) {
71455
+ setState({
71456
+ phase: "exists_prompt",
71457
+ skillName,
71458
+ repo: repoConfig.repo,
71459
+ path: targetPath
71460
+ });
71461
+ return;
71462
+ }
71463
+ await performUpload(skillPath, repoConfig, credentials.token, skillName, targetPath);
71464
+ }
71465
+ validate2().catch((err) => {
71466
+ setState({
71467
+ phase: "error",
71468
+ message: err instanceof Error ? err.message : "Publish failed"
71469
+ });
71470
+ });
71471
+ }, [skillName]);
71472
+ async function performUpload(skillPath, repoConfig, token, skillName2, targetPath) {
71473
+ setState({
71474
+ phase: "uploading",
71475
+ skillName: skillName2,
71476
+ progress: 0,
71477
+ currentFile: "Reading files..."
71478
+ });
71479
+ try {
71480
+ const files = await getFilesRecursively(skillPath);
71481
+ if (files.length === 0) {
71482
+ setState({ phase: "error", message: "No files found in skill directory" });
71483
+ return;
71484
+ }
71485
+ for (let i = 0;i < files.length; i++) {
71486
+ const file2 = files[i];
71487
+ const relativePath = file2.substring(skillPath.length + 1);
71488
+ const remotePath = `${targetPath}/${relativePath}`;
71489
+ setState({
71490
+ phase: "uploading",
71491
+ skillName: skillName2,
71492
+ progress: Math.round((i + 1) / files.length * 100),
71493
+ currentFile: relativePath
71494
+ });
71495
+ const content = await readFile2(file2, "utf-8");
71496
+ const existingSha = await getFileSha(token, repoConfig.repo, remotePath, repoConfig.branch);
71497
+ const result = await uploadFile(token, repoConfig.repo, remotePath, content, repoConfig.branch, existingSha);
71498
+ if (result.noAccess) {
71499
+ setState({ phase: "no_write_access", repo: repoConfig.repo });
71500
+ return;
71501
+ }
71502
+ if (result.notFound) {
71503
+ setState({ phase: "repo_not_found", repo: repoConfig.repo });
71504
+ return;
71505
+ }
71506
+ if (!result.success) {
71507
+ setState({
71508
+ phase: "error",
71509
+ message: result.message || `Failed to upload ${relativePath}`
71510
+ });
71511
+ return;
71512
+ }
71513
+ }
71514
+ const githubUrl = `https://github.com/${repoConfig.repo}/tree/${repoConfig.branch}/${targetPath}`;
71515
+ setState({ phase: "success", skillName: skillName2, githubUrl });
71516
+ } catch (err) {
71517
+ setState({
71518
+ phase: "error",
71519
+ message: err instanceof Error ? err.message : "Upload failed"
71520
+ });
71521
+ }
71522
+ }
71523
+ function handleConfirmOverwrite() {
71524
+ if (!publishContext)
71525
+ return;
71526
+ const { skillPath, repoConfig, token } = publishContext;
71527
+ const basePath = repoConfig.paths.length > 0 ? repoConfig.paths[0] : "";
71528
+ const targetPath = basePath && basePath !== "." ? `${basePath}/${skillName}` : skillName;
71529
+ performUpload(skillPath, repoConfig, token, skillName, targetPath);
71530
+ }
71531
+ function handleCancelOverwrite() {
71532
+ setState({ phase: "cancelled" });
71533
+ }
71534
+ import_react48.useEffect(() => {
71535
+ if (FINAL_PHASES2.includes(state.phase) && outputItems.length === 0) {
71536
+ setOutputItems([{ id: "output" }]);
71537
+ }
71538
+ }, [state.phase, outputItems.length]);
71539
+ import_react48.useEffect(() => {
71540
+ if (outputItems.length > 0) {
71541
+ process.nextTick(() => exit());
71542
+ }
71543
+ }, [outputItems.length, exit]);
71544
+ if (state.phase === "checking") {
71545
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Spinner2, {
71546
+ text: "Validating skill..."
71547
+ }, undefined, false, undefined, this);
71548
+ }
71549
+ if (state.phase === "uploading") {
71550
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71551
+ flexDirection: "column",
71552
+ children: [
71553
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71554
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Spinner2, {
71555
+ text: `Publishing ${state.skillName}... ${state.progress}%`
71556
+ }, undefined, false, undefined, this)
71557
+ }, undefined, false, undefined, this),
71558
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71559
+ marginLeft: 2,
71560
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71561
+ dimColor: true,
71562
+ children: [
71563
+ "Uploading: ",
71564
+ state.currentFile
71565
+ ]
71566
+ }, undefined, true, undefined, this)
71567
+ }, undefined, false, undefined, this)
71568
+ ]
71569
+ }, undefined, true, undefined, this);
71570
+ }
71571
+ if (state.phase === "exists_prompt") {
71572
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(OverwritePrompt, {
71573
+ skillName: state.skillName,
71574
+ repo: state.repo,
71575
+ onConfirm: handleConfirmOverwrite,
71576
+ onCancel: handleCancelOverwrite
71577
+ }, undefined, false, undefined, this);
71578
+ }
71579
+ const renderFinalContent = () => {
71580
+ switch (state.phase) {
71581
+ case "no_default_repo":
71582
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
71583
+ children: [
71584
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71585
+ type: "error",
71586
+ children: "No default repo configured"
71587
+ }, undefined, false, undefined, this),
71588
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71589
+ marginTop: 1,
71590
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71591
+ dimColor: true,
71592
+ children: [
71593
+ "Run 'skilluse repo use ",
71594
+ "<owner/repo>",
71595
+ " to set a default repository."
71596
+ ]
71597
+ }, undefined, true, undefined, this)
71598
+ }, undefined, false, undefined, this)
71599
+ ]
71600
+ }, undefined, true, undefined, this);
71601
+ case "skill_not_found":
71602
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
71603
+ children: [
71604
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71605
+ type: "error",
71606
+ children: [
71607
+ "Skill '",
71608
+ state.skillName,
71609
+ "' not found"
71610
+ ]
71611
+ }, undefined, true, undefined, this),
71612
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71613
+ marginTop: 1,
71614
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71615
+ dimColor: true,
71616
+ children: [
71617
+ "Searched in: ",
71618
+ state.searchPath
71619
+ ]
71620
+ }, undefined, true, undefined, this)
71621
+ }, undefined, false, undefined, this)
71622
+ ]
71623
+ }, undefined, true, undefined, this);
71624
+ case "missing_skill_md":
71625
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
71626
+ children: [
71627
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71628
+ type: "error",
71629
+ children: "SKILL.md not found in skill directory"
71630
+ }, undefined, false, undefined, this),
71631
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71632
+ marginTop: 1,
71633
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71634
+ dimColor: true,
71635
+ children: [
71636
+ "Expected at: ",
71637
+ state.skillPath,
71638
+ "/SKILL.md"
71639
+ ]
71640
+ }, undefined, true, undefined, this)
71641
+ }, undefined, false, undefined, this)
71642
+ ]
71643
+ }, undefined, true, undefined, this);
71644
+ case "invalid_frontmatter":
71645
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71646
+ type: "error",
71647
+ children: [
71648
+ "SKILL.md missing required field: ",
71649
+ state.field
71650
+ ]
71651
+ }, undefined, true, undefined, this);
71652
+ case "auth_required":
71653
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
71654
+ children: [
71655
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71656
+ type: "error",
71657
+ children: "Authentication required"
71658
+ }, undefined, false, undefined, this),
71659
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71660
+ marginTop: 1,
71661
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71662
+ dimColor: true,
71663
+ children: "Run 'skilluse login' to authenticate."
71664
+ }, undefined, false, undefined, this)
71665
+ }, undefined, false, undefined, this)
71666
+ ]
71667
+ }, undefined, true, undefined, this);
71668
+ case "no_write_access":
71669
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
71670
+ children: [
71671
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71672
+ type: "error",
71673
+ children: [
71674
+ "No write access to repo: ",
71675
+ state.repo
71676
+ ]
71677
+ }, undefined, true, undefined, this),
71678
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71679
+ marginTop: 1,
71680
+ flexDirection: "column",
71681
+ children: [
71682
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71683
+ dimColor: true,
71684
+ children: "Possible causes:"
71685
+ }, undefined, false, undefined, this),
71686
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71687
+ dimColor: true,
71688
+ children: "1. Skilluse App not installed on this org/account"
71689
+ }, undefined, false, undefined, this),
71690
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71691
+ dimColor: true,
71692
+ children: "2. App not granted access to this specific repo"
71693
+ }, undefined, false, undefined, this)
71694
+ ]
71695
+ }, undefined, true, undefined, this),
71696
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71697
+ marginTop: 1,
71698
+ flexDirection: "column",
71699
+ children: [
71700
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71701
+ dimColor: true,
71702
+ children: "Install or configure the App for this repo:"
71703
+ }, undefined, false, undefined, this),
71704
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71705
+ color: "cyan",
71706
+ children: "https://github.com/apps/skilluse/installations/new"
71707
+ }, undefined, false, undefined, this),
71708
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71709
+ dimColor: true,
71710
+ children: "Then run 'skilluse login' to refresh your token."
71711
+ }, undefined, false, undefined, this)
71712
+ ]
71713
+ }, undefined, true, undefined, this)
71714
+ ]
71715
+ }, undefined, true, undefined, this);
71716
+ case "repo_not_found":
71717
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
71718
+ children: [
71719
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71720
+ type: "error",
71721
+ children: [
71722
+ "Repository not found: ",
71723
+ state.repo
71724
+ ]
71725
+ }, undefined, true, undefined, this),
71726
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71727
+ marginTop: 1,
71728
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71729
+ dimColor: true,
71730
+ children: "Check that the repository exists and you have access to it."
71731
+ }, undefined, false, undefined, this)
71732
+ }, undefined, false, undefined, this)
71733
+ ]
71734
+ }, undefined, true, undefined, this);
71735
+ case "success":
71736
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
71737
+ children: [
71738
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71739
+ type: "success",
71740
+ children: [
71741
+ "Published '",
71742
+ state.skillName,
71743
+ "'"
71744
+ ]
71745
+ }, undefined, true, undefined, this),
71746
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71747
+ marginTop: 1,
71748
+ marginLeft: 2,
71749
+ children: [
71750
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71751
+ dimColor: true,
71752
+ children: "View at: "
71753
+ }, undefined, false, undefined, this),
71754
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
71755
+ color: "blue",
71756
+ underline: true,
71757
+ children: state.githubUrl
71758
+ }, undefined, false, undefined, this)
71759
+ ]
71760
+ }, undefined, true, undefined, this)
71761
+ ]
71762
+ }, undefined, true, undefined, this);
71763
+ case "cancelled":
71764
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71765
+ type: "warning",
71766
+ children: "Publish cancelled"
71767
+ }, undefined, false, undefined, this);
71768
+ case "error":
71769
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
71770
+ type: "error",
71771
+ children: state.message
71772
+ }, undefined, false, undefined, this);
71773
+ default:
71774
+ return null;
71775
+ }
71776
+ };
71777
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Static, {
71778
+ items: outputItems,
71779
+ children: (item) => /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
71780
+ flexDirection: "column",
71781
+ children: renderFinalContent()
71782
+ }, item.id, false, undefined, this)
71783
+ }, undefined, false, undefined, this);
71784
+ }
71260
71785
  // package.json
71261
71786
  var package_default = {
71262
71787
  name: "skilluse",
71263
- version: "0.7.0",
71788
+ version: "0.9.0",
71264
71789
  description: "CLI tool for managing and installing AI Coding Agent Skills",
71265
71790
  main: "dist/cli.js",
71266
71791
  bin: {
@@ -71287,7 +71812,6 @@ var package_default = {
71287
71812
  dev: "bun --watch src/index.tsx",
71288
71813
  build: `bun build src/cli.tsx --outdir dist --target node --define 'process.env.DEV="false"'`,
71289
71814
  "build:bin": `bun build src/cli.tsx --compile --minify --sourcemap --define 'process.env.DEV="false"' --outfile dist/skilluse`,
71290
- "build:all": "bun run scripts/build-all.ts",
71291
71815
  typecheck: "tsc --noEmit",
71292
71816
  format: "biome format --write .",
71293
71817
  lint: "biome lint .",
@@ -71330,7 +71854,7 @@ var package_default = {
71330
71854
  };
71331
71855
 
71332
71856
  // src/cli.tsx
71333
- var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
71857
+ var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
71334
71858
  var VERSION = process.env.VERSION || package_default.version;
71335
71859
  var BUILD_TIME = process.env.BUILD_TIME || new Date().toISOString();
71336
71860
  var program2 = new Command;
@@ -71340,115 +71864,122 @@ program2.name("skilluse").description("CLI tool for managing and installing AI C
71340
71864
  process.exit(0);
71341
71865
  });
71342
71866
  program2.command("login").description("Authenticate with GitHub").action(() => {
71343
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Login, {
71867
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Login, {
71344
71868
  options: {}
71345
71869
  }, undefined, false, undefined, this));
71346
71870
  });
71347
71871
  program2.command("logout").description("Clear stored credentials").action(() => {
71348
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Logout, {
71872
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Logout, {
71349
71873
  options: {}
71350
71874
  }, undefined, false, undefined, this));
71351
71875
  });
71352
71876
  program2.command("list").description("List installed skills").option("-o, --outdated", "Show only outdated skills").action((opts) => {
71353
- const options18 = options4.parse(opts);
71354
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(List, {
71355
- options: options18
71877
+ const options19 = options4.parse(opts);
71878
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(List, {
71879
+ options: options19
71356
71880
  }, undefined, false, undefined, this));
71357
71881
  });
71358
- program2.command("search <keyword>").description("Search for skills").option("-a, --all", "Search in all configured repos").action((keyword, opts) => {
71359
- const args11 = args8.parse([keyword]);
71360
- const options18 = options15.parse(opts);
71361
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Search, {
71362
- args: args11,
71363
- options: options18
71882
+ program2.command("search <keyword>").description("Search for skills in default repository").action((keyword) => {
71883
+ const args12 = args8.parse([keyword]);
71884
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Search, {
71885
+ args: args12,
71886
+ options: {}
71364
71887
  }, undefined, false, undefined, this));
71365
71888
  });
71366
71889
  program2.command("install <skill-name>").description("Install a skill").option("-g, --global", "Install globally to agent's global skills path").option("-a, --agent <agent>", "Override current agent (e.g., cursor, claude)").action((skillName, opts) => {
71367
- const args11 = args2.parse([skillName]);
71368
- const options18 = options3.parse(opts);
71369
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Install, {
71370
- args: args11,
71371
- options: options18
71890
+ const args12 = args2.parse([skillName]);
71891
+ const options19 = options3.parse(opts);
71892
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Install, {
71893
+ args: args12,
71894
+ options: options19
71372
71895
  }, undefined, false, undefined, this));
71373
71896
  });
71374
71897
  program2.command("uninstall <skill-name>").description("Uninstall a skill").option("-f, --force", "Skip confirmation").action((skillName, opts) => {
71375
- const args11 = args9.parse([skillName]);
71376
- const options18 = options16.parse(opts);
71377
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Uninstall, {
71378
- args: args11,
71379
- options: options18
71898
+ const args12 = args9.parse([skillName]);
71899
+ const options19 = options16.parse(opts);
71900
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Uninstall, {
71901
+ args: args12,
71902
+ options: options19
71380
71903
  }, undefined, false, undefined, this));
71381
71904
  });
71382
- program2.command("upgrade [skill-name]").description("Upgrade skill(s) to latest version").action((skillName) => {
71383
- const args11 = args10.parse([skillName]);
71384
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Upgrade, {
71385
- args: args11,
71386
- options: {}
71905
+ program2.command("upgrade [skill-name]").description("Upgrade skill(s) to latest version").option("-y, --yes", "Skip selection and upgrade all").action((skillName, opts) => {
71906
+ const args12 = args10.parse([skillName]);
71907
+ const options19 = options17.parse(opts);
71908
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Upgrade, {
71909
+ args: args12,
71910
+ options: options19
71387
71911
  }, undefined, false, undefined, this));
71388
71912
  });
71389
71913
  program2.command("info <skill-name>").description("Show skill details").action((skillName) => {
71390
- const args11 = args.parse([skillName]);
71391
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Info, {
71392
- args: args11,
71914
+ const args12 = args.parse([skillName]);
71915
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Info, {
71916
+ args: args12,
71917
+ options: {}
71918
+ }, undefined, false, undefined, this));
71919
+ });
71920
+ program2.command("publish <skill-name>").description("Publish a local skill to the default repository").action((skillName) => {
71921
+ const args12 = args11.parse([skillName]);
71922
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Publish, {
71923
+ args: args12,
71393
71924
  options: {}
71394
71925
  }, undefined, false, undefined, this));
71395
71926
  });
71396
71927
  var repoCmd = program2.command("repo").description("Manage skill repositories");
71397
71928
  repoCmd.command("list").description("List configured repositories").action(() => {
71398
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(RepoList, {
71929
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoList, {
71399
71930
  options: {}
71400
71931
  }, undefined, false, undefined, this));
71401
71932
  });
71402
71933
  repoCmd.command("skills").description("List all skills in current repository").action(() => {
71403
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(RepoSkills, {
71934
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoSkills, {
71404
71935
  options: {}
71405
71936
  }, undefined, false, undefined, this));
71406
71937
  });
71407
71938
  repoCmd.command("add <url>").description("Add a skill repository").option("-p, --path <path>", "Skill path within the repo").option("-b, --branch <branch>", "Branch to use").option("-d, --default", "Set as default repository").action((url2, opts) => {
71408
- const args11 = args3.parse([url2]);
71409
- const options18 = options7.parse(opts);
71410
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(RepoAdd, {
71411
- args: args11,
71412
- options: options18
71939
+ const args12 = args3.parse([url2]);
71940
+ const options19 = options7.parse(opts);
71941
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoAdd, {
71942
+ args: args12,
71943
+ options: options19
71413
71944
  }, undefined, false, undefined, this));
71414
71945
  });
71415
71946
  repoCmd.command("remove <name>").description("Remove a repository").option("-f, --force", "Skip confirmation").action((name, opts) => {
71416
- const args11 = args5.parse([name]);
71417
- const options18 = options12.parse(opts);
71418
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(RepoRemove, {
71419
- args: args11,
71420
- options: options18
71947
+ const args12 = args5.parse([name]);
71948
+ const options19 = options12.parse(opts);
71949
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoRemove, {
71950
+ args: args12,
71951
+ options: options19
71421
71952
  }, undefined, false, undefined, this));
71422
71953
  });
71423
71954
  repoCmd.command("edit <name>").description("Edit repository settings").option("-p, --path <path>", "New skill path").option("-b, --branch <branch>", "New branch").action((name, opts) => {
71424
- const args11 = args4.parse([name]);
71425
- const options18 = options8.parse(opts);
71426
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(RepoEdit, {
71427
- args: args11,
71428
- options: options18
71955
+ const args12 = args4.parse([name]);
71956
+ const options19 = options8.parse(opts);
71957
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoEdit, {
71958
+ args: args12,
71959
+ options: options19
71429
71960
  }, undefined, false, undefined, this));
71430
71961
  });
71431
71962
  repoCmd.command("use <name>").description("Set default repository").action((name, _opts) => {
71432
- const args11 = args6.parse([name]);
71433
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(RepoUse, {
71434
- args: args11,
71963
+ const args12 = args6.parse([name]);
71964
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoUse, {
71965
+ args: args12,
71435
71966
  options: {}
71436
71967
  }, undefined, false, undefined, this));
71437
71968
  });
71438
71969
  repoCmd.action(() => {
71439
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Repo, {
71970
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Repo, {
71440
71971
  options: {}
71441
71972
  }, undefined, false, undefined, this));
71442
71973
  });
71443
71974
  program2.command("agent [agent-id]").description("Switch agent or select interactively").action((agentId) => {
71444
- const args11 = args7.parse([agentId]);
71445
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Agent, {
71446
- args: args11,
71975
+ const args12 = args7.parse([agentId]);
71976
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Agent, {
71977
+ args: args12,
71447
71978
  options: {}
71448
71979
  }, undefined, false, undefined, this));
71449
71980
  });
71450
71981
  program2.action(() => {
71451
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Index, {
71982
+ render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Index, {
71452
71983
  options: {}
71453
71984
  }, undefined, false, undefined, this));
71454
71985
  });