skilluse 0.7.0 → 0.8.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.
- package/README.md +7 -3
- package/dist/cli.js +847 -384
- 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
|
|
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 =
|
|
67035
|
+
const frontmatter = parseFrontmatter2(content);
|
|
66937
67036
|
return {
|
|
66938
67037
|
name: String(frontmatter.name || skill.name),
|
|
66939
67038
|
description: String(frontmatter.description || ""),
|
|
66940
|
-
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:
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
-
'"
|
|
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
|
-
"
|
|
68373
|
-
skill.
|
|
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: [
|
|
@@ -69728,82 +69775,6 @@ function RepoList(_props) {
|
|
|
69728
69775
|
var import_react41 = __toESM(require_react(), 1);
|
|
69729
69776
|
var jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
|
|
69730
69777
|
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
69778
|
function RepoSkills(_props) {
|
|
69808
69779
|
const { exit } = use_app_default();
|
|
69809
69780
|
const [state, setState] = import_react41.useState({ phase: "checking" });
|
|
@@ -69826,14 +69797,23 @@ function RepoSkills(_props) {
|
|
|
69826
69797
|
const installedSkillNames = new Set(config2.installed.filter((s) => s.agent === currentAgent || !s.agent).map((s) => s.name));
|
|
69827
69798
|
const credentials = await getCredentials();
|
|
69828
69799
|
const token = credentials?.token;
|
|
69829
|
-
const result = await fetchSkillsFromRepo(token, repoConfig
|
|
69800
|
+
const result = await fetchSkillsFromRepo(token, repoConfig);
|
|
69830
69801
|
if ("authRequired" in result) {
|
|
69831
69802
|
setState({ phase: "auth_required", message: result.message });
|
|
69832
69803
|
return;
|
|
69833
69804
|
}
|
|
69805
|
+
const skillsWithInstalled = result.map((skill) => ({
|
|
69806
|
+
...skill,
|
|
69807
|
+
installed: installedSkillNames.has(skill.name)
|
|
69808
|
+
})).sort((a, b) => {
|
|
69809
|
+
if (a.installed !== b.installed) {
|
|
69810
|
+
return a.installed ? -1 : 1;
|
|
69811
|
+
}
|
|
69812
|
+
return a.name.localeCompare(b.name);
|
|
69813
|
+
});
|
|
69834
69814
|
setState({
|
|
69835
69815
|
phase: "success",
|
|
69836
|
-
skills:
|
|
69816
|
+
skills: skillsWithInstalled,
|
|
69837
69817
|
repoName: repoConfig.repo
|
|
69838
69818
|
});
|
|
69839
69819
|
}
|
|
@@ -70400,79 +70380,7 @@ function Agent({ args: [agentIdArg] }) {
|
|
|
70400
70380
|
var import_react45 = __toESM(require_react(), 1);
|
|
70401
70381
|
var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
|
|
70402
70382
|
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());
|
|
70423
|
-
}
|
|
70424
|
-
if (key) {
|
|
70425
|
-
result[key] = value;
|
|
70426
|
-
}
|
|
70427
|
-
}
|
|
70428
|
-
return result;
|
|
70429
|
-
}
|
|
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
|
-
}
|
|
70383
|
+
var options15 = exports_external.object({});
|
|
70476
70384
|
function filterSkills(skills, keyword) {
|
|
70477
70385
|
const lowerKeyword = keyword.toLowerCase();
|
|
70478
70386
|
return skills.filter((skill) => {
|
|
@@ -70488,41 +70396,32 @@ function filterSkills(skills, keyword) {
|
|
|
70488
70396
|
return false;
|
|
70489
70397
|
});
|
|
70490
70398
|
}
|
|
70491
|
-
function Search({ args: [keyword]
|
|
70399
|
+
function Search({ args: [keyword] }) {
|
|
70492
70400
|
const { exit } = use_app_default();
|
|
70493
70401
|
const [state, setState] = import_react45.useState({ phase: "checking" });
|
|
70494
70402
|
const [outputItems, setOutputItems] = import_react45.useState([]);
|
|
70495
70403
|
import_react45.useEffect(() => {
|
|
70496
70404
|
async function search() {
|
|
70497
70405
|
const config2 = getConfig();
|
|
70498
|
-
let
|
|
70499
|
-
if (
|
|
70500
|
-
|
|
70501
|
-
} else if (config2.defaultRepo) {
|
|
70502
|
-
const defaultRepoConfig = config2.repos.find((r) => r.repo === config2.defaultRepo);
|
|
70503
|
-
if (defaultRepoConfig) {
|
|
70504
|
-
reposToSearch = [defaultRepoConfig];
|
|
70505
|
-
}
|
|
70406
|
+
let repoConfig;
|
|
70407
|
+
if (config2.defaultRepo) {
|
|
70408
|
+
repoConfig = config2.repos.find((r) => r.repo === config2.defaultRepo);
|
|
70506
70409
|
} else if (config2.repos.length > 0) {
|
|
70507
|
-
|
|
70410
|
+
repoConfig = config2.repos[0];
|
|
70508
70411
|
}
|
|
70509
|
-
if (
|
|
70412
|
+
if (!repoConfig) {
|
|
70510
70413
|
setState({ phase: "no_repos" });
|
|
70511
70414
|
return;
|
|
70512
70415
|
}
|
|
70416
|
+
setState({ phase: "searching", repo: repoConfig.repo });
|
|
70513
70417
|
const credentials = await getCredentials();
|
|
70514
70418
|
const token = credentials?.token;
|
|
70515
|
-
const
|
|
70516
|
-
|
|
70517
|
-
setState({ phase: "
|
|
70518
|
-
|
|
70519
|
-
if ("authRequired" in result) {
|
|
70520
|
-
setState({ phase: "auth_required", message: result.message });
|
|
70521
|
-
return;
|
|
70522
|
-
}
|
|
70523
|
-
allSkills.push(...result);
|
|
70419
|
+
const result = await fetchSkillsFromRepo(token, repoConfig);
|
|
70420
|
+
if ("authRequired" in result) {
|
|
70421
|
+
setState({ phase: "auth_required", message: result.message });
|
|
70422
|
+
return;
|
|
70524
70423
|
}
|
|
70525
|
-
const matchingSkills = filterSkills(
|
|
70424
|
+
const matchingSkills = filterSkills(result, keyword);
|
|
70526
70425
|
setState({ phase: "success", skills: matchingSkills, keyword });
|
|
70527
70426
|
}
|
|
70528
70427
|
search().catch((err) => {
|
|
@@ -70531,7 +70430,7 @@ function Search({ args: [keyword], options: opts }) {
|
|
|
70531
70430
|
message: err instanceof Error ? err.message : "Search failed"
|
|
70532
70431
|
});
|
|
70533
70432
|
});
|
|
70534
|
-
}, [keyword
|
|
70433
|
+
}, [keyword]);
|
|
70535
70434
|
import_react45.useEffect(() => {
|
|
70536
70435
|
const isFinalState = state.phase === "no_repos" || state.phase === "success" || state.phase === "auth_required" || state.phase === "error";
|
|
70537
70436
|
if (isFinalState && outputItems.length === 0) {
|
|
@@ -70731,12 +70630,8 @@ function ConfirmPrompt({
|
|
|
70731
70630
|
children: skill.name
|
|
70732
70631
|
}, undefined, false, undefined, this),
|
|
70733
70632
|
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
|
|
70734
|
-
children:
|
|
70735
|
-
|
|
70736
|
-
skill.version,
|
|
70737
|
-
"?"
|
|
70738
|
-
]
|
|
70739
|
-
}, undefined, true, undefined, this)
|
|
70633
|
+
children: "?"
|
|
70634
|
+
}, undefined, false, undefined, this)
|
|
70740
70635
|
]
|
|
70741
70636
|
}, undefined, true, undefined, this),
|
|
70742
70637
|
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
|
|
@@ -70908,25 +70803,9 @@ var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
|
|
|
70908
70803
|
var args10 = exports_external.tuple([
|
|
70909
70804
|
exports_external.string().optional().describe("Skill name to upgrade (optional, upgrades all if omitted)")
|
|
70910
70805
|
]);
|
|
70911
|
-
var options17 = exports_external.object({
|
|
70912
|
-
|
|
70913
|
-
|
|
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
|
-
}
|
|
70806
|
+
var options17 = exports_external.object({
|
|
70807
|
+
yes: exports_external.boolean().default(false).describe("Skip selection and upgrade all")
|
|
70808
|
+
});
|
|
70930
70809
|
async function checkForUpdate2(token, skill, repoConfig) {
|
|
70931
70810
|
const { repo, branch } = repoConfig;
|
|
70932
70811
|
try {
|
|
@@ -70948,23 +70827,10 @@ async function checkForUpdate2(token, skill, repoConfig) {
|
|
|
70948
70827
|
if (latestSha === skill.commitSha) {
|
|
70949
70828
|
return null;
|
|
70950
70829
|
}
|
|
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
70830
|
return {
|
|
70964
70831
|
skill,
|
|
70965
70832
|
currentSha: skill.commitSha,
|
|
70966
|
-
latestSha
|
|
70967
|
-
latestVersion
|
|
70833
|
+
latestSha
|
|
70968
70834
|
};
|
|
70969
70835
|
} catch {
|
|
70970
70836
|
return null;
|
|
@@ -71015,12 +70881,69 @@ async function downloadSkillFiles2(token, repo, skillPath, branch, targetDir) {
|
|
|
71015
70881
|
await writeFile2(targetPath, content, "utf-8");
|
|
71016
70882
|
}
|
|
71017
70883
|
}
|
|
71018
|
-
function Upgrade({ args: [skillName] }) {
|
|
70884
|
+
function Upgrade({ args: [skillName], options: options18 }) {
|
|
71019
70885
|
const { exit } = use_app_default();
|
|
71020
70886
|
const [state, setState] = import_react47.useState({ phase: "checking" });
|
|
71021
70887
|
const [outputItems, setOutputItems] = import_react47.useState([]);
|
|
70888
|
+
const performUpgrades = import_react47.useCallback(async (upgradesToPerform) => {
|
|
70889
|
+
const config2 = getConfig();
|
|
70890
|
+
const credentials = await getCredentials();
|
|
70891
|
+
const token = credentials?.token;
|
|
70892
|
+
const upgraded = [];
|
|
70893
|
+
for (let i = 0;i < upgradesToPerform.length; i++) {
|
|
70894
|
+
const { skill, latestSha } = upgradesToPerform[i];
|
|
70895
|
+
setState({
|
|
70896
|
+
phase: "upgrading",
|
|
70897
|
+
upgrades: upgradesToPerform,
|
|
70898
|
+
current: i,
|
|
70899
|
+
progress: Math.round(i / upgradesToPerform.length * 100)
|
|
70900
|
+
});
|
|
70901
|
+
try {
|
|
70902
|
+
const repoConfig = config2.repos.find((r) => r.repo === skill.repo);
|
|
70903
|
+
if (!repoConfig)
|
|
70904
|
+
continue;
|
|
70905
|
+
const downloadResult = await downloadSkillFiles2(token, skill.repo, skill.repoPath, repoConfig.branch, skill.installedPath);
|
|
70906
|
+
if (downloadResult && "authRequired" in downloadResult) {
|
|
70907
|
+
setState({
|
|
70908
|
+
phase: "auth_required",
|
|
70909
|
+
message: downloadResult.message
|
|
70910
|
+
});
|
|
70911
|
+
return;
|
|
70912
|
+
}
|
|
70913
|
+
const updatedSkill = {
|
|
70914
|
+
...skill,
|
|
70915
|
+
commitSha: latestSha
|
|
70916
|
+
};
|
|
70917
|
+
addInstalledSkill(updatedSkill);
|
|
70918
|
+
upgraded.push(skill.name);
|
|
70919
|
+
} catch {}
|
|
70920
|
+
}
|
|
70921
|
+
if (upgraded.length > 0) {
|
|
70922
|
+
setState({ phase: "success", upgraded });
|
|
70923
|
+
} else {
|
|
70924
|
+
setState({ phase: "error", message: "All upgrades failed" });
|
|
70925
|
+
}
|
|
70926
|
+
}, []);
|
|
70927
|
+
const handleSelectConfirm = (selectedValues) => {
|
|
70928
|
+
if (state.phase !== "select")
|
|
70929
|
+
return;
|
|
70930
|
+
if (selectedValues.length === 0) {
|
|
70931
|
+
setState({ phase: "cancelled" });
|
|
70932
|
+
return;
|
|
70933
|
+
}
|
|
70934
|
+
const selectedUpgrades = state.upgrades.filter((u) => selectedValues.includes(u.skill.name));
|
|
70935
|
+
performUpgrades(selectedUpgrades).catch((err) => {
|
|
70936
|
+
setState({
|
|
70937
|
+
phase: "error",
|
|
70938
|
+
message: err instanceof Error ? err.message : "Upgrade failed"
|
|
70939
|
+
});
|
|
70940
|
+
});
|
|
70941
|
+
};
|
|
70942
|
+
const handleSelectCancel = () => {
|
|
70943
|
+
setState({ phase: "cancelled" });
|
|
70944
|
+
};
|
|
71022
70945
|
import_react47.useEffect(() => {
|
|
71023
|
-
async function
|
|
70946
|
+
async function checkUpdates() {
|
|
71024
70947
|
const config2 = getConfig();
|
|
71025
70948
|
let skillsToCheck = [];
|
|
71026
70949
|
if (skillName) {
|
|
@@ -71063,51 +70986,21 @@ function Upgrade({ args: [skillName] }) {
|
|
|
71063
70986
|
setState({ phase: "no_updates" });
|
|
71064
70987
|
return;
|
|
71065
70988
|
}
|
|
71066
|
-
|
|
71067
|
-
|
|
71068
|
-
|
|
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" });
|
|
70989
|
+
if (skillName || options18.yes) {
|
|
70990
|
+
await performUpgrades(upgrades);
|
|
70991
|
+
return;
|
|
71100
70992
|
}
|
|
70993
|
+
setState({ phase: "select", upgrades });
|
|
71101
70994
|
}
|
|
71102
|
-
|
|
70995
|
+
checkUpdates().catch((err) => {
|
|
71103
70996
|
setState({
|
|
71104
70997
|
phase: "error",
|
|
71105
70998
|
message: err instanceof Error ? err.message : "Upgrade failed"
|
|
71106
70999
|
});
|
|
71107
71000
|
});
|
|
71108
|
-
}, [skillName]);
|
|
71001
|
+
}, [skillName, options18.yes, performUpgrades]);
|
|
71109
71002
|
import_react47.useEffect(() => {
|
|
71110
|
-
const isFinalState = state.phase === "not_found" || state.phase === "no_updates" || state.phase === "success" || state.phase === "auth_required" || state.phase === "error";
|
|
71003
|
+
const isFinalState = state.phase === "not_found" || state.phase === "no_updates" || state.phase === "success" || state.phase === "auth_required" || state.phase === "cancelled" || state.phase === "error";
|
|
71111
71004
|
if (isFinalState && outputItems.length === 0) {
|
|
71112
71005
|
setOutputItems([{ id: "output" }]);
|
|
71113
71006
|
}
|
|
@@ -71175,6 +71068,11 @@ function Upgrade({ args: [skillName] }) {
|
|
|
71175
71068
|
}, undefined, false, undefined, this)
|
|
71176
71069
|
]
|
|
71177
71070
|
}, undefined, true, undefined, this);
|
|
71071
|
+
case "cancelled":
|
|
71072
|
+
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(StatusMessage, {
|
|
71073
|
+
type: "info",
|
|
71074
|
+
children: "Upgrade cancelled"
|
|
71075
|
+
}, undefined, false, undefined, this);
|
|
71178
71076
|
case "error":
|
|
71179
71077
|
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(StatusMessage, {
|
|
71180
71078
|
type: "error",
|
|
@@ -71192,6 +71090,32 @@ function Upgrade({ args: [skillName] }) {
|
|
|
71192
71090
|
state.phase === "checking_updates" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Spinner2, {
|
|
71193
71091
|
text: `Checking for updates (${state.current}/${state.total})...`
|
|
71194
71092
|
}, undefined, false, undefined, this),
|
|
71093
|
+
state.phase === "select" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
|
|
71094
|
+
flexDirection: "column",
|
|
71095
|
+
children: [
|
|
71096
|
+
/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
|
|
71097
|
+
marginBottom: 1,
|
|
71098
|
+
children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
|
|
71099
|
+
bold: true,
|
|
71100
|
+
children: [
|
|
71101
|
+
"Found ",
|
|
71102
|
+
state.upgrades.length,
|
|
71103
|
+
" skill(s) with updates available:"
|
|
71104
|
+
]
|
|
71105
|
+
}, undefined, true, undefined, this)
|
|
71106
|
+
}, undefined, false, undefined, this),
|
|
71107
|
+
/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(MultiSelect, {
|
|
71108
|
+
items: state.upgrades.map((u) => ({
|
|
71109
|
+
label: u.skill.name,
|
|
71110
|
+
value: u.skill.name,
|
|
71111
|
+
hint: `${u.currentSha.slice(0, 7)} → ${u.latestSha.slice(0, 7)}`
|
|
71112
|
+
})),
|
|
71113
|
+
initialSelected: state.upgrades.map((u) => u.skill.name),
|
|
71114
|
+
onSubmit: handleSelectConfirm,
|
|
71115
|
+
onCancel: handleSelectCancel
|
|
71116
|
+
}, undefined, false, undefined, this)
|
|
71117
|
+
]
|
|
71118
|
+
}, undefined, true, undefined, this),
|
|
71195
71119
|
state.phase === "upgrading" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
|
|
71196
71120
|
flexDirection: "column",
|
|
71197
71121
|
children: [
|
|
@@ -71225,16 +71149,6 @@ function Upgrade({ args: [skillName] }) {
|
|
|
71225
71149
|
" ",
|
|
71226
71150
|
upgrade.skill.name
|
|
71227
71151
|
]
|
|
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
71152
|
}, undefined, true, undefined, this)
|
|
71239
71153
|
]
|
|
71240
71154
|
}, upgrade.skill.name, true, undefined, this)),
|
|
@@ -71257,10 +71171,553 @@ function Upgrade({ args: [skillName] }) {
|
|
|
71257
71171
|
]
|
|
71258
71172
|
}, undefined, true, undefined, this);
|
|
71259
71173
|
}
|
|
71174
|
+
|
|
71175
|
+
// src/commands/publish.tsx
|
|
71176
|
+
import { readdir, readFile as readFile2 } from "node:fs/promises";
|
|
71177
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
71178
|
+
import { join as join5 } from "node:path";
|
|
71179
|
+
var import_react48 = __toESM(require_react(), 1);
|
|
71180
|
+
var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
|
|
71181
|
+
var args11 = exports_external.tuple([exports_external.string().describe("Skill name to publish")]);
|
|
71182
|
+
var options18 = exports_external.object({});
|
|
71183
|
+
var FINAL_PHASES2 = [
|
|
71184
|
+
"success",
|
|
71185
|
+
"error",
|
|
71186
|
+
"no_default_repo",
|
|
71187
|
+
"skill_not_found",
|
|
71188
|
+
"missing_skill_md",
|
|
71189
|
+
"invalid_frontmatter",
|
|
71190
|
+
"auth_required",
|
|
71191
|
+
"no_write_access",
|
|
71192
|
+
"repo_not_found",
|
|
71193
|
+
"cancelled"
|
|
71194
|
+
];
|
|
71195
|
+
function parseFrontmatter4(content) {
|
|
71196
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
71197
|
+
if (!frontmatterMatch) {
|
|
71198
|
+
return {};
|
|
71199
|
+
}
|
|
71200
|
+
const yaml = frontmatterMatch[1];
|
|
71201
|
+
const result = {};
|
|
71202
|
+
const lines = yaml.split(`
|
|
71203
|
+
`);
|
|
71204
|
+
for (const line of lines) {
|
|
71205
|
+
const colonIndex = line.indexOf(":");
|
|
71206
|
+
if (colonIndex === -1)
|
|
71207
|
+
continue;
|
|
71208
|
+
const key = line.substring(0, colonIndex).trim();
|
|
71209
|
+
let value = line.substring(colonIndex + 1).trim();
|
|
71210
|
+
if (key) {
|
|
71211
|
+
result[key] = value;
|
|
71212
|
+
}
|
|
71213
|
+
}
|
|
71214
|
+
return result;
|
|
71215
|
+
}
|
|
71216
|
+
async function getFilesRecursively(dir) {
|
|
71217
|
+
const files = [];
|
|
71218
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
71219
|
+
for (const entry of entries) {
|
|
71220
|
+
const fullPath = join5(dir, entry.name);
|
|
71221
|
+
if (entry.isDirectory()) {
|
|
71222
|
+
const subFiles = await getFilesRecursively(fullPath);
|
|
71223
|
+
files.push(...subFiles);
|
|
71224
|
+
} else {
|
|
71225
|
+
files.push(fullPath);
|
|
71226
|
+
}
|
|
71227
|
+
}
|
|
71228
|
+
return files;
|
|
71229
|
+
}
|
|
71230
|
+
async function checkSkillExists(token, repo, skillPath, branch) {
|
|
71231
|
+
try {
|
|
71232
|
+
const response = await fetch(`https://api.github.com/repos/${repo}/contents/${skillPath}?ref=${branch}`, { headers: buildGitHubHeaders(token) });
|
|
71233
|
+
return response.ok;
|
|
71234
|
+
} catch {
|
|
71235
|
+
return false;
|
|
71236
|
+
}
|
|
71237
|
+
}
|
|
71238
|
+
async function uploadFile(token, repo, path6, content, branch, existingSha) {
|
|
71239
|
+
const url2 = `https://api.github.com/repos/${repo}/contents/${path6}`;
|
|
71240
|
+
const body = {
|
|
71241
|
+
message: `Add ${path6} via skilluse`,
|
|
71242
|
+
content: Buffer.from(content).toString("base64"),
|
|
71243
|
+
branch
|
|
71244
|
+
};
|
|
71245
|
+
if (existingSha) {
|
|
71246
|
+
body.sha = existingSha;
|
|
71247
|
+
}
|
|
71248
|
+
try {
|
|
71249
|
+
const response = await fetch(url2, {
|
|
71250
|
+
method: "PUT",
|
|
71251
|
+
headers: {
|
|
71252
|
+
...buildGitHubHeaders(token),
|
|
71253
|
+
"Content-Type": "application/json"
|
|
71254
|
+
},
|
|
71255
|
+
body: JSON.stringify(body)
|
|
71256
|
+
});
|
|
71257
|
+
if (response.status === 403 || response.status === 401) {
|
|
71258
|
+
return { success: false, noAccess: true };
|
|
71259
|
+
}
|
|
71260
|
+
if (response.status === 404) {
|
|
71261
|
+
return { success: false, notFound: true };
|
|
71262
|
+
}
|
|
71263
|
+
if (!response.ok) {
|
|
71264
|
+
const data = await response.json();
|
|
71265
|
+
return { success: false, message: data.message || `HTTP ${response.status}` };
|
|
71266
|
+
}
|
|
71267
|
+
return { success: true };
|
|
71268
|
+
} catch (err) {
|
|
71269
|
+
return {
|
|
71270
|
+
success: false,
|
|
71271
|
+
message: err instanceof Error ? err.message : "Upload failed"
|
|
71272
|
+
};
|
|
71273
|
+
}
|
|
71274
|
+
}
|
|
71275
|
+
async function getFileSha(token, repo, path6, branch) {
|
|
71276
|
+
try {
|
|
71277
|
+
const response = await fetch(`https://api.github.com/repos/${repo}/contents/${path6}?ref=${branch}`, { headers: buildGitHubHeaders(token) });
|
|
71278
|
+
if (response.ok) {
|
|
71279
|
+
const data = await response.json();
|
|
71280
|
+
return data.sha;
|
|
71281
|
+
}
|
|
71282
|
+
} catch {}
|
|
71283
|
+
return;
|
|
71284
|
+
}
|
|
71285
|
+
function OverwritePrompt({
|
|
71286
|
+
skillName,
|
|
71287
|
+
repo,
|
|
71288
|
+
onConfirm,
|
|
71289
|
+
onCancel
|
|
71290
|
+
}) {
|
|
71291
|
+
use_input_default((input, key) => {
|
|
71292
|
+
if (input.toLowerCase() === "y" || key.return) {
|
|
71293
|
+
onConfirm();
|
|
71294
|
+
} else if (input.toLowerCase() === "n" || key.escape) {
|
|
71295
|
+
onCancel();
|
|
71296
|
+
}
|
|
71297
|
+
});
|
|
71298
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71299
|
+
flexDirection: "column",
|
|
71300
|
+
borderStyle: "round",
|
|
71301
|
+
paddingX: 1,
|
|
71302
|
+
children: [
|
|
71303
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71304
|
+
marginBottom: 1,
|
|
71305
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71306
|
+
color: "yellow",
|
|
71307
|
+
bold: true,
|
|
71308
|
+
children: "Skill Already Exists"
|
|
71309
|
+
}, undefined, false, undefined, this)
|
|
71310
|
+
}, undefined, false, undefined, this),
|
|
71311
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71312
|
+
flexDirection: "column",
|
|
71313
|
+
marginBottom: 1,
|
|
71314
|
+
children: [
|
|
71315
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71316
|
+
children: [
|
|
71317
|
+
"Skill",
|
|
71318
|
+
" ",
|
|
71319
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71320
|
+
color: "cyan",
|
|
71321
|
+
bold: true,
|
|
71322
|
+
children: skillName
|
|
71323
|
+
}, undefined, false, undefined, this),
|
|
71324
|
+
" ",
|
|
71325
|
+
"already exists in repository:"
|
|
71326
|
+
]
|
|
71327
|
+
}, undefined, true, undefined, this),
|
|
71328
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71329
|
+
marginLeft: 2,
|
|
71330
|
+
marginTop: 1,
|
|
71331
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71332
|
+
dimColor: true,
|
|
71333
|
+
children: repo
|
|
71334
|
+
}, undefined, false, undefined, this)
|
|
71335
|
+
}, undefined, false, undefined, this)
|
|
71336
|
+
]
|
|
71337
|
+
}, undefined, true, undefined, this),
|
|
71338
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71339
|
+
children: [
|
|
71340
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71341
|
+
dimColor: true,
|
|
71342
|
+
children: "Press "
|
|
71343
|
+
}, undefined, false, undefined, this),
|
|
71344
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71345
|
+
color: "green",
|
|
71346
|
+
children: "Y"
|
|
71347
|
+
}, undefined, false, undefined, this),
|
|
71348
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71349
|
+
dimColor: true,
|
|
71350
|
+
children: " to overwrite, "
|
|
71351
|
+
}, undefined, false, undefined, this),
|
|
71352
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71353
|
+
color: "red",
|
|
71354
|
+
children: "N"
|
|
71355
|
+
}, undefined, false, undefined, this),
|
|
71356
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71357
|
+
dimColor: true,
|
|
71358
|
+
children: " to cancel"
|
|
71359
|
+
}, undefined, false, undefined, this)
|
|
71360
|
+
]
|
|
71361
|
+
}, undefined, true, undefined, this)
|
|
71362
|
+
]
|
|
71363
|
+
}, undefined, true, undefined, this);
|
|
71364
|
+
}
|
|
71365
|
+
function Publish({ args: [skillName] }) {
|
|
71366
|
+
const { exit } = use_app_default();
|
|
71367
|
+
const [state, setState] = import_react48.useState({ phase: "checking" });
|
|
71368
|
+
const [outputItems, setOutputItems] = import_react48.useState([]);
|
|
71369
|
+
const [publishContext, setPublishContext] = import_react48.useState(null);
|
|
71370
|
+
import_react48.useEffect(() => {
|
|
71371
|
+
async function validate2() {
|
|
71372
|
+
const credentials = await getCredentials();
|
|
71373
|
+
if (!credentials?.token) {
|
|
71374
|
+
setState({ phase: "auth_required" });
|
|
71375
|
+
return;
|
|
71376
|
+
}
|
|
71377
|
+
const config2 = getConfig();
|
|
71378
|
+
if (!config2.defaultRepo) {
|
|
71379
|
+
setState({ phase: "no_default_repo" });
|
|
71380
|
+
return;
|
|
71381
|
+
}
|
|
71382
|
+
const repoConfig = config2.repos.find((r) => r.repo === config2.defaultRepo);
|
|
71383
|
+
if (!repoConfig) {
|
|
71384
|
+
setState({ phase: "no_default_repo" });
|
|
71385
|
+
return;
|
|
71386
|
+
}
|
|
71387
|
+
const agentId = getCurrentAgent();
|
|
71388
|
+
const agent = getAgent(agentId);
|
|
71389
|
+
if (!agent) {
|
|
71390
|
+
setState({ phase: "error", message: `Unknown agent: ${agentId}` });
|
|
71391
|
+
return;
|
|
71392
|
+
}
|
|
71393
|
+
const skillsDir = getSkillsPath(agentId, "local");
|
|
71394
|
+
const skillPath = join5(skillsDir, skillName);
|
|
71395
|
+
if (!existsSync4(skillPath)) {
|
|
71396
|
+
setState({
|
|
71397
|
+
phase: "skill_not_found",
|
|
71398
|
+
skillName,
|
|
71399
|
+
searchPath: skillsDir
|
|
71400
|
+
});
|
|
71401
|
+
return;
|
|
71402
|
+
}
|
|
71403
|
+
const skillMdPath = join5(skillPath, "SKILL.md");
|
|
71404
|
+
if (!existsSync4(skillMdPath)) {
|
|
71405
|
+
setState({ phase: "missing_skill_md", skillPath });
|
|
71406
|
+
return;
|
|
71407
|
+
}
|
|
71408
|
+
const skillMdContent = await readFile2(skillMdPath, "utf-8");
|
|
71409
|
+
const frontmatter = parseFrontmatter4(skillMdContent);
|
|
71410
|
+
if (!frontmatter.name) {
|
|
71411
|
+
setState({ phase: "invalid_frontmatter", field: "name" });
|
|
71412
|
+
return;
|
|
71413
|
+
}
|
|
71414
|
+
if (!frontmatter.description) {
|
|
71415
|
+
setState({ phase: "invalid_frontmatter", field: "description" });
|
|
71416
|
+
return;
|
|
71417
|
+
}
|
|
71418
|
+
setPublishContext({
|
|
71419
|
+
skillPath,
|
|
71420
|
+
repoConfig,
|
|
71421
|
+
token: credentials.token
|
|
71422
|
+
});
|
|
71423
|
+
const basePath = repoConfig.paths.length > 0 ? repoConfig.paths[0] : "";
|
|
71424
|
+
const targetPath = basePath && basePath !== "." ? `${basePath}/${skillName}` : skillName;
|
|
71425
|
+
const exists = await checkSkillExists(credentials.token, repoConfig.repo, targetPath, repoConfig.branch);
|
|
71426
|
+
if (exists) {
|
|
71427
|
+
setState({
|
|
71428
|
+
phase: "exists_prompt",
|
|
71429
|
+
skillName,
|
|
71430
|
+
repo: repoConfig.repo,
|
|
71431
|
+
path: targetPath
|
|
71432
|
+
});
|
|
71433
|
+
return;
|
|
71434
|
+
}
|
|
71435
|
+
await performUpload(skillPath, repoConfig, credentials.token, skillName, targetPath);
|
|
71436
|
+
}
|
|
71437
|
+
validate2().catch((err) => {
|
|
71438
|
+
setState({
|
|
71439
|
+
phase: "error",
|
|
71440
|
+
message: err instanceof Error ? err.message : "Publish failed"
|
|
71441
|
+
});
|
|
71442
|
+
});
|
|
71443
|
+
}, [skillName]);
|
|
71444
|
+
async function performUpload(skillPath, repoConfig, token, skillName2, targetPath) {
|
|
71445
|
+
setState({
|
|
71446
|
+
phase: "uploading",
|
|
71447
|
+
skillName: skillName2,
|
|
71448
|
+
progress: 0,
|
|
71449
|
+
currentFile: "Reading files..."
|
|
71450
|
+
});
|
|
71451
|
+
try {
|
|
71452
|
+
const files = await getFilesRecursively(skillPath);
|
|
71453
|
+
if (files.length === 0) {
|
|
71454
|
+
setState({ phase: "error", message: "No files found in skill directory" });
|
|
71455
|
+
return;
|
|
71456
|
+
}
|
|
71457
|
+
for (let i = 0;i < files.length; i++) {
|
|
71458
|
+
const file2 = files[i];
|
|
71459
|
+
const relativePath = file2.substring(skillPath.length + 1);
|
|
71460
|
+
const remotePath = `${targetPath}/${relativePath}`;
|
|
71461
|
+
setState({
|
|
71462
|
+
phase: "uploading",
|
|
71463
|
+
skillName: skillName2,
|
|
71464
|
+
progress: Math.round((i + 1) / files.length * 100),
|
|
71465
|
+
currentFile: relativePath
|
|
71466
|
+
});
|
|
71467
|
+
const content = await readFile2(file2, "utf-8");
|
|
71468
|
+
const existingSha = await getFileSha(token, repoConfig.repo, remotePath, repoConfig.branch);
|
|
71469
|
+
const result = await uploadFile(token, repoConfig.repo, remotePath, content, repoConfig.branch, existingSha);
|
|
71470
|
+
if (result.noAccess) {
|
|
71471
|
+
setState({ phase: "no_write_access", repo: repoConfig.repo });
|
|
71472
|
+
return;
|
|
71473
|
+
}
|
|
71474
|
+
if (result.notFound) {
|
|
71475
|
+
setState({ phase: "repo_not_found", repo: repoConfig.repo });
|
|
71476
|
+
return;
|
|
71477
|
+
}
|
|
71478
|
+
if (!result.success) {
|
|
71479
|
+
setState({
|
|
71480
|
+
phase: "error",
|
|
71481
|
+
message: result.message || `Failed to upload ${relativePath}`
|
|
71482
|
+
});
|
|
71483
|
+
return;
|
|
71484
|
+
}
|
|
71485
|
+
}
|
|
71486
|
+
const githubUrl = `https://github.com/${repoConfig.repo}/tree/${repoConfig.branch}/${targetPath}`;
|
|
71487
|
+
setState({ phase: "success", skillName: skillName2, githubUrl });
|
|
71488
|
+
} catch (err) {
|
|
71489
|
+
setState({
|
|
71490
|
+
phase: "error",
|
|
71491
|
+
message: err instanceof Error ? err.message : "Upload failed"
|
|
71492
|
+
});
|
|
71493
|
+
}
|
|
71494
|
+
}
|
|
71495
|
+
function handleConfirmOverwrite() {
|
|
71496
|
+
if (!publishContext)
|
|
71497
|
+
return;
|
|
71498
|
+
const { skillPath, repoConfig, token } = publishContext;
|
|
71499
|
+
const basePath = repoConfig.paths.length > 0 ? repoConfig.paths[0] : "";
|
|
71500
|
+
const targetPath = basePath && basePath !== "." ? `${basePath}/${skillName}` : skillName;
|
|
71501
|
+
performUpload(skillPath, repoConfig, token, skillName, targetPath);
|
|
71502
|
+
}
|
|
71503
|
+
function handleCancelOverwrite() {
|
|
71504
|
+
setState({ phase: "cancelled" });
|
|
71505
|
+
}
|
|
71506
|
+
import_react48.useEffect(() => {
|
|
71507
|
+
if (FINAL_PHASES2.includes(state.phase) && outputItems.length === 0) {
|
|
71508
|
+
setOutputItems([{ id: "output" }]);
|
|
71509
|
+
}
|
|
71510
|
+
}, [state.phase, outputItems.length]);
|
|
71511
|
+
import_react48.useEffect(() => {
|
|
71512
|
+
if (outputItems.length > 0) {
|
|
71513
|
+
process.nextTick(() => exit());
|
|
71514
|
+
}
|
|
71515
|
+
}, [outputItems.length, exit]);
|
|
71516
|
+
if (state.phase === "checking") {
|
|
71517
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Spinner2, {
|
|
71518
|
+
text: "Validating skill..."
|
|
71519
|
+
}, undefined, false, undefined, this);
|
|
71520
|
+
}
|
|
71521
|
+
if (state.phase === "uploading") {
|
|
71522
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71523
|
+
flexDirection: "column",
|
|
71524
|
+
children: [
|
|
71525
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71526
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Spinner2, {
|
|
71527
|
+
text: `Publishing ${state.skillName}... ${state.progress}%`
|
|
71528
|
+
}, undefined, false, undefined, this)
|
|
71529
|
+
}, undefined, false, undefined, this),
|
|
71530
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71531
|
+
marginLeft: 2,
|
|
71532
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71533
|
+
dimColor: true,
|
|
71534
|
+
children: [
|
|
71535
|
+
"Uploading: ",
|
|
71536
|
+
state.currentFile
|
|
71537
|
+
]
|
|
71538
|
+
}, undefined, true, undefined, this)
|
|
71539
|
+
}, undefined, false, undefined, this)
|
|
71540
|
+
]
|
|
71541
|
+
}, undefined, true, undefined, this);
|
|
71542
|
+
}
|
|
71543
|
+
if (state.phase === "exists_prompt") {
|
|
71544
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(OverwritePrompt, {
|
|
71545
|
+
skillName: state.skillName,
|
|
71546
|
+
repo: state.repo,
|
|
71547
|
+
onConfirm: handleConfirmOverwrite,
|
|
71548
|
+
onCancel: handleCancelOverwrite
|
|
71549
|
+
}, undefined, false, undefined, this);
|
|
71550
|
+
}
|
|
71551
|
+
const renderFinalContent = () => {
|
|
71552
|
+
switch (state.phase) {
|
|
71553
|
+
case "no_default_repo":
|
|
71554
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
|
|
71555
|
+
children: [
|
|
71556
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71557
|
+
type: "error",
|
|
71558
|
+
children: "No default repo configured"
|
|
71559
|
+
}, undefined, false, undefined, this),
|
|
71560
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71561
|
+
marginTop: 1,
|
|
71562
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71563
|
+
dimColor: true,
|
|
71564
|
+
children: [
|
|
71565
|
+
"Run 'skilluse repo use ",
|
|
71566
|
+
"<owner/repo>",
|
|
71567
|
+
" to set a default repository."
|
|
71568
|
+
]
|
|
71569
|
+
}, undefined, true, undefined, this)
|
|
71570
|
+
}, undefined, false, undefined, this)
|
|
71571
|
+
]
|
|
71572
|
+
}, undefined, true, undefined, this);
|
|
71573
|
+
case "skill_not_found":
|
|
71574
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
|
|
71575
|
+
children: [
|
|
71576
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71577
|
+
type: "error",
|
|
71578
|
+
children: [
|
|
71579
|
+
"Skill '",
|
|
71580
|
+
state.skillName,
|
|
71581
|
+
"' not found"
|
|
71582
|
+
]
|
|
71583
|
+
}, undefined, true, undefined, this),
|
|
71584
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71585
|
+
marginTop: 1,
|
|
71586
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71587
|
+
dimColor: true,
|
|
71588
|
+
children: [
|
|
71589
|
+
"Searched in: ",
|
|
71590
|
+
state.searchPath
|
|
71591
|
+
]
|
|
71592
|
+
}, undefined, true, undefined, this)
|
|
71593
|
+
}, undefined, false, undefined, this)
|
|
71594
|
+
]
|
|
71595
|
+
}, undefined, true, undefined, this);
|
|
71596
|
+
case "missing_skill_md":
|
|
71597
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
|
|
71598
|
+
children: [
|
|
71599
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71600
|
+
type: "error",
|
|
71601
|
+
children: "SKILL.md not found in skill directory"
|
|
71602
|
+
}, undefined, false, undefined, this),
|
|
71603
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71604
|
+
marginTop: 1,
|
|
71605
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71606
|
+
dimColor: true,
|
|
71607
|
+
children: [
|
|
71608
|
+
"Expected at: ",
|
|
71609
|
+
state.skillPath,
|
|
71610
|
+
"/SKILL.md"
|
|
71611
|
+
]
|
|
71612
|
+
}, undefined, true, undefined, this)
|
|
71613
|
+
}, undefined, false, undefined, this)
|
|
71614
|
+
]
|
|
71615
|
+
}, undefined, true, undefined, this);
|
|
71616
|
+
case "invalid_frontmatter":
|
|
71617
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71618
|
+
type: "error",
|
|
71619
|
+
children: [
|
|
71620
|
+
"SKILL.md missing required field: ",
|
|
71621
|
+
state.field
|
|
71622
|
+
]
|
|
71623
|
+
}, undefined, true, undefined, this);
|
|
71624
|
+
case "auth_required":
|
|
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: "Authentication required"
|
|
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: "Run 'skilluse login' to authenticate."
|
|
71636
|
+
}, undefined, false, undefined, this)
|
|
71637
|
+
}, undefined, false, undefined, this)
|
|
71638
|
+
]
|
|
71639
|
+
}, undefined, true, undefined, this);
|
|
71640
|
+
case "no_write_access":
|
|
71641
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71642
|
+
type: "error",
|
|
71643
|
+
children: [
|
|
71644
|
+
"No write access to repo: ",
|
|
71645
|
+
state.repo
|
|
71646
|
+
]
|
|
71647
|
+
}, undefined, true, undefined, this);
|
|
71648
|
+
case "repo_not_found":
|
|
71649
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
|
|
71650
|
+
children: [
|
|
71651
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71652
|
+
type: "error",
|
|
71653
|
+
children: [
|
|
71654
|
+
"Repository not found: ",
|
|
71655
|
+
state.repo
|
|
71656
|
+
]
|
|
71657
|
+
}, undefined, true, undefined, this),
|
|
71658
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71659
|
+
marginTop: 1,
|
|
71660
|
+
children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71661
|
+
dimColor: true,
|
|
71662
|
+
children: "Check that the repository exists and you have access to it."
|
|
71663
|
+
}, undefined, false, undefined, this)
|
|
71664
|
+
}, undefined, false, undefined, this)
|
|
71665
|
+
]
|
|
71666
|
+
}, undefined, true, undefined, this);
|
|
71667
|
+
case "success":
|
|
71668
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(jsx_dev_runtime25.Fragment, {
|
|
71669
|
+
children: [
|
|
71670
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71671
|
+
type: "success",
|
|
71672
|
+
children: [
|
|
71673
|
+
"Published '",
|
|
71674
|
+
state.skillName,
|
|
71675
|
+
"'"
|
|
71676
|
+
]
|
|
71677
|
+
}, undefined, true, undefined, this),
|
|
71678
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71679
|
+
marginTop: 1,
|
|
71680
|
+
marginLeft: 2,
|
|
71681
|
+
children: [
|
|
71682
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71683
|
+
dimColor: true,
|
|
71684
|
+
children: "View at: "
|
|
71685
|
+
}, undefined, false, undefined, this),
|
|
71686
|
+
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
|
|
71687
|
+
color: "blue",
|
|
71688
|
+
underline: true,
|
|
71689
|
+
children: state.githubUrl
|
|
71690
|
+
}, undefined, false, undefined, this)
|
|
71691
|
+
]
|
|
71692
|
+
}, undefined, true, undefined, this)
|
|
71693
|
+
]
|
|
71694
|
+
}, undefined, true, undefined, this);
|
|
71695
|
+
case "cancelled":
|
|
71696
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71697
|
+
type: "warning",
|
|
71698
|
+
children: "Publish cancelled"
|
|
71699
|
+
}, undefined, false, undefined, this);
|
|
71700
|
+
case "error":
|
|
71701
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusMessage, {
|
|
71702
|
+
type: "error",
|
|
71703
|
+
children: state.message
|
|
71704
|
+
}, undefined, false, undefined, this);
|
|
71705
|
+
default:
|
|
71706
|
+
return null;
|
|
71707
|
+
}
|
|
71708
|
+
};
|
|
71709
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Static, {
|
|
71710
|
+
items: outputItems,
|
|
71711
|
+
children: (item) => /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
|
|
71712
|
+
flexDirection: "column",
|
|
71713
|
+
children: renderFinalContent()
|
|
71714
|
+
}, item.id, false, undefined, this)
|
|
71715
|
+
}, undefined, false, undefined, this);
|
|
71716
|
+
}
|
|
71260
71717
|
// package.json
|
|
71261
71718
|
var package_default = {
|
|
71262
71719
|
name: "skilluse",
|
|
71263
|
-
version: "0.
|
|
71720
|
+
version: "0.8.0",
|
|
71264
71721
|
description: "CLI tool for managing and installing AI Coding Agent Skills",
|
|
71265
71722
|
main: "dist/cli.js",
|
|
71266
71723
|
bin: {
|
|
@@ -71287,7 +71744,6 @@ var package_default = {
|
|
|
71287
71744
|
dev: "bun --watch src/index.tsx",
|
|
71288
71745
|
build: `bun build src/cli.tsx --outdir dist --target node --define 'process.env.DEV="false"'`,
|
|
71289
71746
|
"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
71747
|
typecheck: "tsc --noEmit",
|
|
71292
71748
|
format: "biome format --write .",
|
|
71293
71749
|
lint: "biome lint .",
|
|
@@ -71330,7 +71786,7 @@ var package_default = {
|
|
|
71330
71786
|
};
|
|
71331
71787
|
|
|
71332
71788
|
// src/cli.tsx
|
|
71333
|
-
var
|
|
71789
|
+
var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
|
|
71334
71790
|
var VERSION = process.env.VERSION || package_default.version;
|
|
71335
71791
|
var BUILD_TIME = process.env.BUILD_TIME || new Date().toISOString();
|
|
71336
71792
|
var program2 = new Command;
|
|
@@ -71340,115 +71796,122 @@ program2.name("skilluse").description("CLI tool for managing and installing AI C
|
|
|
71340
71796
|
process.exit(0);
|
|
71341
71797
|
});
|
|
71342
71798
|
program2.command("login").description("Authenticate with GitHub").action(() => {
|
|
71343
|
-
render_default(/* @__PURE__ */
|
|
71799
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Login, {
|
|
71344
71800
|
options: {}
|
|
71345
71801
|
}, undefined, false, undefined, this));
|
|
71346
71802
|
});
|
|
71347
71803
|
program2.command("logout").description("Clear stored credentials").action(() => {
|
|
71348
|
-
render_default(/* @__PURE__ */
|
|
71804
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Logout, {
|
|
71349
71805
|
options: {}
|
|
71350
71806
|
}, undefined, false, undefined, this));
|
|
71351
71807
|
});
|
|
71352
71808
|
program2.command("list").description("List installed skills").option("-o, --outdated", "Show only outdated skills").action((opts) => {
|
|
71353
|
-
const
|
|
71354
|
-
render_default(/* @__PURE__ */
|
|
71355
|
-
options:
|
|
71809
|
+
const options19 = options4.parse(opts);
|
|
71810
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(List, {
|
|
71811
|
+
options: options19
|
|
71356
71812
|
}, undefined, false, undefined, this));
|
|
71357
71813
|
});
|
|
71358
|
-
program2.command("search <keyword>").description("Search for skills
|
|
71359
|
-
const
|
|
71360
|
-
|
|
71361
|
-
|
|
71362
|
-
|
|
71363
|
-
options: options18
|
|
71814
|
+
program2.command("search <keyword>").description("Search for skills in default repository").action((keyword) => {
|
|
71815
|
+
const args12 = args8.parse([keyword]);
|
|
71816
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Search, {
|
|
71817
|
+
args: args12,
|
|
71818
|
+
options: {}
|
|
71364
71819
|
}, undefined, false, undefined, this));
|
|
71365
71820
|
});
|
|
71366
71821
|
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
|
|
71368
|
-
const
|
|
71369
|
-
render_default(/* @__PURE__ */
|
|
71370
|
-
args:
|
|
71371
|
-
options:
|
|
71822
|
+
const args12 = args2.parse([skillName]);
|
|
71823
|
+
const options19 = options3.parse(opts);
|
|
71824
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Install, {
|
|
71825
|
+
args: args12,
|
|
71826
|
+
options: options19
|
|
71372
71827
|
}, undefined, false, undefined, this));
|
|
71373
71828
|
});
|
|
71374
71829
|
program2.command("uninstall <skill-name>").description("Uninstall a skill").option("-f, --force", "Skip confirmation").action((skillName, opts) => {
|
|
71375
|
-
const
|
|
71376
|
-
const
|
|
71377
|
-
render_default(/* @__PURE__ */
|
|
71378
|
-
args:
|
|
71379
|
-
options:
|
|
71830
|
+
const args12 = args9.parse([skillName]);
|
|
71831
|
+
const options19 = options16.parse(opts);
|
|
71832
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Uninstall, {
|
|
71833
|
+
args: args12,
|
|
71834
|
+
options: options19
|
|
71380
71835
|
}, undefined, false, undefined, this));
|
|
71381
71836
|
});
|
|
71382
|
-
program2.command("upgrade [skill-name]").description("Upgrade skill(s) to latest version").action((skillName) => {
|
|
71383
|
-
const
|
|
71384
|
-
|
|
71385
|
-
|
|
71386
|
-
|
|
71837
|
+
program2.command("upgrade [skill-name]").description("Upgrade skill(s) to latest version").option("-y, --yes", "Skip selection and upgrade all").action((skillName, opts) => {
|
|
71838
|
+
const args12 = args10.parse([skillName]);
|
|
71839
|
+
const options19 = options17.parse(opts);
|
|
71840
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Upgrade, {
|
|
71841
|
+
args: args12,
|
|
71842
|
+
options: options19
|
|
71387
71843
|
}, undefined, false, undefined, this));
|
|
71388
71844
|
});
|
|
71389
71845
|
program2.command("info <skill-name>").description("Show skill details").action((skillName) => {
|
|
71390
|
-
const
|
|
71391
|
-
render_default(/* @__PURE__ */
|
|
71392
|
-
args:
|
|
71846
|
+
const args12 = args.parse([skillName]);
|
|
71847
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Info, {
|
|
71848
|
+
args: args12,
|
|
71849
|
+
options: {}
|
|
71850
|
+
}, undefined, false, undefined, this));
|
|
71851
|
+
});
|
|
71852
|
+
program2.command("publish <skill-name>").description("Publish a local skill to the default repository").action((skillName) => {
|
|
71853
|
+
const args12 = args11.parse([skillName]);
|
|
71854
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Publish, {
|
|
71855
|
+
args: args12,
|
|
71393
71856
|
options: {}
|
|
71394
71857
|
}, undefined, false, undefined, this));
|
|
71395
71858
|
});
|
|
71396
71859
|
var repoCmd = program2.command("repo").description("Manage skill repositories");
|
|
71397
71860
|
repoCmd.command("list").description("List configured repositories").action(() => {
|
|
71398
|
-
render_default(/* @__PURE__ */
|
|
71861
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoList, {
|
|
71399
71862
|
options: {}
|
|
71400
71863
|
}, undefined, false, undefined, this));
|
|
71401
71864
|
});
|
|
71402
71865
|
repoCmd.command("skills").description("List all skills in current repository").action(() => {
|
|
71403
|
-
render_default(/* @__PURE__ */
|
|
71866
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoSkills, {
|
|
71404
71867
|
options: {}
|
|
71405
71868
|
}, undefined, false, undefined, this));
|
|
71406
71869
|
});
|
|
71407
71870
|
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
|
|
71409
|
-
const
|
|
71410
|
-
render_default(/* @__PURE__ */
|
|
71411
|
-
args:
|
|
71412
|
-
options:
|
|
71871
|
+
const args12 = args3.parse([url2]);
|
|
71872
|
+
const options19 = options7.parse(opts);
|
|
71873
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoAdd, {
|
|
71874
|
+
args: args12,
|
|
71875
|
+
options: options19
|
|
71413
71876
|
}, undefined, false, undefined, this));
|
|
71414
71877
|
});
|
|
71415
71878
|
repoCmd.command("remove <name>").description("Remove a repository").option("-f, --force", "Skip confirmation").action((name, opts) => {
|
|
71416
|
-
const
|
|
71417
|
-
const
|
|
71418
|
-
render_default(/* @__PURE__ */
|
|
71419
|
-
args:
|
|
71420
|
-
options:
|
|
71879
|
+
const args12 = args5.parse([name]);
|
|
71880
|
+
const options19 = options12.parse(opts);
|
|
71881
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoRemove, {
|
|
71882
|
+
args: args12,
|
|
71883
|
+
options: options19
|
|
71421
71884
|
}, undefined, false, undefined, this));
|
|
71422
71885
|
});
|
|
71423
71886
|
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
|
|
71425
|
-
const
|
|
71426
|
-
render_default(/* @__PURE__ */
|
|
71427
|
-
args:
|
|
71428
|
-
options:
|
|
71887
|
+
const args12 = args4.parse([name]);
|
|
71888
|
+
const options19 = options8.parse(opts);
|
|
71889
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoEdit, {
|
|
71890
|
+
args: args12,
|
|
71891
|
+
options: options19
|
|
71429
71892
|
}, undefined, false, undefined, this));
|
|
71430
71893
|
});
|
|
71431
71894
|
repoCmd.command("use <name>").description("Set default repository").action((name, _opts) => {
|
|
71432
|
-
const
|
|
71433
|
-
render_default(/* @__PURE__ */
|
|
71434
|
-
args:
|
|
71895
|
+
const args12 = args6.parse([name]);
|
|
71896
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(RepoUse, {
|
|
71897
|
+
args: args12,
|
|
71435
71898
|
options: {}
|
|
71436
71899
|
}, undefined, false, undefined, this));
|
|
71437
71900
|
});
|
|
71438
71901
|
repoCmd.action(() => {
|
|
71439
|
-
render_default(/* @__PURE__ */
|
|
71902
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Repo, {
|
|
71440
71903
|
options: {}
|
|
71441
71904
|
}, undefined, false, undefined, this));
|
|
71442
71905
|
});
|
|
71443
71906
|
program2.command("agent [agent-id]").description("Switch agent or select interactively").action((agentId) => {
|
|
71444
|
-
const
|
|
71445
|
-
render_default(/* @__PURE__ */
|
|
71446
|
-
args:
|
|
71907
|
+
const args12 = args7.parse([agentId]);
|
|
71908
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Agent, {
|
|
71909
|
+
args: args12,
|
|
71447
71910
|
options: {}
|
|
71448
71911
|
}, undefined, false, undefined, this));
|
|
71449
71912
|
});
|
|
71450
71913
|
program2.action(() => {
|
|
71451
|
-
render_default(/* @__PURE__ */
|
|
71914
|
+
render_default(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Index, {
|
|
71452
71915
|
options: {}
|
|
71453
71916
|
}, undefined, false, undefined, this));
|
|
71454
71917
|
});
|