skills-manager-cli 2026.8.26-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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +103 -0
  3. package/README.zh-CN.md +103 -0
  4. package/dist/cli/main.js +261 -0
  5. package/dist/cli/main.js.map +1 -0
  6. package/dist/cli.js +3 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/core/catalog/agent-catalog.json +1134 -0
  9. package/dist/core/catalog/evaluate-detection.js +41 -0
  10. package/dist/core/catalog/evaluate-detection.js.map +1 -0
  11. package/dist/core/catalog/extract.js +388 -0
  12. package/dist/core/catalog/extract.js.map +1 -0
  13. package/dist/core/catalog/resolve-path.js +29 -0
  14. package/dist/core/catalog/resolve-path.js.map +1 -0
  15. package/dist/core/catalog/validate-snapshot.js +117 -0
  16. package/dist/core/catalog/validate-snapshot.js.map +1 -0
  17. package/dist/core/index.js +6 -0
  18. package/dist/core/index.js.map +1 -0
  19. package/dist/core/model/catalog.js +7 -0
  20. package/dist/core/model/catalog.js.map +1 -0
  21. package/dist/core/model/index.js +7 -0
  22. package/dist/core/model/index.js.map +1 -0
  23. package/dist/core/ports/filesystem.js +2 -0
  24. package/dist/core/ports/filesystem.js.map +1 -0
  25. package/dist/core/ports/git.js +2 -0
  26. package/dist/core/ports/git.js.map +1 -0
  27. package/dist/core/ports/process-runner.js +2 -0
  28. package/dist/core/ports/process-runner.js.map +1 -0
  29. package/dist/core/services/activity-service.js +36 -0
  30. package/dist/core/services/activity-service.js.map +1 -0
  31. package/dist/core/services/adopt-service.js +7 -0
  32. package/dist/core/services/adopt-service.js.map +1 -0
  33. package/dist/core/services/archive-service.js +35 -0
  34. package/dist/core/services/archive-service.js.map +1 -0
  35. package/dist/core/services/backup-service.js +94 -0
  36. package/dist/core/services/backup-service.js.map +1 -0
  37. package/dist/core/services/catalog-service.js +123 -0
  38. package/dist/core/services/catalog-service.js.map +1 -0
  39. package/dist/core/services/distribute-service.js +474 -0
  40. package/dist/core/services/distribute-service.js.map +1 -0
  41. package/dist/core/services/doctor-service.js +75 -0
  42. package/dist/core/services/doctor-service.js.map +1 -0
  43. package/dist/core/services/index.js +54 -0
  44. package/dist/core/services/index.js.map +1 -0
  45. package/dist/core/services/init-service.js +234 -0
  46. package/dist/core/services/init-service.js.map +1 -0
  47. package/dist/core/services/install-service.js +73 -0
  48. package/dist/core/services/install-service.js.map +1 -0
  49. package/dist/core/services/migration-service.js +102 -0
  50. package/dist/core/services/migration-service.js.map +1 -0
  51. package/dist/core/services/package-service.js +33 -0
  52. package/dist/core/services/package-service.js.map +1 -0
  53. package/dist/core/services/registry-service.js +133 -0
  54. package/dist/core/services/registry-service.js.map +1 -0
  55. package/dist/core/services/skill-home-resolver.js +33 -0
  56. package/dist/core/services/skill-home-resolver.js.map +1 -0
  57. package/dist/core/services/skill-home-service.js +35 -0
  58. package/dist/core/services/skill-home-service.js.map +1 -0
  59. package/dist/core/services/source-service.js +109 -0
  60. package/dist/core/services/source-service.js.map +1 -0
  61. package/dist/core/services/update-service.js +93 -0
  62. package/dist/core/services/update-service.js.map +1 -0
  63. package/dist/core/services/view-service.js +45 -0
  64. package/dist/core/services/view-service.js.map +1 -0
  65. package/dist/dashboard/server/main.js +427 -0
  66. package/dist/dashboard/server/main.js.map +1 -0
  67. package/dist/dashboard/server/render-markdown.js +75 -0
  68. package/dist/dashboard/server/render-markdown.js.map +1 -0
  69. package/dist/dashboard/server/skill-file.js +129 -0
  70. package/dist/dashboard/server/skill-file.js.map +1 -0
  71. package/dist/dashboard-web/assets/index-B43GPIpA.js +13 -0
  72. package/dist/dashboard-web/assets/index-CzbkHV2A.css +1 -0
  73. package/dist/dashboard-web/index.html +13 -0
  74. package/dist/infra/fs-skill-home.js +87 -0
  75. package/dist/infra/fs-skill-home.js.map +1 -0
  76. package/dist/infra/git-cli.js +36 -0
  77. package/dist/infra/git-cli.js.map +1 -0
  78. package/dist/infra/index.js +5 -0
  79. package/dist/infra/index.js.map +1 -0
  80. package/dist/infra/runtime.js +23 -0
  81. package/dist/infra/runtime.js.map +1 -0
  82. package/dist/infra/shell-runner.js +18 -0
  83. package/dist/infra/shell-runner.js.map +1 -0
  84. package/dist/shared/errors.js +17 -0
  85. package/dist/shared/errors.js.map +1 -0
  86. package/dist/shared/result.js +17 -0
  87. package/dist/shared/result.js.map +1 -0
  88. package/dist/shared/validation.js +92 -0
  89. package/dist/shared/validation.js.map +1 -0
  90. package/docs/CLI.md +75 -0
  91. package/package.json +73 -0
