sdd-toolkit 2.0.2 → 2.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/package.json +1 -1
- package/src/index.js +102 -107
- package/src/lib/messages.js +6 -3
- package/src/lib/transformers.js +40 -26
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -6,9 +6,9 @@ const path = require('path');
|
|
|
6
6
|
const { intro, outro, multiselect, spinner, note, select, text } = require('@clack/prompts');
|
|
7
7
|
const pc = require('picocolors');
|
|
8
8
|
|
|
9
|
-
// Internal Modules
|
|
10
|
-
const { loadAgents } = require('./lib/agents');
|
|
11
|
-
const { setLocale, t, getLocale } = require('./lib/i18n');
|
|
9
|
+
// Internal Modules
|
|
10
|
+
const { loadAgents } = require('./lib/agents');
|
|
11
|
+
const { setLocale, t, getLocale } = require('./lib/i18n');
|
|
12
12
|
const {
|
|
13
13
|
toGeminiTOML,
|
|
14
14
|
toRooConfig,
|
|
@@ -19,7 +19,8 @@ const {
|
|
|
19
19
|
toClaudeCommand,
|
|
20
20
|
toPlainSystemPrompt,
|
|
21
21
|
toTraeRules,
|
|
22
|
-
|
|
22
|
+
toOpenCodeSkill,
|
|
23
|
+
toAntigravitySkill
|
|
23
24
|
} = require('./lib/transformers');
|
|
24
25
|
const { generateWorkflowGuide } = require('./lib/docs');
|
|
25
26
|
const { view } = require('./commands/view');
|
|
@@ -71,11 +72,12 @@ async function main() {
|
|
|
71
72
|
if (fs.existsSync(path.join(process.cwd(), '.claude'))) tools.push('claude');
|
|
72
73
|
if (fs.existsSync(path.join(process.cwd(), '.trae'))) tools.push('trae');
|
|
73
74
|
if (fs.existsSync(path.join(process.cwd(), '.kilocode'))) tools.push('kilo');
|
|
74
|
-
if (fs.existsSync(path.join(process.cwd(), '.github'))) tools.push('copilot');
|
|
75
|
+
if (fs.existsSync(path.join(process.cwd(), '.github'))) tools.push('copilot');
|
|
75
76
|
if (fs.existsSync(path.join(process.cwd(), '.roo'))) tools.push('roo');
|
|
76
77
|
if (fs.existsSync(path.join(process.cwd(), '.opencode'))) tools.push('opencode');
|
|
77
78
|
if (fs.existsSync(path.join(process.cwd(), 'prompts'))) tools.push('web');
|
|
78
79
|
|
|
80
|
+
if (fs.existsSync(path.join(process.cwd(), '.antigravity'))) tools.push('antigravity');
|
|
79
81
|
if (tools.length === 0) {
|
|
80
82
|
note(t('UPGRADE.NO_CONFIG'), t('UPGRADE.NO_CONFIG_TITLE'));
|
|
81
83
|
} else {
|
|
@@ -99,10 +101,10 @@ async function main() {
|
|
|
99
101
|
}
|
|
100
102
|
} catch (e) {
|
|
101
103
|
s.stop(pc.red(t('SCAFFOLD.ERROR')));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// 2. Feature 3: Global Rules
|
|
105
|
-
const globalRules = await text({
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 2. Feature 3: Global Rules
|
|
107
|
+
const globalRules = await text({
|
|
106
108
|
message: t('SETUP.GLOBAL_RULES'),
|
|
107
109
|
placeholder: t('SETUP.GLOBAL_RULES_HINT'),
|
|
108
110
|
required: false
|
|
@@ -127,7 +129,8 @@ async function main() {
|
|
|
127
129
|
{ value: 'kilo', label: t('TOOLS.KILO'), hint: '.kilocode/workflows/*.md' },
|
|
128
130
|
{ value: 'copilot', label: t('TOOLS.COPILOT'), hint: '.github/prompts/*.md' },
|
|
129
131
|
{ value: 'web', label: t('TOOLS.WEB'), hint: 'prompts/*.txt' },
|
|
130
|
-
{ value: 'opencode', label: t('TOOLS.OPENCODE'), hint: '.opencode/
|
|
132
|
+
{ value: 'opencode', label: t('TOOLS.OPENCODE'), hint: '.opencode/skills/*' },
|
|
133
|
+
{ value: 'antigravity', label: t('TOOLS.ANTIGRAVITY'), hint: '.antigravity/skills/*' }
|
|
131
134
|
],
|
|
132
135
|
required: true,
|
|
133
136
|
hint: t('SETUP.TOOL_HINT')
|
|
@@ -175,17 +178,17 @@ async function processAgentsInstallation(tools, options) {
|
|
|
175
178
|
})
|
|
176
179
|
);
|
|
177
180
|
},
|
|
178
|
-
roo: async (validAgents, options) => {
|
|
179
|
-
const targetDir = path.join(process.cwd(), '.roo', 'commands');
|
|
180
|
-
await fsp.mkdir(targetDir, { recursive: true });
|
|
181
|
-
|
|
182
|
-
await Promise.all(
|
|
183
|
-
validAgents.map((agent) => {
|
|
184
|
-
const md = toOpenCodeAgent(agent, options);
|
|
185
|
-
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
186
|
-
})
|
|
187
|
-
);
|
|
188
|
-
},
|
|
181
|
+
roo: async (validAgents, options) => {
|
|
182
|
+
const targetDir = path.join(process.cwd(), '.roo', 'commands');
|
|
183
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
184
|
+
|
|
185
|
+
await Promise.all(
|
|
186
|
+
validAgents.map((agent) => {
|
|
187
|
+
const md = toOpenCodeAgent(agent, options);
|
|
188
|
+
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
189
|
+
})
|
|
190
|
+
);
|
|
191
|
+
},
|
|
189
192
|
cline: async (validAgents, options) => {
|
|
190
193
|
const targetDir = path.join(process.cwd(), '.cline');
|
|
191
194
|
await fsp.mkdir(targetDir, { recursive: true });
|
|
@@ -212,31 +215,31 @@ async function processAgentsInstallation(tools, options) {
|
|
|
212
215
|
})
|
|
213
216
|
);
|
|
214
217
|
},
|
|
215
|
-
claude: async (validAgents, options) => {
|
|
216
|
-
const targetDir = path.join(process.cwd(), '.claude', 'commands', 'agents');
|
|
217
|
-
await fsp.mkdir(targetDir, { recursive: true });
|
|
218
|
-
|
|
219
|
-
await Promise.all(
|
|
220
|
-
validAgents.map((agent) => {
|
|
221
|
-
const md = toClaudeCommand(agent, options);
|
|
222
|
-
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
223
|
-
})
|
|
224
|
-
);
|
|
225
|
-
},
|
|
226
|
-
cursor: async (validAgents, options) => {
|
|
227
|
-
const commandsDir = path.join(process.cwd(), '.cursor', 'commands');
|
|
228
|
-
await fsp.mkdir(commandsDir, { recursive: true });
|
|
229
|
-
|
|
230
|
-
await Promise.all(
|
|
231
|
-
validAgents.map((agent) => {
|
|
232
|
-
const mdc = toCursorMDC(agent, options);
|
|
233
|
-
return fsp.writeFile(path.join(commandsDir, `${agent.slug}.mdc`), mdc);
|
|
234
|
-
})
|
|
235
|
-
);
|
|
236
|
-
},
|
|
237
|
-
kilo: async (validAgents, options) => {
|
|
238
|
-
const targetDir = path.join(process.cwd(), '.kilocode', 'workflows');
|
|
239
|
-
await fsp.mkdir(targetDir, { recursive: true });
|
|
218
|
+
claude: async (validAgents, options) => {
|
|
219
|
+
const targetDir = path.join(process.cwd(), '.claude', 'commands', 'agents');
|
|
220
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
221
|
+
|
|
222
|
+
await Promise.all(
|
|
223
|
+
validAgents.map((agent) => {
|
|
224
|
+
const md = toClaudeCommand(agent, options);
|
|
225
|
+
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
},
|
|
229
|
+
cursor: async (validAgents, options) => {
|
|
230
|
+
const commandsDir = path.join(process.cwd(), '.cursor', 'commands');
|
|
231
|
+
await fsp.mkdir(commandsDir, { recursive: true });
|
|
232
|
+
|
|
233
|
+
await Promise.all(
|
|
234
|
+
validAgents.map((agent) => {
|
|
235
|
+
const mdc = toCursorMDC(agent, options);
|
|
236
|
+
return fsp.writeFile(path.join(commandsDir, `${agent.slug}.mdc`), mdc);
|
|
237
|
+
})
|
|
238
|
+
);
|
|
239
|
+
},
|
|
240
|
+
kilo: async (validAgents, options) => {
|
|
241
|
+
const targetDir = path.join(process.cwd(), '.kilocode', 'workflows');
|
|
242
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
240
243
|
|
|
241
244
|
await Promise.all(
|
|
242
245
|
validAgents.map((agent) => {
|
|
@@ -245,22 +248,22 @@ async function processAgentsInstallation(tools, options) {
|
|
|
245
248
|
})
|
|
246
249
|
);
|
|
247
250
|
},
|
|
248
|
-
copilot: async (validAgents, options) => {
|
|
249
|
-
const githubDir = path.join(process.cwd(), '.github');
|
|
250
|
-
const promptsDir = path.join(githubDir, 'prompts');
|
|
251
|
-
await fsp.mkdir(promptsDir, { recursive: true });
|
|
252
|
-
|
|
253
|
-
await Promise.all(
|
|
254
|
-
validAgents.map((agent) => {
|
|
255
|
-
const md = toCopilotInstructions(agent, options);
|
|
256
|
-
return fsp.writeFile(path.join(promptsDir, `${agent.slug}.md`), md);
|
|
257
|
-
})
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
const mainAgent = validAgents.find((a) => a.slug.includes('coder')) || validAgents[0];
|
|
261
|
-
const mainInstructions = toCopilotInstructions(mainAgent, options);
|
|
262
|
-
await fsp.writeFile(path.join(githubDir, 'prompts.md'), mainInstructions);
|
|
263
|
-
},
|
|
251
|
+
copilot: async (validAgents, options) => {
|
|
252
|
+
const githubDir = path.join(process.cwd(), '.github');
|
|
253
|
+
const promptsDir = path.join(githubDir, 'prompts');
|
|
254
|
+
await fsp.mkdir(promptsDir, { recursive: true });
|
|
255
|
+
|
|
256
|
+
await Promise.all(
|
|
257
|
+
validAgents.map((agent) => {
|
|
258
|
+
const md = toCopilotInstructions(agent, options);
|
|
259
|
+
return fsp.writeFile(path.join(promptsDir, `${agent.slug}.md`), md);
|
|
260
|
+
})
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
const mainAgent = validAgents.find((a) => a.slug.includes('coder')) || validAgents[0];
|
|
264
|
+
const mainInstructions = toCopilotInstructions(mainAgent, options);
|
|
265
|
+
await fsp.writeFile(path.join(githubDir, 'prompts.md'), mainInstructions);
|
|
266
|
+
},
|
|
264
267
|
trae: async (validAgents, options) => {
|
|
265
268
|
const traeDir = path.join(process.cwd(), '.trae');
|
|
266
269
|
await fsp.mkdir(traeDir, { recursive: true });
|
|
@@ -280,51 +283,43 @@ async function processAgentsInstallation(tools, options) {
|
|
|
280
283
|
})
|
|
281
284
|
);
|
|
282
285
|
},
|
|
283
|
-
opencode: async (validAgents, options) => {
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
await
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
let userRules = '';
|
|
321
|
-
if (options.globalRules && options.globalRules.trim()) {
|
|
322
|
-
userRules = '\n\n# User Specified Rules\n\n' + options.globalRules.split('\n').filter(line => line.trim()).map(line => '- ' + line.trim()).join('\n');
|
|
323
|
-
}
|
|
324
|
-
agentsMdContent += userRules;
|
|
325
|
-
|
|
326
|
-
await fsp.writeFile(agentsMdPath, agentsMdContent);
|
|
327
|
-
}
|
|
286
|
+
opencode: async (validAgents, options) => {
|
|
287
|
+
const skillsDir = path.join(process.cwd(), '.opencode', 'skills');
|
|
288
|
+
|
|
289
|
+
// Ensure base directory exists
|
|
290
|
+
await fsp.mkdir(skillsDir, { recursive: true });
|
|
291
|
+
|
|
292
|
+
await Promise.all(
|
|
293
|
+
validAgents.map(async (agent) => {
|
|
294
|
+
// Create specific folder for the skill: .opencode/skills/[agent-slug]/
|
|
295
|
+
// Ensure compatibility with naming rules (lowercase, alphanumeric, single hyphens)
|
|
296
|
+
const skillName = agent.slug.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
297
|
+
const agentSkillDir = path.join(skillsDir, skillName);
|
|
298
|
+
|
|
299
|
+
await fsp.mkdir(agentSkillDir, { recursive: true });
|
|
300
|
+
|
|
301
|
+
const skillContent = toOpenCodeSkill(agent, options);
|
|
302
|
+
return fsp.writeFile(path.join(agentSkillDir, 'SKILL.md'), skillContent);
|
|
303
|
+
})
|
|
304
|
+
);
|
|
305
|
+
},
|
|
306
|
+
antigravity: async (validAgents, options) => {
|
|
307
|
+
const skillsDir = path.join(process.cwd(), '.antigravity', 'skills');
|
|
308
|
+
|
|
309
|
+
// Ensure base directory exists (though we will mkdir for each agent)
|
|
310
|
+
await fsp.mkdir(skillsDir, { recursive: true });
|
|
311
|
+
|
|
312
|
+
await Promise.all(
|
|
313
|
+
validAgents.map(async (agent) => {
|
|
314
|
+
// Create specific folder for the skill: .antigravity/skills/[agent-slug]/
|
|
315
|
+
const agentSkillDir = path.join(skillsDir, agent.slug);
|
|
316
|
+
await fsp.mkdir(agentSkillDir, { recursive: true });
|
|
317
|
+
|
|
318
|
+
const skillContent = toAntigravitySkill(agent, options);
|
|
319
|
+
return fsp.writeFile(path.join(agentSkillDir, 'SKILL.md'), skillContent);
|
|
320
|
+
})
|
|
321
|
+
);
|
|
322
|
+
}
|
|
328
323
|
};
|
|
329
324
|
|
|
330
325
|
for (const tool of tools) {
|
package/src/lib/messages.js
CHANGED
|
@@ -51,7 +51,8 @@ const EN = {
|
|
|
51
51
|
KILO: 'Kilo Code',
|
|
52
52
|
COPILOT: 'GitHub Copilot',
|
|
53
53
|
WEB: 'OpenAI / Claude',
|
|
54
|
-
OPENCODE: 'OpenCode',
|
|
54
|
+
OPENCODE: 'OpenCode (Skills)',
|
|
55
|
+
ANTIGRAVITY: 'Antigravity (Skills)',
|
|
55
56
|
},
|
|
56
57
|
LANGUAGE_RULES: {
|
|
57
58
|
EN: 'Always reply in English unless told otherwise.',
|
|
@@ -124,7 +125,8 @@ const PT_BR = {
|
|
|
124
125
|
KILO: 'Kilo Code',
|
|
125
126
|
COPILOT: 'GitHub Copilot',
|
|
126
127
|
WEB: 'OpenAI / Claude',
|
|
127
|
-
OPENCODE: 'OpenCode',
|
|
128
|
+
OPENCODE: 'OpenCode (Skills)',
|
|
129
|
+
ANTIGRAVITY: 'Antigravity (Skills)',
|
|
128
130
|
},
|
|
129
131
|
LANGUAGE_RULES: {
|
|
130
132
|
EN: 'Always reply in English unless told otherwise.',
|
|
@@ -197,7 +199,8 @@ const ES = {
|
|
|
197
199
|
KILO: 'Kilo Code',
|
|
198
200
|
COPILOT: 'GitHub Copilot',
|
|
199
201
|
WEB: 'OpenAI / Claude',
|
|
200
|
-
OPENCODE: 'OpenCode',
|
|
202
|
+
OPENCODE: 'OpenCode (Skills)',
|
|
203
|
+
ANTIGRAVITY: 'Antigravity (Skills)',
|
|
201
204
|
},
|
|
202
205
|
LANGUAGE_RULES: {
|
|
203
206
|
EN: 'Always reply in English unless told otherwise.',
|
package/src/lib/transformers.js
CHANGED
|
@@ -252,44 +252,34 @@ ${allRules.length > 0 ? '## Constraints\n' + allRules.map(r => `- ${r}`).join('\
|
|
|
252
252
|
`;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
+
|
|
255
256
|
/**
|
|
256
|
-
* Converte para OpenCode
|
|
257
|
+
* Converte para OpenCode Skill (SKILL.md)
|
|
258
|
+
* Ref: https://opencode.ai/docs/skills/
|
|
257
259
|
*/
|
|
258
|
-
function
|
|
260
|
+
function toOpenCodeSkill(agent, options = {}) {
|
|
259
261
|
const languageRule = getLanguageRule(options.locale);
|
|
260
262
|
const allRules = [languageRule, ...(agent.rules || [])];
|
|
261
263
|
|
|
262
|
-
//
|
|
263
|
-
const
|
|
264
|
-
const tools = {
|
|
265
|
-
write: !isReadOnly,
|
|
266
|
-
edit: !isReadOnly,
|
|
267
|
-
bash: !isReadOnly
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
const frontmatter = {
|
|
271
|
-
description: agent.description || agent.role,
|
|
272
|
-
mode: 'subagent',
|
|
273
|
-
temperature: 0.3,
|
|
274
|
-
tools
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
const frontmatterStr = Object.entries(frontmatter)
|
|
278
|
-
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
|
279
|
-
.join('\n');
|
|
264
|
+
// Ensure slug is compliant (lowercase, alphanumeric, single hyphens)
|
|
265
|
+
const skillName = agent.slug.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
280
266
|
|
|
281
267
|
return `---
|
|
282
|
-
${
|
|
268
|
+
name: ${skillName}
|
|
269
|
+
description: ${agent.description || agent.role}
|
|
270
|
+
license: MIT
|
|
271
|
+
compatibility: opencode
|
|
272
|
+
metadata:
|
|
273
|
+
role: ${agent.role}
|
|
283
274
|
---
|
|
284
|
-
|
|
285
275
|
# ${agent.name} ${agent.emoji}
|
|
286
276
|
|
|
287
277
|
**Role**: ${agent.role}
|
|
288
278
|
|
|
279
|
+
## Instructions
|
|
289
280
|
${agent.systemPrompt.trim()}
|
|
290
281
|
|
|
291
|
-
## Rules
|
|
292
|
-
${allRules.map(rule => `- ${rule}`).join('\n')}
|
|
282
|
+
${allRules.length > 0 ? '## Rules & Guidelines\n' + allRules.map(r => `- ${r}`).join('\n') : ''}
|
|
293
283
|
`;
|
|
294
284
|
}
|
|
295
285
|
|
|
@@ -312,6 +302,29 @@ ${allRules.length > 0 ? '## Constraints\n' + allRules.map(r => `- ${r}`).join('\
|
|
|
312
302
|
`;
|
|
313
303
|
}
|
|
314
304
|
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Converte para Antigravity Skill (SKILL.md)
|
|
308
|
+
*/
|
|
309
|
+
function toAntigravitySkill(agent, options = {}) {
|
|
310
|
+
const languageRule = getLanguageRule(options.locale);
|
|
311
|
+
const allRules = [languageRule, ...(agent.rules || [])];
|
|
312
|
+
|
|
313
|
+
return `---
|
|
314
|
+
name: ${agent.name}
|
|
315
|
+
description: ${agent.description || agent.role}
|
|
316
|
+
---
|
|
317
|
+
# ${agent.name} ${agent.emoji}
|
|
318
|
+
|
|
319
|
+
**Role**: ${agent.role}
|
|
320
|
+
|
|
321
|
+
## Instructions
|
|
322
|
+
${agent.systemPrompt.trim()}
|
|
323
|
+
|
|
324
|
+
${allRules.length > 0 ? '## Rules & Guidelines\n' + allRules.map(r => `- ${r}`).join('\n') : ''}
|
|
325
|
+
`;
|
|
326
|
+
}
|
|
327
|
+
|
|
315
328
|
module.exports = {
|
|
316
329
|
toGeminiTOML,
|
|
317
330
|
toRooConfig,
|
|
@@ -321,6 +334,7 @@ module.exports = {
|
|
|
321
334
|
toWindsurfRules,
|
|
322
335
|
toClaudeCommand,
|
|
323
336
|
toPlainSystemPrompt,
|
|
324
|
-
|
|
325
|
-
toTraeRules
|
|
337
|
+
toOpenCodeSkill,
|
|
338
|
+
toTraeRules,
|
|
339
|
+
toAntigravitySkill
|
|
326
340
|
};
|