skillfish 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/installer.d.ts +1 -1
- package/dist/lib/installer.js +16 -17
- package/package.json +2 -2
package/dist/lib/installer.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export interface InstallResult {
|
|
|
21
21
|
export interface InstallOptions {
|
|
22
22
|
force: boolean;
|
|
23
23
|
baseDir: string;
|
|
24
|
-
/** Branch to clone from. If not specified,
|
|
24
|
+
/** Branch to clone from. If not specified, giget will use the repository's default branch. */
|
|
25
25
|
branch?: string;
|
|
26
26
|
}
|
|
27
27
|
export interface CopyResult {
|
package/dist/lib/installer.js
CHANGED
|
@@ -6,18 +6,18 @@ import { existsSync, mkdirSync, cpSync, rmSync, lstatSync, readdirSync, } from '
|
|
|
6
6
|
import { homedir } from 'os';
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
import { randomUUID } from 'crypto';
|
|
9
|
-
import
|
|
9
|
+
import { downloadTemplate } from 'giget';
|
|
10
10
|
import { SKILL_FILENAME } from './github.js';
|
|
11
11
|
/**
|
|
12
|
-
* Validates a branch name for safe use in
|
|
12
|
+
* Validates a branch name for safe use in giget source strings.
|
|
13
13
|
* Git branch names can contain alphanumerics, dots, hyphens, underscores, and slashes.
|
|
14
|
-
* We explicitly reject '#' which is used as a delimiter in
|
|
14
|
+
* We explicitly reject '#' which is used as a delimiter in giget syntax.
|
|
15
15
|
*/
|
|
16
16
|
function isValidBranchName(branch) {
|
|
17
17
|
if (!branch || branch.length > 255)
|
|
18
18
|
return false;
|
|
19
19
|
// Allow alphanumerics, dots, hyphens, underscores, and slashes (for feature branches)
|
|
20
|
-
// Reject anything else, especially '#' which would break
|
|
20
|
+
// Reject anything else, especially '#' which would break giget parsing
|
|
21
21
|
return /^[\w./-]+$/.test(branch) && !branch.includes('#');
|
|
22
22
|
}
|
|
23
23
|
// === Error Types ===
|
|
@@ -102,20 +102,24 @@ export async function installSkill(owner, repo, skillPath, skillName, agents, op
|
|
|
102
102
|
const tmpDir = join(homedir(), '.cache', 'skillfish', `${owner}-${repo}-${randomUUID()}`);
|
|
103
103
|
mkdirSync(tmpDir, { recursive: true, mode: 0o700 });
|
|
104
104
|
try {
|
|
105
|
-
// Download skill
|
|
106
|
-
// Build
|
|
105
|
+
// Download skill using giget (tarball-based, works reliably on all repo sizes)
|
|
106
|
+
// Build giget source: github:owner/repo[/subpath][#branch]
|
|
107
107
|
const downloadPath = skillPath === SKILL_FILENAME ? '' : skillPath;
|
|
108
|
-
let
|
|
108
|
+
let source = downloadPath
|
|
109
|
+
? `github:${owner}/${repo}/${downloadPath}`
|
|
110
|
+
: `github:${owner}/${repo}`;
|
|
109
111
|
// Append branch if specified (critical for repos with non-standard default branches like 'canary')
|
|
110
112
|
// Validate branch name to prevent injection attacks via malformed branch names
|
|
111
113
|
if (branch) {
|
|
112
114
|
if (!isValidBranchName(branch)) {
|
|
113
115
|
throw new Error(`Invalid branch name: ${branch}`);
|
|
114
116
|
}
|
|
115
|
-
|
|
117
|
+
source = `${source}#${branch}`;
|
|
116
118
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
await downloadTemplate(source, {
|
|
120
|
+
dir: tmpDir,
|
|
121
|
+
forceClean: true,
|
|
122
|
+
});
|
|
119
123
|
// Validate download
|
|
120
124
|
const skillMdPath = join(tmpDir, SKILL_FILENAME);
|
|
121
125
|
if (!existsSync(skillMdPath)) {
|
|
@@ -154,13 +158,8 @@ export async function installSkill(owner, repo, skillPath, skillName, agents, op
|
|
|
154
158
|
}
|
|
155
159
|
else {
|
|
156
160
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
157
|
-
// Provide more helpful error messages for common
|
|
158
|
-
|
|
159
|
-
if (errMsg.includes('could not find commit hash')) {
|
|
160
|
-
const branchInfo = branch ? ` (branch: ${branch})` : '';
|
|
161
|
-
result.failureReason = `Could not clone repository. The branch or path may not exist, or there may be a network issue. Tried: ${owner}/${repo}${skillPath !== SKILL_FILENAME ? `/${skillPath}` : ''}${branchInfo}`;
|
|
162
|
-
}
|
|
163
|
-
else if (errMsg.includes('404')) {
|
|
161
|
+
// Provide more helpful error messages for common failures
|
|
162
|
+
if (errMsg.includes('404') || errMsg.includes('Not Found')) {
|
|
164
163
|
result.failureReason = `Repository or path not found: ${owner}/${repo}${skillPath !== SKILL_FILENAME ? `/${skillPath}` : ''}`;
|
|
165
164
|
}
|
|
166
165
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillfish",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Install AI agent skills from GitHub with a single command",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@clack/prompts": "^0.11.0",
|
|
59
59
|
"commander": "^14.0.2",
|
|
60
|
-
"
|
|
60
|
+
"giget": "^3.1.1",
|
|
61
61
|
"picocolors": "^1.1.1"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|