@@ -0,0 +1,41 @@
1
+ import { resolveCatalogTemplate } from './resolve-path.js';
2
+ /** Evaluate one detection condition against injected context. Pure: data in, boolean out. */
3
+ export function evaluateCondition(condition, context) {
4
+ switch (condition.kind) {
5
+ case 'env-set':
6
+ return Boolean(context.env[condition.variable]?.trim());
7
+ case 'env-value':
8
+ return context.env[condition.variable] === condition.equals;
9
+ case 'env-matches':
10
+ return context.env[condition.variable] !== undefined && new RegExp(condition.pattern).test(context.env[condition.variable]);
11
+ case 'no-tty':
12
+ return !context.isTty;
13
+ case 'path-exists': {
14
+ const resolved = resolveCatalogTemplate(condition.path, context);
15
+ return resolved !== null && context.pathExists(resolved);
16
+ }
17
+ case 'cwd-path-exists':
18
+ return context.cwdPathExists(condition.path);
19
+ case 'cwd-package-dep':
20
+ return context.packageHasDependency(condition.package);
21
+ case 'never':
22
+ return false;
23
+ case 'any':
24
+ return condition.conditions.some((child) => evaluateCondition(child, context));
25
+ case 'all':
26
+ return condition.conditions.every((child) => evaluateCondition(child, context));
27
+ }
28
+ }
29
+ /**
30
+ * The detected set: agents whose install probe or env probe matches this
31
+ * machine — the same rules over the same data `npx skills` uses with no -a.
32
+ */
33
+ export function detectAgents(snapshot, context) {
34
+ const hit = snapshot.agents.filter((agent) => {
35
+ if (evaluateCondition(agent.installProbe, context))
36
+ return true;
37
+ return agent.envProbe !== null && evaluateCondition(agent.envProbe, context);
38
+ });
39
+ return hit.map((agent) => agent.id).sort();
40
+ }
41
+ //# sourceMappingURL=evaluate-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate-detection.js","sourceRoot":"","sources":["../../../src/core/catalog/evaluate-detection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAiB3D,6FAA6F;AAC7F,MAAM,UAAU,iBAAiB,CAAC,SAA6B,EAAE,OAAyB;IACxF,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,KAAK,WAAW;YACd,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC;QAC9D,KAAK,aAAa;YAChB,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,SAAS,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAW,CAAC,CAAC;QACxI,KAAK,QAAQ;YACX,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QACxB,KAAK,aAAa,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACjE,OAAO,QAAQ,KAAK,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC;QACD,KAAK,iBAAiB;YACpB,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/C,KAAK,iBAAiB;YACpB,OAAO,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACzD,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;QACf,KAAK,KAAK;YACR,OAAO,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QACjF,KAAK,KAAK;YACR,OAAO,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IACpF,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAyB,EAAE,OAAyB;IAC/E,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3C,IAAI,iBAAiB,CAAC,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAChE,OAAO,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,388 @@
1
+ import { SkillsManagerError } from '../../shared/errors.js';
2
+ import { validateCatalogSnapshot } from './validate-snapshot.js';
3
+ const NOTICE = 'Agent table extracted from vercel-labs/skills (src/agents.ts, src/detect-agent.ts, mirroring @vercel/detect-agent runtime detection). All MIT. Copyright (c) 2026 Vercel, Inc.';
4
+ /**
5
+ * Runtime env-detection rules mirrored from @vercel/detect-agent's
6
+ * determineAgent() (dist/index.js). Its agents.json is a spec document, not
7
+ * runtime truth — the shipped if-chain differs (no CODEX_SANDBOX_NETWORK_
8
+ * DISABLED, no OPENCODE, no ANTIGRAVITY_CLI_ALIAS), so we mirror the code.
9
+ * The AI_AGENT pass-through override is intentionally not modelled.
10
+ */
11
+ const DETERMINE_AGENT_RULES = [
12
+ { name: 'cursor', condition: { kind: 'env-set', variable: 'CURSOR_TRACE_ID' } },
13
+ {
14
+ name: 'cursor-cli',
15
+ condition: {
16
+ kind: 'any',
17
+ conditions: [{ kind: 'env-set', variable: 'CURSOR_AGENT' }, { kind: 'env-value', variable: 'CURSOR_EXTENSION_HOST_ROLE', equals: 'agent-exec' }],
18
+ },
19
+ },
20
+ { name: 'gemini', condition: { kind: 'env-set', variable: 'GEMINI_CLI' } },
21
+ {
22
+ name: 'codex',
23
+ condition: { kind: 'any', conditions: [{ kind: 'env-set', variable: 'CODEX_SANDBOX' }, { kind: 'env-set', variable: 'CODEX_CI' }, { kind: 'env-set', variable: 'CODEX_THREAD_ID' }] },
24
+ },
25
+ { name: 'antigravity', condition: { kind: 'env-set', variable: 'ANTIGRAVITY_AGENT' } },
26
+ { name: 'augment-cli', condition: { kind: 'env-set', variable: 'AUGMENT_AGENT' } },
27
+ { name: 'opencode', condition: { kind: 'env-set', variable: 'OPENCODE_CLIENT' } },
28
+ { name: 'claude', condition: { kind: 'any', conditions: [{ kind: 'env-set', variable: 'CLAUDECODE' }, { kind: 'env-set', variable: 'CLAUDE_CODE' }] } },
29
+ {
30
+ name: 'cowork',
31
+ condition: { kind: 'all', conditions: [{ kind: 'env-set', variable: 'CLAUDE_CODE_IS_COWORK' }, { kind: 'any', conditions: [{ kind: 'env-set', variable: 'CLAUDECODE' }, { kind: 'env-set', variable: 'CLAUDE_CODE' }] }] },
32
+ },
33
+ { name: 'replit', condition: { kind: 'env-set', variable: 'REPL_ID' } },
34
+ {
35
+ name: 'github-copilot',
36
+ condition: { kind: 'any', conditions: [{ kind: 'env-set', variable: 'COPILOT_MODEL' }, { kind: 'env-set', variable: 'COPILOT_ALLOW_ALL' }, { kind: 'env-set', variable: 'COPILOT_GITHUB_TOKEN' }] },
37
+ },
38
+ { name: 'devin', condition: { kind: 'path-exists', path: '/opt/.devin' } },
39
+ ];
40
+ const INSTALL_HELPERS = {
41
+ 'isZCodeInstalled()': {
42
+ kind: 'any',
43
+ conditions: [{ kind: 'path-exists', path: '~/.zcode' }, { kind: 'path-exists', path: '/Applications/ZCode.app' }],
44
+ },
45
+ 'isKimchiInstalled()': { kind: 'path-exists', path: '~/.config/kimchi' },
46
+ 'isMiniMaxCodeInstalled()': {
47
+ kind: 'any',
48
+ conditions: [{ kind: 'path-exists', path: '~/.minimax' }, { kind: 'path-exists', path: '/Applications/MiniMax Code.app' }],
49
+ },
50
+ 'isPositAssistantInstalled()': {
51
+ kind: 'any',
52
+ conditions: [{ kind: 'path-exists', path: '~/.posit/assistant' }, { kind: 'path-exists', path: '~/.positai' }],
53
+ },
54
+ };
55
+ function unsupported(agentId, detail) {
56
+ throw new SkillsManagerError('catalog_extract_unsupported', `Cannot translate upstream shape for agent "${agentId}": ${detail}. The upstream source layout changed; update the extractor.`);
57
+ }
58
+ /** Split on a top-level operator, ignoring parentheses and string literals. */
59
+ function splitTopLevel(expression, operator) {
60
+ let depth = 0;
61
+ let quote = false;
62
+ const parts = [];
63
+ let current = '';
64
+ for (let index = 0; index < expression.length; index += 1) {
65
+ const char = expression[index];
66
+ if (quote) {
67
+ current += char;
68
+ if (char === "'")
69
+ quote = false;
70
+ continue;
71
+ }
72
+ if (char === "'") {
73
+ quote = true;
74
+ current += char;
75
+ continue;
76
+ }
77
+ if (char === '(')
78
+ depth += 1;
79
+ if (char === ')')
80
+ depth -= 1;
81
+ if (depth === 0 && expression.startsWith(operator, index)) {
82
+ parts.push(current);
83
+ current = '';
84
+ index += operator.length - 1;
85
+ continue;
86
+ }
87
+ current += char;
88
+ }
89
+ if (parts.length === 0)
90
+ return null;
91
+ parts.push(current);
92
+ return parts.every((part) => part.trim()) ? parts : null;
93
+ }
94
+ function unparenthesize(expression) {
95
+ let value = expression.trim();
96
+ while (value.startsWith('(') && value.endsWith(')')) {
97
+ // Strip the wrapping parens only when they enclose the WHOLE expression.
98
+ let depth = 0;
99
+ let quote = false;
100
+ let closingAt = -1;
101
+ for (let index = 0; index < value.length; index += 1) {
102
+ const char = value[index];
103
+ if (quote) {
104
+ if (char === "'")
105
+ quote = false;
106
+ continue;
107
+ }
108
+ if (char === "'") {
109
+ quote = true;
110
+ continue;
111
+ }
112
+ if (char === '(')
113
+ depth += 1;
114
+ if (char === ')') {
115
+ depth -= 1;
116
+ if (depth === 0) {
117
+ closingAt = index;
118
+ break;
119
+ }
120
+ }
121
+ }
122
+ if (closingAt !== value.length - 1)
123
+ break;
124
+ value = value.slice(1, -1).trim();
125
+ }
126
+ return value;
127
+ }
128
+ function stringArgs(call) {
129
+ return [...call.matchAll(/'((?:[^'\\]|\\.)*)'/g)].map((match) => match[1]);
130
+ }
131
+ function translateExistsArg(arg, agentId) {
132
+ const trimmed = arg.trim();
133
+ const joinMatch = trimmed.match(/^join\((.+)\)$/s);
134
+ if (joinMatch) {
135
+ const first = joinMatch[1].split(',')[0].trim();
136
+ const rest = stringArgs(joinMatch[1]);
137
+ const tail = rest.join('/');
138
+ if (first === 'home')
139
+ return { kind: 'path-exists', path: tail ? `~/${tail}` : '~' };
140
+ if (first === 'process.cwd()' || first === 'cwd')
141
+ return { kind: 'cwd-path-exists', path: tail };
142
+ if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(first))
143
+ return { kind: 'path-exists', path: tail ? `$${first}/${tail}` : `$${first}` };
144
+ return unsupported(agentId, `unrecognized join() base "${first}"`);
145
+ }
146
+ if (trimmed === 'home')
147
+ return { kind: 'path-exists', path: '~' };
148
+ if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(trimmed))
149
+ return { kind: 'path-exists', path: `$${trimmed}` };
150
+ if (/^'/.test(trimmed))
151
+ return { kind: 'path-exists', path: stringArgs(trimmed)[0] };
152
+ return unsupported(agentId, `unrecognized existsSync() argument "${trimmed}"`);
153
+ }
154
+ function translateExpression(expression, agentId) {
155
+ const value = unparenthesize(expression);
156
+ if (value === 'false')
157
+ return { kind: 'never' };
158
+ const orParts = splitTopLevel(value, '||');
159
+ if (orParts)
160
+ return { kind: 'any', conditions: orParts.map((part) => translateExpression(part, agentId)) };
161
+ const andParts = splitTopLevel(value, '&&');
162
+ if (andParts) {
163
+ // `!!variable && existsSync(join(variable, ...))` guards an optional path
164
+ // variable; the guard is redundant because an unset variable resolves to
165
+ // null and the path-exists condition simply cannot match.
166
+ const meaningful = andParts.filter((part) => !/^!![a-zA-Z][a-zA-Z0-9]*$/.test(part.trim()));
167
+ if (meaningful.length === 0)
168
+ return unsupported(agentId, `expression is only variable guards: ${value}`);
169
+ const conditions = meaningful.map((part) => translateExpression(part, agentId));
170
+ return conditions.length === 1 ? conditions[0] : { kind: 'all', conditions };
171
+ }
172
+ if (/^is\w+Installed\(\)$/.test(value)) {
173
+ const helper = INSTALL_HELPERS[value];
174
+ if (helper)
175
+ return helper;
176
+ return unsupported(agentId, `unknown installed-helper "${value}"`);
177
+ }
178
+ const packageDep = value.match(/^packageJsonHasDependency\(join\([^)]*\),\s*'([^']+)'\)$/);
179
+ if (packageDep)
180
+ return { kind: 'cwd-package-dep', package: packageDep[1] };
181
+ const exists = value.match(/^existsSync\((.+)\)$/s);
182
+ if (exists)
183
+ return translateExistsArg(exists[1], agentId);
184
+ return unsupported(agentId, `unrecognized expression "${value}"`);
185
+ }
186
+ function translateDetectInstalled(detectBody, agentId) {
187
+ const returns = [...detectBody.matchAll(/return\s+([\s\S]*?);/g)].map((match) => match[1].replace(/\s+/g, ' ').trim());
188
+ if (returns.length === 0)
189
+ return unsupported(agentId, 'detectInstalled has no return statement');
190
+ return translateExpression(returns.join(' && '), agentId);
191
+ }
192
+ function parsePathVariables(agentsTs) {
193
+ const variables = [];
194
+ for (const line of agentsTs.split('\n')) {
195
+ const trimmed = line.trim();
196
+ const envWithFallback = trimmed.match(/^const (\w+) = process\.env\.(\w+)\?\.trim\(\) \|\| join\(home, '([^']+)'\);$/);
197
+ if (envWithFallback) {
198
+ variables.push({ name: envWithFallback[1], envVar: envWithFallback[2], default: `~/${envWithFallback[3]}` });
199
+ continue;
200
+ }
201
+ const envOnly = trimmed.match(/^const (\w+) = process\.env\.(\w+)\?\.trim\(\);$/);
202
+ if (envOnly) {
203
+ variables.push({ name: envOnly[1], envVar: envOnly[2] });
204
+ continue;
205
+ }
206
+ const xdg = trimmed.match(/^const (\w+) = xdgConfig \?\? join\(home, '([^']+)'\);$/);
207
+ if (xdg)
208
+ variables.push({ name: xdg[1], envVar: 'XDG_CONFIG_HOME', default: `~/${xdg[2]}` });
209
+ }
210
+ return variables;
211
+ }
212
+ function balancedBlock(source, openIndex) {
213
+ let depth = 0;
214
+ let quote = false;
215
+ for (let index = openIndex; index < source.length; index += 1) {
216
+ const char = source[index];
217
+ if (quote) {
218
+ if (char === "'")
219
+ quote = false;
220
+ continue;
221
+ }
222
+ if (char === "'") {
223
+ quote = true;
224
+ continue;
225
+ }
226
+ if (char === '{')
227
+ depth += 1;
228
+ if (char === '}') {
229
+ depth -= 1;
230
+ if (depth === 0)
231
+ return source.slice(openIndex + 1, index);
232
+ }
233
+ }
234
+ throw new SkillsManagerError('catalog_extract_unsupported', 'Unbalanced braces in upstream source');
235
+ }
236
+ /** Remove line and block comments; apostrophes inside them would otherwise break quote-aware brace balancing. */
237
+ function stripComments(source) {
238
+ let result = '';
239
+ let quote = false;
240
+ for (let index = 0; index < source.length; index += 1) {
241
+ const char = source[index];
242
+ const next = source[index + 1];
243
+ if (quote) {
244
+ result += char;
245
+ if (char === "'")
246
+ quote = false;
247
+ continue;
248
+ }
249
+ if (char === "'") {
250
+ quote = true;
251
+ result += char;
252
+ continue;
253
+ }
254
+ if (char === '/' && next === '/') {
255
+ while (index < source.length && source[index] !== '\n')
256
+ index += 1;
257
+ result += '\n';
258
+ continue;
259
+ }
260
+ if (char === '/' && next === '*') {
261
+ index += 2;
262
+ while (index < source.length && !(source[index] === '*' && source[index + 1] === '/'))
263
+ index += 1;
264
+ index += 1;
265
+ continue;
266
+ }
267
+ result += char;
268
+ }
269
+ return result;
270
+ }
271
+ function parseAgentsRecord(agentsTs) {
272
+ const source = stripComments(agentsTs);
273
+ const marker = source.indexOf('export const agents');
274
+ if (marker === -1)
275
+ throw new SkillsManagerError('catalog_extract_unsupported', 'agents record not found in upstream agents.ts');
276
+ const openBrace = source.indexOf('{', marker);
277
+ const body = balancedBlock(source, openBrace);
278
+ const members = [];
279
+ let index = 0;
280
+ while (index < body.length) {
281
+ const head = body.slice(index).match(/^\s*,?\s*(?:'([^']+)'|([a-zA-Z-]+)):\s*\{/);
282
+ if (!head)
283
+ break;
284
+ const id = head[1] || head[2];
285
+ const memberStart = index + (head[0].length - 1);
286
+ const memberBody = balancedBlock(body, memberStart);
287
+ members.push({ id, body: memberBody });
288
+ index = memberStart + memberBody.length + 2;
289
+ }
290
+ return members;
291
+ }
292
+ function translateGlobalSkillsDir(field, agentId) {
293
+ const value = field.trim();
294
+ if (value === 'undefined' || value === '')
295
+ return null;
296
+ if (value === 'getOpenClawGlobalSkillsDir()')
297
+ return '~/.openclaw/skills';
298
+ const joinMatch = value.match(/^join\((.+)\)$/s);
299
+ if (!joinMatch)
300
+ return unsupported(agentId, `unrecognized globalSkillsDir "${value}"`);
301
+ const first = joinMatch[1].split(',')[0].trim();
302
+ const tail = stringArgs(joinMatch[1]).join('/');
303
+ if (first === 'home')
304
+ return `~/${tail}`;
305
+ if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(first))
306
+ return `$${first}/${tail}`;
307
+ return unsupported(agentId, `unrecognized globalSkillsDir base "${first}"`);
308
+ }
309
+ function readField(memberBody, field) {
310
+ const match = memberBody.match(new RegExp(`^\\s*${field}:\\s*([\\s\\S]*?),\\n`, 'm'));
311
+ if (!match)
312
+ return null;
313
+ return match[1].trim();
314
+ }
315
+ function parseEnvProbes(detectAgentTs) {
316
+ const mappingBlock = detectAgentTs.match(/const agentNameToType[^=]*=\s*\{([\s\S]*?)\};/);
317
+ if (!mappingBlock)
318
+ throw new SkillsManagerError('catalog_extract_unsupported', 'agentNameToType mapping not found in upstream detect-agent.ts');
319
+ const nameToType = new Map();
320
+ for (const match of mappingBlock[1].matchAll(/(?:'([^']+)'|([a-zA-Z-]+))\s*:\s*'([^']+)'/g)) {
321
+ nameToType.set(match[1] || match[2], match[3]);
322
+ }
323
+ const rulesByName = new Map(DETERMINE_AGENT_RULES.map((rule) => [rule.name, rule]));
324
+ // Upstream refines cursor/cursor-cli hits down to strong signals only
325
+ // (weak CURSOR_TRACE_ID is present in plain Cursor terminals); replicate
326
+ // that by using the cursor-cli rule for the cursor family.
327
+ const refinesCursor = detectAgentTs.includes('hasStrongCursorAgentSignal');
328
+ const probes = new Map();
329
+ for (const [name, type] of nameToType) {
330
+ let rule = rulesByName.get(name);
331
+ if (!rule)
332
+ continue;
333
+ if (refinesCursor && (name === 'cursor' || name === 'cursor-cli'))
334
+ rule = rulesByName.get('cursor-cli');
335
+ if (!rule)
336
+ continue;
337
+ const existing = probes.get(type) || [];
338
+ const serialized = JSON.stringify(rule.condition);
339
+ if (!existing.some((condition) => JSON.stringify(condition) === serialized))
340
+ probes.set(type, [...existing, rule.condition]);
341
+ }
342
+ const merged = new Map();
343
+ for (const [type, conditions] of probes) {
344
+ merged.set(type, conditions.length === 1 ? conditions[0] : { kind: 'any', conditions });
345
+ }
346
+ return merged;
347
+ }
348
+ export function extractCatalogSnapshot(sources) {
349
+ const pathVariables = parsePathVariables(sources.agentsTs);
350
+ const envProbes = parseEnvProbes(sources.detectAgentTs);
351
+ const agents = parseAgentsRecord(sources.agentsTs).map(({ id, body }) => {
352
+ const label = readField(body, 'displayName')?.replace(/^'|'$/g, '');
353
+ const skillsDir = readField(body, 'skillsDir')?.replace(/^'|'$/g, '');
354
+ if (!label || !skillsDir)
355
+ unsupported(id, 'displayName or skillsDir missing');
356
+ const globalSkillsDir = translateGlobalSkillsDir(readField(body, 'globalSkillsDir') || 'undefined', id);
357
+ const detectMatch = body.match(/detectInstalled:\s*async\s*\(\)\s*=>\s*/);
358
+ if (!detectMatch)
359
+ unsupported(id, 'detectInstalled not found');
360
+ const afterArrow = detectMatch.index + detectMatch[0].length;
361
+ const isBlock = body[afterArrow] === '{';
362
+ const installProbe = isBlock
363
+ ? translateDetectInstalled(balancedBlock(body, afterArrow), id)
364
+ : translateExpression(body.slice(afterArrow).replace(/,\s*$/, ''), id);
365
+ return {
366
+ id,
367
+ label: label,
368
+ skillsDir: skillsDir,
369
+ globalSkillsDir,
370
+ installProbe,
371
+ envProbe: envProbes.get(id) || null,
372
+ };
373
+ });
374
+ return validateCatalogSnapshot({
375
+ version: 1,
376
+ source: {
377
+ repo: 'vercel-labs/skills',
378
+ files: ['src/agents.ts', 'src/detect-agent.ts'],
379
+ commit: sources.commit,
380
+ date: sources.date,
381
+ license: 'MIT',
382
+ notice: NOTICE,
383
+ },
384
+ pathVariables,
385
+ agents,
386
+ });
387
+ }
388
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../../src/core/catalog/extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Resolve a snapshot path template to an absolute path.
3
+ * `~` expands to homeDir; `$name` expands via the path-variables table
4
+ * (env override first, then the declared default). A variable with neither
5
+ * resolves to null — callers treat that as "rule cannot match here".
6
+ */
7
+ export function resolveCatalogTemplate(template, context) {
8
+ if (template.startsWith('$')) {
9
+ const match = template.match(/^\$([a-zA-Z][a-zA-Z0-9]*)(.*)$/);
10
+ if (!match)
11
+ return null;
12
+ const [, name, rest] = match;
13
+ const spec = context.variables.find((variable) => variable.name === name);
14
+ if (!spec)
15
+ return null;
16
+ const override = spec.envVar ? context.env[spec.envVar]?.trim() : undefined;
17
+ const base = override || spec.default;
18
+ if (!base)
19
+ return null;
20
+ const resolved = resolveCatalogTemplate(base, context);
21
+ return resolved === null ? null : resolved + rest;
22
+ }
23
+ if (template === '~')
24
+ return context.homeDir;
25
+ if (template.startsWith('~/'))
26
+ return context.homeDir + template.slice(1);
27
+ return template;
28
+ }
29
+ //# sourceMappingURL=resolve-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-path.js","sourceRoot":"","sources":["../../../src/core/catalog/resolve-path.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB,EAAE,OAAwB;IAC/E,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAC/D,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;QAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC1E,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,MAAM,IAAI,GAAG,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC;QACtC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC;IACpD,CAAC;IACD,IAAI,QAAQ,KAAK,GAAG;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC;IAC7C,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1E,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,117 @@
1
+ import { SkillsManagerError } from '../../shared/errors.js';
2
+ const AGENT_ID_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
3
+ const LEAF_KINDS = new Set(['env-set', 'env-value', 'env-matches', 'no-tty', 'path-exists', 'cwd-path-exists', 'cwd-package-dep', 'never']);
4
+ const REMEDIATION = 'The bundled agent catalog snapshot is broken. Reinstall the package, or run `skills-manager catalog refresh` to rebuild it from upstream.';
5
+ function fail(detail) {
6
+ throw new SkillsManagerError('catalog_invalid', `Invalid agent catalog snapshot: ${detail} ${REMEDIATION}`);
7
+ }
8
+ function isRecord(value) {
9
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
10
+ }
11
+ function validateVariables(variables) {
12
+ if (!Array.isArray(variables))
13
+ fail('pathVariables must be an array');
14
+ const seen = new Set();
15
+ return variables.map((raw) => {
16
+ if (!isRecord(raw))
17
+ fail('each pathVariables entry must be an object');
18
+ const name = raw.name;
19
+ if (typeof name !== 'string' || !/^[a-zA-Z][a-zA-Z0-9]*$/.test(name))
20
+ fail(`pathVariables entry has an invalid name: ${JSON.stringify(name)}`);
21
+ if (seen.has(name))
22
+ fail(`pathVariables contains a duplicate name: ${name}`);
23
+ seen.add(name);
24
+ if (raw.envVar !== undefined && typeof raw.envVar !== 'string')
25
+ fail(`pathVariables ${name}: envVar must be a string`);
26
+ if (raw.default !== undefined && typeof raw.default !== 'string')
27
+ fail(`pathVariables ${name}: default must be a string`);
28
+ return raw;
29
+ });
30
+ }
31
+ function validateCondition(condition, where) {
32
+ if (!isRecord(condition) || typeof condition.kind !== 'string')
33
+ fail(`${where} must be a detection condition object with a kind`);
34
+ const kind = condition.kind;
35
+ if (kind === 'any' || kind === 'all') {
36
+ if (!Array.isArray(condition.conditions) || condition.conditions.length === 0)
37
+ fail(`${where} (${kind}) needs a non-empty conditions array`);
38
+ condition.conditions.forEach((child, index) => validateCondition(child, `${where}.${kind}[${index}]`));
39
+ return condition;
40
+ }
41
+ if (!LEAF_KINDS.has(kind))
42
+ fail(`${where} has an unknown condition kind: ${kind}`);
43
+ if (kind === 'env-set' && typeof condition.variable !== 'string')
44
+ fail(`${where} (env-set) needs a string variable`);
45
+ if (kind === 'env-value' && (typeof condition.variable !== 'string' || typeof condition.equals !== 'string'))
46
+ fail(`${where} (env-value) needs string variable and equals`);
47
+ if (kind === 'env-matches' && (typeof condition.variable !== 'string' || typeof condition.pattern !== 'string'))
48
+ fail(`${where} (env-matches) needs string variable and pattern`);
49
+ if (kind === 'path-exists' && (typeof condition.path !== 'string' || !condition.path))
50
+ fail(`${where} (path-exists) needs a non-empty path template`);
51
+ if (kind === 'cwd-path-exists' && (typeof condition.path !== 'string' || !condition.path || condition.path.includes('..')))
52
+ fail(`${where} (cwd-path-exists) needs a non-empty relative path`);
53
+ if (kind === 'cwd-package-dep' && typeof condition.package !== 'string')
54
+ fail(`${where} (cwd-package-dep) needs a string package`);
55
+ return condition;
56
+ }
57
+ function validateAgent(raw, index, knownVariables) {
58
+ if (!isRecord(raw))
59
+ fail(`agents[${index}] must be an object`);
60
+ const id = raw.id;
61
+ if (typeof id !== 'string' || !AGENT_ID_PATTERN.test(id))
62
+ fail(`agents[${index}] has an invalid id: ${JSON.stringify(id)} (expected kebab-case like "claude-code")`);
63
+ if (typeof raw.label !== 'string' || !raw.label)
64
+ fail(`agent ${id}: label must be a non-empty string`);
65
+ if (typeof raw.skillsDir !== 'string' || !raw.skillsDir)
66
+ fail(`agent ${id}: skillsDir must be a non-empty string`);
67
+ if (raw.skillsDir.startsWith('/') || raw.skillsDir.includes('..'))
68
+ fail(`agent ${id}: skillsDir must be a relative path inside the project, got ${raw.skillsDir}`);
69
+ if (raw.globalSkillsDir !== null && typeof raw.globalSkillsDir !== 'string')
70
+ fail(`agent ${id}: globalSkillsDir must be a path template or null`);
71
+ if (typeof raw.globalSkillsDir === 'string' && !raw.globalSkillsDir)
72
+ fail(`agent ${id}: globalSkillsDir must be non-empty when present`);
73
+ if (raw.globalSkillsDir !== null && raw.globalSkillsDir !== undefined) {
74
+ const variable = variableReference(String(raw.globalSkillsDir));
75
+ if (variable && !knownVariables.has(variable))
76
+ fail(`agent ${id}: globalSkillsDir references unknown path variable $${variable}`);
77
+ }
78
+ if (raw.installProbe === undefined)
79
+ fail(`agent ${id}: installProbe is required`);
80
+ if (raw.envProbe !== null && raw.envProbe !== undefined)
81
+ validateCondition(raw.envProbe, `agent ${id} envProbe`);
82
+ const installProbe = validateCondition(raw.installProbe, `agent ${id} installProbe`);
83
+ return { ...raw, installProbe };
84
+ }
85
+ function variableReference(template) {
86
+ const match = template.match(/^\$([a-zA-Z][a-zA-Z0-9]*)(\/|$)/);
87
+ return match ? match[1] : null;
88
+ }
89
+ /** Parse and validate raw snapshot data (JSON.parse output or injected fixture). Throws a catalog_invalid error with remediation guidance. */
90
+ export function validateCatalogSnapshot(data) {
91
+ if (!isRecord(data))
92
+ fail('snapshot must be a JSON object');
93
+ if (data.version !== 1)
94
+ fail(`unsupported version ${JSON.stringify(data.version)}; expected 1`);
95
+ if (!isRecord(data.source))
96
+ fail('source stamp is missing');
97
+ for (const field of ['repo', 'commit', 'date', 'license', 'notice']) {
98
+ if (typeof data.source[field] !== 'string' || !data.source[field])
99
+ fail(`source.${field} must be a non-empty string`);
100
+ }
101
+ if (!Array.isArray(data.source.files) || data.source.files.length === 0)
102
+ fail('source.files must be a non-empty array');
103
+ if (!Array.isArray(data.agents) || data.agents.length === 0)
104
+ fail('agents must be a non-empty array');
105
+ const pathVariables = validateVariables(data.pathVariables);
106
+ const variables = new Set(pathVariables.map((variable) => variable.name));
107
+ const seen = new Set();
108
+ const agents = data.agents.map((raw, index) => {
109
+ const agent = validateAgent(raw, index, variables);
110
+ if (seen.has(agent.id))
111
+ fail(`duplicate agent id: ${agent.id}`);
112
+ seen.add(agent.id);
113
+ return agent;
114
+ });
115
+ return { ...data, pathVariables, agents };
116
+ }
117
+ //# sourceMappingURL=validate-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-snapshot.js","sourceRoot":"","sources":["../../../src/core/catalog/validate-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './model/index.js';
2
+ export * from './ports/filesystem.js';
3
+ export * from './ports/git.js';
4
+ export * from './ports/process-runner.js';
5
+ export * from './services/index.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC"}