vskill 0.5.102 → 0.5.104
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 +24 -2
- package/agents.json +1 -1
- package/dist/agents/agents-registry.d.ts +13 -2
- package/dist/agents/agents-registry.js +120 -57
- package/dist/agents/agents-registry.js.map +1 -1
- package/dist/commands/diff.d.ts +9 -0
- package/dist/commands/diff.js +139 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/eval/serve.js +25 -83
- package/dist/commands/eval/serve.js.map +1 -1
- package/dist/commands/skill.d.ts +32 -0
- package/dist/commands/skill.js +392 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/update.js +15 -4
- package/dist/commands/update.js.map +1 -1
- package/dist/core/skill-emitter.d.ts +37 -0
- package/dist/core/skill-emitter.js +333 -0
- package/dist/core/skill-emitter.js.map +1 -0
- package/dist/core/skill-generator.d.ts +27 -0
- package/dist/core/skill-generator.js +100 -0
- package/dist/core/skill-generator.js.map +1 -0
- package/dist/eval-server/api-routes.d.ts +0 -7
- package/dist/eval-server/api-routes.js +5 -29
- package/dist/eval-server/api-routes.js.map +1 -1
- package/dist/eval-server/authoring-routes.d.ts +1 -0
- package/dist/eval-server/authoring-routes.js +42 -0
- package/dist/eval-server/authoring-routes.js.map +1 -1
- package/dist/eval-server/boot-preflight.d.ts +1 -0
- package/dist/eval-server/boot-preflight.js +17 -0
- package/dist/eval-server/boot-preflight.js.map +1 -0
- package/dist/eval-server/providers.d.ts +16 -0
- package/dist/eval-server/providers.js +45 -0
- package/dist/eval-server/providers.js.map +1 -0
- package/dist/eval-server/skill-create-routes.d.ts +62 -0
- package/dist/eval-server/skill-create-routes.js +79 -132
- package/dist/eval-server/skill-create-routes.js.map +1 -1
- package/dist/eval-ui/assets/{CommandPalette-BSGTaiI4.js → CommandPalette-DiPALzlG.js} +1 -1
- package/dist/eval-ui/assets/CreateSkillPage-BMrFELep.js +12 -0
- package/dist/eval-ui/assets/{UpdateDropdown-stNmCWki.js → UpdateDropdown-Bj8kZzuR.js} +1 -1
- package/dist/eval-ui/assets/_shimNode-D3bBqrAh.js +1 -0
- package/dist/eval-ui/assets/index-BSPDkfZG.js +102 -0
- package/dist/eval-ui/assets/index-C0Gc_4KC.css +1 -0
- package/dist/eval-ui/assets/resolve-binary-DIxhrZ6O.js +2 -0
- package/dist/eval-ui/index.html +2 -2
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/installer/canonical.d.ts +2 -0
- package/dist/installer/canonical.js +35 -4
- package/dist/installer/canonical.js.map +1 -1
- package/dist/utils/agent-filter.js +5 -4
- package/dist/utils/agent-filter.js.map +1 -1
- package/dist/utils/resolve-binary.d.ts +22 -0
- package/dist/utils/resolve-binary.js +44 -0
- package/dist/utils/resolve-binary.js.map +1 -1
- package/package.json +1 -1
- package/scripts/preuninstall.cjs +2 -9
- package/dist/eval-ui/assets/index-BoCK_s7q.js +0 -91
- package/dist/eval-ui/assets/index-D5FxVeoM.css +0 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://www.npmjs.com/package/vskill"><img src="https://img.shields.io/npm/dw/vskill?color=cb3837&logo=npm&label=downloads" alt="downloads" /></a>
|
|
11
11
|
<img src="https://img.shields.io/badge/agents-49_platforms-0969DA" alt="49 agents" />
|
|
12
12
|
<img src="https://img.shields.io/badge/plugins-5-8B5CF6" alt="5 plugins" />
|
|
13
|
-
<img src="https://img.shields.io/badge/skills-
|
|
13
|
+
<img src="https://img.shields.io/badge/skills-8-10B981" alt="8 skills" />
|
|
14
14
|
<a href="https://verified-skill.com"><img src="https://img.shields.io/badge/registry-verified--skill.com-F59E0B" alt="registry" /></a>
|
|
15
15
|
<img src="https://img.shields.io/badge/license-MIT-green" alt="MIT" />
|
|
16
16
|
</p>
|
|
@@ -124,7 +124,7 @@ Then invoke as `/plugin:skill` in your agent:
|
|
|
124
124
|
| **mobile** | React Native, Expo, Flutter, SwiftUI, Jetpack Compose, app store | `appstore` |
|
|
125
125
|
| **marketing** | Social media content creation, posting, and engagement across 11 platforms, plus Slack messaging | `social-media-posting` `slack-messaging` |
|
|
126
126
|
| **google-workspace** | Google Workspace CLI (gws) for Drive, Sheets, Docs, Calendar, Chat, Admin | `gws` |
|
|
127
|
-
| **skills** | Skill discovery and
|
|
127
|
+
| **skills** | Skill discovery, recommendations, and authoring | `scout` `skill-builder` |
|
|
128
128
|
| **productivity** | Expert network survey completion and paid expertise sharing | `survey-passing` |
|
|
129
129
|
|
|
130
130
|
<br/>
|
|
@@ -166,6 +166,28 @@ vskill init Initialize vskill in a project
|
|
|
166
166
|
|
|
167
167
|
<br/>
|
|
168
168
|
|
|
169
|
+
## Skill Authoring
|
|
170
|
+
|
|
171
|
+
Create and manage universal cross-tool skills with the `vskill skill` command family.
|
|
172
|
+
The bundled `skill-builder` meta-skill drives the flow from inside any supported
|
|
173
|
+
agent host (Claude Code, Cursor, Codex, Gemini CLI, etc.) with an automatic
|
|
174
|
+
path A/B/C fallback chain.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
vskill skill new --prompt "lint markdown" --targets=claude-code,codex
|
|
178
|
+
vskill skill import ./existing-skill/SKILL.md
|
|
179
|
+
vskill skill list
|
|
180
|
+
vskill skill info skill-builder
|
|
181
|
+
vskill skill publish skill-builder
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Every emitted skill carries an `x-sw-schema-version: 1` marker on its frontmatter,
|
|
185
|
+
and ships with a `<name>-divergence.md` report that documents any frontmatter
|
|
186
|
+
fields dropped or translated per target (e.g. `allowed-tools` → OpenCode
|
|
187
|
+
`permission.bash: ask`).
|
|
188
|
+
|
|
189
|
+
<br/>
|
|
190
|
+
|
|
169
191
|
## Security Audit
|
|
170
192
|
|
|
171
193
|
Scan entire projects for security issues — not just skills:
|
package/agents.json
CHANGED
|
@@ -30,8 +30,19 @@ export interface AgentDefinition {
|
|
|
30
30
|
globalSkillsDir: string;
|
|
31
31
|
/** Whether this agent supports the universal skill format */
|
|
32
32
|
isUniversal: boolean;
|
|
33
|
-
/**
|
|
34
|
-
|
|
33
|
+
/** Detect whether the agent is installed.
|
|
34
|
+
*
|
|
35
|
+
* 0706 T-002: historically this was a literal shell string (e.g. `'which
|
|
36
|
+
* claude'`) executed through `exec()`. That pipes through `cmd.exe` on
|
|
37
|
+
* Windows where `which`, `~`, `&&`, `2>/dev/null`, etc. don't exist, so
|
|
38
|
+
* detection returned empty on Windows. New preferred form is a function
|
|
39
|
+
* that returns a boolean (using `detectBinary()` + direct fs probes).
|
|
40
|
+
*
|
|
41
|
+
* The string form is retained as a legacy escape hatch so this change is
|
|
42
|
+
* non-breaking for any external consumer who built their own registry
|
|
43
|
+
* row with a shell string. `detectInstalledAgents()` handles both shapes.
|
|
44
|
+
*/
|
|
45
|
+
detectInstalled: string | (() => Promise<boolean>);
|
|
35
46
|
/** Parent company or organization */
|
|
36
47
|
parentCompany: string;
|
|
37
48
|
/** Feature support matrix */
|
|
@@ -7,6 +7,35 @@
|
|
|
7
7
|
* Source of truth for the count: `TOTAL_AGENTS` (derived from AGENTS_REGISTRY.length).
|
|
8
8
|
* The numbers in this header are documentation only; tests assert against TOTAL_AGENTS.
|
|
9
9
|
*/
|
|
10
|
+
// 0706 T-002 / T-003: imports for function-based detectInstalled.
|
|
11
|
+
// `detectBinary` is the platform-aware replacement for literal "which <bin>"
|
|
12
|
+
// strings that fail on Windows cmd.exe.
|
|
13
|
+
//
|
|
14
|
+
// 0703 follow-up: node:fs / node:os / node:path / resolve-binary all pull
|
|
15
|
+
// node-only APIs that vite refuses to bundle for the browser. The UI imports
|
|
16
|
+
// AGENTS_REGISTRY purely for static data (ids, display names, feature
|
|
17
|
+
// flags). Lazy-import every runtime probe so the UI bundle ignores them
|
|
18
|
+
// while server callers pay a one-shot dynamic import inside `detectInstalled`.
|
|
19
|
+
async function detectBinary(binary) {
|
|
20
|
+
const mod = await import("../utils/resolve-binary.js");
|
|
21
|
+
return mod.detectBinary(binary);
|
|
22
|
+
}
|
|
23
|
+
async function fsExistsAsync(path) {
|
|
24
|
+
const fs = await import("node:fs");
|
|
25
|
+
return fs.existsSync(path);
|
|
26
|
+
}
|
|
27
|
+
async function fsReaddirAsync(path) {
|
|
28
|
+
const fs = await import("node:fs");
|
|
29
|
+
return fs.readdirSync(path);
|
|
30
|
+
}
|
|
31
|
+
async function pathJoinAsync(...parts) {
|
|
32
|
+
const p = await import("node:path");
|
|
33
|
+
return p.join(...parts);
|
|
34
|
+
}
|
|
35
|
+
async function osHomedirAsync() {
|
|
36
|
+
const os = await import("node:os");
|
|
37
|
+
return os.homedir();
|
|
38
|
+
}
|
|
10
39
|
/** 0694 (AC-US1-04): Backward-compat alias map for renamed agent ids.
|
|
11
40
|
* Consumed by `getAgent()` so existing scripts/lockfiles continue to work
|
|
12
41
|
* after a rename. Keys are legacy ids, values are current canonical ids. */
|
|
@@ -31,7 +60,7 @@ export const AGENTS_REGISTRY = [
|
|
|
31
60
|
localSkillsDir: '.amp/skills',
|
|
32
61
|
globalSkillsDir: '~/.config/agents/skills',
|
|
33
62
|
isUniversal: true,
|
|
34
|
-
detectInstalled: '
|
|
63
|
+
detectInstalled: () => detectBinary('amp'),
|
|
35
64
|
parentCompany: 'Sourcegraph',
|
|
36
65
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
37
66
|
},
|
|
@@ -41,7 +70,7 @@ export const AGENTS_REGISTRY = [
|
|
|
41
70
|
localSkillsDir: '.cline/skills',
|
|
42
71
|
globalSkillsDir: '~/.cline/skills',
|
|
43
72
|
isUniversal: true,
|
|
44
|
-
detectInstalled: '
|
|
73
|
+
detectInstalled: () => detectBinary('cline'),
|
|
45
74
|
parentCompany: 'Cline',
|
|
46
75
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
47
76
|
},
|
|
@@ -51,7 +80,7 @@ export const AGENTS_REGISTRY = [
|
|
|
51
80
|
localSkillsDir: '.codex/skills',
|
|
52
81
|
globalSkillsDir: '~/.codex/skills',
|
|
53
82
|
isUniversal: true,
|
|
54
|
-
detectInstalled: '
|
|
83
|
+
detectInstalled: () => detectBinary('codex'),
|
|
55
84
|
parentCompany: 'OpenAI',
|
|
56
85
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
57
86
|
},
|
|
@@ -61,7 +90,7 @@ export const AGENTS_REGISTRY = [
|
|
|
61
90
|
localSkillsDir: '.cursor/skills',
|
|
62
91
|
globalSkillsDir: '~/.cursor/skills',
|
|
63
92
|
isUniversal: true,
|
|
64
|
-
detectInstalled: '
|
|
93
|
+
detectInstalled: () => detectBinary('cursor'),
|
|
65
94
|
parentCompany: 'Anysphere',
|
|
66
95
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
67
96
|
},
|
|
@@ -71,7 +100,7 @@ export const AGENTS_REGISTRY = [
|
|
|
71
100
|
localSkillsDir: '.gemini/skills',
|
|
72
101
|
globalSkillsDir: '~/.gemini/skills',
|
|
73
102
|
isUniversal: true,
|
|
74
|
-
detectInstalled: '
|
|
103
|
+
detectInstalled: () => detectBinary('gemini'),
|
|
75
104
|
parentCompany: 'Google',
|
|
76
105
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: true },
|
|
77
106
|
},
|
|
@@ -86,7 +115,25 @@ export const AGENTS_REGISTRY = [
|
|
|
86
115
|
localSkillsDir: '.github/copilot/skills',
|
|
87
116
|
globalSkillsDir: '~/.config/github-copilot/skills',
|
|
88
117
|
isUniversal: true,
|
|
89
|
-
|
|
118
|
+
// 0706 T-003: pure-Node detection — the old shell pipe
|
|
119
|
+
// (`which code && ls ~/.vscode/extensions/github.copilot-* 2>/dev/null`)
|
|
120
|
+
// can't run on Windows cmd.exe (no `which`, no `~`, no `&&`, no
|
|
121
|
+
// `2>/dev/null`). Replace with a portable probe: VS Code on PATH AND
|
|
122
|
+
// at least one `github.copilot-*` dir under `~/.vscode/extensions`.
|
|
123
|
+
detectInstalled: async () => {
|
|
124
|
+
if (!(await detectBinary('code')))
|
|
125
|
+
return false;
|
|
126
|
+
const extDir = await pathJoinAsync(await osHomedirAsync(), '.vscode', 'extensions');
|
|
127
|
+
if (!(await fsExistsAsync(extDir)))
|
|
128
|
+
return false;
|
|
129
|
+
try {
|
|
130
|
+
const entries = await fsReaddirAsync(extDir);
|
|
131
|
+
return entries.some((e) => e.startsWith('github.copilot-'));
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
},
|
|
90
137
|
parentCompany: 'GitHub (Microsoft)',
|
|
91
138
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
92
139
|
},
|
|
@@ -96,7 +143,7 @@ export const AGENTS_REGISTRY = [
|
|
|
96
143
|
localSkillsDir: '.kimi/skills',
|
|
97
144
|
globalSkillsDir: '~/.config/agents/skills',
|
|
98
145
|
isUniversal: true,
|
|
99
|
-
detectInstalled: '
|
|
146
|
+
detectInstalled: () => detectBinary('kimi'),
|
|
100
147
|
parentCompany: 'Moonshot AI',
|
|
101
148
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
102
149
|
},
|
|
@@ -106,7 +153,7 @@ export const AGENTS_REGISTRY = [
|
|
|
106
153
|
localSkillsDir: '.opencode/skills',
|
|
107
154
|
globalSkillsDir: '~/.config/opencode/skills',
|
|
108
155
|
isUniversal: true,
|
|
109
|
-
detectInstalled: '
|
|
156
|
+
detectInstalled: () => detectBinary('opencode'),
|
|
110
157
|
parentCompany: 'Community',
|
|
111
158
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: true },
|
|
112
159
|
},
|
|
@@ -119,7 +166,7 @@ export const AGENTS_REGISTRY = [
|
|
|
119
166
|
localSkillsDir: '.agent/skills',
|
|
120
167
|
globalSkillsDir: '~/.gemini/antigravity/skills',
|
|
121
168
|
isUniversal: false,
|
|
122
|
-
detectInstalled: '
|
|
169
|
+
detectInstalled: () => detectBinary('antigravity'),
|
|
123
170
|
parentCompany: 'Google',
|
|
124
171
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
125
172
|
},
|
|
@@ -129,7 +176,7 @@ export const AGENTS_REGISTRY = [
|
|
|
129
176
|
localSkillsDir: '.augment/skills',
|
|
130
177
|
globalSkillsDir: '~/.augment/skills',
|
|
131
178
|
isUniversal: false,
|
|
132
|
-
detectInstalled: '
|
|
179
|
+
detectInstalled: () => detectBinary('augment'),
|
|
133
180
|
parentCompany: 'Augment',
|
|
134
181
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
135
182
|
},
|
|
@@ -139,7 +186,7 @@ export const AGENTS_REGISTRY = [
|
|
|
139
186
|
localSkillsDir: '.claude/skills',
|
|
140
187
|
globalSkillsDir: '~/.claude/skills',
|
|
141
188
|
isUniversal: false,
|
|
142
|
-
detectInstalled: '
|
|
189
|
+
detectInstalled: () => detectBinary('claude'),
|
|
143
190
|
parentCompany: 'Anthropic',
|
|
144
191
|
featureSupport: { slashCommands: true, hooks: true, mcp: true, customSystemPrompt: true },
|
|
145
192
|
pluginCacheDir: '~/.claude/plugins/cache',
|
|
@@ -151,7 +198,7 @@ export const AGENTS_REGISTRY = [
|
|
|
151
198
|
localSkillsDir: '.openclaw/skills',
|
|
152
199
|
globalSkillsDir: '~/.openclaw/skills',
|
|
153
200
|
isUniversal: false,
|
|
154
|
-
detectInstalled: '
|
|
201
|
+
detectInstalled: () => detectBinary('openclaw'),
|
|
155
202
|
parentCompany: 'Community',
|
|
156
203
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
157
204
|
},
|
|
@@ -161,7 +208,7 @@ export const AGENTS_REGISTRY = [
|
|
|
161
208
|
localSkillsDir: '.replit/skills',
|
|
162
209
|
globalSkillsDir: '~/.config/agents/skills',
|
|
163
210
|
isUniversal: false,
|
|
164
|
-
detectInstalled: '
|
|
211
|
+
detectInstalled: () => detectBinary('replit'),
|
|
165
212
|
parentCompany: 'Replit',
|
|
166
213
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
167
214
|
isRemoteOnly: true,
|
|
@@ -172,7 +219,7 @@ export const AGENTS_REGISTRY = [
|
|
|
172
219
|
localSkillsDir: '.codebuddy/skills',
|
|
173
220
|
globalSkillsDir: '~/.codebuddy/skills',
|
|
174
221
|
isUniversal: false,
|
|
175
|
-
detectInstalled: '
|
|
222
|
+
detectInstalled: () => detectBinary('codebuddy'),
|
|
176
223
|
parentCompany: 'CodeBuddy',
|
|
177
224
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
178
225
|
},
|
|
@@ -182,7 +229,7 @@ export const AGENTS_REGISTRY = [
|
|
|
182
229
|
localSkillsDir: '.commandcode/skills',
|
|
183
230
|
globalSkillsDir: '~/.commandcode/skills',
|
|
184
231
|
isUniversal: false,
|
|
185
|
-
detectInstalled: '
|
|
232
|
+
detectInstalled: () => detectBinary('command-code'),
|
|
186
233
|
parentCompany: 'Command',
|
|
187
234
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
188
235
|
},
|
|
@@ -192,7 +239,7 @@ export const AGENTS_REGISTRY = [
|
|
|
192
239
|
localSkillsDir: '.continue/skills',
|
|
193
240
|
globalSkillsDir: '~/.continue/skills',
|
|
194
241
|
isUniversal: false,
|
|
195
|
-
detectInstalled: '
|
|
242
|
+
detectInstalled: () => detectBinary('continue'),
|
|
196
243
|
parentCompany: 'Continue',
|
|
197
244
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
198
245
|
},
|
|
@@ -202,7 +249,7 @@ export const AGENTS_REGISTRY = [
|
|
|
202
249
|
localSkillsDir: '.crush/skills',
|
|
203
250
|
globalSkillsDir: '~/.config/crush/skills',
|
|
204
251
|
isUniversal: false,
|
|
205
|
-
detectInstalled: '
|
|
252
|
+
detectInstalled: () => detectBinary('crush'),
|
|
206
253
|
parentCompany: 'Crush',
|
|
207
254
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
208
255
|
},
|
|
@@ -212,7 +259,7 @@ export const AGENTS_REGISTRY = [
|
|
|
212
259
|
localSkillsDir: '.factory/skills',
|
|
213
260
|
globalSkillsDir: '~/.factory/skills',
|
|
214
261
|
isUniversal: false,
|
|
215
|
-
detectInstalled: '
|
|
262
|
+
detectInstalled: () => detectBinary('droid'),
|
|
216
263
|
parentCompany: 'Factory',
|
|
217
264
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
218
265
|
},
|
|
@@ -222,7 +269,7 @@ export const AGENTS_REGISTRY = [
|
|
|
222
269
|
localSkillsDir: '.goose/skills',
|
|
223
270
|
globalSkillsDir: '~/.config/goose/skills',
|
|
224
271
|
isUniversal: false,
|
|
225
|
-
detectInstalled: '
|
|
272
|
+
detectInstalled: () => detectBinary('goose'),
|
|
226
273
|
parentCompany: 'Block',
|
|
227
274
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: true },
|
|
228
275
|
},
|
|
@@ -232,7 +279,7 @@ export const AGENTS_REGISTRY = [
|
|
|
232
279
|
localSkillsDir: '.junie/skills',
|
|
233
280
|
globalSkillsDir: '~/.junie/skills',
|
|
234
281
|
isUniversal: false,
|
|
235
|
-
detectInstalled: '
|
|
282
|
+
detectInstalled: () => detectBinary('junie'),
|
|
236
283
|
parentCompany: 'JetBrains',
|
|
237
284
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
238
285
|
},
|
|
@@ -242,7 +289,7 @@ export const AGENTS_REGISTRY = [
|
|
|
242
289
|
localSkillsDir: '.iflow/skills',
|
|
243
290
|
globalSkillsDir: '~/.iflow/skills',
|
|
244
291
|
isUniversal: false,
|
|
245
|
-
detectInstalled: '
|
|
292
|
+
detectInstalled: () => detectBinary('iflow'),
|
|
246
293
|
parentCompany: 'iFlow',
|
|
247
294
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
248
295
|
},
|
|
@@ -252,7 +299,7 @@ export const AGENTS_REGISTRY = [
|
|
|
252
299
|
localSkillsDir: '.kilocode/skills',
|
|
253
300
|
globalSkillsDir: '~/.kilocode/skills',
|
|
254
301
|
isUniversal: false,
|
|
255
|
-
detectInstalled: '
|
|
302
|
+
detectInstalled: () => detectBinary('kilocode'),
|
|
256
303
|
parentCompany: 'Kilo Code',
|
|
257
304
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
258
305
|
},
|
|
@@ -262,7 +309,7 @@ export const AGENTS_REGISTRY = [
|
|
|
262
309
|
localSkillsDir: '.kiro/skills',
|
|
263
310
|
globalSkillsDir: '~/.kiro/skills',
|
|
264
311
|
isUniversal: false,
|
|
265
|
-
detectInstalled: '
|
|
312
|
+
detectInstalled: () => detectBinary('kiro'),
|
|
266
313
|
parentCompany: 'AWS',
|
|
267
314
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
268
315
|
},
|
|
@@ -272,7 +319,7 @@ export const AGENTS_REGISTRY = [
|
|
|
272
319
|
localSkillsDir: '.kode/skills',
|
|
273
320
|
globalSkillsDir: '~/.kode/skills',
|
|
274
321
|
isUniversal: false,
|
|
275
|
-
detectInstalled: '
|
|
322
|
+
detectInstalled: () => detectBinary('kode'),
|
|
276
323
|
parentCompany: 'Kode',
|
|
277
324
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
278
325
|
},
|
|
@@ -282,7 +329,7 @@ export const AGENTS_REGISTRY = [
|
|
|
282
329
|
localSkillsDir: '.mcpjam/skills',
|
|
283
330
|
globalSkillsDir: '~/.mcpjam/skills',
|
|
284
331
|
isUniversal: false,
|
|
285
|
-
detectInstalled: '
|
|
332
|
+
detectInstalled: () => detectBinary('mcpjam'),
|
|
286
333
|
parentCompany: 'MCPJam',
|
|
287
334
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: false },
|
|
288
335
|
},
|
|
@@ -292,7 +339,7 @@ export const AGENTS_REGISTRY = [
|
|
|
292
339
|
localSkillsDir: '.vibe/skills',
|
|
293
340
|
globalSkillsDir: '~/.vibe/skills',
|
|
294
341
|
isUniversal: false,
|
|
295
|
-
detectInstalled: '
|
|
342
|
+
detectInstalled: () => detectBinary('vibe'),
|
|
296
343
|
parentCompany: 'Mistral AI',
|
|
297
344
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
298
345
|
},
|
|
@@ -302,7 +349,7 @@ export const AGENTS_REGISTRY = [
|
|
|
302
349
|
localSkillsDir: '.mux/skills',
|
|
303
350
|
globalSkillsDir: '~/.mux/skills',
|
|
304
351
|
isUniversal: false,
|
|
305
|
-
detectInstalled: '
|
|
352
|
+
detectInstalled: () => detectBinary('mux'),
|
|
306
353
|
parentCompany: 'Mux',
|
|
307
354
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
308
355
|
},
|
|
@@ -312,7 +359,7 @@ export const AGENTS_REGISTRY = [
|
|
|
312
359
|
localSkillsDir: '.openhands/skills',
|
|
313
360
|
globalSkillsDir: '~/.openhands/skills',
|
|
314
361
|
isUniversal: false,
|
|
315
|
-
detectInstalled: '
|
|
362
|
+
detectInstalled: () => detectBinary('openhands'),
|
|
316
363
|
parentCompany: 'All Hands AI',
|
|
317
364
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
318
365
|
},
|
|
@@ -322,7 +369,7 @@ export const AGENTS_REGISTRY = [
|
|
|
322
369
|
localSkillsDir: '.pi/skills',
|
|
323
370
|
globalSkillsDir: '~/.pi/agent/skills',
|
|
324
371
|
isUniversal: false,
|
|
325
|
-
detectInstalled: '
|
|
372
|
+
detectInstalled: () => detectBinary('pi'),
|
|
326
373
|
parentCompany: 'Pi',
|
|
327
374
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
328
375
|
},
|
|
@@ -332,7 +379,7 @@ export const AGENTS_REGISTRY = [
|
|
|
332
379
|
localSkillsDir: '.qoder/skills',
|
|
333
380
|
globalSkillsDir: '~/.qoder/skills',
|
|
334
381
|
isUniversal: false,
|
|
335
|
-
detectInstalled: '
|
|
382
|
+
detectInstalled: () => detectBinary('qoder'),
|
|
336
383
|
parentCompany: 'Qoder',
|
|
337
384
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
338
385
|
},
|
|
@@ -342,7 +389,7 @@ export const AGENTS_REGISTRY = [
|
|
|
342
389
|
localSkillsDir: '.qwen/skills',
|
|
343
390
|
globalSkillsDir: '~/.qwen/skills',
|
|
344
391
|
isUniversal: false,
|
|
345
|
-
detectInstalled: '
|
|
392
|
+
detectInstalled: () => detectBinary('qwen-code'),
|
|
346
393
|
parentCompany: 'Alibaba',
|
|
347
394
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
348
395
|
},
|
|
@@ -352,7 +399,7 @@ export const AGENTS_REGISTRY = [
|
|
|
352
399
|
localSkillsDir: '.roo/skills',
|
|
353
400
|
globalSkillsDir: '~/.roo/skills',
|
|
354
401
|
isUniversal: false,
|
|
355
|
-
detectInstalled: '
|
|
402
|
+
detectInstalled: () => detectBinary('roo'),
|
|
356
403
|
parentCompany: 'Roo',
|
|
357
404
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
358
405
|
},
|
|
@@ -362,7 +409,7 @@ export const AGENTS_REGISTRY = [
|
|
|
362
409
|
localSkillsDir: '.trae/skills',
|
|
363
410
|
globalSkillsDir: '~/.trae/skills',
|
|
364
411
|
isUniversal: false,
|
|
365
|
-
detectInstalled: '
|
|
412
|
+
detectInstalled: () => detectBinary('trae'),
|
|
366
413
|
parentCompany: 'ByteDance',
|
|
367
414
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: true },
|
|
368
415
|
},
|
|
@@ -372,7 +419,7 @@ export const AGENTS_REGISTRY = [
|
|
|
372
419
|
localSkillsDir: '.trae-cn/skills',
|
|
373
420
|
globalSkillsDir: '~/.trae-cn/skills',
|
|
374
421
|
isUniversal: false,
|
|
375
|
-
detectInstalled: '
|
|
422
|
+
detectInstalled: () => detectBinary('trae-cn'),
|
|
376
423
|
parentCompany: 'ByteDance',
|
|
377
424
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: true },
|
|
378
425
|
},
|
|
@@ -382,7 +429,7 @@ export const AGENTS_REGISTRY = [
|
|
|
382
429
|
localSkillsDir: '.windsurf/skills',
|
|
383
430
|
globalSkillsDir: '~/.codeium/windsurf/skills',
|
|
384
431
|
isUniversal: false,
|
|
385
|
-
detectInstalled: '
|
|
432
|
+
detectInstalled: () => detectBinary('windsurf'),
|
|
386
433
|
parentCompany: 'Codeium',
|
|
387
434
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
388
435
|
},
|
|
@@ -392,7 +439,7 @@ export const AGENTS_REGISTRY = [
|
|
|
392
439
|
localSkillsDir: '.zencoder/skills',
|
|
393
440
|
globalSkillsDir: '~/.zencoder/skills',
|
|
394
441
|
isUniversal: false,
|
|
395
|
-
detectInstalled: '
|
|
442
|
+
detectInstalled: () => detectBinary('zencoder'),
|
|
396
443
|
parentCompany: 'ZenCoder',
|
|
397
444
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
398
445
|
},
|
|
@@ -402,7 +449,7 @@ export const AGENTS_REGISTRY = [
|
|
|
402
449
|
localSkillsDir: '.neovate/skills',
|
|
403
450
|
globalSkillsDir: '~/.neovate/skills',
|
|
404
451
|
isUniversal: false,
|
|
405
|
-
detectInstalled: '
|
|
452
|
+
detectInstalled: () => detectBinary('neovate'),
|
|
406
453
|
parentCompany: 'Neovate',
|
|
407
454
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
408
455
|
},
|
|
@@ -412,7 +459,7 @@ export const AGENTS_REGISTRY = [
|
|
|
412
459
|
localSkillsDir: '.pochi/skills',
|
|
413
460
|
globalSkillsDir: '~/.pochi/skills',
|
|
414
461
|
isUniversal: false,
|
|
415
|
-
detectInstalled: '
|
|
462
|
+
detectInstalled: () => detectBinary('pochi'),
|
|
416
463
|
parentCompany: 'Pochi',
|
|
417
464
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
418
465
|
},
|
|
@@ -422,7 +469,7 @@ export const AGENTS_REGISTRY = [
|
|
|
422
469
|
localSkillsDir: '.adal/skills',
|
|
423
470
|
globalSkillsDir: '~/.adal/skills',
|
|
424
471
|
isUniversal: false,
|
|
425
|
-
detectInstalled: '
|
|
472
|
+
detectInstalled: () => detectBinary('adal'),
|
|
426
473
|
parentCompany: 'Adal',
|
|
427
474
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
428
475
|
},
|
|
@@ -432,7 +479,7 @@ export const AGENTS_REGISTRY = [
|
|
|
432
479
|
localSkillsDir: '.cortex/skills',
|
|
433
480
|
globalSkillsDir: '~/.snowflake/cortex/skills',
|
|
434
481
|
isUniversal: false,
|
|
435
|
-
detectInstalled: '
|
|
482
|
+
detectInstalled: () => detectBinary('cortex'),
|
|
436
483
|
parentCompany: 'Cortex',
|
|
437
484
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
438
485
|
},
|
|
@@ -442,7 +489,7 @@ export const AGENTS_REGISTRY = [
|
|
|
442
489
|
localSkillsDir: '.aider/skills',
|
|
443
490
|
globalSkillsDir: '~/.aider/skills',
|
|
444
491
|
isUniversal: false,
|
|
445
|
-
detectInstalled: '
|
|
492
|
+
detectInstalled: () => detectBinary('aider'),
|
|
446
493
|
parentCompany: 'Aider',
|
|
447
494
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
448
495
|
},
|
|
@@ -452,7 +499,7 @@ export const AGENTS_REGISTRY = [
|
|
|
452
499
|
localSkillsDir: '.tabnine/skills',
|
|
453
500
|
globalSkillsDir: '~/.tabnine/skills',
|
|
454
501
|
isUniversal: false,
|
|
455
|
-
detectInstalled: '
|
|
502
|
+
detectInstalled: () => detectBinary('tabnine'),
|
|
456
503
|
parentCompany: 'Tabnine',
|
|
457
504
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
458
505
|
},
|
|
@@ -465,7 +512,7 @@ export const AGENTS_REGISTRY = [
|
|
|
465
512
|
localSkillsDir: '.devin/skills',
|
|
466
513
|
globalSkillsDir: '~/.devin/skills',
|
|
467
514
|
isUniversal: false,
|
|
468
|
-
detectInstalled: '
|
|
515
|
+
detectInstalled: () => detectBinary('devin'),
|
|
469
516
|
parentCompany: 'Cognition',
|
|
470
517
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
471
518
|
isRemoteOnly: true,
|
|
@@ -477,7 +524,7 @@ export const AGENTS_REGISTRY = [
|
|
|
477
524
|
localSkillsDir: '.bolt/skills',
|
|
478
525
|
globalSkillsDir: '~/.bolt/skills',
|
|
479
526
|
isUniversal: false,
|
|
480
|
-
detectInstalled: '
|
|
527
|
+
detectInstalled: () => detectBinary('bolt'),
|
|
481
528
|
parentCompany: 'StackBlitz',
|
|
482
529
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
483
530
|
isRemoteOnly: true,
|
|
@@ -489,7 +536,7 @@ export const AGENTS_REGISTRY = [
|
|
|
489
536
|
localSkillsDir: '.v0/skills',
|
|
490
537
|
globalSkillsDir: '~/.v0/skills',
|
|
491
538
|
isUniversal: false,
|
|
492
|
-
detectInstalled: '
|
|
539
|
+
detectInstalled: () => detectBinary('v0'),
|
|
493
540
|
parentCompany: 'Vercel',
|
|
494
541
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
495
542
|
isRemoteOnly: true,
|
|
@@ -500,7 +547,7 @@ export const AGENTS_REGISTRY = [
|
|
|
500
547
|
localSkillsDir: '.gpt-pilot/skills',
|
|
501
548
|
globalSkillsDir: '~/.gpt-pilot/skills',
|
|
502
549
|
isUniversal: false,
|
|
503
|
-
detectInstalled: '
|
|
550
|
+
detectInstalled: () => detectBinary('gpt-pilot'),
|
|
504
551
|
parentCompany: 'Pythagora',
|
|
505
552
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
506
553
|
},
|
|
@@ -510,7 +557,7 @@ export const AGENTS_REGISTRY = [
|
|
|
510
557
|
localSkillsDir: '.plandex/skills',
|
|
511
558
|
globalSkillsDir: '~/.plandex/skills',
|
|
512
559
|
isUniversal: false,
|
|
513
|
-
detectInstalled: '
|
|
560
|
+
detectInstalled: () => detectBinary('plandex'),
|
|
514
561
|
parentCompany: 'Plandex',
|
|
515
562
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
516
563
|
},
|
|
@@ -520,7 +567,7 @@ export const AGENTS_REGISTRY = [
|
|
|
520
567
|
localSkillsDir: '.sweep/skills',
|
|
521
568
|
globalSkillsDir: '~/.sweep/skills',
|
|
522
569
|
isUniversal: false,
|
|
523
|
-
detectInstalled: '
|
|
570
|
+
detectInstalled: () => detectBinary('sweep'),
|
|
524
571
|
parentCompany: 'Sweep AI',
|
|
525
572
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
526
573
|
},
|
|
@@ -530,7 +577,7 @@ export const AGENTS_REGISTRY = [
|
|
|
530
577
|
localSkillsDir: '.mentat/skills',
|
|
531
578
|
globalSkillsDir: '~/.mentat/skills',
|
|
532
579
|
isUniversal: false,
|
|
533
|
-
detectInstalled: '
|
|
580
|
+
detectInstalled: () => detectBinary('mentat'),
|
|
534
581
|
parentCompany: 'AbanteAI',
|
|
535
582
|
featureSupport: { slashCommands: false, hooks: false, mcp: false, customSystemPrompt: true },
|
|
536
583
|
},
|
|
@@ -545,7 +592,7 @@ export const AGENTS_REGISTRY = [
|
|
|
545
592
|
localSkillsDir: '.copilot/skills',
|
|
546
593
|
globalSkillsDir: '~/.copilot/skills',
|
|
547
594
|
isUniversal: false,
|
|
548
|
-
detectInstalled: '
|
|
595
|
+
detectInstalled: () => detectBinary('copilot'),
|
|
549
596
|
parentCompany: 'GitHub (Microsoft)',
|
|
550
597
|
featureSupport: { slashCommands: true, hooks: false, mcp: true, customSystemPrompt: true },
|
|
551
598
|
},
|
|
@@ -559,7 +606,7 @@ export const AGENTS_REGISTRY = [
|
|
|
559
606
|
localSkillsDir: '.warp/skills',
|
|
560
607
|
globalSkillsDir: '~/.warp/skills',
|
|
561
608
|
isUniversal: false,
|
|
562
|
-
detectInstalled: '
|
|
609
|
+
detectInstalled: () => detectBinary('warp'),
|
|
563
610
|
parentCompany: 'Warp',
|
|
564
611
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: true },
|
|
565
612
|
},
|
|
@@ -573,7 +620,7 @@ export const AGENTS_REGISTRY = [
|
|
|
573
620
|
localSkillsDir: '.amazonq/skills',
|
|
574
621
|
globalSkillsDir: '~/.aws/amazonq/skills',
|
|
575
622
|
isUniversal: false,
|
|
576
|
-
detectInstalled: '
|
|
623
|
+
detectInstalled: () => detectBinary('q'),
|
|
577
624
|
parentCompany: 'AWS',
|
|
578
625
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: true },
|
|
579
626
|
},
|
|
@@ -588,7 +635,7 @@ export const AGENTS_REGISTRY = [
|
|
|
588
635
|
localSkillsDir: '.zed/skills',
|
|
589
636
|
globalSkillsDir: '~/.config/zed/skills',
|
|
590
637
|
isUniversal: false,
|
|
591
|
-
detectInstalled: '
|
|
638
|
+
detectInstalled: () => detectBinary('zed'),
|
|
592
639
|
parentCompany: 'Zed Industries',
|
|
593
640
|
featureSupport: { slashCommands: false, hooks: false, mcp: true, customSystemPrompt: true },
|
|
594
641
|
},
|
|
@@ -739,11 +786,27 @@ export async function detectInstalledAgents() {
|
|
|
739
786
|
// so the Tier 2 directory fallback would false-positive without this guard.
|
|
740
787
|
if (agent.isRemoteOnly === true)
|
|
741
788
|
return;
|
|
742
|
-
// Tier 1: CLI binary detection
|
|
789
|
+
// Tier 1: CLI binary detection.
|
|
790
|
+
//
|
|
791
|
+
// 0706 T-002: `detectInstalled` can be a legacy shell string (e.g.
|
|
792
|
+
// `'which claude'`) OR a function returning `Promise<boolean>`. Strings
|
|
793
|
+
// still go through exec (kept for backward compat with any external
|
|
794
|
+
// consumer that built rows the old way); functions are called directly
|
|
795
|
+
// — they own their own platform branching via `detectBinary()`.
|
|
743
796
|
try {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
797
|
+
const detector = agent.detectInstalled;
|
|
798
|
+
if (typeof detector === 'function') {
|
|
799
|
+
const ok = await detector();
|
|
800
|
+
if (ok) {
|
|
801
|
+
results.push(agent);
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
await execAsync(detector);
|
|
807
|
+
results.push(agent);
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
747
810
|
}
|
|
748
811
|
catch {
|
|
749
812
|
// Binary not found — try directory fallback
|