bmad-module-ultracode-goal 0.1.0
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/.claude-plugin/marketplace.json +20 -0
- package/.gitattributes +16 -0
- package/.nvmrc +1 -0
- package/LICENSE +27 -0
- package/README.md +200 -0
- package/docs/_internal/RELEASING.md +101 -0
- package/docs/_internal/STABILITY.md +62 -0
- package/docs/architecture.md +77 -0
- package/docs/assets/ucg-logo.svg +73 -0
- package/docs/gate-model.md +109 -0
- package/docs/getting-started.md +51 -0
- package/docs/health-check.md +61 -0
- package/docs/how-it-works.md +73 -0
- package/docs/index.md +25 -0
- package/docs/parallel-mode.md +33 -0
- package/docs/troubleshooting.md +56 -0
- package/docs/why-ultracode-goal.md +34 -0
- package/package.json +100 -0
- package/skills/.gitkeep +0 -0
- package/skills/module.yaml +12 -0
- package/skills/ultracode-goal/SKILL.md +75 -0
- package/skills/ultracode-goal/assets/execute-epic.workflow.js +208 -0
- package/skills/ultracode-goal/customize.toml +47 -0
- package/skills/ultracode-goal/references/define-done.md +41 -0
- package/skills/ultracode-goal/references/execute.md +90 -0
- package/skills/ultracode-goal/references/finalize.md +64 -0
- package/skills/ultracode-goal/references/gate.md +70 -0
- package/skills/ultracode-goal/references/health-check.md +332 -0
- package/skills/ultracode-goal/references/ingest-and-scope.md +46 -0
- package/skills/ultracode-goal/references/preflight.md +100 -0
- package/skills/ultracode-goal/scripts/gate_eval.py +280 -0
- package/skills/ultracode-goal/scripts/health_check_fp.py +196 -0
- package/skills/ultracode-goal/scripts/hooks/budget_stop.py +162 -0
- package/skills/ultracode-goal/scripts/hooks/guard_pretooluse.py +174 -0
- package/skills/ultracode-goal/scripts/preflight_check.py +399 -0
- package/tools/cli/commands/install.js +36 -0
- package/tools/cli/commands/status.js +161 -0
- package/tools/cli/commands/uninstall.js +175 -0
- package/tools/cli/commands/update.js +65 -0
- package/tools/cli/lib/ide-skills.js +218 -0
- package/tools/cli/lib/installer.js +226 -0
- package/tools/cli/lib/manifest.js +100 -0
- package/tools/cli/lib/platform-codes.yaml +223 -0
- package/tools/cli/lib/ui.js +353 -0
- package/tools/cli/lib/version-check.js +86 -0
- package/tools/cli/ucg-cli.js +45 -0
- package/tools/ucg-npx-wrapper.js +36 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UCG Installer - Core orchestrator
|
|
3
|
+
* Copies the ultracode-goal skill, installs it to IDEs, writes config + manifest.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const path = require('node:path');
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const { spinner } = require('@clack/prompts');
|
|
9
|
+
const yaml = require('js-yaml');
|
|
10
|
+
const { installSkillsToIdes } = require('./ide-skills');
|
|
11
|
+
const { writeManifest } = require('./manifest');
|
|
12
|
+
|
|
13
|
+
// Dev-only artifacts never shipped into a user's project
|
|
14
|
+
const DEV_ARTIFACTS = new Set(['.analysis', '.decision-log.md', '__pycache__', '.pytest_cache', '.DS_Store', 'Thumbs.db']);
|
|
15
|
+
|
|
16
|
+
class Installer {
|
|
17
|
+
constructor() {
|
|
18
|
+
// Resolve directories relative to this file (tools/cli/lib/ -> up 3 levels)
|
|
19
|
+
const repoRoot = path.resolve(__dirname, '..', '..', '..');
|
|
20
|
+
this.srcDir = path.join(repoRoot, 'skills');
|
|
21
|
+
this.docsDir = path.join(repoRoot, 'docs');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async install(config) {
|
|
25
|
+
const { projectDir, ucgFolder } = config;
|
|
26
|
+
const ucgDir = path.join(projectDir, ucgFolder);
|
|
27
|
+
const action = config._action || 'fresh';
|
|
28
|
+
const s = spinner();
|
|
29
|
+
|
|
30
|
+
// Handle update vs fresh for existing installation
|
|
31
|
+
if (action === 'update' && (await fs.pathExists(ucgDir))) {
|
|
32
|
+
const configPath = path.join(ucgDir, 'config.yaml');
|
|
33
|
+
if (!config._savedConfigYaml && (await fs.pathExists(configPath))) {
|
|
34
|
+
config._savedConfigYaml = await fs.readFile(configPath, 'utf8');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// On update, extract settings from saved config
|
|
38
|
+
if (config._savedConfigYaml) {
|
|
39
|
+
try {
|
|
40
|
+
const savedData = yaml.load(config._savedConfigYaml);
|
|
41
|
+
if (!config.ides && savedData.ides) config.ides = savedData.ides;
|
|
42
|
+
if (config.install_learning == null && savedData.install_learning != null) config.install_learning = savedData.install_learning;
|
|
43
|
+
} catch {
|
|
44
|
+
/* ignore parse errors, defaults will apply */
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
s.start('Updating UCG files...');
|
|
49
|
+
await fs.remove(ucgDir);
|
|
50
|
+
s.stop('Old files cleared');
|
|
51
|
+
} else if (action === 'fresh' && (await fs.pathExists(ucgDir))) {
|
|
52
|
+
s.start('Removing existing UCG installation...');
|
|
53
|
+
await fs.remove(ucgDir);
|
|
54
|
+
s.stop('Old installation removed');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Ensure parent directory exists (for _bmad/ucg/)
|
|
58
|
+
await fs.ensureDir(path.dirname(ucgDir));
|
|
59
|
+
|
|
60
|
+
// Step 1: Copy source files
|
|
61
|
+
s.start('Copying UCG files...');
|
|
62
|
+
try {
|
|
63
|
+
await this.copySrcFiles(ucgDir);
|
|
64
|
+
s.stop('UCG files copied');
|
|
65
|
+
} catch (error) {
|
|
66
|
+
s.stop('Failed to copy UCG files');
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Step 2: Update .gitignore (the skill merges hooks into .claude/settings.local.json
|
|
71
|
+
// at preflight — that file must never be committed)
|
|
72
|
+
await this.updateGitignore(projectDir);
|
|
73
|
+
|
|
74
|
+
// Step 3: Write config.yaml
|
|
75
|
+
s.start('Writing configuration...');
|
|
76
|
+
try {
|
|
77
|
+
await this.writeConfig(ucgDir, config);
|
|
78
|
+
s.stop('Configuration saved');
|
|
79
|
+
} catch (error) {
|
|
80
|
+
s.stop('Failed to write configuration');
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Step 4: Copy learning material (optional)
|
|
85
|
+
if (config.install_learning !== false) {
|
|
86
|
+
s.start('Copying learning & reference material...');
|
|
87
|
+
try {
|
|
88
|
+
await this.copyLearningMaterial(projectDir);
|
|
89
|
+
s.stop('Learning material added to _ucg-learn/');
|
|
90
|
+
} catch (error) {
|
|
91
|
+
s.stop('Failed to copy learning material');
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Step 5: Install the skill to selected IDEs
|
|
97
|
+
let ideDirectories = [];
|
|
98
|
+
const selectedIdes = config.ides || [];
|
|
99
|
+
if (selectedIdes.length > 0) {
|
|
100
|
+
s.start('Installing the skill to IDEs...');
|
|
101
|
+
try {
|
|
102
|
+
const ideResult = await installSkillsToIdes(projectDir, ucgDir, selectedIdes);
|
|
103
|
+
ideDirectories = ideResult.directories || [];
|
|
104
|
+
if (ideResult.installed > 0) {
|
|
105
|
+
s.stop(`Skill installed for ${ideResult.ides.join(', ')}`);
|
|
106
|
+
} else {
|
|
107
|
+
s.stop('No IDE skill installation needed');
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
s.stop('Failed to install the skill to IDEs');
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Step 6: Write installation manifest
|
|
116
|
+
s.start('Writing manifest...');
|
|
117
|
+
try {
|
|
118
|
+
const packageJson = require('../../../package.json');
|
|
119
|
+
await writeManifest(projectDir, config, {
|
|
120
|
+
version: packageJson.version,
|
|
121
|
+
ideDirectories,
|
|
122
|
+
});
|
|
123
|
+
s.stop('Installation manifest saved');
|
|
124
|
+
} catch (error) {
|
|
125
|
+
s.stop('Failed to write manifest');
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return { success: true, ucgDir, projectDir };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Copy skills/ content into the target UCG directory.
|
|
134
|
+
* The single ultracode-goal skill directory is copied alongside module.yaml,
|
|
135
|
+
* filtering out dev/test artifacts that have no place in a user's project.
|
|
136
|
+
*/
|
|
137
|
+
async copySrcFiles(ucgDir) {
|
|
138
|
+
const copyFilter = (src) => {
|
|
139
|
+
const base = path.basename(src);
|
|
140
|
+
if (DEV_ARTIFACTS.has(base)) return false;
|
|
141
|
+
// Skip pytest suites — dev-only, not needed at runtime
|
|
142
|
+
if (base === 'tests' && path.basename(path.dirname(src)) === 'scripts') return false;
|
|
143
|
+
return true;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// Copy skill directories — each is a self-contained skill
|
|
147
|
+
const srcEntries = await fs.readdir(this.srcDir, { withFileTypes: true });
|
|
148
|
+
for (const entry of srcEntries) {
|
|
149
|
+
if (entry.isDirectory()) {
|
|
150
|
+
await fs.copy(path.join(this.srcDir, entry.name), path.join(ucgDir, entry.name), { filter: copyFilter });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Copy the module manifest
|
|
155
|
+
const moduleYaml = path.join(this.srcDir, 'module.yaml');
|
|
156
|
+
if (await fs.pathExists(moduleYaml)) {
|
|
157
|
+
await fs.copy(moduleYaml, path.join(ucgDir, 'module.yaml'));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Write VERSION file for UCG version resolution in installed projects
|
|
161
|
+
const packageJson = require('../../../package.json');
|
|
162
|
+
await fs.writeFile(path.join(ucgDir, 'VERSION'), packageJson.version, 'utf8');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async writeConfig(ucgDir, config) {
|
|
166
|
+
// On update, restore the user's existing config
|
|
167
|
+
if (config._savedConfigYaml) {
|
|
168
|
+
await fs.writeFile(path.join(ucgDir, 'config.yaml'), config._savedConfigYaml, 'utf8');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Get user name from git or system
|
|
173
|
+
const getUserName = () => {
|
|
174
|
+
try {
|
|
175
|
+
const { execSync } = require('node:child_process');
|
|
176
|
+
return execSync('git config user.name', { encoding: 'utf8' }).trim() || 'Developer';
|
|
177
|
+
} catch {
|
|
178
|
+
return 'Developer';
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const configData = {
|
|
183
|
+
user_name: getUserName(),
|
|
184
|
+
project_name: config.project_name || 'Untitled Project',
|
|
185
|
+
communication_language: 'en',
|
|
186
|
+
document_output_language: 'en',
|
|
187
|
+
output_folder: config.output_folder || '_bmad-output',
|
|
188
|
+
ucg_folder: config.ucgFolder,
|
|
189
|
+
ides: config.ides || [],
|
|
190
|
+
install_learning: config.install_learning !== false,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const yamlStr = yaml.dump(configData, { lineWidth: -1 });
|
|
194
|
+
await fs.writeFile(path.join(ucgDir, 'config.yaml'), `# UCG Configuration - Generated by installer\n${yamlStr}`, 'utf8');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async updateGitignore(projectDir) {
|
|
198
|
+
const gitignorePath = path.join(projectDir, '.gitignore');
|
|
199
|
+
const entry = '.claude/settings.local.json';
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
if (await fs.pathExists(gitignorePath)) {
|
|
203
|
+
const content = await fs.readFile(gitignorePath, 'utf8');
|
|
204
|
+
// Check if entry already present (exact line match)
|
|
205
|
+
const lines = content.split('\n');
|
|
206
|
+
if (lines.some((line) => line.trim() === entry)) return;
|
|
207
|
+
// Append with preceding newline if file doesn't end with one
|
|
208
|
+
const prefix = content.endsWith('\n') ? '' : '\n';
|
|
209
|
+
await fs.appendFile(gitignorePath, `${prefix}${entry}\n`, 'utf8');
|
|
210
|
+
} else {
|
|
211
|
+
await fs.writeFile(gitignorePath, `${entry}\n`, 'utf8');
|
|
212
|
+
}
|
|
213
|
+
} catch {
|
|
214
|
+
// Non-critical — don't fail the install over .gitignore
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async copyLearningMaterial(projectDir) {
|
|
219
|
+
const learnDir = path.join(projectDir, '_ucg-learn');
|
|
220
|
+
if (await fs.pathExists(this.docsDir)) {
|
|
221
|
+
await fs.copy(this.docsDir, learnDir);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
module.exports = { Installer };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UCG Manifest - Tracks installed files for uninstall and smart updates.
|
|
3
|
+
* Writes _bmad/_config/ucg-manifest.yaml after each install.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const path = require('node:path');
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const yaml = require('js-yaml');
|
|
9
|
+
|
|
10
|
+
const MANIFEST_DIR = '_bmad/_config';
|
|
11
|
+
const MANIFEST_FILE = 'ucg-manifest.yaml';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Recursively collect all file paths under a directory,
|
|
15
|
+
* returned as paths relative to projectDir.
|
|
16
|
+
*/
|
|
17
|
+
async function collectFiles(dir, projectDir) {
|
|
18
|
+
const files = [];
|
|
19
|
+
if (!(await fs.pathExists(dir))) return files;
|
|
20
|
+
|
|
21
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
22
|
+
for (const entry of entries) {
|
|
23
|
+
const fullPath = path.join(dir, entry.name);
|
|
24
|
+
if (entry.isDirectory()) {
|
|
25
|
+
const subFiles = await collectFiles(fullPath, projectDir);
|
|
26
|
+
files.push(...subFiles);
|
|
27
|
+
} else {
|
|
28
|
+
files.push(path.relative(projectDir, fullPath));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return files;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Build and write the manifest after installation.
|
|
36
|
+
*
|
|
37
|
+
* @param {string} projectDir - Project root
|
|
38
|
+
* @param {object} config - Install config (ucgFolder, ides, etc.)
|
|
39
|
+
* @param {object} options - Additional info (version, ideDirectories)
|
|
40
|
+
*/
|
|
41
|
+
async function writeManifest(projectDir, config, options = {}) {
|
|
42
|
+
const ucgFolder = config.ucgFolder || '_bmad/ucg';
|
|
43
|
+
const ucgDir = path.join(projectDir, ucgFolder);
|
|
44
|
+
|
|
45
|
+
// Collect all installed files
|
|
46
|
+
const ucgFiles = await collectFiles(ucgDir, projectDir);
|
|
47
|
+
|
|
48
|
+
// Collect IDE skill directory files (installed to each IDE's skills/ dir)
|
|
49
|
+
const ideDirectories = options.ideDirectories || [];
|
|
50
|
+
const ideSkillFiles = [];
|
|
51
|
+
for (const ideDir of ideDirectories) {
|
|
52
|
+
const fullDir = path.join(projectDir, ideDir);
|
|
53
|
+
const files = await collectFiles(fullDir, projectDir);
|
|
54
|
+
ideSkillFiles.push(...files);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Collect learning material files
|
|
58
|
+
const learnDir = path.join(projectDir, '_ucg-learn');
|
|
59
|
+
const learnFiles = await collectFiles(learnDir, projectDir);
|
|
60
|
+
|
|
61
|
+
const manifest = {
|
|
62
|
+
version: options.version || 'unknown',
|
|
63
|
+
installed_at: new Date().toISOString(),
|
|
64
|
+
action: config._action || 'fresh',
|
|
65
|
+
module: 'ucg',
|
|
66
|
+
ucg_folder: ucgFolder,
|
|
67
|
+
ides: config.ides || [],
|
|
68
|
+
directories: [ucgFolder, ...ideDirectories, ...(learnFiles.length > 0 ? ['_ucg-learn'] : [])],
|
|
69
|
+
files: {
|
|
70
|
+
ucg: ucgFiles,
|
|
71
|
+
ide_skills: ideSkillFiles,
|
|
72
|
+
learning: learnFiles,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const manifestDir = path.join(projectDir, MANIFEST_DIR);
|
|
77
|
+
await fs.ensureDir(manifestDir);
|
|
78
|
+
|
|
79
|
+
const yamlStr = yaml.dump(manifest, { lineWidth: -1, sortKeys: false });
|
|
80
|
+
await fs.writeFile(
|
|
81
|
+
path.join(manifestDir, MANIFEST_FILE),
|
|
82
|
+
`# UCG Installation Manifest - Generated by installer\n# Do not edit manually\n${yamlStr}`,
|
|
83
|
+
'utf8',
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Read an existing manifest, or return null if none exists.
|
|
89
|
+
*/
|
|
90
|
+
async function readManifest(projectDir) {
|
|
91
|
+
const manifestPath = path.join(projectDir, MANIFEST_DIR, MANIFEST_FILE);
|
|
92
|
+
try {
|
|
93
|
+
const content = await fs.readFile(manifestPath, 'utf8');
|
|
94
|
+
return yaml.load(content) || null;
|
|
95
|
+
} catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = { writeManifest, readManifest, MANIFEST_DIR, MANIFEST_FILE };
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# BMAD Platform Codes Configuration
|
|
2
|
+
#
|
|
3
|
+
# Each platform entry has:
|
|
4
|
+
# name: Display name shown to users
|
|
5
|
+
# preferred: Whether shown as a recommended option on install
|
|
6
|
+
# suspended: (optional) Message explaining why install is blocked
|
|
7
|
+
# skill_invocation_prefix: (optional) Prefix users type to invoke a named
|
|
8
|
+
# skill in this IDE's chat. Examples:
|
|
9
|
+
# "/" — slash command, e.g. /ultracode-goal (most IDEs)
|
|
10
|
+
# "$" — dollar mention, e.g. $ultracode-goal (Codex)
|
|
11
|
+
# "/skill:" — namespaced slash, e.g. /skill:ultracode-goal (Pi)
|
|
12
|
+
# Omit when the IDE only auto-invokes skills from descriptions and has
|
|
13
|
+
# no manual invocation form (Cline, GitHub Copilot, Junie, etc.).
|
|
14
|
+
# installer:
|
|
15
|
+
# target_dir: Directory where skill directories are installed
|
|
16
|
+
# legacy_targets: (optional) Old target dirs to clean up on reinstall
|
|
17
|
+
platforms:
|
|
18
|
+
antigravity:
|
|
19
|
+
name: "Google Antigravity"
|
|
20
|
+
preferred: false
|
|
21
|
+
skill_invocation_prefix: "/"
|
|
22
|
+
installer:
|
|
23
|
+
detection_marker: .agent/antigravity
|
|
24
|
+
legacy_targets:
|
|
25
|
+
- .agent/workflows
|
|
26
|
+
target_dir: .agent/skills
|
|
27
|
+
|
|
28
|
+
auggie:
|
|
29
|
+
name: "Auggie"
|
|
30
|
+
preferred: false
|
|
31
|
+
skill_invocation_prefix: "/"
|
|
32
|
+
installer:
|
|
33
|
+
legacy_targets:
|
|
34
|
+
- .augment/commands
|
|
35
|
+
target_dir: .augment/skills
|
|
36
|
+
|
|
37
|
+
claude-code:
|
|
38
|
+
name: "Claude Code"
|
|
39
|
+
preferred: true
|
|
40
|
+
skill_invocation_prefix: "/"
|
|
41
|
+
installer:
|
|
42
|
+
legacy_targets:
|
|
43
|
+
- .claude/commands
|
|
44
|
+
target_dir: .claude/skills
|
|
45
|
+
|
|
46
|
+
cline:
|
|
47
|
+
name: "Cline"
|
|
48
|
+
preferred: false
|
|
49
|
+
# Auto-invoked from descriptions; no manual prefix
|
|
50
|
+
installer:
|
|
51
|
+
detection_marker: .clinerules
|
|
52
|
+
legacy_targets:
|
|
53
|
+
- .clinerules/workflows
|
|
54
|
+
target_dir: .cline/skills
|
|
55
|
+
|
|
56
|
+
codex:
|
|
57
|
+
name: "Codex"
|
|
58
|
+
preferred: false
|
|
59
|
+
skill_invocation_prefix: "$"
|
|
60
|
+
installer:
|
|
61
|
+
detection_marker: .codex
|
|
62
|
+
legacy_targets:
|
|
63
|
+
- .codex/prompts
|
|
64
|
+
target_dir: .agents/skills
|
|
65
|
+
|
|
66
|
+
codebuddy:
|
|
67
|
+
name: "CodeBuddy"
|
|
68
|
+
preferred: false
|
|
69
|
+
skill_invocation_prefix: "/"
|
|
70
|
+
installer:
|
|
71
|
+
legacy_targets:
|
|
72
|
+
- .codebuddy/commands
|
|
73
|
+
target_dir: .codebuddy/skills
|
|
74
|
+
|
|
75
|
+
crush:
|
|
76
|
+
name: "Crush"
|
|
77
|
+
preferred: false
|
|
78
|
+
# Auto-invoked from descriptions; no manual prefix
|
|
79
|
+
installer:
|
|
80
|
+
legacy_targets:
|
|
81
|
+
- .crush/commands
|
|
82
|
+
target_dir: .crush/skills
|
|
83
|
+
|
|
84
|
+
cursor:
|
|
85
|
+
name: "Cursor"
|
|
86
|
+
preferred: true
|
|
87
|
+
skill_invocation_prefix: "/"
|
|
88
|
+
installer:
|
|
89
|
+
legacy_targets:
|
|
90
|
+
- .cursor/commands
|
|
91
|
+
target_dir: .cursor/skills
|
|
92
|
+
|
|
93
|
+
gemini:
|
|
94
|
+
name: "Gemini CLI"
|
|
95
|
+
preferred: false
|
|
96
|
+
skill_invocation_prefix: "/"
|
|
97
|
+
installer:
|
|
98
|
+
legacy_targets:
|
|
99
|
+
- .gemini/commands
|
|
100
|
+
target_dir: .gemini/skills
|
|
101
|
+
|
|
102
|
+
github-copilot:
|
|
103
|
+
name: "GitHub Copilot"
|
|
104
|
+
preferred: false
|
|
105
|
+
# Auto-invoked from descriptions; no manual prefix
|
|
106
|
+
installer:
|
|
107
|
+
detection_marker: .github/copilot-instructions.md
|
|
108
|
+
legacy_targets:
|
|
109
|
+
- .github/agents
|
|
110
|
+
- .github/prompts
|
|
111
|
+
target_dir: .github/skills
|
|
112
|
+
|
|
113
|
+
iflow:
|
|
114
|
+
name: "iFlow"
|
|
115
|
+
preferred: false
|
|
116
|
+
skill_invocation_prefix: "/"
|
|
117
|
+
installer:
|
|
118
|
+
legacy_targets:
|
|
119
|
+
- .iflow/commands
|
|
120
|
+
target_dir: .iflow/skills
|
|
121
|
+
|
|
122
|
+
junie:
|
|
123
|
+
name: "Junie"
|
|
124
|
+
preferred: false
|
|
125
|
+
# Auto-invoked from descriptions; no manual prefix
|
|
126
|
+
installer:
|
|
127
|
+
target_dir: .junie/skills
|
|
128
|
+
|
|
129
|
+
kilo:
|
|
130
|
+
name: "KiloCoder"
|
|
131
|
+
preferred: false
|
|
132
|
+
# Auto-invoked from descriptions; no manual prefix
|
|
133
|
+
installer:
|
|
134
|
+
legacy_targets:
|
|
135
|
+
- .kilocode/workflows
|
|
136
|
+
target_dir: .kilocode/skills
|
|
137
|
+
|
|
138
|
+
kiro:
|
|
139
|
+
name: "Kiro"
|
|
140
|
+
preferred: false
|
|
141
|
+
# Auto-invoked from descriptions; no manual prefix
|
|
142
|
+
installer:
|
|
143
|
+
legacy_targets:
|
|
144
|
+
- .kiro/steering
|
|
145
|
+
target_dir: .kiro/skills
|
|
146
|
+
|
|
147
|
+
ona:
|
|
148
|
+
name: "Ona"
|
|
149
|
+
preferred: false
|
|
150
|
+
skill_invocation_prefix: "/"
|
|
151
|
+
installer:
|
|
152
|
+
target_dir: .ona/skills
|
|
153
|
+
|
|
154
|
+
opencode:
|
|
155
|
+
name: "OpenCode"
|
|
156
|
+
preferred: false
|
|
157
|
+
skill_invocation_prefix: "/"
|
|
158
|
+
installer:
|
|
159
|
+
legacy_targets:
|
|
160
|
+
- .opencode/agents
|
|
161
|
+
- .opencode/commands
|
|
162
|
+
- .opencode/agent
|
|
163
|
+
- .opencode/command
|
|
164
|
+
target_dir: .opencode/skills
|
|
165
|
+
|
|
166
|
+
pi:
|
|
167
|
+
name: "Pi"
|
|
168
|
+
preferred: false
|
|
169
|
+
skill_invocation_prefix: "/skill:"
|
|
170
|
+
installer:
|
|
171
|
+
target_dir: .pi/skills
|
|
172
|
+
|
|
173
|
+
qoder:
|
|
174
|
+
name: "Qoder"
|
|
175
|
+
preferred: false
|
|
176
|
+
skill_invocation_prefix: "/"
|
|
177
|
+
installer:
|
|
178
|
+
target_dir: .qoder/skills
|
|
179
|
+
|
|
180
|
+
qwen:
|
|
181
|
+
name: "QwenCoder"
|
|
182
|
+
preferred: false
|
|
183
|
+
skill_invocation_prefix: "/"
|
|
184
|
+
installer:
|
|
185
|
+
legacy_targets:
|
|
186
|
+
- .qwen/commands
|
|
187
|
+
target_dir: .qwen/skills
|
|
188
|
+
|
|
189
|
+
roo:
|
|
190
|
+
name: "Roo Code"
|
|
191
|
+
preferred: false
|
|
192
|
+
skill_invocation_prefix: "/"
|
|
193
|
+
installer:
|
|
194
|
+
legacy_targets:
|
|
195
|
+
- .roo/commands
|
|
196
|
+
target_dir: .roo/skills
|
|
197
|
+
|
|
198
|
+
rovo-dev:
|
|
199
|
+
name: "Rovo Dev"
|
|
200
|
+
preferred: false
|
|
201
|
+
# Auto-invoked from descriptions; no manual prefix
|
|
202
|
+
installer:
|
|
203
|
+
legacy_targets:
|
|
204
|
+
- .rovodev/workflows
|
|
205
|
+
target_dir: .rovodev/skills
|
|
206
|
+
|
|
207
|
+
trae:
|
|
208
|
+
name: "Trae"
|
|
209
|
+
preferred: false
|
|
210
|
+
# Auto-invoked from descriptions; no manual prefix
|
|
211
|
+
installer:
|
|
212
|
+
legacy_targets:
|
|
213
|
+
- .trae/rules
|
|
214
|
+
target_dir: .trae/skills
|
|
215
|
+
|
|
216
|
+
windsurf:
|
|
217
|
+
name: "Windsurf"
|
|
218
|
+
preferred: false
|
|
219
|
+
skill_invocation_prefix: "/"
|
|
220
|
+
installer:
|
|
221
|
+
legacy_targets:
|
|
222
|
+
- .windsurf/workflows
|
|
223
|
+
target_dir: .windsurf/skills
|