vskill 1.1.1 → 1.2.1
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 +12 -3
- package/agents.json +1 -1
- package/dist/api/client.d.ts +1 -1
- package/dist/api/client.js +14 -7
- package/dist/api/client.js.map +1 -1
- package/dist/blocklist/blocklist.d.ts +12 -0
- package/dist/blocklist/blocklist.js +19 -0
- package/dist/blocklist/blocklist.js.map +1 -1
- package/dist/commands/add.js +98 -49
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.js +38 -2
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/diff.js +8 -0
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/info.js +7 -0
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/outdated.js +29 -4
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/pin.js +7 -2
- package/dist/commands/pin.js.map +1 -1
- package/dist/commands/submit.js +8 -0
- package/dist/commands/submit.js.map +1 -1
- package/dist/commands/update.js +14 -3
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/versions.js +11 -0
- package/dist/commands/versions.js.map +1 -1
- package/dist/discovery/github-tree.js +20 -1
- package/dist/discovery/github-tree.js.map +1 -1
- package/dist/eval-server/api-routes.js +33 -2
- package/dist/eval-server/api-routes.js.map +1 -1
- package/dist/eval-server/install-skill-routes.d.ts +2 -0
- package/dist/eval-server/install-skill-routes.js +7 -0
- package/dist/eval-server/install-skill-routes.js.map +1 -1
- package/dist/eval-server/oauth-github-routes.js +25 -0
- package/dist/eval-server/oauth-github-routes.js.map +1 -1
- package/dist/eval-server/origin-resolver.d.ts +6 -0
- package/dist/eval-server/origin-resolver.js +35 -5
- package/dist/eval-server/origin-resolver.js.map +1 -1
- package/dist/eval-server/platform-proxy.d.ts +3 -3
- package/dist/eval-server/platform-proxy.js +10 -25
- package/dist/eval-server/platform-proxy.js.map +1 -1
- package/dist/eval-server/studio-privacy.d.ts +26 -0
- package/dist/eval-server/studio-privacy.js +129 -0
- package/dist/eval-server/studio-privacy.js.map +1 -0
- package/dist/eval-ui/assets/{CreateSkillPage-ENMve2K8.js → CreateSkillPage-DXOVLzCp.js} +1 -1
- package/dist/eval-ui/assets/{FindSkillsPalette-BMVKCk6E.js → FindSkillsPalette-D_qkIke-.js} +2 -2
- package/dist/eval-ui/assets/{SearchPaletteCore-C9G-ySXc.js → SearchPaletteCore-BbJxHT_o.js} +1 -1
- package/dist/eval-ui/assets/{SkillDetailPanel-BCJj8p79.js → SkillDetailPanel-DMkcBtBv.js} +1 -1
- package/dist/eval-ui/assets/{UpdateDropdown-C4BH7W_M.js → UpdateDropdown-CH05KQXq.js} +1 -1
- package/dist/eval-ui/assets/{main-tzMA8J07.js → main-DpG_H4H8.js} +5 -5
- package/dist/eval-ui/index.html +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/github-fetch.d.ts +30 -0
- package/dist/lib/github-fetch.js +146 -5
- package/dist/lib/github-fetch.js.map +1 -1
- package/dist/lib/private-source.d.ts +77 -0
- package/dist/lib/private-source.js +392 -0
- package/dist/lib/private-source.js.map +1 -0
- package/dist/lib/repo-visibility.d.ts +25 -0
- package/dist/lib/repo-visibility.js +80 -0
- package/dist/lib/repo-visibility.js.map +1 -0
- package/dist/lockfile/lockfile.d.ts +2 -0
- package/dist/lockfile/lockfile.js +13 -0
- package/dist/lockfile/lockfile.js.map +1 -1
- package/dist/lockfile/types.d.ts +5 -0
- package/dist/marketplace/marketplace.js +8 -1
- package/dist/marketplace/marketplace.js.map +1 -1
- package/dist/updater/source-fetcher.js +15 -11
- package/dist/updater/source-fetcher.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// private-source.ts — the one place that decides whether an installed skill
|
|
3
|
+
// may be mentioned to verified-skill.com.
|
|
4
|
+
//
|
|
5
|
+
// Rule: nothing about a skill from a private GitHub repo (its name, the repo,
|
|
6
|
+
// paths, hashes) is sent to the platform. A GitHub-sourced skill whose repo
|
|
7
|
+
// visibility is unknown is treated as private: visibility is resolved through
|
|
8
|
+
// the cached `GET /repos/{owner}/{repo}` call (getDefaultBranch), and if that
|
|
9
|
+
// does not confirm the repo is public (404, no token, rate limit, network
|
|
10
|
+
// error) the skill stays local. Registry installs came from the platform, so
|
|
11
|
+
// they are always fine to send. A local plugin-dir install counts as public
|
|
12
|
+
// only when its checkout's `origin` remote is a GitHub repo confirmed public.
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
import { execFileSync } from "node:child_process";
|
|
15
|
+
import { mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { dirname, join, resolve } from "node:path";
|
|
18
|
+
import { readLockfile } from "../lockfile/lockfile.js";
|
|
19
|
+
import { parseSource } from "../resolvers/source-resolver.js";
|
|
20
|
+
import { getRepoVisibility, getRepoVisibilityFailure, } from "./repo-visibility.js";
|
|
21
|
+
/** Parse "owner/repo", "github.com/owner/repo" URLs and git@github.com remotes. */
|
|
22
|
+
export function parseGitHubRepoRef(ref) {
|
|
23
|
+
if (!ref)
|
|
24
|
+
return null;
|
|
25
|
+
const trimmed = ref.trim();
|
|
26
|
+
const url = trimmed.match(/^(?:git\+)?(?:https?:\/\/|ssh:\/\/git@|git:\/\/)(?:www\.)?github\.com[/:]([^/\s]+)\/([^/\s?#]+?)(?:\.git)?\/?(?:[?#].*)?$/i);
|
|
27
|
+
if (url)
|
|
28
|
+
return { owner: url[1], repo: url[2] };
|
|
29
|
+
const scp = trimmed.match(/^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/i);
|
|
30
|
+
if (scp)
|
|
31
|
+
return { owner: scp[1], repo: scp[2] };
|
|
32
|
+
// Bare "owner/repo" only — anything with a scheme or host is not GitHub.
|
|
33
|
+
if (/[:@]/.test(trimmed))
|
|
34
|
+
return null;
|
|
35
|
+
const bare = trimmed.match(/^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?$/);
|
|
36
|
+
return bare ? { owner: bare[1], repo: bare[2] } : null;
|
|
37
|
+
}
|
|
38
|
+
// Loaded lazily: the GitHub client pulls in the keychain, which modules that
|
|
39
|
+
// only read lockfiles (e.g. the Studio routes) should not load. One shared
|
|
40
|
+
// promise so concurrent lookups wait for the same module.
|
|
41
|
+
let githubTree = null;
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Remembered public repos. When GitHub rate-limits us or is unreachable, a
|
|
44
|
+
// repo confirmed public within the last 30 days still counts as public, so
|
|
45
|
+
// its skills keep getting registry checks and updates. Only public repos are
|
|
46
|
+
// stored (private repo names never land on disk), and a repo GitHub later
|
|
47
|
+
// reports as private or missing is dropped.
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
const REMEMBERED_PUBLIC_TTL_MS = 30 * 24 * 60 * 60 * 1000;
|
|
50
|
+
/** Path of the remembered-public file; null when disabled (VSKILL_VISIBILITY_CACHE=0). */
|
|
51
|
+
export function visibilityCachePath() {
|
|
52
|
+
const override = process.env.VSKILL_VISIBILITY_CACHE;
|
|
53
|
+
if (override === "0" || override === "off")
|
|
54
|
+
return null;
|
|
55
|
+
if (override)
|
|
56
|
+
return override;
|
|
57
|
+
const dir = process.env.VSKILL_CONFIG_DIR || join(homedir(), ".vskill");
|
|
58
|
+
return join(dir, "repo-visibility.json");
|
|
59
|
+
}
|
|
60
|
+
function readRemembered() {
|
|
61
|
+
const path = visibilityCachePath();
|
|
62
|
+
if (!path)
|
|
63
|
+
return {};
|
|
64
|
+
try {
|
|
65
|
+
const data = JSON.parse(readFileSync(path, "utf8"));
|
|
66
|
+
return data && typeof data.public === "object" && data.public ? data.public : {};
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function writeRemembered(update) {
|
|
73
|
+
const path = visibilityCachePath();
|
|
74
|
+
if (!path)
|
|
75
|
+
return;
|
|
76
|
+
try {
|
|
77
|
+
const entries = readRemembered();
|
|
78
|
+
if (!update(entries))
|
|
79
|
+
return;
|
|
80
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
81
|
+
writeFileSync(path, JSON.stringify({ public: entries }, null, 2) + "\n", { mode: 0o600 });
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Best-effort: the live GitHub answer still decides this run.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Keys already written by this process, so repeated lookups write once.
|
|
88
|
+
const rememberedThisRun = new Set();
|
|
89
|
+
function rememberVisibility(key, visibility) {
|
|
90
|
+
const marker = `${key}:${visibility}`;
|
|
91
|
+
if (rememberedThisRun.has(marker))
|
|
92
|
+
return;
|
|
93
|
+
rememberedThisRun.add(marker);
|
|
94
|
+
writeRemembered((entries) => {
|
|
95
|
+
if (visibility === "public") {
|
|
96
|
+
entries[key] = { checkedAt: Date.now() };
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
if (!(key in entries))
|
|
100
|
+
return false;
|
|
101
|
+
delete entries[key];
|
|
102
|
+
return true;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function rememberedPublicAt(key) {
|
|
106
|
+
const at = readRemembered()[key]?.checkedAt;
|
|
107
|
+
if (typeof at !== "number" || Date.now() - at > REMEMBERED_PUBLIC_TTL_MS)
|
|
108
|
+
return null;
|
|
109
|
+
return at;
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Repos GitHub could not answer for. Their skills are kept private for this
|
|
113
|
+
// run; commands list them so the skip is never silent.
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
const unconfirmed = new Map();
|
|
116
|
+
// In-flight lookups, so concurrent checks of one repo share a request.
|
|
117
|
+
const inFlight = new Map();
|
|
118
|
+
let unconfirmedWarned = false;
|
|
119
|
+
let rememberedWarned = false;
|
|
120
|
+
function failureText(reason) {
|
|
121
|
+
return reason === "rate_limited" ? "GitHub is rate-limiting requests" : "GitHub could not be reached";
|
|
122
|
+
}
|
|
123
|
+
function warnUnconfirmed(ref, reason) {
|
|
124
|
+
if (unconfirmedWarned)
|
|
125
|
+
return;
|
|
126
|
+
unconfirmedWarned = true;
|
|
127
|
+
process.stderr.write(`vskill: ${failureText(reason)}, so ${ref} could not be confirmed public. ` +
|
|
128
|
+
"Its skills are treated as private this run (no verified-skill.com checks or registry updates). " +
|
|
129
|
+
"Set GITHUB_TOKEN or run `vskill auth login`, then retry.\n");
|
|
130
|
+
}
|
|
131
|
+
function warnRemembered(ref, reason, checkedAt) {
|
|
132
|
+
if (rememberedWarned)
|
|
133
|
+
return;
|
|
134
|
+
rememberedWarned = true;
|
|
135
|
+
const day = new Date(checkedAt).toISOString().slice(0, 10);
|
|
136
|
+
process.stderr.write(`vskill: ${failureText(reason)}; using the visibility of ${ref} last confirmed public on ${day}.\n`);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Repos whose visibility GitHub could not confirm in this process (rate
|
|
140
|
+
* limit or outage), with the reason. Their skills were treated as private.
|
|
141
|
+
*/
|
|
142
|
+
export function getUnconfirmedRepos() {
|
|
143
|
+
return [...unconfirmed.values()];
|
|
144
|
+
}
|
|
145
|
+
/** One line naming the skills that were skipped because GitHub did not answer, or null. */
|
|
146
|
+
export function unconfirmedSkipNote() {
|
|
147
|
+
const repos = getUnconfirmedRepos();
|
|
148
|
+
if (repos.length === 0)
|
|
149
|
+
return null;
|
|
150
|
+
const reason = repos.some((r) => r.reason === "rate_limited")
|
|
151
|
+
? "GitHub rate limit"
|
|
152
|
+
: "GitHub unreachable";
|
|
153
|
+
const names = repos.slice(0, 5).map((r) => r.repo).join(", ");
|
|
154
|
+
const more = repos.length > 5 ? ` and ${repos.length - 5} more` : "";
|
|
155
|
+
return (`Skipped registry checks for skills from ${repos.length} repo${repos.length === 1 ? "" : "s"} ` +
|
|
156
|
+
`whose visibility could not be confirmed (${reason}): ${names}${more}. ` +
|
|
157
|
+
"Set GITHUB_TOKEN or run `vskill auth login`, then retry.");
|
|
158
|
+
}
|
|
159
|
+
/** @internal test-only */
|
|
160
|
+
export function _resetPrivateSourceForTests() {
|
|
161
|
+
unconfirmed.clear();
|
|
162
|
+
inFlight.clear();
|
|
163
|
+
rememberedThisRun.clear();
|
|
164
|
+
unconfirmedWarned = false;
|
|
165
|
+
rememberedWarned = false;
|
|
166
|
+
}
|
|
167
|
+
async function lookUpVisibility(owner, repo) {
|
|
168
|
+
const ref = `${owner}/${repo}`;
|
|
169
|
+
const key = ref.toLowerCase();
|
|
170
|
+
const known = getRepoVisibility(ref);
|
|
171
|
+
if (known !== "unknown")
|
|
172
|
+
return known;
|
|
173
|
+
try {
|
|
174
|
+
githubTree ??= import("../discovery/github-tree.js");
|
|
175
|
+
const { getDefaultBranch } = await githubTree;
|
|
176
|
+
await getDefaultBranch(owner, repo);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// getDefaultBranch never throws today; stay fail-closed if it ever does.
|
|
180
|
+
}
|
|
181
|
+
const live = getRepoVisibility(ref);
|
|
182
|
+
const failure = getRepoVisibilityFailure(ref);
|
|
183
|
+
if (live !== "unknown" || !failure) {
|
|
184
|
+
// A real answer: public, private, or 404 (private or gone).
|
|
185
|
+
rememberVisibility(key, live);
|
|
186
|
+
return live;
|
|
187
|
+
}
|
|
188
|
+
const checkedAt = rememberedPublicAt(key);
|
|
189
|
+
if (checkedAt !== null) {
|
|
190
|
+
warnRemembered(ref, failure, checkedAt);
|
|
191
|
+
return "public";
|
|
192
|
+
}
|
|
193
|
+
unconfirmed.set(key, { repo: ref, reason: failure });
|
|
194
|
+
warnUnconfirmed(ref, failure);
|
|
195
|
+
return "unknown";
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Visibility check for a repo the user named themselves (`vskill diff
|
|
199
|
+
* owner/repo/skill`, `vskill submit owner/repo`, a Studio install
|
|
200
|
+
* identifier) that is not installed. Private when GitHub says private or
|
|
201
|
+
* hides it (404). When GitHub does not answer (rate limit, outage), the
|
|
202
|
+
* user's own request goes ahead: the name came from them, and blocking it
|
|
203
|
+
* would break public lookups on shared CI runners. Installed skills never
|
|
204
|
+
* use this; they fail closed (isPrivateSource).
|
|
205
|
+
*/
|
|
206
|
+
export async function isTypedRepoPrivate(owner, repo) {
|
|
207
|
+
const ref = `${owner}/${repo}`;
|
|
208
|
+
if (getRepoVisibility(ref) === "unknown") {
|
|
209
|
+
try {
|
|
210
|
+
githubTree ??= import("../discovery/github-tree.js");
|
|
211
|
+
const { getDefaultBranch } = await githubTree;
|
|
212
|
+
await getDefaultBranch(owner, repo);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// getDefaultBranch never throws today.
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
const visibility = getRepoVisibility(ref);
|
|
219
|
+
if (visibility !== "unknown")
|
|
220
|
+
return visibility === "private";
|
|
221
|
+
return !getRepoVisibilityFailure(ref);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Resolve a GitHub repo's visibility, reusing the process-wide cached
|
|
225
|
+
* `GET /repos/{owner}/{repo}` call. When GitHub rate-limits or is
|
|
226
|
+
* unreachable, a repo confirmed public in the last 30 days still counts as
|
|
227
|
+
* public; otherwise it stays "unknown" (treated as private) and is reported
|
|
228
|
+
* by getUnconfirmedRepos(). Never throws.
|
|
229
|
+
*/
|
|
230
|
+
export function resolveRepoVisibility(owner, repo) {
|
|
231
|
+
const key = `${owner}/${repo}`.toLowerCase();
|
|
232
|
+
let pending = inFlight.get(key);
|
|
233
|
+
if (!pending) {
|
|
234
|
+
pending = lookUpVisibility(owner, repo).finally(() => inFlight.delete(key));
|
|
235
|
+
inFlight.set(key, pending);
|
|
236
|
+
}
|
|
237
|
+
return pending;
|
|
238
|
+
}
|
|
239
|
+
/** True unless GitHub confirms the repo is public. */
|
|
240
|
+
export async function isPrivateOrUnknownRepo(owner, repo) {
|
|
241
|
+
return (await resolveRepoVisibility(owner, repo)) !== "public";
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The GitHub repo behind a local checkout's `origin` remote; null when the
|
|
245
|
+
* directory is not a git checkout, has no remote, or the remote is not GitHub.
|
|
246
|
+
*/
|
|
247
|
+
export function localDirGitHubRepo(dir, opts = {}) {
|
|
248
|
+
if (!dir)
|
|
249
|
+
return null;
|
|
250
|
+
const cwd = resolve(dir);
|
|
251
|
+
const git = (args) => execFileSync("git", args, { cwd, stdio: ["ignore", "pipe", "ignore"], timeout: 5_000 })
|
|
252
|
+
.toString()
|
|
253
|
+
.trim();
|
|
254
|
+
try {
|
|
255
|
+
// Only the directory's own checkout counts. git searches parent folders,
|
|
256
|
+
// so a private plugin copied into a public repo (vendor/, dotfiles)
|
|
257
|
+
// would otherwise inherit that repo's public origin.
|
|
258
|
+
// (A skill authored inside a checkout passes allowParentCheckout: it
|
|
259
|
+
// belongs to that repo.)
|
|
260
|
+
if (!opts.allowParentCheckout && !sameDir(git(["rev-parse", "--show-toplevel"]), cwd))
|
|
261
|
+
return null;
|
|
262
|
+
const remote = git(["remote", "get-url", "origin"]);
|
|
263
|
+
// A remote must be a GitHub URL or scp-style address; a bare "a/b" is a
|
|
264
|
+
// local path, not the GitHub repo a/b.
|
|
265
|
+
if (!/[:@]/.test(remote))
|
|
266
|
+
return null;
|
|
267
|
+
return parseGitHubRepoRef(remote);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function sameDir(a, b) {
|
|
274
|
+
const norm = (p) => {
|
|
275
|
+
try {
|
|
276
|
+
return realpathSync(p);
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return resolve(p);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
return norm(a) === norm(b);
|
|
283
|
+
}
|
|
284
|
+
/** The GitHub repo a lock entry was installed from, when it has one. */
|
|
285
|
+
export function lockEntryGitHubRepo(entry) {
|
|
286
|
+
const parsed = parseSource(entry.source ?? "");
|
|
287
|
+
if (parsed.type === "github" || parsed.type === "github-plugin" || parsed.type === "marketplace") {
|
|
288
|
+
return { owner: parsed.owner, repo: parsed.repo };
|
|
289
|
+
}
|
|
290
|
+
if (parsed.type === "registry" || parsed.type === "local")
|
|
291
|
+
return null;
|
|
292
|
+
return parseGitHubRepoRef(entry.sourceRepoUrl);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* True when nothing about this installed skill may be sent to the platform.
|
|
296
|
+
* GitHub-sourced entries are checked against GitHub (fail closed).
|
|
297
|
+
*/
|
|
298
|
+
export async function isPrivateSource(entry) {
|
|
299
|
+
if (!entry)
|
|
300
|
+
return false;
|
|
301
|
+
if (entry.sourcePrivate)
|
|
302
|
+
return true;
|
|
303
|
+
const parsed = parseSource(entry.source ?? "");
|
|
304
|
+
if (parsed.type === "registry")
|
|
305
|
+
return false;
|
|
306
|
+
const gh = parsed.type === "local" ? localDirGitHubRepo(parsed.baseName) : lockEntryGitHubRepo(entry);
|
|
307
|
+
if (gh)
|
|
308
|
+
return isPrivateOrUnknownRepo(gh.owner, gh.repo);
|
|
309
|
+
// A local plugin dir without its own GitHub origin, or a source vskill
|
|
310
|
+
// cannot parse, has no confirmed-public origin. Only legacy entries with no
|
|
311
|
+
// source at all (registry-era installs) still count as public.
|
|
312
|
+
if (parsed.type === "local")
|
|
313
|
+
return true;
|
|
314
|
+
return parsed.type === "unknown" && (entry.source ?? "").trim() !== "";
|
|
315
|
+
}
|
|
316
|
+
/** Lock entries that may be sent to the platform, in their original order. */
|
|
317
|
+
export async function filterPublicEntries(entries) {
|
|
318
|
+
const flags = await Promise.all(entries.map(([, entry]) => isPrivateSource(entry)));
|
|
319
|
+
return entries.filter((_, i) => !flags[i]);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Find the lock entry a user-typed skill name refers to: the lock key itself,
|
|
323
|
+
* or the canonical "owner/repo/skill" form of a GitHub-sourced entry.
|
|
324
|
+
*/
|
|
325
|
+
export function findLockEntry(lock, name) {
|
|
326
|
+
if (!lock?.skills)
|
|
327
|
+
return null;
|
|
328
|
+
const direct = lock.skills[name];
|
|
329
|
+
if (direct)
|
|
330
|
+
return direct;
|
|
331
|
+
const parts = name.split("/");
|
|
332
|
+
if (parts.length === 1) {
|
|
333
|
+
// A skill inside a plugin install (keyed by plugin name): match the
|
|
334
|
+
// recorded files, then the key ignoring case.
|
|
335
|
+
const file = `${name}/SKILL.md`;
|
|
336
|
+
const lower = name.toLowerCase();
|
|
337
|
+
for (const [key, entry] of Object.entries(lock.skills)) {
|
|
338
|
+
if (key.toLowerCase() === lower)
|
|
339
|
+
return entry;
|
|
340
|
+
if (entry.files?.some((f) => f === file || f.endsWith(`/${file}`)))
|
|
341
|
+
return entry;
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
if (parts.length !== 3)
|
|
346
|
+
return null;
|
|
347
|
+
const [owner, repo, skill] = parts;
|
|
348
|
+
const entry = lock.skills[skill];
|
|
349
|
+
if (!entry)
|
|
350
|
+
return null;
|
|
351
|
+
const gh = lockEntryGitHubRepo(entry);
|
|
352
|
+
if (!gh)
|
|
353
|
+
return null;
|
|
354
|
+
return gh.owner.toLowerCase() === owner.toLowerCase() && gh.repo.toLowerCase() === repo.toLowerCase()
|
|
355
|
+
? entry
|
|
356
|
+
: null;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* True when a skill name the user typed must not be sent to the platform:
|
|
360
|
+
* an installed skill from a private (or unconfirmed) source, or an
|
|
361
|
+
* "owner/repo/skill" name whose repo GitHub reports as private or hides
|
|
362
|
+
* (that covers skills inside private plugins, whose lock entries are keyed
|
|
363
|
+
* by the plugin). A bare name that is not installed is a registry lookup.
|
|
364
|
+
*/
|
|
365
|
+
export async function isPrivateSkillName(name) {
|
|
366
|
+
const entry = findInstalledLockEntry(name);
|
|
367
|
+
if (entry)
|
|
368
|
+
return isPrivateSource(entry);
|
|
369
|
+
const parts = name.split("/");
|
|
370
|
+
if (parts.length === 3 && parts.every(Boolean)) {
|
|
371
|
+
// Not installed: the user typed this name (see isTypedRepoPrivate).
|
|
372
|
+
return isTypedRepoPrivate(parts[0], parts[1]);
|
|
373
|
+
}
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* The lock entry for a skill name the user typed, from the project lockfile
|
|
378
|
+
* or, failing that, the user-global one (`~/.agents/vskill.lock`), so a skill
|
|
379
|
+
* installed with `--global` is recognised from any directory.
|
|
380
|
+
*/
|
|
381
|
+
export function findInstalledLockEntry(name) {
|
|
382
|
+
const project = findLockEntry(readLockfile(), name);
|
|
383
|
+
if (project)
|
|
384
|
+
return project;
|
|
385
|
+
try {
|
|
386
|
+
return findLockEntry(readLockfile(join(homedir(), ".agents")), name);
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
//# sourceMappingURL=private-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"private-source.js","sourceRoot":"","sources":["../../src/lib/private-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type RepoVisibility = "public" | "private" | "unknown";
|
|
2
|
+
/**
|
|
3
|
+
* Why GitHub gave no visibility answer for a repo: it is rate-limiting us, or
|
|
4
|
+
* it (or the network) is unavailable. A plain 404 is not a failure: the repo
|
|
5
|
+
* is private (or gone), and stays "unknown".
|
|
6
|
+
*/
|
|
7
|
+
export type VisibilityFailure = "rate_limited" | "unavailable";
|
|
8
|
+
/** Record what GitHub reported for a repo's visibility. */
|
|
9
|
+
export declare function recordRepoVisibility(owner: string, repo: string, data: {
|
|
10
|
+
private?: unknown;
|
|
11
|
+
visibility?: unknown;
|
|
12
|
+
}): void;
|
|
13
|
+
/**
|
|
14
|
+
* What this process has learned about a repo's visibility. Callers must treat
|
|
15
|
+
* "unknown" as private (see lib/private-source.ts).
|
|
16
|
+
*/
|
|
17
|
+
export declare function getRepoVisibility(ref: string | undefined | null): RepoVisibility;
|
|
18
|
+
/** Record that GitHub could not answer the visibility lookup for a repo. */
|
|
19
|
+
export declare function recordRepoVisibilityFailure(owner: string, repo: string, reason: VisibilityFailure): void;
|
|
20
|
+
/** Why the last visibility lookup for `ref` failed, if it did. */
|
|
21
|
+
export declare function getRepoVisibilityFailure(ref: string | undefined | null): VisibilityFailure | undefined;
|
|
22
|
+
/** True when `ref` ("owner/repo" or a github.com URL) was seen as private. */
|
|
23
|
+
export declare function isKnownPrivateRepo(ref: string | undefined | null): boolean;
|
|
24
|
+
/** @internal test-only */
|
|
25
|
+
export declare function _resetRepoVisibilityForTests(): void;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// repo-visibility.ts — remembers which GitHub repos this process has seen as
|
|
3
|
+
// private, so nothing about them (names, URLs, skill paths) is sent to
|
|
4
|
+
// verified-skill.com: no install telemetry, no auto-submission for scanning.
|
|
5
|
+
// Populated from the `GET /repos/{owner}/{repo}` call install already makes
|
|
6
|
+
// (getDefaultBranch), so it costs no extra requests.
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
const privateRepos = new Set();
|
|
9
|
+
const publicRepos = new Set();
|
|
10
|
+
const failures = new Map();
|
|
11
|
+
function keyOf(ref) {
|
|
12
|
+
const m = ref
|
|
13
|
+
.trim()
|
|
14
|
+
.replace(/^https?:\/\/github\.com\//i, "")
|
|
15
|
+
.match(/^([^/\s]+)\/([^/\s?#]+)/);
|
|
16
|
+
if (!m)
|
|
17
|
+
return null;
|
|
18
|
+
return `${m[1]}/${m[2].replace(/\.git$/i, "")}`.toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
/** Record what GitHub reported for a repo's visibility. */
|
|
21
|
+
export function recordRepoVisibility(owner, repo, data) {
|
|
22
|
+
const key = keyOf(`${owner}/${repo}`);
|
|
23
|
+
if (!key)
|
|
24
|
+
return;
|
|
25
|
+
failures.delete(key);
|
|
26
|
+
const isPrivate = data.private === true || data.visibility === "private" || data.visibility === "internal";
|
|
27
|
+
if (isPrivate) {
|
|
28
|
+
privateRepos.add(key);
|
|
29
|
+
publicRepos.delete(key);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
privateRepos.delete(key);
|
|
33
|
+
// Only an explicit "public" answer confirms a repo is public; anything
|
|
34
|
+
// else stays unknown, which every caller treats as private.
|
|
35
|
+
if (data.private === false || data.visibility === "public")
|
|
36
|
+
publicRepos.add(key);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* What this process has learned about a repo's visibility. Callers must treat
|
|
40
|
+
* "unknown" as private (see lib/private-source.ts).
|
|
41
|
+
*/
|
|
42
|
+
export function getRepoVisibility(ref) {
|
|
43
|
+
if (!ref)
|
|
44
|
+
return "unknown";
|
|
45
|
+
const key = keyOf(ref);
|
|
46
|
+
if (!key)
|
|
47
|
+
return "unknown";
|
|
48
|
+
if (privateRepos.has(key))
|
|
49
|
+
return "private";
|
|
50
|
+
if (publicRepos.has(key))
|
|
51
|
+
return "public";
|
|
52
|
+
return "unknown";
|
|
53
|
+
}
|
|
54
|
+
/** Record that GitHub could not answer the visibility lookup for a repo. */
|
|
55
|
+
export function recordRepoVisibilityFailure(owner, repo, reason) {
|
|
56
|
+
const key = keyOf(`${owner}/${repo}`);
|
|
57
|
+
if (key)
|
|
58
|
+
failures.set(key, reason);
|
|
59
|
+
}
|
|
60
|
+
/** Why the last visibility lookup for `ref` failed, if it did. */
|
|
61
|
+
export function getRepoVisibilityFailure(ref) {
|
|
62
|
+
if (!ref)
|
|
63
|
+
return undefined;
|
|
64
|
+
const key = keyOf(ref);
|
|
65
|
+
return key ? failures.get(key) : undefined;
|
|
66
|
+
}
|
|
67
|
+
/** True when `ref` ("owner/repo" or a github.com URL) was seen as private. */
|
|
68
|
+
export function isKnownPrivateRepo(ref) {
|
|
69
|
+
if (!ref)
|
|
70
|
+
return false;
|
|
71
|
+
const key = keyOf(ref);
|
|
72
|
+
return key ? privateRepos.has(key) : false;
|
|
73
|
+
}
|
|
74
|
+
/** @internal test-only */
|
|
75
|
+
export function _resetRepoVisibilityForTests() {
|
|
76
|
+
privateRepos.clear();
|
|
77
|
+
publicRepos.clear();
|
|
78
|
+
failures.clear();
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=repo-visibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-visibility.js","sourceRoot":"","sources":["../../src/lib/repo-visibility.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,8 @@ import type { VskillLock, SkillLockEntry } from "./types.js";
|
|
|
4
4
|
* Returns null if the lockfile does not exist.
|
|
5
5
|
*/
|
|
6
6
|
export declare function readLockfile(dir?: string): VskillLock | null;
|
|
7
|
+
/** "owner/repo" (or a github.com URL) for a lock entry's upstream repo. */
|
|
8
|
+
export declare function sourceRepoRef(entry: SkillLockEntry): string | null;
|
|
7
9
|
/**
|
|
8
10
|
* Write a VskillLock object to disk.
|
|
9
11
|
*/
|
|
@@ -5,6 +5,7 @@ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
|
5
5
|
import { join, dirname } from "node:path";
|
|
6
6
|
import { getProjectRoot } from "./project-root.js";
|
|
7
7
|
import { migrateLock } from "./migration.js";
|
|
8
|
+
import { isKnownPrivateRepo } from "../lib/repo-visibility.js";
|
|
8
9
|
const LOCKFILE_NAME = "vskill.lock";
|
|
9
10
|
const SKILLS_SH_LOCKFILE = ".skill-lock.json";
|
|
10
11
|
function lockPath(dir) {
|
|
@@ -26,11 +27,23 @@ export function readLockfile(dir) {
|
|
|
26
27
|
return null;
|
|
27
28
|
}
|
|
28
29
|
}
|
|
30
|
+
/** "owner/repo" (or a github.com URL) for a lock entry's upstream repo. */
|
|
31
|
+
export function sourceRepoRef(entry) {
|
|
32
|
+
if (entry.sourceRepoUrl)
|
|
33
|
+
return entry.sourceRepoUrl;
|
|
34
|
+
const m = (entry.source ?? "").match(/^(?:github|github-plugin|marketplace):([^/#\s]+\/[^/#\s]+)/);
|
|
35
|
+
return m ? m[1] : null;
|
|
36
|
+
}
|
|
29
37
|
/**
|
|
30
38
|
* Write a VskillLock object to disk.
|
|
31
39
|
*/
|
|
32
40
|
export function writeLockfile(lock, dir) {
|
|
33
41
|
lock.updatedAt = new Date().toISOString();
|
|
42
|
+
for (const entry of Object.values(lock.skills)) {
|
|
43
|
+
if (!entry.sourcePrivate && isKnownPrivateRepo(sourceRepoRef(entry))) {
|
|
44
|
+
entry.sourcePrivate = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
34
47
|
const p = lockPath(dir);
|
|
35
48
|
mkdirSync(dirname(p), { recursive: true });
|
|
36
49
|
writeFileSync(p, JSON.stringify(lock, null, 2) + "\n", "utf-8");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../src/lockfile/lockfile.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../src/lockfile/lockfile.ts"],"names":[],"mappings":"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"}
|
package/dist/lockfile/types.d.ts
CHANGED
|
@@ -28,6 +28,11 @@ export interface SkillLockEntry {
|
|
|
28
28
|
sourceCommitSha?: string;
|
|
29
29
|
/** Plugin namespace that provided this skill, when installed from a plugin layout. */
|
|
30
30
|
sourcePluginName?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Installed from a private GitHub repo. Such skills are only ever updated
|
|
33
|
+
* from that repo: no registry fallback, no registry lookups, no telemetry.
|
|
34
|
+
*/
|
|
35
|
+
sourcePrivate?: boolean;
|
|
31
36
|
}
|
|
32
37
|
export interface VskillLock {
|
|
33
38
|
version: 1;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
2
|
// Marketplace.json parser -- parse .claude-plugin/marketplace.json
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
|
+
import { githubFetch } from "../lib/github-fetch.js";
|
|
4
5
|
// ---- Parser ---------------------------------------------------------------
|
|
5
6
|
/**
|
|
6
7
|
* Parse marketplace.json content and extract available plugins.
|
|
@@ -129,13 +130,19 @@ export async function discoverUnregisteredPlugins(owner, repo, manifestContent,
|
|
|
129
130
|
.map((p) => p.source.replace(/^\.\//, "").replace(/^plugins\//, ""))
|
|
130
131
|
.filter(Boolean));
|
|
131
132
|
try {
|
|
132
|
-
|
|
133
|
+
// githubFetch carries the user's token, so private marketplace repos
|
|
134
|
+
// list too (a bare fetch is anonymous and 404s on a private repo).
|
|
135
|
+
const res = await githubFetch(`https://api.github.com/repos/${owner}/${repo}/contents/plugins`, {
|
|
133
136
|
headers: {
|
|
134
137
|
Accept: "application/vnd.github.v3+json",
|
|
135
138
|
"User-Agent": "vskill-cli",
|
|
136
139
|
},
|
|
137
140
|
signal: AbortSignal.timeout(10000),
|
|
138
141
|
});
|
|
142
|
+
// No plugins/ folder is a normal layout (skills/ at the repo root), not a
|
|
143
|
+
// failed lookup.
|
|
144
|
+
if (res.status === 404)
|
|
145
|
+
return { plugins: [], failed: false };
|
|
139
146
|
if (!res.ok) {
|
|
140
147
|
onResponse?.(res);
|
|
141
148
|
return { plugins: [], failed: true };
|