vskill 0.5.85 → 0.5.87

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.
@@ -7,10 +7,14 @@
7
7
  // 3. Root: {root}/skills/{skill}/SKILL.md (plugin = repo basename)
8
8
  // 4. Self: {root}/SKILL.md (root IS the skill directory itself)
9
9
  // 5. Flat: {root}/{skill}/SKILL.md (skills as direct children of root)
10
+ //
11
+ // 0686 adds tri-scope scanning (own | installed | global) via
12
+ // scanSkillsTriScope(), plus symlink + installMethod classification.
10
13
  // ---------------------------------------------------------------------------
11
- import { readdirSync, existsSync } from "node:fs";
14
+ import { readdirSync, existsSync, lstatSync, realpathSync, statSync } from "node:fs";
12
15
  import { join, basename, dirname, relative, sep } from "node:path";
13
16
  import { AGENTS_REGISTRY } from "../agents/agents-registry.js";
17
+ import { resolveGlobalSkillsDir } from "./path-utils.js";
14
18
  // ---------------------------------------------------------------------------
15
19
  // Origin classification — detect if a skill lives inside an agent config
16
20
  // directory (installed/consumed) vs. a user's own project (source/editable).
@@ -55,21 +59,29 @@ export function classifyOrigin(skillDir, root) {
55
59
  }
56
60
  return "source";
57
61
  }
