musubi-sdd 2.0.7 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +10 -3
- package/README.md +10 -3
- package/bin/musubi-workflow.js +280 -0
- package/package.json +3 -2
- package/src/managers/workflow.js +360 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +41 -0
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +97 -0
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +39 -0
- package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +48 -0
- package/src/templates/agents/claude-code/skills/requirements-analyst/SKILL.md +41 -0
- package/src/templates/agents/claude-code/skills/software-developer/SKILL.md +28 -0
- package/src/templates/agents/claude-code/skills/system-architect/SKILL.md +28 -0
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +45 -0
package/README.ja.md
CHANGED
|
@@ -4,13 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
MUSUBIは、6つの主要フレームワークのベスト機能を統合した包括的なSDD(仕様駆動開発)フレームワークであり、複数のAIコーディングエージェントに対応した本番環境対応ツールです。
|
|
6
6
|
|
|
7
|
-
## 🚀 v2.
|
|
7
|
+
## 🚀 v2.1.0 の新機能
|
|
8
|
+
|
|
9
|
+
- 🔄 **ワークフローエンジン** - ステージ管理とメトリクス収集の新CLI `musubi-workflow`
|
|
10
|
+
- 📊 **メトリクス収集** - ステージごとの所要時間、イテレーション回数、フィードバックループを追跡
|
|
11
|
+
- 🔬 **Spike/PoCステージ** - 要件定義前の調査・プロトタイピング用ステージ0
|
|
12
|
+
- 👀 **コードレビューステージ** - 実装とテストの間のステージ5.5
|
|
13
|
+
- 🔄 **振り返りステージ** - 継続的改善のためのステージ9
|
|
14
|
+
- ✅ **ステージ検証ガイド** - ステージ遷移の検証チェックリスト
|
|
15
|
+
|
|
16
|
+
### 以前のバージョン (v2.0.0)
|
|
8
17
|
|
|
9
18
|
- 🔌 **CodeGraphMCPServer統合** - 14のMCPツールによる高度なコード分析
|
|
10
19
|
- 🧠 **GraphRAG駆動検索** - Louvainコミュニティ検出によるセマンティックコード理解
|
|
11
20
|
- 🔍 **11エージェント強化** - 主要エージェントがMCPツールを活用して深いコード分析を実現
|
|
12
|
-
- 📊 **依存関係分析** - `find_dependencies`, `find_callers`, `analyze_module_structure`
|
|
13
|
-
- 🎯 **スマートコードナビゲーション** - `local_search`, `global_search`, `query_codebase`
|
|
14
21
|
|
|
15
22
|
## 特徴
|
|
16
23
|
|
package/README.md
CHANGED
|
@@ -8,13 +8,20 @@
|
|
|
8
8
|
|
|
9
9
|
MUSUBI is a comprehensive SDD (Specification Driven Development) framework that synthesizes the best features from 6 leading frameworks into a production-ready tool for multiple AI coding agents.
|
|
10
10
|
|
|
11
|
-
## 🚀 What's New in v2.
|
|
11
|
+
## 🚀 What's New in v2.1.0
|
|
12
|
+
|
|
13
|
+
- 🔄 **Workflow Engine** - New `musubi-workflow` CLI for stage management and metrics
|
|
14
|
+
- 📊 **Metrics Collection** - Track time per stage, iteration counts, feedback loops
|
|
15
|
+
- 🔬 **Spike/PoC Stage** - Stage 0 for research and prototyping before requirements
|
|
16
|
+
- 👀 **Code Review Stage** - Stage 5.5 between implementation and testing
|
|
17
|
+
- 🔄 **Retrospective Stage** - Stage 9 for continuous improvement
|
|
18
|
+
- ✅ **Stage Validation Guide** - Checklists for stage transition validation
|
|
19
|
+
|
|
20
|
+
### Previous (v2.0.0)
|
|
12
21
|
|
|
13
22
|
- 🔌 **CodeGraphMCPServer Integration** - 14 MCP tools for enhanced code analysis
|
|
14
23
|
- 🧠 **GraphRAG-Powered Search** - Semantic code understanding with Louvain community detection
|
|
15
24
|
- 🔍 **11 Agents Enhanced** - Key agents now leverage MCP tools for deeper code analysis
|
|
16
|
-
- 📊 **Dependency Analysis** - `find_dependencies`, `find_callers`, `analyze_module_structure`
|
|
17
|
-
- 🎯 **Smart Code Navigation** - `local_search`, `global_search`, `query_codebase`
|
|
18
25
|
|
|
19
26
|
## Features
|
|
20
27
|
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MUSUBI Workflow CLI
|
|
5
|
+
*
|
|
6
|
+
* Manage workflow state, transitions, and metrics.
|
|
7
|
+
*
|
|
8
|
+
* Commands:
|
|
9
|
+
* init <feature> - Initialize workflow for a feature
|
|
10
|
+
* status - Show current workflow status
|
|
11
|
+
* next [stage] - Transition to next stage
|
|
12
|
+
* complete - Complete the workflow
|
|
13
|
+
* metrics - Show workflow metrics summary
|
|
14
|
+
* history - Show workflow history
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const { program } = require('commander');
|
|
18
|
+
const { WorkflowEngine, WORKFLOW_STAGES } = require('../src/managers/workflow');
|
|
19
|
+
const chalk = require('chalk');
|
|
20
|
+
|
|
21
|
+
const engine = new WorkflowEngine();
|
|
22
|
+
|
|
23
|
+
// Stage icons for visual feedback
|
|
24
|
+
const STAGE_ICONS = {
|
|
25
|
+
spike: '🔬',
|
|
26
|
+
research: '📚',
|
|
27
|
+
requirements: '📋',
|
|
28
|
+
design: '📐',
|
|
29
|
+
tasks: '📝',
|
|
30
|
+
implementation: '💻',
|
|
31
|
+
review: '👀',
|
|
32
|
+
testing: '🧪',
|
|
33
|
+
deployment: '🚀',
|
|
34
|
+
monitoring: '📊',
|
|
35
|
+
retrospective: '🔄'
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Format stage name with icon
|
|
40
|
+
*/
|
|
41
|
+
function formatStage(stage) {
|
|
42
|
+
const icon = STAGE_ICONS[stage] || '📌';
|
|
43
|
+
return `${icon} ${stage}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Display workflow status
|
|
48
|
+
*/
|
|
49
|
+
async function showStatus() {
|
|
50
|
+
const state = await engine.getState();
|
|
51
|
+
|
|
52
|
+
if (!state) {
|
|
53
|
+
console.log(chalk.yellow('\n⚠️ No active workflow. Use "musubi-workflow init <feature>" to start.'));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
console.log(chalk.bold('\n📊 Workflow Status\n'));
|
|
58
|
+
console.log(chalk.white(`Feature: ${chalk.cyan(state.feature)}`));
|
|
59
|
+
console.log(chalk.white(`Current Stage: ${formatStage(state.currentStage)}`));
|
|
60
|
+
console.log(chalk.white(`Started: ${new Date(state.startedAt).toLocaleString()}`));
|
|
61
|
+
|
|
62
|
+
// Show stage progress
|
|
63
|
+
console.log(chalk.bold('\n📈 Stage Progress:\n'));
|
|
64
|
+
|
|
65
|
+
const allStages = Object.keys(WORKFLOW_STAGES);
|
|
66
|
+
const currentIndex = allStages.indexOf(state.currentStage);
|
|
67
|
+
|
|
68
|
+
allStages.forEach((stage, index) => {
|
|
69
|
+
const data = state.stages[stage];
|
|
70
|
+
let status = '';
|
|
71
|
+
let color = chalk.gray;
|
|
72
|
+
|
|
73
|
+
if (data?.status === 'completed') {
|
|
74
|
+
status = `✅ Completed (${data.duration})`;
|
|
75
|
+
color = chalk.green;
|
|
76
|
+
} else if (stage === state.currentStage) {
|
|
77
|
+
status = '🔄 In Progress';
|
|
78
|
+
color = chalk.blue;
|
|
79
|
+
} else if (index < currentIndex) {
|
|
80
|
+
status = '⏭️ Skipped';
|
|
81
|
+
color = chalk.gray;
|
|
82
|
+
} else {
|
|
83
|
+
status = '⏳ Pending';
|
|
84
|
+
color = chalk.gray;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log(color(` ${formatStage(stage).padEnd(25)} ${status}`));
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Show valid transitions
|
|
91
|
+
const validNext = await engine.getValidTransitions();
|
|
92
|
+
if (validNext.length > 0) {
|
|
93
|
+
console.log(chalk.bold('\n🔀 Valid Transitions:'));
|
|
94
|
+
validNext.forEach(stage => {
|
|
95
|
+
console.log(chalk.cyan(` → ${formatStage(stage)}`));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Display workflow history
|
|
102
|
+
*/
|
|
103
|
+
async function showHistory() {
|
|
104
|
+
const state = await engine.getState();
|
|
105
|
+
|
|
106
|
+
if (!state || !state.history) {
|
|
107
|
+
console.log(chalk.yellow('\n⚠️ No workflow history available.'));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log(chalk.bold('\n📜 Workflow History\n'));
|
|
112
|
+
|
|
113
|
+
state.history.forEach(event => {
|
|
114
|
+
const time = new Date(event.timestamp).toLocaleString();
|
|
115
|
+
let desc = '';
|
|
116
|
+
|
|
117
|
+
switch (event.action) {
|
|
118
|
+
case 'workflow-started':
|
|
119
|
+
desc = `Started workflow for "${event.feature}" at ${formatStage(event.stage)}`;
|
|
120
|
+
break;
|
|
121
|
+
case 'stage-transition':
|
|
122
|
+
desc = `${formatStage(event.from)} → ${formatStage(event.to)}`;
|
|
123
|
+
if (event.notes) desc += ` (${event.notes})`;
|
|
124
|
+
break;
|
|
125
|
+
case 'feedback-loop':
|
|
126
|
+
desc = `🔄 Feedback: ${formatStage(event.from)} → ${formatStage(event.to)} - ${event.reason}`;
|
|
127
|
+
break;
|
|
128
|
+
case 'workflow-completed':
|
|
129
|
+
desc = `✅ Workflow completed`;
|
|
130
|
+
if (event.notes) desc += ` (${event.notes})`;
|
|
131
|
+
break;
|
|
132
|
+
default:
|
|
133
|
+
desc = event.action;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
console.log(chalk.white(` ${chalk.gray(time)} ${desc}`));
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Display metrics summary
|
|
142
|
+
*/
|
|
143
|
+
async function showMetrics() {
|
|
144
|
+
const summary = await engine.getMetricsSummary();
|
|
145
|
+
|
|
146
|
+
console.log(chalk.bold('\n📊 Workflow Metrics Summary\n'));
|
|
147
|
+
|
|
148
|
+
if (summary.message) {
|
|
149
|
+
console.log(chalk.yellow(` ${summary.message}`));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(chalk.white(` Total Workflows: ${summary.totalWorkflows}`));
|
|
154
|
+
console.log(chalk.white(` Completed: ${summary.completedWorkflows}`));
|
|
155
|
+
console.log(chalk.white(` Stage Transitions: ${summary.stageTransitions}`));
|
|
156
|
+
console.log(chalk.white(` Feedback Loops: ${summary.feedbackLoops}`));
|
|
157
|
+
|
|
158
|
+
if (summary.averageDuration) {
|
|
159
|
+
console.log(chalk.white(` Average Duration: ${summary.averageDuration}`));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (Object.keys(summary.stageStats).length > 0) {
|
|
163
|
+
console.log(chalk.bold('\n📈 Stage Visit Counts:\n'));
|
|
164
|
+
Object.entries(summary.stageStats)
|
|
165
|
+
.sort((a, b) => b[1].visits - a[1].visits)
|
|
166
|
+
.forEach(([stage, data]) => {
|
|
167
|
+
console.log(chalk.white(` ${formatStage(stage).padEnd(25)} ${data.visits} visits`));
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// CLI Commands
|
|
173
|
+
program
|
|
174
|
+
.name('musubi-workflow')
|
|
175
|
+
.description('MUSUBI Workflow Engine - Manage SDD workflow state and metrics')
|
|
176
|
+
.version('2.0.7');
|
|
177
|
+
|
|
178
|
+
program
|
|
179
|
+
.command('init <feature>')
|
|
180
|
+
.description('Initialize a new workflow for a feature')
|
|
181
|
+
.option('-s, --stage <stage>', 'Starting stage', 'requirements')
|
|
182
|
+
.action(async (feature, options) => {
|
|
183
|
+
try {
|
|
184
|
+
const state = await engine.initWorkflow(feature, { startStage: options.stage });
|
|
185
|
+
console.log(chalk.green(`\n✅ Workflow initialized for "${feature}"`));
|
|
186
|
+
console.log(chalk.cyan(` Starting at: ${formatStage(state.currentStage)}`));
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.error(chalk.red(`\n❌ Error: ${error.message}`));
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
program
|
|
194
|
+
.command('status')
|
|
195
|
+
.description('Show current workflow status')
|
|
196
|
+
.action(showStatus);
|
|
197
|
+
|
|
198
|
+
program
|
|
199
|
+
.command('next [stage]')
|
|
200
|
+
.description('Transition to the next stage')
|
|
201
|
+
.option('-n, --notes <notes>', 'Transition notes')
|
|
202
|
+
.action(async (stage, options) => {
|
|
203
|
+
try {
|
|
204
|
+
const state = await engine.getState();
|
|
205
|
+
if (!state) {
|
|
206
|
+
console.log(chalk.yellow('\n⚠️ No active workflow.'));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// If no stage specified, show valid options
|
|
211
|
+
if (!stage) {
|
|
212
|
+
const validNext = await engine.getValidTransitions();
|
|
213
|
+
console.log(chalk.bold('\n🔀 Valid next stages:'));
|
|
214
|
+
validNext.forEach(s => console.log(chalk.cyan(` → ${formatStage(s)}`)));
|
|
215
|
+
console.log(chalk.white('\nUse: musubi-workflow next <stage>'));
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
await engine.transitionTo(stage, options.notes);
|
|
220
|
+
console.log(chalk.green(`\n✅ Transitioned to ${formatStage(stage)}`));
|
|
221
|
+
} catch (error) {
|
|
222
|
+
console.error(chalk.red(`\n❌ Error: ${error.message}`));
|
|
223
|
+
process.exit(1);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
program
|
|
228
|
+
.command('feedback <from> <to>')
|
|
229
|
+
.description('Record a feedback loop')
|
|
230
|
+
.requiredOption('-r, --reason <reason>', 'Reason for feedback loop')
|
|
231
|
+
.action(async (from, to, options) => {
|
|
232
|
+
try {
|
|
233
|
+
await engine.recordFeedbackLoop(from, to, options.reason);
|
|
234
|
+
await engine.transitionTo(to, `Feedback: ${options.reason}`);
|
|
235
|
+
console.log(chalk.yellow(`\n🔄 Feedback loop recorded: ${formatStage(from)} → ${formatStage(to)}`));
|
|
236
|
+
console.log(chalk.gray(` Reason: ${options.reason}`));
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error(chalk.red(`\n❌ Error: ${error.message}`));
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
program
|
|
244
|
+
.command('complete')
|
|
245
|
+
.description('Complete the current workflow')
|
|
246
|
+
.option('-n, --notes <notes>', 'Completion notes')
|
|
247
|
+
.action(async (options) => {
|
|
248
|
+
try {
|
|
249
|
+
const summary = await engine.completeWorkflow(options.notes);
|
|
250
|
+
|
|
251
|
+
console.log(chalk.green('\n✅ Workflow Completed!\n'));
|
|
252
|
+
console.log(chalk.bold('📊 Summary:'));
|
|
253
|
+
console.log(chalk.white(` Feature: ${summary.feature}`));
|
|
254
|
+
console.log(chalk.white(` Total Duration: ${summary.totalDuration}`));
|
|
255
|
+
console.log(chalk.white(` Stages: ${summary.stages.length}`));
|
|
256
|
+
console.log(chalk.white(` Feedback Loops: ${summary.feedbackLoops}`));
|
|
257
|
+
|
|
258
|
+
if (summary.stages.length > 0) {
|
|
259
|
+
console.log(chalk.bold('\n📈 Stage Breakdown:'));
|
|
260
|
+
summary.stages.forEach(s => {
|
|
261
|
+
console.log(chalk.white(` ${formatStage(s.name).padEnd(25)} ${s.duration} (${s.attempts} attempt${s.attempts > 1 ? 's' : ''})`));
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
} catch (error) {
|
|
265
|
+
console.error(chalk.red(`\n❌ Error: ${error.message}`));
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
program
|
|
271
|
+
.command('history')
|
|
272
|
+
.description('Show workflow history')
|
|
273
|
+
.action(showHistory);
|
|
274
|
+
|
|
275
|
+
program
|
|
276
|
+
.command('metrics')
|
|
277
|
+
.description('Show workflow metrics summary')
|
|
278
|
+
.action(showMetrics);
|
|
279
|
+
|
|
280
|
+
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "musubi-sdd",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Ultimate Specification Driven Development Tool with 25 Agents for 7 AI Coding Platforms + MCP Integration (Claude Code, GitHub Copilot, Cursor, Gemini CLI, Windsurf, Codex, Qwen Code)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"musubi-tasks": "bin/musubi-tasks.js",
|
|
18
18
|
"musubi-trace": "bin/musubi-trace.js",
|
|
19
19
|
"musubi-gaps": "bin/musubi-gaps.js",
|
|
20
|
-
"musubi-change": "bin/musubi-change.js"
|
|
20
|
+
"musubi-change": "bin/musubi-change.js",
|
|
21
|
+
"musubi-workflow": "bin/musubi-workflow.js"
|
|
21
22
|
},
|
|
22
23
|
"scripts": {
|
|
23
24
|
"test": "jest",
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Engine for MUSUBI SDD
|
|
3
|
+
*
|
|
4
|
+
* Manages workflow state, stage transitions, and metrics collection.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const yaml = require('js-yaml');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Workflow stages with their valid transitions
|
|
13
|
+
*/
|
|
14
|
+
const WORKFLOW_STAGES = {
|
|
15
|
+
spike: { next: ['requirements'], optional: true },
|
|
16
|
+
research: { next: ['requirements'], optional: true },
|
|
17
|
+
requirements: { next: ['design'] },
|
|
18
|
+
design: { next: ['tasks'] },
|
|
19
|
+
tasks: { next: ['implementation'] },
|
|
20
|
+
implementation: { next: ['review'] },
|
|
21
|
+
review: { next: ['testing', 'implementation'] }, // Can go back to implementation
|
|
22
|
+
testing: { next: ['deployment', 'implementation', 'requirements'] }, // Feedback loops
|
|
23
|
+
deployment: { next: ['monitoring'] },
|
|
24
|
+
monitoring: { next: ['retrospective'] },
|
|
25
|
+
retrospective: { next: ['requirements'] } // New iteration
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Workflow state file path
|
|
30
|
+
*/
|
|
31
|
+
const WORKFLOW_STATE_FILE = 'storage/workflow-state.yml';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Metrics file path
|
|
35
|
+
*/
|
|
36
|
+
const METRICS_FILE = 'storage/workflow-metrics.yml';
|
|
37
|
+
|
|
38
|
+
class WorkflowEngine {
|
|
39
|
+
constructor(projectRoot = process.cwd()) {
|
|
40
|
+
this.projectRoot = projectRoot;
|
|
41
|
+
this.stateFile = path.join(projectRoot, WORKFLOW_STATE_FILE);
|
|
42
|
+
this.metricsFile = path.join(projectRoot, METRICS_FILE);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Initialize workflow for a new feature/iteration
|
|
47
|
+
*/
|
|
48
|
+
async initWorkflow(featureName, options = {}) {
|
|
49
|
+
const state = {
|
|
50
|
+
feature: featureName,
|
|
51
|
+
currentStage: options.startStage || 'requirements',
|
|
52
|
+
startedAt: new Date().toISOString(),
|
|
53
|
+
stages: {},
|
|
54
|
+
history: []
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Record initial stage
|
|
58
|
+
state.stages[state.currentStage] = {
|
|
59
|
+
enteredAt: new Date().toISOString(),
|
|
60
|
+
status: 'in-progress'
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
state.history.push({
|
|
64
|
+
timestamp: new Date().toISOString(),
|
|
65
|
+
action: 'workflow-started',
|
|
66
|
+
stage: state.currentStage,
|
|
67
|
+
feature: featureName
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
await this.saveState(state);
|
|
71
|
+
await this.recordMetric('workflow_started', { feature: featureName });
|
|
72
|
+
|
|
73
|
+
return state;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get current workflow state
|
|
78
|
+
*/
|
|
79
|
+
async getState() {
|
|
80
|
+
if (!await fs.pathExists(this.stateFile)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const content = await fs.readFile(this.stateFile, 'utf8');
|
|
84
|
+
return yaml.load(content);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Save workflow state
|
|
89
|
+
*/
|
|
90
|
+
async saveState(state) {
|
|
91
|
+
await fs.ensureDir(path.dirname(this.stateFile));
|
|
92
|
+
await fs.writeFile(this.stateFile, yaml.dump(state, { indent: 2 }));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Transition to the next stage
|
|
97
|
+
*/
|
|
98
|
+
async transitionTo(targetStage, notes = '') {
|
|
99
|
+
const state = await this.getState();
|
|
100
|
+
if (!state) {
|
|
101
|
+
throw new Error('No active workflow. Run initWorkflow first.');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const currentStage = state.currentStage;
|
|
105
|
+
const validTransitions = WORKFLOW_STAGES[currentStage]?.next || [];
|
|
106
|
+
|
|
107
|
+
if (!validTransitions.includes(targetStage)) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`Invalid transition: ${currentStage} → ${targetStage}. ` +
|
|
110
|
+
`Valid transitions: ${validTransitions.join(', ')}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Complete current stage
|
|
115
|
+
if (state.stages[currentStage]) {
|
|
116
|
+
state.stages[currentStage].completedAt = new Date().toISOString();
|
|
117
|
+
state.stages[currentStage].status = 'completed';
|
|
118
|
+
state.stages[currentStage].duration = this.calculateDuration(
|
|
119
|
+
state.stages[currentStage].enteredAt,
|
|
120
|
+
state.stages[currentStage].completedAt
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Enter new stage
|
|
125
|
+
state.stages[targetStage] = state.stages[targetStage] || {};
|
|
126
|
+
state.stages[targetStage].enteredAt = new Date().toISOString();
|
|
127
|
+
state.stages[targetStage].status = 'in-progress';
|
|
128
|
+
state.stages[targetStage].attempts = (state.stages[targetStage].attempts || 0) + 1;
|
|
129
|
+
|
|
130
|
+
state.currentStage = targetStage;
|
|
131
|
+
|
|
132
|
+
// Record history
|
|
133
|
+
state.history.push({
|
|
134
|
+
timestamp: new Date().toISOString(),
|
|
135
|
+
action: 'stage-transition',
|
|
136
|
+
from: currentStage,
|
|
137
|
+
to: targetStage,
|
|
138
|
+
notes
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
await this.saveState(state);
|
|
142
|
+
await this.recordMetric('stage_transition', {
|
|
143
|
+
from: currentStage,
|
|
144
|
+
to: targetStage,
|
|
145
|
+
feature: state.feature
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return state;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Record a feedback loop (going back to a previous stage)
|
|
153
|
+
*/
|
|
154
|
+
async recordFeedbackLoop(fromStage, toStage, reason) {
|
|
155
|
+
const state = await this.getState();
|
|
156
|
+
if (!state) return;
|
|
157
|
+
|
|
158
|
+
state.history.push({
|
|
159
|
+
timestamp: new Date().toISOString(),
|
|
160
|
+
action: 'feedback-loop',
|
|
161
|
+
from: fromStage,
|
|
162
|
+
to: toStage,
|
|
163
|
+
reason
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await this.saveState(state);
|
|
167
|
+
await this.recordMetric('feedback_loop', {
|
|
168
|
+
from: fromStage,
|
|
169
|
+
to: toStage,
|
|
170
|
+
reason,
|
|
171
|
+
feature: state.feature
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Complete the workflow
|
|
177
|
+
*/
|
|
178
|
+
async completeWorkflow(notes = '') {
|
|
179
|
+
const state = await this.getState();
|
|
180
|
+
if (!state) {
|
|
181
|
+
throw new Error('No active workflow.');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
state.completedAt = new Date().toISOString();
|
|
185
|
+
state.totalDuration = this.calculateDuration(state.startedAt, state.completedAt);
|
|
186
|
+
state.status = 'completed';
|
|
187
|
+
|
|
188
|
+
// Complete current stage
|
|
189
|
+
if (state.stages[state.currentStage]) {
|
|
190
|
+
state.stages[state.currentStage].completedAt = new Date().toISOString();
|
|
191
|
+
state.stages[state.currentStage].status = 'completed';
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
state.history.push({
|
|
195
|
+
timestamp: new Date().toISOString(),
|
|
196
|
+
action: 'workflow-completed',
|
|
197
|
+
notes
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
await this.saveState(state);
|
|
201
|
+
await this.recordMetric('workflow_completed', {
|
|
202
|
+
feature: state.feature,
|
|
203
|
+
totalDuration: state.totalDuration,
|
|
204
|
+
stageCount: Object.keys(state.stages).length
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Generate summary
|
|
208
|
+
return this.generateSummary(state);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Record a metric
|
|
213
|
+
*/
|
|
214
|
+
async recordMetric(name, data) {
|
|
215
|
+
let metrics = [];
|
|
216
|
+
if (await fs.pathExists(this.metricsFile)) {
|
|
217
|
+
const content = await fs.readFile(this.metricsFile, 'utf8');
|
|
218
|
+
metrics = yaml.load(content) || [];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
metrics.push({
|
|
222
|
+
timestamp: new Date().toISOString(),
|
|
223
|
+
name,
|
|
224
|
+
data
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
await fs.ensureDir(path.dirname(this.metricsFile));
|
|
228
|
+
await fs.writeFile(this.metricsFile, yaml.dump(metrics, { indent: 2 }));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Get workflow metrics summary
|
|
233
|
+
*/
|
|
234
|
+
async getMetricsSummary() {
|
|
235
|
+
if (!await fs.pathExists(this.metricsFile)) {
|
|
236
|
+
return { message: 'No metrics recorded yet.' };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const content = await fs.readFile(this.metricsFile, 'utf8');
|
|
240
|
+
const metrics = yaml.load(content) || [];
|
|
241
|
+
|
|
242
|
+
const summary = {
|
|
243
|
+
totalWorkflows: 0,
|
|
244
|
+
completedWorkflows: 0,
|
|
245
|
+
feedbackLoops: 0,
|
|
246
|
+
stageTransitions: 0,
|
|
247
|
+
averageDuration: null,
|
|
248
|
+
stageStats: {}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const durations = [];
|
|
252
|
+
|
|
253
|
+
metrics.forEach(m => {
|
|
254
|
+
switch (m.name) {
|
|
255
|
+
case 'workflow_started':
|
|
256
|
+
summary.totalWorkflows++;
|
|
257
|
+
break;
|
|
258
|
+
case 'workflow_completed':
|
|
259
|
+
summary.completedWorkflows++;
|
|
260
|
+
if (m.data.totalDuration) {
|
|
261
|
+
durations.push(this.parseDuration(m.data.totalDuration));
|
|
262
|
+
}
|
|
263
|
+
break;
|
|
264
|
+
case 'feedback_loop':
|
|
265
|
+
summary.feedbackLoops++;
|
|
266
|
+
break;
|
|
267
|
+
case 'stage_transition': {
|
|
268
|
+
summary.stageTransitions++;
|
|
269
|
+
const to = m.data.to;
|
|
270
|
+
summary.stageStats[to] = summary.stageStats[to] || { visits: 0 };
|
|
271
|
+
summary.stageStats[to].visits++;
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
if (durations.length > 0) {
|
|
278
|
+
const avgMs = durations.reduce((a, b) => a + b, 0) / durations.length;
|
|
279
|
+
summary.averageDuration = this.formatDuration(avgMs);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return summary;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Generate workflow summary
|
|
287
|
+
*/
|
|
288
|
+
generateSummary(state) {
|
|
289
|
+
const stages = Object.entries(state.stages).map(([name, data]) => ({
|
|
290
|
+
name,
|
|
291
|
+
duration: data.duration || 'N/A',
|
|
292
|
+
attempts: data.attempts || 1
|
|
293
|
+
}));
|
|
294
|
+
|
|
295
|
+
const feedbackLoops = state.history.filter(h => h.action === 'feedback-loop');
|
|
296
|
+
|
|
297
|
+
return {
|
|
298
|
+
feature: state.feature,
|
|
299
|
+
totalDuration: state.totalDuration,
|
|
300
|
+
stages,
|
|
301
|
+
feedbackLoops: feedbackLoops.length,
|
|
302
|
+
feedbackDetails: feedbackLoops
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Calculate duration between two ISO timestamps
|
|
308
|
+
*/
|
|
309
|
+
calculateDuration(start, end) {
|
|
310
|
+
const ms = new Date(end) - new Date(start);
|
|
311
|
+
return this.formatDuration(ms);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Format milliseconds to human readable duration
|
|
316
|
+
*/
|
|
317
|
+
formatDuration(ms) {
|
|
318
|
+
const seconds = Math.floor(ms / 1000);
|
|
319
|
+
const minutes = Math.floor(seconds / 60);
|
|
320
|
+
const hours = Math.floor(minutes / 60);
|
|
321
|
+
const days = Math.floor(hours / 24);
|
|
322
|
+
|
|
323
|
+
if (days > 0) return `${days}d ${hours % 24}h`;
|
|
324
|
+
if (hours > 0) return `${hours}h ${minutes % 60}m`;
|
|
325
|
+
if (minutes > 0) return `${minutes}m`;
|
|
326
|
+
return `${seconds}s`;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Parse duration string to milliseconds
|
|
331
|
+
*/
|
|
332
|
+
parseDuration(duration) {
|
|
333
|
+
const match = duration.match(/(\d+)([dhms])/g);
|
|
334
|
+
if (!match) return 0;
|
|
335
|
+
|
|
336
|
+
let ms = 0;
|
|
337
|
+
match.forEach(part => {
|
|
338
|
+
const value = parseInt(part);
|
|
339
|
+
const unit = part.slice(-1);
|
|
340
|
+
switch (unit) {
|
|
341
|
+
case 'd': ms += value * 24 * 60 * 60 * 1000; break;
|
|
342
|
+
case 'h': ms += value * 60 * 60 * 1000; break;
|
|
343
|
+
case 'm': ms += value * 60 * 1000; break;
|
|
344
|
+
case 's': ms += value * 1000; break;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
return ms;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Get valid next stages from current state
|
|
352
|
+
*/
|
|
353
|
+
async getValidTransitions() {
|
|
354
|
+
const state = await this.getState();
|
|
355
|
+
if (!state) return [];
|
|
356
|
+
return WORKFLOW_STAGES[state.currentStage]?.next || [];
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
module.exports = { WorkflowEngine, WORKFLOW_STAGES };
|
|
@@ -77,6 +77,47 @@ EARS形式の要件ドキュメントが存在する場合は参照してくだ
|
|
|
77
77
|
|
|
78
78
|
要件ドキュメントを参照することで、プロジェクトの要求事項を正確に理解し、traceabilityを確保できます。
|
|
79
79
|
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Workflow Engine Integration (v2.1.0)
|
|
83
|
+
|
|
84
|
+
**Code Reviewer** は **Stage 5: Review** を担当します。
|
|
85
|
+
|
|
86
|
+
### ワークフロー連携
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# コードレビュー開始時(Stage 5へ遷移)
|
|
90
|
+
musubi-workflow next review
|
|
91
|
+
|
|
92
|
+
# レビュー完了時(Stage 6へ遷移)
|
|
93
|
+
musubi-workflow next testing
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### レビュー結果に応じたアクション
|
|
97
|
+
|
|
98
|
+
**レビュー承認の場合**:
|
|
99
|
+
```bash
|
|
100
|
+
musubi-workflow next testing
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**修正が必要な場合(フィードバックループ)**:
|
|
104
|
+
```bash
|
|
105
|
+
musubi-workflow feedback review implementation -r "コード品質の問題を発見"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### レビュー完了チェックリスト
|
|
109
|
+
|
|
110
|
+
レビューステージを完了する前に確認:
|
|
111
|
+
|
|
112
|
+
- [ ] コード品質チェック完了
|
|
113
|
+
- [ ] SOLID原則の遵守確認
|
|
114
|
+
- [ ] セキュリティレビュー完了
|
|
115
|
+
- [ ] パフォーマンス考慮事項確認
|
|
116
|
+
- [ ] テストカバレッジ確認
|
|
117
|
+
- [ ] ドキュメント更新確認
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
80
121
|
## 3. Documentation Language Policy
|
|
81
122
|
|
|
82
123
|
**CRITICAL: 英語版と日本語版の両方を必ず作成**
|
|
@@ -75,6 +75,7 @@ The Orchestrator can leverage all MUSUBI CLI commands to execute tasks efficient
|
|
|
75
75
|
|
|
76
76
|
| Command | Purpose | Example |
|
|
77
77
|
| --------------------- | ------------------------------ | ------------------------------------ |
|
|
78
|
+
| `musubi-workflow` | Workflow state & metrics | `musubi-workflow init <feature>` |
|
|
78
79
|
| `musubi-requirements` | EARS requirements management | `musubi-requirements init <feature>` |
|
|
79
80
|
| `musubi-design` | C4 + ADR design documents | `musubi-design init <feature>` |
|
|
80
81
|
| `musubi-tasks` | Task breakdown management | `musubi-tasks init <feature>` |
|
|
@@ -95,6 +96,16 @@ The Orchestrator can leverage all MUSUBI CLI commands to execute tasks efficient
|
|
|
95
96
|
|
|
96
97
|
### Detailed Command Options
|
|
97
98
|
|
|
99
|
+
**musubi-workflow** (v2.1.0 NEW):
|
|
100
|
+
|
|
101
|
+
- `init <feature>` - Initialize workflow for a feature
|
|
102
|
+
- `status` - Show current workflow status and stage
|
|
103
|
+
- `next [stage]` - Transition to next stage
|
|
104
|
+
- `feedback <from> <to> -r <reason>` - Record feedback loop
|
|
105
|
+
- `complete` - Complete workflow with summary
|
|
106
|
+
- `history` - View workflow event history
|
|
107
|
+
- `metrics` - Show workflow metrics summary
|
|
108
|
+
|
|
98
109
|
**musubi-requirements**:
|
|
99
110
|
|
|
100
111
|
- `init <feature>` - Initialize requirements document
|
|
@@ -442,6 +453,92 @@ EARS形式の要件ドキュメントが存在する場合は参照してくだ
|
|
|
442
453
|
|
|
443
454
|
---
|
|
444
455
|
|
|
456
|
+
## Workflow Engine Integration (v2.1.0)
|
|
457
|
+
|
|
458
|
+
**NEW**: Orchestratorはワークフローエンジンを使用して、開発プロセスの状態管理とメトリクス収集を行います。
|
|
459
|
+
|
|
460
|
+
### ワークフロー開始時
|
|
461
|
+
|
|
462
|
+
新機能開発やプロジェクト開始時に、ワークフローを初期化します:
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
# ワークフロー初期化
|
|
466
|
+
musubi-workflow init <feature-name>
|
|
467
|
+
|
|
468
|
+
# 例
|
|
469
|
+
musubi-workflow init user-authentication
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### ステージ遷移
|
|
473
|
+
|
|
474
|
+
各ステージの作業完了時に、次のステージへ遷移します:
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
# 現在のステータス確認
|
|
478
|
+
musubi-workflow status
|
|
479
|
+
|
|
480
|
+
# 次のステージへ遷移
|
|
481
|
+
musubi-workflow next design
|
|
482
|
+
musubi-workflow next tasks
|
|
483
|
+
musubi-workflow next implementation
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### 10ステージ ワークフロー
|
|
487
|
+
|
|
488
|
+
| Stage | Name | Description | CLI Command |
|
|
489
|
+
|-------|------|-------------|-------------|
|
|
490
|
+
| 0 | Spike/PoC | 調査・プロトタイピング | `musubi-workflow next spike` |
|
|
491
|
+
| 1 | Requirements | 要件定義 | `musubi-requirements` |
|
|
492
|
+
| 2 | Design | 設計(C4 + ADR) | `musubi-design` |
|
|
493
|
+
| 3 | Tasks | タスク分解 | `musubi-tasks` |
|
|
494
|
+
| 4 | Implementation | 実装 | - |
|
|
495
|
+
| 5 | Review | コードレビュー | `musubi-workflow next review` |
|
|
496
|
+
| 6 | Testing | テスト | `musubi-validate` |
|
|
497
|
+
| 7 | Deployment | デプロイ | - |
|
|
498
|
+
| 8 | Monitoring | モニタリング | - |
|
|
499
|
+
| 9 | Retrospective | 振り返り | `musubi-workflow complete` |
|
|
500
|
+
|
|
501
|
+
### フィードバックループ
|
|
502
|
+
|
|
503
|
+
問題発見時に前のステージに戻る場合:
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
# レビューで問題発見 → 実装に戻る
|
|
507
|
+
musubi-workflow feedback review implementation -r "リファクタリング必要"
|
|
508
|
+
|
|
509
|
+
# テストで問題発見 → 要件に戻る
|
|
510
|
+
musubi-workflow feedback testing requirements -r "要件の不整合を発見"
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### メトリクス活用
|
|
514
|
+
|
|
515
|
+
プロジェクト完了時やレトロスペクティブで分析:
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
# ワークフロー完了(サマリー表示)
|
|
519
|
+
musubi-workflow complete
|
|
520
|
+
|
|
521
|
+
# メトリクスサマリー
|
|
522
|
+
musubi-workflow metrics
|
|
523
|
+
|
|
524
|
+
# 履歴確認
|
|
525
|
+
musubi-workflow history
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Orchestrator推奨フロー
|
|
529
|
+
|
|
530
|
+
```markdown
|
|
531
|
+
1. ユーザーから新機能リクエストを受信
|
|
532
|
+
2. `musubi-workflow init <feature>` でワークフロー開始
|
|
533
|
+
3. 各ステージで適切なエージェントを呼び出し
|
|
534
|
+
4. ステージ完了時に `musubi-workflow next <stage>` で遷移
|
|
535
|
+
5. 問題発見時は `musubi-workflow feedback` でループ記録
|
|
536
|
+
6. 全ステージ完了後 `musubi-workflow complete` で終了
|
|
537
|
+
7. メトリクスを元にプロセス改善を提案
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
445
542
|
## 重要:対話モードについて
|
|
446
543
|
|
|
447
544
|
**CRITICAL: 1問1答の徹底**
|
|
@@ -66,6 +66,45 @@ These files contain the project's "memory" - shared context that ensures consist
|
|
|
66
66
|
- You can proceed with the task without them
|
|
67
67
|
- Consider suggesting the user run `@steering` to bootstrap project memory
|
|
68
68
|
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Workflow Engine Integration (v2.1.0)
|
|
72
|
+
|
|
73
|
+
**MUSUBI Workflow Engine** を使用してプロジェクトの進捗を管理できます。
|
|
74
|
+
|
|
75
|
+
### ワークフロー状態確認
|
|
76
|
+
|
|
77
|
+
プロジェクト作業開始時に、現在のワークフロー状態を確認:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
musubi-workflow status
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### プロジェクトマネージャーの役割
|
|
84
|
+
|
|
85
|
+
| ワークフローステージ | PMの主な責務 |
|
|
86
|
+
|---------------------|-------------|
|
|
87
|
+
| Stage 0: Spike | 調査範囲の定義、期間設定 |
|
|
88
|
+
| Stage 1-3: Requirements→Design→Tasks | 進捗追跡、リソース配分 |
|
|
89
|
+
| Stage 4-6: Implementation→Review→Testing | リスク管理、ブロッカー解消 |
|
|
90
|
+
| Stage 7-8: Deployment→Monitoring | リリース計画、本番監視 |
|
|
91
|
+
| Stage 9: Retrospective | 振り返りファシリテーション |
|
|
92
|
+
|
|
93
|
+
### 推奨コマンド
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# ワークフロー初期化(新プロジェクト開始時)
|
|
97
|
+
musubi-workflow init <project-name>
|
|
98
|
+
|
|
99
|
+
# メトリクス確認(進捗レビュー時)
|
|
100
|
+
musubi-workflow metrics
|
|
101
|
+
|
|
102
|
+
# 履歴確認(振り返り時)
|
|
103
|
+
musubi-workflow history
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
69
108
|
## 3. Documentation Language Policy
|
|
70
109
|
|
|
71
110
|
**CRITICAL: 英語版と日本語版の両方を必ず作成**
|
|
@@ -26,6 +26,54 @@ allowed-tools: [Read, Write, Bash, Glob, TodoWrite]
|
|
|
26
26
|
|
|
27
27
|
You are a Release Coordinator specializing in multi-component release management and deployment orchestration.
|
|
28
28
|
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Project Memory (Steering System)
|
|
32
|
+
|
|
33
|
+
**CRITICAL: Always check steering files before starting any task**
|
|
34
|
+
|
|
35
|
+
Before beginning work, **ALWAYS** read the following files if they exist in the `steering/` directory:
|
|
36
|
+
|
|
37
|
+
- **`steering/structure.md`** - Architecture patterns, directory organization
|
|
38
|
+
- **`steering/tech.md`** - Technology stack, frameworks, deployment tools
|
|
39
|
+
- **`steering/product.md`** - Business context, product purpose
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Workflow Engine Integration (v2.1.0)
|
|
44
|
+
|
|
45
|
+
**Release Coordinator** は **Stage 7: Deployment** を担当します。
|
|
46
|
+
|
|
47
|
+
### ワークフロー連携
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# デプロイ開始時(Stage 7へ遷移)
|
|
51
|
+
musubi-workflow next deployment
|
|
52
|
+
|
|
53
|
+
# デプロイ完了時(Stage 8へ遷移)
|
|
54
|
+
musubi-workflow next monitoring
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### リリースタイプ別フロー
|
|
58
|
+
|
|
59
|
+
| リリースタイプ | ワークフローアクション |
|
|
60
|
+
|---------------|----------------------|
|
|
61
|
+
| Hotfix | `musubi-workflow init hotfix-xxx` → 高速パス |
|
|
62
|
+
| Patch | 通常フロー(Stage 6→7→8) |
|
|
63
|
+
| Minor/Major | 完全フロー(Stage 0→9) |
|
|
64
|
+
|
|
65
|
+
### デプロイ完了チェックリスト
|
|
66
|
+
|
|
67
|
+
デプロイステージを完了する前に確認:
|
|
68
|
+
|
|
69
|
+
- [ ] ステージング環境でのテスト完了
|
|
70
|
+
- [ ] 本番デプロイ完了
|
|
71
|
+
- [ ] ヘルスチェック確認
|
|
72
|
+
- [ ] ロールバック手順準備
|
|
73
|
+
- [ ] リリースノート作成
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
29
77
|
## Responsibilities
|
|
30
78
|
|
|
31
79
|
1. **Release Planning**: Coordinate releases across multiple components
|
|
@@ -68,6 +68,47 @@ These files contain the project's "memory" - shared context that ensures consist
|
|
|
68
68
|
- You can proceed with the task without them
|
|
69
69
|
- Consider suggesting the user run `@steering` to bootstrap project memory
|
|
70
70
|
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Workflow Engine Integration (v2.1.0)
|
|
74
|
+
|
|
75
|
+
**Requirements Analyst** は **Stage 1: Requirements** を担当します。
|
|
76
|
+
|
|
77
|
+
### ワークフロー連携
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# 要件定義開始時(Stage 1へ遷移)
|
|
81
|
+
musubi-workflow next requirements
|
|
82
|
+
|
|
83
|
+
# 要件定義完了時(Stage 2へ遷移)
|
|
84
|
+
musubi-workflow next design
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### ステージ完了チェックリスト
|
|
88
|
+
|
|
89
|
+
要件定義ステージを完了する前に確認:
|
|
90
|
+
|
|
91
|
+
- [ ] SRS(Software Requirements Specification)が作成済み
|
|
92
|
+
- [ ] 機能要件がEARS形式で定義済み
|
|
93
|
+
- [ ] 非機能要件が定義済み
|
|
94
|
+
- [ ] ユーザーストーリーが作成済み
|
|
95
|
+
- [ ] 要件のトレーサビリティIDが付与済み
|
|
96
|
+
- [ ] ステークホルダーの承認を取得
|
|
97
|
+
|
|
98
|
+
### フィードバックループ
|
|
99
|
+
|
|
100
|
+
後続ステージで要件の問題が発見された場合:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# 設計で問題発見 → 要件に戻る
|
|
104
|
+
musubi-workflow feedback design requirements -r "要件の曖昧さを解消"
|
|
105
|
+
|
|
106
|
+
# テストで問題発見 → 要件に戻る
|
|
107
|
+
musubi-workflow feedback testing requirements -r "受入基準の修正が必要"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
71
112
|
## 3. Documentation Language Policy
|
|
72
113
|
|
|
73
114
|
**CRITICAL: 英語版と日本語版の両方を必ず作成**
|
|
@@ -104,6 +104,34 @@ EARS形式の要件ドキュメントが存在する場合は参照してくだ
|
|
|
104
104
|
|
|
105
105
|
要件ドキュメントを参照することで、プロジェクトの要求事項を正確に理解し、traceabilityを確保できます。
|
|
106
106
|
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Workflow Engine Integration (v2.1.0)
|
|
110
|
+
|
|
111
|
+
**Software Developer** は **Stage 4: Implementation** を担当します。
|
|
112
|
+
|
|
113
|
+
### ワークフロー連携
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# 実装開始時(Stage 4へ遷移)
|
|
117
|
+
musubi-workflow next implementation
|
|
118
|
+
|
|
119
|
+
# 実装完了時(Stage 5へ遷移)
|
|
120
|
+
musubi-workflow next review
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 実装完了チェックリスト
|
|
124
|
+
|
|
125
|
+
実装ステージを完了する前に確認:
|
|
126
|
+
|
|
127
|
+
- [ ] 機能実装完了
|
|
128
|
+
- [ ] ユニットテスト作成完了
|
|
129
|
+
- [ ] コードがlint/formatに準拠
|
|
130
|
+
- [ ] 設計ドキュメントとの整合性確認
|
|
131
|
+
- [ ] トレーサビリティID付与
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
107
135
|
## 3. Documentation Language Policy
|
|
108
136
|
|
|
109
137
|
**CRITICAL: 英語版と日本語版の両方を必ず作成**
|
|
@@ -105,6 +105,34 @@ These files contain the project's "memory" - shared context that ensures consist
|
|
|
105
105
|
- You can proceed with the task without them
|
|
106
106
|
- Consider suggesting the user run `@steering` to bootstrap project memory
|
|
107
107
|
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Workflow Engine Integration (v2.1.0)
|
|
111
|
+
|
|
112
|
+
**System Architect** は **Stage 2: Design** を担当します。
|
|
113
|
+
|
|
114
|
+
### ワークフロー連携
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# 設計開始時(Stage 2へ遷移)
|
|
118
|
+
musubi-workflow next design
|
|
119
|
+
|
|
120
|
+
# 設計完了時(Stage 3へ遷移)
|
|
121
|
+
musubi-workflow next tasks
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 設計完了チェックリスト
|
|
125
|
+
|
|
126
|
+
設計ステージを完了する前に確認:
|
|
127
|
+
|
|
128
|
+
- [ ] C4モデル(Context, Container, Component)作成完了
|
|
129
|
+
- [ ] ADR(Architecture Decision Records)作成完了
|
|
130
|
+
- [ ] 要件とのトレーサビリティ確認
|
|
131
|
+
- [ ] 非機能要件の設計反映確認
|
|
132
|
+
- [ ] ステークホルダーレビュー完了
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
108
136
|
## 4. Documentation Language Policy
|
|
109
137
|
|
|
110
138
|
**CRITICAL: 英語版と日本語版の両方を必ず作成**
|
|
@@ -147,6 +147,51 @@ EARS形式の要件ドキュメントが存在する場合は参照してくだ
|
|
|
147
147
|
|
|
148
148
|
要件ドキュメントを参照することで、プロジェクトの要求事項を正確に理解し、traceabilityを確保できます。
|
|
149
149
|
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Workflow Engine Integration (v2.1.0)
|
|
153
|
+
|
|
154
|
+
**Test Engineer** は **Stage 6: Testing** を担当します。
|
|
155
|
+
|
|
156
|
+
### ワークフロー連携
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# テスト開始時(Stage 6へ遷移)
|
|
160
|
+
musubi-workflow next testing
|
|
161
|
+
|
|
162
|
+
# テスト完了時(Stage 7へ遷移)
|
|
163
|
+
musubi-workflow next deployment
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### テスト結果に応じたアクション
|
|
167
|
+
|
|
168
|
+
**テスト成功の場合**:
|
|
169
|
+
```bash
|
|
170
|
+
musubi-workflow next deployment
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**テスト失敗の場合(フィードバックループ)**:
|
|
174
|
+
```bash
|
|
175
|
+
# 実装に問題がある場合
|
|
176
|
+
musubi-workflow feedback testing implementation -r "テスト失敗: バグを発見"
|
|
177
|
+
|
|
178
|
+
# 要件に問題がある場合
|
|
179
|
+
musubi-workflow feedback testing requirements -r "要件の不整合を発見"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### テスト完了チェックリスト
|
|
183
|
+
|
|
184
|
+
テストステージを完了する前に確認:
|
|
185
|
+
|
|
186
|
+
- [ ] ユニットテスト実行完了(カバレッジ80%以上)
|
|
187
|
+
- [ ] 統合テスト実行完了
|
|
188
|
+
- [ ] E2Eテスト実行完了
|
|
189
|
+
- [ ] 全テストがパス
|
|
190
|
+
- [ ] リグレッションテスト完了
|
|
191
|
+
- [ ] テストレポート生成完了
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
150
195
|
## 3. Documentation Language Policy
|
|
151
196
|
|
|
152
197
|
**CRITICAL: 英語版と日本語版の両方を必ず作成**
|