musubi-sdd 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/LICENSE +21 -0
- package/README.ja.md +531 -0
- package/README.md +531 -0
- package/bin/musubi-init.js +321 -0
- package/bin/musubi.js +359 -0
- package/package.json +55 -0
- package/src/agents/registry.js +242 -0
- package/src/templates/agents/claude-code/CLAUDE.md +232 -0
- package/src/templates/agents/claude-code/commands/sdd-design.md +673 -0
- package/src/templates/agents/claude-code/commands/sdd-implement.md +777 -0
- package/src/templates/agents/claude-code/commands/sdd-requirements.md +438 -0
- package/src/templates/agents/claude-code/commands/sdd-steering.md +334 -0
- package/src/templates/agents/claude-code/commands/sdd-tasks.md +582 -0
- package/src/templates/agents/claude-code/commands/sdd-validate.md +710 -0
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/SKILL.md +3055 -0
- package/src/templates/agents/claude-code/skills/api-designer/SKILL.md +1364 -0
- package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +482 -0
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/SKILL.md +397 -0
- package/src/templates/agents/claude-code/skills/cloud-architect/SKILL.md +1468 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +906 -0
- package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +466 -0
- package/src/templates/agents/claude-code/skills/database-administrator/SKILL.md +3522 -0
- package/src/templates/agents/claude-code/skills/database-schema-designer/SKILL.md +1158 -0
- package/src/templates/agents/claude-code/skills/devops-engineer/SKILL.md +647 -0
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +574 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +464 -0
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +769 -0
- package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +1059 -0
- package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +653 -0
- package/src/templates/agents/claude-code/skills/requirements-analyst/SKILL.md +1287 -0
- package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +1107 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +404 -0
- package/src/templates/agents/claude-code/skills/software-developer/SKILL.md +1254 -0
- package/src/templates/agents/claude-code/skills/steering/SKILL.md +383 -0
- package/src/templates/agents/claude-code/skills/system-architect/SKILL.md +1288 -0
- package/src/templates/agents/claude-code/skills/technical-writer/SKILL.md +712 -0
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +1262 -0
- package/src/templates/agents/claude-code/skills/traceability-auditor/SKILL.md +298 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1009 -0
- package/src/templates/agents/codex/AGENTS.md +138 -0
- package/src/templates/agents/codex/commands/sdd-design.md +673 -0
- package/src/templates/agents/codex/commands/sdd-implement.md +777 -0
- package/src/templates/agents/codex/commands/sdd-requirements.md +438 -0
- package/src/templates/agents/codex/commands/sdd-steering.md +334 -0
- package/src/templates/agents/codex/commands/sdd-tasks.md +582 -0
- package/src/templates/agents/codex/commands/sdd-validate.md +710 -0
- package/src/templates/agents/cursor/AGENTS.md +138 -0
- package/src/templates/agents/cursor/commands/sdd-design.md +673 -0
- package/src/templates/agents/cursor/commands/sdd-implement.md +777 -0
- package/src/templates/agents/cursor/commands/sdd-requirements.md +438 -0
- package/src/templates/agents/cursor/commands/sdd-steering.md +334 -0
- package/src/templates/agents/cursor/commands/sdd-tasks.md +582 -0
- package/src/templates/agents/cursor/commands/sdd-validate.md +710 -0
- package/src/templates/agents/gemini-cli/GEMINI.md +128 -0
- package/src/templates/agents/gemini-cli/commands/sdd-design.toml +359 -0
- package/src/templates/agents/gemini-cli/commands/sdd-implement.toml +484 -0
- package/src/templates/agents/gemini-cli/commands/sdd-requirements.toml +291 -0
- package/src/templates/agents/gemini-cli/commands/sdd-steering.toml +209 -0
- package/src/templates/agents/gemini-cli/commands/sdd-tasks.toml +441 -0
- package/src/templates/agents/gemini-cli/commands/sdd-validate.toml +553 -0
- package/src/templates/agents/github-copilot/AGENTS.md +138 -0
- package/src/templates/agents/github-copilot/commands/sdd-design.md +673 -0
- package/src/templates/agents/github-copilot/commands/sdd-implement.md +777 -0
- package/src/templates/agents/github-copilot/commands/sdd-requirements.md +438 -0
- package/src/templates/agents/github-copilot/commands/sdd-steering.md +334 -0
- package/src/templates/agents/github-copilot/commands/sdd-tasks.md +582 -0
- package/src/templates/agents/github-copilot/commands/sdd-validate.md +710 -0
- package/src/templates/agents/qwen-code/QWEN.md +128 -0
- package/src/templates/agents/qwen-code/commands/sdd-design.md +673 -0
- package/src/templates/agents/qwen-code/commands/sdd-implement.md +777 -0
- package/src/templates/agents/qwen-code/commands/sdd-requirements.md +438 -0
- package/src/templates/agents/qwen-code/commands/sdd-steering.md +334 -0
- package/src/templates/agents/qwen-code/commands/sdd-tasks.md +582 -0
- package/src/templates/agents/qwen-code/commands/sdd-validate.md +710 -0
- package/src/templates/agents/windsurf/AGENTS.md +138 -0
- package/src/templates/agents/windsurf/commands/sdd-design.md +673 -0
- package/src/templates/agents/windsurf/commands/sdd-implement.md +777 -0
- package/src/templates/agents/windsurf/commands/sdd-requirements.md +438 -0
- package/src/templates/agents/windsurf/commands/sdd-steering.md +334 -0
- package/src/templates/agents/windsurf/commands/sdd-tasks.md +582 -0
- package/src/templates/agents/windsurf/commands/sdd-validate.md +710 -0
- package/src/templates/shared/constitution/constitution.md +408 -0
- package/src/templates/shared/constitution/ears-format.md +613 -0
- package/src/templates/shared/constitution/workflow.md +653 -0
- package/src/templates/shared/documents/design.md +737 -0
- package/src/templates/shared/documents/requirements.md +329 -0
- package/src/templates/shared/documents/research.md +494 -0
- package/src/templates/shared/documents/tasks.md +781 -0
- package/src/templates/shared/steering/product.md +544 -0
- package/src/templates/shared/steering/structure.md +405 -0
- package/src/templates/shared/steering/tech.md +537 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MUSUBI Initialization Script
|
|
5
|
+
*
|
|
6
|
+
* Initializes a new project with MUSUBI SDD tools for various AI coding agents:
|
|
7
|
+
* - Claude Code: .claude/skills/ (25 skills) + .claude/commands/
|
|
8
|
+
* - GitHub Copilot: .github/prompts/
|
|
9
|
+
* - Cursor: .cursor/commands/
|
|
10
|
+
* - Gemini CLI: .gemini/commands/
|
|
11
|
+
* - Codex CLI: .codex/prompts/
|
|
12
|
+
* - Qwen Code: .qwen/commands/
|
|
13
|
+
* - Windsurf: .windsurf/workflows/
|
|
14
|
+
*
|
|
15
|
+
* All agents get:
|
|
16
|
+
* - steering/ directory with project memory
|
|
17
|
+
* - templates/ for documents
|
|
18
|
+
* - Constitutional governance
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const fs = require('fs-extra');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const chalk = require('chalk');
|
|
24
|
+
const inquirer = require('inquirer');
|
|
25
|
+
|
|
26
|
+
const TEMPLATE_DIR = path.join(__dirname, '..', 'src', 'templates');
|
|
27
|
+
const SHARED_TEMPLATE_DIR = path.join(TEMPLATE_DIR, 'shared');
|
|
28
|
+
const AGENTS_TEMPLATE_DIR = path.join(TEMPLATE_DIR, 'agents');
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Main initialization function
|
|
32
|
+
* @param {object} agent - Agent definition from registry
|
|
33
|
+
* @param {string} agentKey - Agent key (e.g., 'claude-code', 'cursor')
|
|
34
|
+
*/
|
|
35
|
+
async function main(agent, agentKey) {
|
|
36
|
+
// If called directly without agent parameter, default to Claude Code
|
|
37
|
+
if (!agent) {
|
|
38
|
+
const { getAgentDefinition } = require('../src/agents/registry');
|
|
39
|
+
agent = getAgentDefinition('claude-code');
|
|
40
|
+
agentKey = 'claude-code';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log(chalk.blue.bold('\n🎯 MUSUBI - Ultimate Specification Driven Development\n'));
|
|
44
|
+
console.log(chalk.white(`Initializing for: ${chalk.bold(agent.label)}\n`));
|
|
45
|
+
|
|
46
|
+
// Check if already initialized for this agent
|
|
47
|
+
const agentDir = agent.layout.agentDir;
|
|
48
|
+
if (fs.existsSync(agentDir)) {
|
|
49
|
+
const { overwrite } = await inquirer.prompt([
|
|
50
|
+
{
|
|
51
|
+
type: 'confirm',
|
|
52
|
+
name: 'overwrite',
|
|
53
|
+
message: `MUSUBI for ${agent.label} is already initialized. Overwrite?`,
|
|
54
|
+
default: false
|
|
55
|
+
}
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
if (!overwrite) {
|
|
59
|
+
console.log(chalk.yellow('Initialization cancelled.'));
|
|
60
|
+
process.exit(0);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Collect project information
|
|
65
|
+
const prompts = [
|
|
66
|
+
{
|
|
67
|
+
type: 'input',
|
|
68
|
+
name: 'projectName',
|
|
69
|
+
message: 'Project name:',
|
|
70
|
+
default: path.basename(process.cwd())
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
type: 'input',
|
|
74
|
+
name: 'description',
|
|
75
|
+
message: 'Project description:',
|
|
76
|
+
default: 'A software project using MUSUBI SDD'
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: 'list',
|
|
80
|
+
name: 'projectType',
|
|
81
|
+
message: 'Project type:',
|
|
82
|
+
choices: ['Greenfield (0→1)', 'Brownfield (1→n)', 'Both']
|
|
83
|
+
}
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
// Skills selection is only for Claude Code (Skills API exclusive)
|
|
87
|
+
if (agent.features.hasSkills) {
|
|
88
|
+
prompts.push({
|
|
89
|
+
type: 'checkbox',
|
|
90
|
+
name: 'skills',
|
|
91
|
+
message: 'Select skills to install (all recommended):',
|
|
92
|
+
choices: [
|
|
93
|
+
{ name: 'Core (orchestrator, steering, constitution-enforcer)', value: 'core', checked: true },
|
|
94
|
+
{ name: 'Requirements & Planning (requirements-analyst, project-manager, change-impact-analyzer)', value: 'requirements', checked: true },
|
|
95
|
+
{ name: 'Architecture & Design (system-architect, api-designer, database-schema-designer, ui-ux-designer)', value: 'architecture', checked: true },
|
|
96
|
+
{ name: 'Development (software-developer)', value: 'development', checked: true },
|
|
97
|
+
{ name: 'Quality & Review (test-engineer, code-reviewer, bug-hunter, quality-assurance, traceability-auditor)', value: 'quality', checked: true },
|
|
98
|
+
{ name: 'Security & Performance (security-auditor, performance-optimizer)', value: 'security', checked: true },
|
|
99
|
+
{ name: 'Infrastructure (devops-engineer, cloud-architect, database-administrator, site-reliability-engineer, release-coordinator)', value: 'infrastructure', checked: true },
|
|
100
|
+
{ name: 'Documentation (technical-writer, ai-ml-engineer)', value: 'documentation', checked: true }
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
prompts.push(
|
|
106
|
+
{
|
|
107
|
+
type: 'confirm',
|
|
108
|
+
name: 'createSteering',
|
|
109
|
+
message: 'Generate initial steering context?',
|
|
110
|
+
default: true
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
type: 'confirm',
|
|
114
|
+
name: 'createConstitution',
|
|
115
|
+
message: 'Create constitutional governance?',
|
|
116
|
+
default: true
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const answers = await inquirer.prompt(prompts);
|
|
121
|
+
|
|
122
|
+
console.log(chalk.green('\n✨ Initializing MUSUBI...\n'));
|
|
123
|
+
|
|
124
|
+
// Create directory structure (agent-specific + shared)
|
|
125
|
+
const dirs = [
|
|
126
|
+
'steering',
|
|
127
|
+
'steering/rules',
|
|
128
|
+
'templates',
|
|
129
|
+
'storage/specs',
|
|
130
|
+
'storage/changes',
|
|
131
|
+
'storage/features'
|
|
132
|
+
];
|
|
133
|
+
|
|
134
|
+
// Add agent-specific directories
|
|
135
|
+
if (agent.layout.skillsDir) {
|
|
136
|
+
dirs.unshift(agent.layout.skillsDir);
|
|
137
|
+
}
|
|
138
|
+
if (agent.layout.commandsDir) {
|
|
139
|
+
dirs.unshift(agent.layout.commandsDir);
|
|
140
|
+
}
|
|
141
|
+
if (agent.layout.agentDir && !dirs.includes(agent.layout.agentDir)) {
|
|
142
|
+
dirs.unshift(agent.layout.agentDir);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
for (const dir of dirs) {
|
|
146
|
+
await fs.ensureDir(dir);
|
|
147
|
+
console.log(chalk.gray(` Created ${dir}/`));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Install skills (Claude Code only)
|
|
151
|
+
if (agent.features.hasSkills && answers.skills) {
|
|
152
|
+
const skillGroups = {
|
|
153
|
+
core: ['orchestrator', 'steering', 'constitution-enforcer'],
|
|
154
|
+
requirements: ['requirements-analyst', 'project-manager', 'change-impact-analyzer'],
|
|
155
|
+
architecture: ['system-architect', 'api-designer', 'database-schema-designer', 'ui-ux-designer'],
|
|
156
|
+
development: ['software-developer'],
|
|
157
|
+
quality: ['test-engineer', 'code-reviewer', 'bug-hunter', 'quality-assurance', 'traceability-auditor'],
|
|
158
|
+
security: ['security-auditor', 'performance-optimizer'],
|
|
159
|
+
infrastructure: ['devops-engineer', 'cloud-architect', 'database-administrator', 'site-reliability-engineer', 'release-coordinator'],
|
|
160
|
+
documentation: ['technical-writer', 'ai-ml-engineer']
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
let skillCount = 0;
|
|
164
|
+
for (const group of answers.skills) {
|
|
165
|
+
for (const skill of skillGroups[group]) {
|
|
166
|
+
await copySkill(skill, agent);
|
|
167
|
+
skillCount++;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
console.log(chalk.green(`\n Installed ${skillCount} skills`));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Install commands/prompts/workflows
|
|
175
|
+
if (agent.features.hasCommands) {
|
|
176
|
+
await copyCommands(agent, agentKey);
|
|
177
|
+
const commandType = agentKey === 'github-copilot' || agentKey === 'codex' ? 'prompts' :
|
|
178
|
+
agentKey === 'windsurf' ? 'workflows' : 'commands';
|
|
179
|
+
console.log(chalk.green(` Installed ${commandType}`));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Generate steering context
|
|
183
|
+
if (answers.createSteering) {
|
|
184
|
+
await generateSteering(answers);
|
|
185
|
+
console.log(chalk.green(' Generated steering context'));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Create constitution
|
|
189
|
+
if (answers.createConstitution) {
|
|
190
|
+
await createConstitution();
|
|
191
|
+
console.log(chalk.green(' Created constitutional governance'));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Create README
|
|
195
|
+
await createReadme(answers, agent, agentKey);
|
|
196
|
+
console.log(chalk.green(` Created ${agent.layout.docFile || 'MUSUBI.md'} guide`));
|
|
197
|
+
|
|
198
|
+
// Success message
|
|
199
|
+
console.log(chalk.blue.bold(`\n✅ MUSUBI initialization complete for ${agent.label}!\n`));
|
|
200
|
+
console.log(chalk.white('Next steps:'));
|
|
201
|
+
console.log(chalk.gray(' 1. Review steering/ context files'));
|
|
202
|
+
console.log(chalk.gray(' 2. Review steering/rules/constitution.md'));
|
|
203
|
+
|
|
204
|
+
if (agent.features.hasSkills) {
|
|
205
|
+
console.log(chalk.gray(` 3. Start using ${agent.label} with MUSUBI skills`));
|
|
206
|
+
} else {
|
|
207
|
+
console.log(chalk.gray(` 3. Start using ${agent.label} with MUSUBI`));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const cmdExample = agent.commands.requirements.replace(' <feature>', ' authentication');
|
|
211
|
+
console.log(chalk.gray(` 4. Try commands: ${cmdExample}\n`));
|
|
212
|
+
console.log(chalk.cyan('Learn more: https://github.com/your-org/musubi\n'));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function copySkill(skillName, agent) {
|
|
216
|
+
const srcDir = path.join(AGENTS_TEMPLATE_DIR, 'claude-code', 'skills', skillName);
|
|
217
|
+
const destDir = path.join(agent.layout.skillsDir, skillName);
|
|
218
|
+
await fs.copy(srcDir, destDir);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async function copyCommands(agent, agentKey) {
|
|
222
|
+
const srcDir = path.join(AGENTS_TEMPLATE_DIR, agentKey, 'commands');
|
|
223
|
+
const destDir = agent.layout.commandsDir;
|
|
224
|
+
|
|
225
|
+
// If agent-specific templates don't exist yet, fall back to Claude Code templates
|
|
226
|
+
if (!fs.existsSync(srcDir)) {
|
|
227
|
+
const fallbackSrc = path.join(AGENTS_TEMPLATE_DIR, 'claude-code', 'commands');
|
|
228
|
+
await fs.copy(fallbackSrc, destDir);
|
|
229
|
+
} else {
|
|
230
|
+
await fs.copy(srcDir, destDir);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function generateSteering(answers) {
|
|
235
|
+
const steeringTemplates = path.join(SHARED_TEMPLATE_DIR, 'steering');
|
|
236
|
+
|
|
237
|
+
// Copy and customize steering files
|
|
238
|
+
const files = ['structure.md', 'tech.md', 'product.md'];
|
|
239
|
+
for (const file of files) {
|
|
240
|
+
let content = await fs.readFile(path.join(steeringTemplates, file), 'utf8');
|
|
241
|
+
|
|
242
|
+
// Replace placeholders
|
|
243
|
+
content = content.replace(/\{\{PROJECT_NAME\}\}/g, answers.projectName);
|
|
244
|
+
content = content.replace(/\{\{DESCRIPTION\}\}/g, answers.description);
|
|
245
|
+
content = content.replace(/\{\{DATE\}\}/g, new Date().toISOString().split('T')[0]);
|
|
246
|
+
|
|
247
|
+
await fs.writeFile(path.join('steering', file), content);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function createConstitution() {
|
|
252
|
+
const constitutionTemplate = path.join(SHARED_TEMPLATE_DIR, 'constitution', 'constitution.md');
|
|
253
|
+
await fs.copy(constitutionTemplate, 'steering/rules/constitution.md');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function createReadme(answers, agent, agentKey) {
|
|
257
|
+
const skillsSection = agent.features.hasSkills && answers.skills
|
|
258
|
+
? `This project uses **MUSUBI** (Ultimate Specification Driven Development) with ${answers.skills.length} skill groups.
|
|
259
|
+
|
|
260
|
+
### Available Skills
|
|
261
|
+
|
|
262
|
+
Check \`${agent.layout.skillsDir}/\` directory for all installed skills.
|
|
263
|
+
|
|
264
|
+
`
|
|
265
|
+
: `This project uses **MUSUBI** (Ultimate Specification Driven Development).
|
|
266
|
+
|
|
267
|
+
`;
|
|
268
|
+
|
|
269
|
+
const commandType = agentKey === 'github-copilot' || agentKey === 'codex' ? 'Prompts' :
|
|
270
|
+
agentKey === 'windsurf' ? 'Workflows' : 'Commands';
|
|
271
|
+
|
|
272
|
+
const readme = `# MUSUBI - ${answers.projectName}
|
|
273
|
+
|
|
274
|
+
${answers.description}
|
|
275
|
+
|
|
276
|
+
## Initialized with MUSUBI SDD for ${agent.label}
|
|
277
|
+
|
|
278
|
+
${skillsSection}
|
|
279
|
+
### ${commandType}
|
|
280
|
+
|
|
281
|
+
- \`${agent.commands.steering}\` - Generate/update project memory
|
|
282
|
+
- \`${agent.commands.requirements}\` - Create EARS requirements
|
|
283
|
+
- \`${agent.commands.design}\` - Generate C4 + ADR design
|
|
284
|
+
- \`${agent.commands.tasks}\` - Break down into tasks
|
|
285
|
+
- \`${agent.commands.implement}\` - Execute implementation
|
|
286
|
+
- \`${agent.commands.validate}\` - Validate constitutional compliance
|
|
287
|
+
|
|
288
|
+
### Project Memory
|
|
289
|
+
|
|
290
|
+
- \`steering/structure.md\` - Architecture patterns
|
|
291
|
+
- \`steering/tech.md\` - Technology stack
|
|
292
|
+
- \`steering/product.md\` - Product context
|
|
293
|
+
- \`steering/rules/constitution.md\` - 9 Constitutional Articles
|
|
294
|
+
|
|
295
|
+
### Learn More
|
|
296
|
+
|
|
297
|
+
- [MUSUBI Documentation](https://github.com/your-org/musubi)
|
|
298
|
+
- [Constitutional Governance](steering/rules/constitution.md)
|
|
299
|
+
- [8-Stage SDD Workflow](steering/rules/workflow.md)
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
**Agent**: ${agent.label}
|
|
304
|
+
**Initialized**: ${new Date().toISOString().split('T')[0]}
|
|
305
|
+
**MUSUBI Version**: 0.1.0
|
|
306
|
+
`;
|
|
307
|
+
|
|
308
|
+
const filename = agent.layout.docFile || 'MUSUBI.md';
|
|
309
|
+
await fs.writeFile(filename, readme);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Export for use from musubi.js
|
|
313
|
+
module.exports = main;
|
|
314
|
+
|
|
315
|
+
// Allow direct execution for backward compatibility
|
|
316
|
+
if (require.main === module) {
|
|
317
|
+
main().catch(err => {
|
|
318
|
+
console.error(chalk.red('\n❌ Initialization failed:'), err.message);
|
|
319
|
+
process.exit(1);
|
|
320
|
+
});
|
|
321
|
+
}
|
package/bin/musubi.js
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MUSUBI CLI - Main Entry Point
|
|
5
|
+
*
|
|
6
|
+
* Provides commands for managing MUSUBI SDD projects:
|
|
7
|
+
* - musubi init - Initialize project with MUSUBI
|
|
8
|
+
* - musubi status - Show MUSUBI project status
|
|
9
|
+
* - musubi validate - Validate constitutional compliance
|
|
10
|
+
* - musubi version - Show version information
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { Command } = require('commander');
|
|
14
|
+
const chalk = require('chalk');
|
|
15
|
+
const fs = require('fs-extra');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { detectAgentFromFlags, getAgentDefinition, getAllAliasFlags } = require('../src/agents/registry');
|
|
18
|
+
|
|
19
|
+
const program = new Command();
|
|
20
|
+
|
|
21
|
+
// Package info
|
|
22
|
+
const packageJson = require('../package.json');
|
|
23
|
+
|
|
24
|
+
program
|
|
25
|
+
.name('musubi')
|
|
26
|
+
.description('MUSUBI - Ultimate Specification Driven Development Tool')
|
|
27
|
+
.version(packageJson.version, '-v, --version', 'Output the current version');
|
|
28
|
+
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Command: init
|
|
31
|
+
// ============================================================================
|
|
32
|
+
const initCommand = program
|
|
33
|
+
.command('init')
|
|
34
|
+
.description('Initialize MUSUBI in current project');
|
|
35
|
+
|
|
36
|
+
// Add all agent selection flags dynamically
|
|
37
|
+
const aliasFlags = getAllAliasFlags();
|
|
38
|
+
aliasFlags.forEach(flag => {
|
|
39
|
+
initCommand.option(`--${flag}`, `Select agent: ${flag}`);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
initCommand.action((options) => {
|
|
43
|
+
const agentKey = detectAgentFromFlags(options);
|
|
44
|
+
const agent = getAgentDefinition(agentKey);
|
|
45
|
+
|
|
46
|
+
console.log(chalk.blue(`Initializing MUSUBI for ${chalk.bold(agent.label)}...`));
|
|
47
|
+
console.log(chalk.gray(`Description: ${agent.description}\n`));
|
|
48
|
+
|
|
49
|
+
// Delegate to musubi-init.js with agent info
|
|
50
|
+
require('./musubi-init.js')(agent, agentKey);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Command: status
|
|
55
|
+
// ============================================================================
|
|
56
|
+
program
|
|
57
|
+
.command('status')
|
|
58
|
+
.description('Show MUSUBI project status')
|
|
59
|
+
.action(async () => {
|
|
60
|
+
console.log(chalk.blue.bold('\n📊 MUSUBI Project Status\n'));
|
|
61
|
+
|
|
62
|
+
const cwd = process.cwd();
|
|
63
|
+
|
|
64
|
+
// Check if MUSUBI is initialized
|
|
65
|
+
const skillsDir = path.join(cwd, '.claude', 'skills');
|
|
66
|
+
const steeringDir = path.join(cwd, 'steering');
|
|
67
|
+
|
|
68
|
+
if (!fs.existsSync(skillsDir) && !fs.existsSync(steeringDir)) {
|
|
69
|
+
console.log(chalk.yellow('⚠️ MUSUBI is not initialized in this project.'));
|
|
70
|
+
console.log(chalk.gray('\nRun: musubi init\n'));
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log(chalk.green('✅ MUSUBI is initialized\n'));
|
|
75
|
+
|
|
76
|
+
// Count skills
|
|
77
|
+
if (fs.existsSync(skillsDir)) {
|
|
78
|
+
const skills = fs.readdirSync(skillsDir);
|
|
79
|
+
console.log(chalk.white(`📁 Claude Code Skills: ${skills.length} installed`));
|
|
80
|
+
console.log(chalk.gray(` Location: .claude/skills/\n`));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check steering files
|
|
84
|
+
console.log(chalk.white('🧭 Steering Context:'));
|
|
85
|
+
const steeringFiles = ['structure.md', 'tech.md', 'product.md'];
|
|
86
|
+
let steeringComplete = true;
|
|
87
|
+
|
|
88
|
+
for (const file of steeringFiles) {
|
|
89
|
+
const filePath = path.join(steeringDir, file);
|
|
90
|
+
if (fs.existsSync(filePath)) {
|
|
91
|
+
const stats = fs.statSync(filePath);
|
|
92
|
+
const lastModified = stats.mtime.toISOString().split('T')[0];
|
|
93
|
+
console.log(chalk.green(` ✅ ${file} (updated: ${lastModified})`));
|
|
94
|
+
} else {
|
|
95
|
+
console.log(chalk.red(` ❌ ${file} (missing)`));
|
|
96
|
+
steeringComplete = false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!steeringComplete) {
|
|
101
|
+
console.log(chalk.yellow('\n⚠️ Steering files incomplete. Run: /sdd-steering'));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Check constitutional governance
|
|
105
|
+
const constitutionPath = path.join(steeringDir, 'rules', 'constitution.md');
|
|
106
|
+
if (fs.existsSync(constitutionPath)) {
|
|
107
|
+
console.log(chalk.green('\n✅ Constitutional Governance: Enabled'));
|
|
108
|
+
} else {
|
|
109
|
+
console.log(chalk.yellow('\n⚠️ Constitutional Governance: Not found'));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Check for specifications
|
|
113
|
+
const specsDir = path.join(cwd, 'storage', 'specs');
|
|
114
|
+
if (fs.existsSync(specsDir)) {
|
|
115
|
+
const specs = fs.readdirSync(specsDir).filter(f => f.endsWith('.md'));
|
|
116
|
+
console.log(chalk.white(`\n📄 Specifications: ${specs.length} documents`));
|
|
117
|
+
if (specs.length > 0) {
|
|
118
|
+
console.log(chalk.gray(' Latest specs:'));
|
|
119
|
+
specs.slice(0, 5).forEach(spec => {
|
|
120
|
+
console.log(chalk.gray(` - ${spec}`));
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
console.log(chalk.blue('\n💡 Next steps:'));
|
|
126
|
+
console.log(chalk.gray(' - Review steering files in steering/'));
|
|
127
|
+
console.log(chalk.gray(' - Create requirements: /sdd-requirements [feature]'));
|
|
128
|
+
console.log(chalk.gray(' - Validate compliance: musubi validate\n'));
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Command: validate
|
|
133
|
+
// ============================================================================
|
|
134
|
+
program
|
|
135
|
+
.command('validate [feature]')
|
|
136
|
+
.description('Validate constitutional compliance')
|
|
137
|
+
.option('-a, --all', 'Validate all features')
|
|
138
|
+
.option('-v, --verbose', 'Verbose output')
|
|
139
|
+
.action(async (feature, options) => {
|
|
140
|
+
console.log(chalk.blue.bold('\n🔍 MUSUBI Validation\n'));
|
|
141
|
+
|
|
142
|
+
const cwd = process.cwd();
|
|
143
|
+
const steeringDir = path.join(cwd, 'steering');
|
|
144
|
+
const constitutionPath = path.join(steeringDir, 'rules', 'constitution.md');
|
|
145
|
+
|
|
146
|
+
// Check if MUSUBI is initialized
|
|
147
|
+
if (!fs.existsSync(constitutionPath)) {
|
|
148
|
+
console.log(chalk.red('❌ MUSUBI not initialized or constitution.md missing'));
|
|
149
|
+
console.log(chalk.gray('\nRun: musubi init\n'));
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(chalk.white('📋 Validation Checklist:\n'));
|
|
154
|
+
|
|
155
|
+
// Article I: Library-First
|
|
156
|
+
console.log(chalk.white('Article I: Library-First Principle'));
|
|
157
|
+
const libDir = path.join(cwd, 'lib');
|
|
158
|
+
if (fs.existsSync(libDir)) {
|
|
159
|
+
const libraries = fs.readdirSync(libDir).filter(f => {
|
|
160
|
+
return fs.statSync(path.join(libDir, f)).isDirectory();
|
|
161
|
+
});
|
|
162
|
+
if (libraries.length > 0) {
|
|
163
|
+
console.log(chalk.green(` ✅ ${libraries.length} libraries found in lib/`));
|
|
164
|
+
if (options.verbose) {
|
|
165
|
+
libraries.forEach(lib => console.log(chalk.gray(` - ${lib}`)));
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
console.log(chalk.yellow(' ⚠️ No libraries found in lib/'));
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
console.log(chalk.yellow(' ⚠️ lib/ directory not found'));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Article II: CLI Interface
|
|
175
|
+
console.log(chalk.white('\nArticle II: CLI Interface Mandate'));
|
|
176
|
+
if (fs.existsSync(libDir)) {
|
|
177
|
+
const libraries = fs.readdirSync(libDir).filter(f => {
|
|
178
|
+
return fs.statSync(path.join(libDir, f)).isDirectory();
|
|
179
|
+
});
|
|
180
|
+
let cliCount = 0;
|
|
181
|
+
libraries.forEach(lib => {
|
|
182
|
+
const cliPath = path.join(libDir, lib, 'cli.ts');
|
|
183
|
+
const cliJsPath = path.join(libDir, lib, 'cli.js');
|
|
184
|
+
if (fs.existsSync(cliPath) || fs.existsSync(cliJsPath)) {
|
|
185
|
+
cliCount++;
|
|
186
|
+
if (options.verbose) {
|
|
187
|
+
console.log(chalk.green(` ✅ ${lib}/cli.ts`));
|
|
188
|
+
}
|
|
189
|
+
} else if (options.verbose) {
|
|
190
|
+
console.log(chalk.red(` ❌ ${lib}/cli.ts (missing)`));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
if (cliCount === libraries.length && libraries.length > 0) {
|
|
194
|
+
console.log(chalk.green(` ✅ All ${libraries.length} libraries have CLI interfaces`));
|
|
195
|
+
} else {
|
|
196
|
+
console.log(chalk.yellow(` ⚠️ ${cliCount}/${libraries.length} libraries have CLI`));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Article IV: EARS Format
|
|
201
|
+
console.log(chalk.white('\nArticle IV: EARS Requirements Format'));
|
|
202
|
+
const specsDir = path.join(cwd, 'storage', 'specs');
|
|
203
|
+
if (fs.existsSync(specsDir)) {
|
|
204
|
+
const requirementFiles = fs.readdirSync(specsDir)
|
|
205
|
+
.filter(f => f.includes('requirements') && f.endsWith('.md'));
|
|
206
|
+
|
|
207
|
+
if (requirementFiles.length > 0) {
|
|
208
|
+
console.log(chalk.green(` ✅ ${requirementFiles.length} requirements documents found`));
|
|
209
|
+
|
|
210
|
+
// Basic EARS pattern check
|
|
211
|
+
let earsCompliant = 0;
|
|
212
|
+
requirementFiles.forEach(file => {
|
|
213
|
+
const content = fs.readFileSync(path.join(specsDir, file), 'utf8');
|
|
214
|
+
const hasEarsPatterns = /\b(WHEN|WHILE|IF|WHERE|SHALL)\b/.test(content);
|
|
215
|
+
if (hasEarsPatterns) {
|
|
216
|
+
earsCompliant++;
|
|
217
|
+
if (options.verbose) {
|
|
218
|
+
console.log(chalk.green(` ✅ ${file}`));
|
|
219
|
+
}
|
|
220
|
+
} else if (options.verbose) {
|
|
221
|
+
console.log(chalk.yellow(` ⚠️ ${file} (no EARS patterns detected)`));
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
if (earsCompliant === requirementFiles.length) {
|
|
226
|
+
console.log(chalk.green(` ✅ All requirements use EARS format`));
|
|
227
|
+
} else {
|
|
228
|
+
console.log(chalk.yellow(` ⚠️ ${earsCompliant}/${requirementFiles.length} documents have EARS patterns`));
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
console.log(chalk.gray(' ℹ️ No requirements documents found'));
|
|
232
|
+
}
|
|
233
|
+
} else {
|
|
234
|
+
console.log(chalk.gray(' ℹ️ storage/specs/ not found'));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Article VI: Project Memory
|
|
238
|
+
console.log(chalk.white('\nArticle VI: Project Memory (Steering System)'));
|
|
239
|
+
const steeringFiles = ['structure.md', 'tech.md', 'product.md'];
|
|
240
|
+
let steeringCount = 0;
|
|
241
|
+
steeringFiles.forEach(file => {
|
|
242
|
+
const filePath = path.join(steeringDir, file);
|
|
243
|
+
if (fs.existsSync(filePath)) {
|
|
244
|
+
steeringCount++;
|
|
245
|
+
if (options.verbose) {
|
|
246
|
+
console.log(chalk.green(` ✅ steering/${file}`));
|
|
247
|
+
}
|
|
248
|
+
} else if (options.verbose) {
|
|
249
|
+
console.log(chalk.red(` ❌ steering/${file} (missing)`));
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
if (steeringCount === 3) {
|
|
254
|
+
console.log(chalk.green(' ✅ All steering files present'));
|
|
255
|
+
} else {
|
|
256
|
+
console.log(chalk.yellow(` ⚠️ ${steeringCount}/3 steering files present`));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Summary
|
|
260
|
+
console.log(chalk.blue('\n📊 Validation Summary:'));
|
|
261
|
+
console.log(chalk.white(' For comprehensive validation, use Claude Code:'));
|
|
262
|
+
console.log(chalk.gray(' /sdd-validate [feature-name]\n'));
|
|
263
|
+
console.log(chalk.white(' Or invoke skills directly:'));
|
|
264
|
+
console.log(chalk.gray(' @constitution-enforcer validate [path]'));
|
|
265
|
+
console.log(chalk.gray(' @traceability-auditor validate requirements.md\n'));
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// ============================================================================
|
|
269
|
+
// Command: info
|
|
270
|
+
// ============================================================================
|
|
271
|
+
program
|
|
272
|
+
.command('info')
|
|
273
|
+
.description('Show MUSUBI version and environment info')
|
|
274
|
+
.action(() => {
|
|
275
|
+
const { getAgentList } = require('../src/agents/registry');
|
|
276
|
+
|
|
277
|
+
console.log(chalk.blue.bold('\n🎯 MUSUBI Information\n'));
|
|
278
|
+
console.log(chalk.white(`Version: ${packageJson.version}`));
|
|
279
|
+
console.log(chalk.white(`Description: ${packageJson.description}`));
|
|
280
|
+
console.log(chalk.white(`License: ${packageJson.license}\n`));
|
|
281
|
+
|
|
282
|
+
console.log(chalk.white('Environment:'));
|
|
283
|
+
console.log(chalk.gray(` Node.js: ${process.version}`));
|
|
284
|
+
console.log(chalk.gray(` npm: ${process.env.npm_config_user_agent?.split(' ')[0] || 'N/A'}`));
|
|
285
|
+
console.log(chalk.gray(` Platform: ${process.platform}`));
|
|
286
|
+
console.log(chalk.gray(` CWD: ${process.cwd()}\n`));
|
|
287
|
+
|
|
288
|
+
console.log(chalk.white('Supported AI Coding Agents (7):'));
|
|
289
|
+
const agents = getAgentList();
|
|
290
|
+
agents.forEach(agentKey => {
|
|
291
|
+
const agent = getAgentDefinition(agentKey);
|
|
292
|
+
const flags = agent.aliasFlags.join(', ');
|
|
293
|
+
console.log(chalk.gray(` ${agent.label} - ${flags}`));
|
|
294
|
+
});
|
|
295
|
+
console.log('');
|
|
296
|
+
|
|
297
|
+
console.log(chalk.white('Documentation:'));
|
|
298
|
+
console.log(chalk.gray(' https://github.com/your-org/musubi\n'));
|
|
299
|
+
|
|
300
|
+
console.log(chalk.white('25 Claude Code Skills:'));
|
|
301
|
+
console.log(chalk.gray(' Orchestration: orchestrator, steering, constitution-enforcer'));
|
|
302
|
+
console.log(chalk.gray(' Requirements: requirements-analyst, project-manager, change-impact-analyzer'));
|
|
303
|
+
console.log(chalk.gray(' Architecture: system-architect, api-designer, database-schema-designer, ui-ux-designer'));
|
|
304
|
+
console.log(chalk.gray(' Development: software-developer'));
|
|
305
|
+
console.log(chalk.gray(' Quality: test-engineer, code-reviewer, bug-hunter, quality-assurance, traceability-auditor'));
|
|
306
|
+
console.log(chalk.gray(' Security: security-auditor, performance-optimizer'));
|
|
307
|
+
console.log(chalk.gray(' Infrastructure: devops-engineer, cloud-architect, database-administrator, site-reliability-engineer, release-coordinator'));
|
|
308
|
+
console.log(chalk.gray(' Documentation: technical-writer, ai-ml-engineer\n'));
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// ============================================================================
|
|
312
|
+
// Command: help (custom formatting)
|
|
313
|
+
// ============================================================================
|
|
314
|
+
program.on('--help', () => {
|
|
315
|
+
console.log('');
|
|
316
|
+
console.log('Examples:');
|
|
317
|
+
console.log(' $ musubi init # Initialize MUSUBI (Claude Code, default)');
|
|
318
|
+
console.log(' $ musubi init --cursor # Initialize for Cursor IDE');
|
|
319
|
+
console.log(' $ musubi init --copilot # Initialize for GitHub Copilot');
|
|
320
|
+
console.log(' $ musubi init --gemini # Initialize for Gemini CLI');
|
|
321
|
+
console.log(' $ musubi init --codex # Initialize for Codex CLI');
|
|
322
|
+
console.log(' $ musubi init --qwen # Initialize for Qwen Code');
|
|
323
|
+
console.log(' $ musubi init --windsurf # Initialize for Windsurf IDE');
|
|
324
|
+
console.log(' $ musubi status # Show project status');
|
|
325
|
+
console.log(' $ musubi validate # Quick validation check');
|
|
326
|
+
console.log(' $ musubi info # Show version and supported agents');
|
|
327
|
+
console.log('');
|
|
328
|
+
console.log('Agent Selection Flags:');
|
|
329
|
+
console.log(' --claude, --claude-code # Claude Code (default)');
|
|
330
|
+
console.log(' --copilot, --github-copilot # GitHub Copilot');
|
|
331
|
+
console.log(' --cursor # Cursor IDE');
|
|
332
|
+
console.log(' --gemini, --gemini-cli # Gemini CLI');
|
|
333
|
+
console.log(' --codex, --codex-cli # Codex CLI');
|
|
334
|
+
console.log(' --qwen, --qwen-code # Qwen Code');
|
|
335
|
+
console.log(' --windsurf # Windsurf IDE');
|
|
336
|
+
console.log('');
|
|
337
|
+
console.log('Claude Code Usage (default):');
|
|
338
|
+
console.log(' /sdd-steering # Generate project memory');
|
|
339
|
+
console.log(' /sdd-requirements [feature] # Create EARS requirements');
|
|
340
|
+
console.log(' /sdd-design [feature] # Generate technical design');
|
|
341
|
+
console.log(' /sdd-tasks [feature] # Break down into tasks');
|
|
342
|
+
console.log(' /sdd-implement [feature] # Execute implementation');
|
|
343
|
+
console.log(' /sdd-validate [feature] # Validate compliance');
|
|
344
|
+
console.log('');
|
|
345
|
+
console.log('Claude Code Skills (25 specialized skills):');
|
|
346
|
+
console.log(' @orchestrator, @steering, @requirements-analyst, @system-architect,');
|
|
347
|
+
console.log(' @software-developer, @test-engineer, @code-reviewer, and 18 more...');
|
|
348
|
+
console.log('');
|
|
349
|
+
console.log('Note: Skills API is Claude Code exclusive. Other agents use commands/prompts.');
|
|
350
|
+
console.log('');
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// Parse arguments
|
|
354
|
+
program.parse(process.argv);
|
|
355
|
+
|
|
356
|
+
// Show help if no command provided
|
|
357
|
+
if (!process.argv.slice(2).length) {
|
|
358
|
+
program.outputHelp();
|
|
359
|
+
}
|