62
+ /** Map a first-segment directory name back to the owning registry agent, if any.
63
+ * Accepts inputs like ".claude" and ".cursor". Returns null for unknown. */
64
+ function agentIdForLocalPrefix(firstSegment) {
65
+ for (const agent of AGENTS_REGISTRY) {
66
+ const agentFirst = agent.localSkillsDir.split("/")[0];
67
+ if (agentFirst === firstSegment)
68
+ return agent.id;
69
+ }
70
+ return null;
71
+ }
72
+ // ---------------------------------------------------------------------------
73
+ // Two-scope scanner (pre-0686 surface kept stable for /api/skills callers)
74
+ // ---------------------------------------------------------------------------
58
75
  export async function scanSkills(root) {
59
76
  const skills = [];
60
77
  if (!existsSync(root))
61
78
  return skills;
62
79
  // Layout 4: root IS the skill directory itself → {root}/SKILL.md
63
- // Walk up from the skill dir to find the plugin name:
64
- // .../plugins/{plugin}/skills/{skill}/ → plugin = grandparent of skill
65
- // .../skills/{skill}/ → plugin = parent above "skills"
66
- // Fallback to immediate parent if structure is unknown.
67
80
  if (existsSync(join(root, "SKILL.md"))) {
68
81
  const skillName = basename(root);
69
- const parent = basename(dirname(root)); // e.g. "skills"
82
+ const parent = basename(dirname(root));
70
83
  let pluginName;
71
84
  if (parent === "skills") {
72
- // Standard layout: .../plugins/{plugin}/skills/{skill}/ or .../{plugin}/skills/{skill}/
73
85
  pluginName = basename(dirname(dirname(root))) || "default";
74
86
  }
75
87
  else {
@@ -90,16 +102,13 @@ export async function scanSkills(root) {
90
102
  // Layout 3: root-level skills/ directory → {root}/skills/{skill}/SKILL.md
91
103
  scanSkillsDir(basename(root) || "default", join(root, "skills"), skills, root);
92
104
  // Layout 1: direct plugin subdirs → {root}/{plugin}/skills/{skill}/SKILL.md
93
- // Exclude "skills" (Layout 3) and "plugins" (Layout 2) from being treated as plugins
94
105
  scanPluginDirs(root, skills, ["skills", "plugins"], root);
95
106
  // Layout 2: nested plugins/ dir → {root}/plugins/{plugin}/skills/{skill}/SKILL.md
96
- // Only exclude "plugins" to prevent recursion; "skills" is a valid plugin name here
97
107
  const pluginsDir = join(root, "plugins");
98
108
  if (existsSync(pluginsDir)) {
99
109
  scanPluginDirs(pluginsDir, skills, ["plugins"], root);
100
110
  }
101
111
  // Layout 5: flat → {root}/{skill}/SKILL.md (skills as direct children of root)
102
- // Only pick up directories not already matched by layouts 1-3.
103
112
  if (skills.length === 0) {
104
113
  const defaultPlugin = basename(root) || "default";
105
114
  scanSkillsDir(defaultPlugin, root, skills, root);
@@ -110,7 +119,7 @@ function scanPluginDirs(dir, skills, exclude, root) {
110
119
  let entries;
111
120
  try {
112
121
  entries = readdirSync(dir, { withFileTypes: true })
113
- .filter((d) => d.isDirectory() && !exclude.includes(d.name))
122
+ .filter((d) => isDirOrDirSymlink(d, join(dir, d.name)) && !exclude.includes(d.name))
114
123
  .map((d) => d.name);
115
124
  }
116
125
  catch {
@@ -126,7 +135,7 @@ function scanSkillsDir(plugin, skillsDir, skills, root) {
126
135
  let skillDirs;
127
136
  try {
128
137
  skillDirs = readdirSync(skillsDir, { withFileTypes: true })
129
- .filter((d) => d.isDirectory())
138
+ .filter((d) => isDirOrDirSymlink(d, join(skillsDir, d.name)))
130
139
  .map((d) => d.name);
131
140
  }
132
141
  catch {
@@ -142,4 +151,175 @@ function scanSkillsDir(plugin, skillsDir, skills, root) {
142
151
  skills.push({ plugin, skill, dir: skillDir, hasEvals, hasBenchmark, origin: classifyOrigin(skillDir, root) });
143
152
  }
144
153
  }
154
+ /**
155
+ * Scan a project root and an agent's global skills dir, returning all three
156
+ * scopes tagged with scope/installMethod/symlink metadata.
157
+ */
158
+ export async function scanSkillsTriScope(root, opts) {
159
+ const results = [];
160
+ // --- OWN + INSTALLED (local project scan) ---
161
+ const localSkills = await scanSkills(root);
162
+ for (const s of localSkills) {
163
+ results.push(enrichWithScopeAndSymlink(s, root));
164
+ }
165
+ // --- GLOBAL (agent's home skills dir) ---
166
+ const agent = AGENTS_REGISTRY.find((a) => a.id === opts.agentId);
167
+ if (agent) {
168
+ const globalDir = opts.home
169
+ ? join(opts.home, firstNonTildeSegment(agent.globalSkillsDir))
170
+ : resolveGlobalSkillsDir(agent);
171
+ if (existsSync(globalDir)) {
172
+ // Agent's global dir points at `.../skills/` — iterate children as skills.
173
+ const globals = [];
174
+ scanSkillsDir(agent.id, globalDir, globals, globalDir);
175
+ for (const g of globals) {
176
+ results.push({
177
+ ...g,
178
+ origin: "installed",
179
+ scope: "global",
180
+ sourceAgent: agent.id,
181
+ ...symlinkFieldsFor(g.dir),
182
+ installMethod: installMethodFor(g.dir, "global"),
183
+ });
184
+ }
185
+ }
186
+ }
187
+ return results;
188
+ }
189
+ /** Convert a globalSkillsDir pattern like `~/.claude/skills` to just the
190
+ * after-the-tilde portion (`.claude/skills`) for joining onto an injected
191
+ * fixture home. */
192
+ function firstNonTildeSegment(p) {
193
+ if (p.startsWith("~/") || p.startsWith("~\\"))
194
+ return p.slice(2);
195
+ if (p.startsWith("~"))
196
+ return p.slice(1);
197
+ return p;
198
+ }
199
+ /** Fold 0686 scope/symlink/installMethod/sourceAgent fields onto a SkillInfo
200
+ * returned by the two-scope scanner. */
201
+ function enrichWithScopeAndSymlink(s, root) {
202
+ const scope = s.origin === "installed" ? "installed" : "own";
203
+ const symlink = symlinkFieldsFor(s.dir);
204
+ const installMethod = installMethodFor(s.dir, scope, symlink.isSymlink);
205
+ const sourceAgent = scope === "own" ? null : deriveSourceAgentFromDir(s.dir, root);
206
+ return { ...s, scope, sourceAgent, ...symlink, installMethod };
207
+ }
208
+ /** Walk one level up through the relative path to identify the owning agent
209
+ * (e.g. `.claude/skills/foo` → `claude-code`). */
210
+ function deriveSourceAgentFromDir(skillDir, root) {
211
+ const rel = relative(root, skillDir).split(sep).join("/");
212
+ const first = rel.split("/")[0];
213
+ if (!first)
214
+ return null;
215
+ return agentIdForLocalPrefix(first);
216
+ }
217
+ /** Compute `{ isSymlink, symlinkTarget }` for a skill dir, with cycle safety.
218
+ * Uses lstatSync to detect the link, then realpathSync to resolve it. If the
219
+ * realpath walks through the same inode twice we treat it as a cycle and set
220
+ * the target to null (AC-US8-04). */
221
+ function symlinkFieldsFor(skillDir) {
222
+ let isSymlink = false;
223
+ try {
224
+ isSymlink = lstatSync(skillDir).isSymbolicLink();
225
+ }
226
+ catch {
227
+ return { isSymlink: false, symlinkTarget: null };
228
+ }
229
+ if (!isSymlink)
230
+ return { isSymlink: false, symlinkTarget: null };
231
+ // Manual walk so we can detect cycles deterministically rather than relying
232
+ // on realpathSync's exception on ELOOP (behavior varies by platform).
233
+ const seen = new Set();
234
+ let current = skillDir;
235
+ try {
236
+ const firstKey = inodeKey(current);
237
+ if (firstKey)
238
+ seen.add(firstKey);
239
+ // Bounded hop count in case the platform doesn't error on a cycle.
240
+ for (let hops = 0; hops < 40; hops++) {
241
+ let st;
242
+ try {
243
+ st = lstatSync(current);
244
+ }
245
+ catch {
246
+ return { isSymlink: true, symlinkTarget: null };
247
+ }
248
+ if (!st.isSymbolicLink()) {
249
+ // We reached the real target — validate it's still there.
250
+ try {
251
+ statSync(current);
252
+ }
253
+ catch {
254
+ return { isSymlink: true, symlinkTarget: null };
255
+ }
256
+ return { isSymlink: true, symlinkTarget: current };
257
+ }
258
+ let next;
259
+ try {
260
+ next = realpathSync.native?.(current) ?? realpathSync(current);
261
+ }
262
+ catch {
263
+ // realpath may ELOOP on a cycle — that's exactly the scenario we warn about.
264
+ console.warn(`[skill-scanner] cycle detected while resolving ${skillDir}`);
265
+ return { isSymlink: true, symlinkTarget: null };
266
+ }
267
+ const key = inodeKey(next);
268
+ if (!key) {
269
+ return { isSymlink: true, symlinkTarget: null };
270
+ }
271
+ if (seen.has(key)) {
272
+ console.warn(`[skill-scanner] cycle detected while resolving ${skillDir}`);
273
+ return { isSymlink: true, symlinkTarget: null };
274
+ }
275
+ seen.add(key);
276
+ if (next === current) {
277
+ return { isSymlink: true, symlinkTarget: current };
278
+ }
279
+ current = next;
280
+ }
281
+ console.warn(`[skill-scanner] symlink depth exceeded while resolving ${skillDir}`);
282
+ return { isSymlink: true, symlinkTarget: null };
283
+ }
284
+ catch {
285
+ return { isSymlink: true, symlinkTarget: null };
286
+ }
287
+ }
288
+ function inodeKey(p) {
289
+ try {
290
+ const st = lstatSync(p);
291
+ return `${st.dev}:${st.ino}`;
292
+ }
293
+ catch {
294
+ return null;
295
+ }
296
+ }
297
+ function installMethodFor(skillDir, scope, isSymlink) {
298
+ if (scope === "own")
299
+ return "authored";
300
+ const symlink = isSymlink ?? lstatSafeIsSymlink(skillDir);
301
+ return symlink ? "symlinked" : "copied";
302
+ }
303
+ function lstatSafeIsSymlink(p) {
304
+ try {
305
+ return lstatSync(p).isSymbolicLink();
306
+ }
307
+ catch {
308
+ return false;
309
+ }
310
+ }
311
+ /** Accept plain directories AND symlinks whose target is a directory. */
312
+ function isDirOrDirSymlink(d, fullPath) {
313
+ if (d.isDirectory())
314
+ return true;
315
+ if (!d.isSymbolicLink())
316
+ return false;
317
+ try {
318
+ return statSync(fullPath).isDirectory();
319
+ }
320
+ catch {
321
+ // Broken symlink, or a cycle that ELOOPs on stat — either way, skip it.
322
+ return false;
323
+ }
324
+ }
145
325
  //# sourceMappingURL=skill-scanner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-scanner.js","sourceRoot":"","sources":["../../src/eval/skill-scanner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skill-scanner.js","sourceRoot":"","sources":["../../src/eval/skill-scanner.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { Router } from "./router.js";
2
+ import type { SkillInfo } from "../eval/skill-scanner.js";
2
3
  import type { ProviderName } from "../eval/llm.js";
3
4
  import type { AgentDefinition } from "../agents/agents-registry.js";
4
5
  export interface InstalledAgentEntry {
@@ -17,6 +18,52 @@ export interface InstalledAgentsResponse {
17
18
  * Returns all known agents with installed flag based on detected agents.
18
19
  */
19
20
  export declare function buildInstalledAgentsResponse(detectedAgents: AgentDefinition[]): InstalledAgentsResponse;
21
+ export interface AgentScopeEntry {
22
+ id: string;
23
+ displayName: string;
24
+ featureSupport: AgentDefinition["featureSupport"];
25
+ isUniversal: boolean;
26
+ parentCompany: string;
27
+ detected: boolean;
28
+ isDefault: boolean;
29
+ localSkillCount: number;
30
+ globalSkillCount: number;
31
+ resolvedLocalDir: string;
32
+ resolvedGlobalDir: string;
33
+ lastSync: string | null;
34
+ health: "ok" | "stale" | "missing";
35
+ }
36
+ export interface AgentsResponse {
37
+ agents: AgentScopeEntry[];
38
+ suggested: string;
39
+ sharedFolders: Array<{
40
+ path: string;
41
+ consumers: string[];
42
+ }>;
43
+ }
44
+ /** Test hook — clear the 30 s cache so the next buildAgentsResponse() re-scans. */
45
+ export declare function resetAgentPresenceCache(): void;
46
+ interface BuildAgentsOptions {
47
+ /** Project root (typically eval-server cwd). */
48
+ root: string;
49
+ /** Override home dir (primarily for tests / fixture homes). */
50
+ home?: string;
51
+ /** Agents whose CLI binary is on PATH — optional; callers may pre-detect. */
52
+ detectedBinaries?: Set<string>;
53
+ }
54
+ /**
55
+ * Build the /api/agents response. Filters to agents with presence and
56
+ * includes per-agent counts, resolved paths, and shared-folder grouping.
57
+ *
58
+ * Results are cached for 30s keyed by `(root, home, binaries)` so repeated
59
+ * polls don't re-walk the filesystem.
60
+ */
61
+ export declare function buildAgentsResponse(opts: BuildAgentsOptions): Promise<AgentsResponse>;
62
+ export interface SkillScopeFilter {
63
+ scope?: string;
64
+ agent?: string;
65
+ }
66
+ export declare function filterSkillsByScopeAndAgent<T extends SkillInfo>(skills: T[], filter: SkillScopeFilter): T[];
20
67
  export declare function extractDescription(skillContent: string): string;
21
68
  export interface SkillMetadataFields {
22
69
  description: string | null;
@@ -55,8 +102,41 @@ interface ModelOption {
55
102
  id: string;
56
103
  label: string;
57
104
  }
105
+ type OpenRouterCacheEntry = {
106
+ value: Array<{
107
+ id: string;
108
+ name: string;
109
+ contextWindow?: number;
110
+ pricing: {
111
+ prompt: number;
112
+ completion: number;
113
+ };
114
+ }>;
115
+ fetchedAt: number;
116
+ };
117
+ export declare const OPENROUTER_CACHE: Map<string, OpenRouterCacheEntry>;
118
+ export declare function resetOpenRouterCache(): void;
58
119
  /** Test hook: clear all probe caches so the next detectAvailableProviders() re-probes. */
59
120
  export declare function resetDetectionCache(): void;
121
+ /**
122
+ * Detection block — surfaces wrapper-folder presence and binary availability
123
+ * so the UI can render accurate "installed" dots and "install me" CTAs.
124
+ *
125
+ * Shape is part of the /api/config response (the frontend types.ts is
126
+ * read-only per the 0682 ownership boundary, so the field is carried as
127
+ * opaque JSON and consumed by useAgentCatalog via its own typing).
128
+ */
129
+ export interface DetectionInfo {
130
+ wrapperFolders: Record<string, boolean>;
131
+ binaries: Record<string, boolean>;
132
+ }
133
+ export declare function resetProjectDetectionCache(): void;
134
+ /**
135
+ * Scan the project root for known agent wrapper folders and the system
136
+ * PATH for known agent binaries. Cheap synchronous scan (`existsSync` +
137
+ * `which`) cached for 30 s so repeated `/api/config` polls don't burn CPU.
138
+ */
139
+ export declare function detectProjectAgents(root: string): DetectionInfo;
60
140
  export declare function detectAvailableProviders(): Promise<Array<{
61
141
  id: ProviderName;
62
142
  label: string;