mddd-cli 1.0.2 → 1.0.4
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/bin/cli.js +115 -123
- package/package.json +2 -2
- package/readme.md +7 -1
package/bin/cli.js
CHANGED
|
@@ -7,20 +7,20 @@ import pc from 'picocolors';
|
|
|
7
7
|
|
|
8
8
|
const program = new Command();
|
|
9
9
|
|
|
10
|
-
//
|
|
10
|
+
// Searches for the closest macro (*.spec.md) by recursively traversing the directory tree
|
|
11
11
|
function findClosestMacro(currentDir) {
|
|
12
12
|
let dir = currentDir;
|
|
13
13
|
while (dir !== path.parse(dir).root) {
|
|
14
14
|
try {
|
|
15
15
|
const files = fs.readdirSync(dir);
|
|
16
|
-
//
|
|
16
|
+
// Looks for any .spec.md file that is higher in the tree
|
|
17
17
|
const macroFile = files.find(f => f.endsWith('.spec.md') && f !== `${path.basename(currentDir)}.spec.md`);
|
|
18
18
|
|
|
19
19
|
if (macroFile) {
|
|
20
20
|
return path.join(dir, macroFile);
|
|
21
21
|
}
|
|
22
22
|
} catch (e) {
|
|
23
|
-
//
|
|
23
|
+
// Silences read permission errors in system folders
|
|
24
24
|
break;
|
|
25
25
|
}
|
|
26
26
|
dir = path.dirname(dir);
|
|
@@ -30,230 +30,222 @@ function findClosestMacro(currentDir) {
|
|
|
30
30
|
|
|
31
31
|
program
|
|
32
32
|
.name('md')
|
|
33
|
-
.description('
|
|
33
|
+
.description('Manager for co-located specifications for Mermaid Diagram Driven Development (MDDD)')
|
|
34
34
|
.version('3.0.0');
|
|
35
35
|
|
|
36
36
|
// ==========================================
|
|
37
|
-
//
|
|
37
|
+
// COMMAND: md init
|
|
38
38
|
// ==========================================
|
|
39
39
|
program
|
|
40
40
|
.command('init')
|
|
41
|
-
.description('
|
|
41
|
+
.description('Initializes the universal system prompt to guide any AI in the project under the MDDD methodology')
|
|
42
42
|
.action(() => {
|
|
43
43
|
const agentsDir = '.agents';
|
|
44
44
|
const skillsDir = path.join(agentsDir, 'skills');
|
|
45
45
|
|
|
46
|
-
// 1.
|
|
46
|
+
// 1. Creates folder structure
|
|
47
47
|
if (!fs.existsSync(agentsDir)) fs.mkdirSync(agentsDir);
|
|
48
48
|
if (!fs.existsSync(skillsDir)) fs.mkdirSync(skillsDir);
|
|
49
49
|
|
|
50
|
-
const promptContent = `#
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
## 1.
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
## 2.
|
|
60
|
-
|
|
61
|
-
1.
|
|
62
|
-
2.
|
|
63
|
-
3.
|
|
64
|
-
4.
|
|
65
|
-
|
|
66
|
-
## 3.
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
**
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
**
|
|
84
|
-
1.
|
|
85
|
-
2.
|
|
86
|
-
2.
|
|
87
|
-
3.
|
|
88
|
-
4.
|
|
89
|
-
5.
|
|
50
|
+
const promptContent = `# Mermaid Diagram Driven Development (MDDD) Protocol
|
|
51
|
+
|
|
52
|
+
You must strictly follow the modular feature specification architecture before changing, writing, or auditing productive code.
|
|
53
|
+
|
|
54
|
+
## 1. Tree Structure and Co-location
|
|
55
|
+
Visual specifications live universally in Markdown format (.md) exactly at the same level as the code they describe:
|
|
56
|
+
- Macro modules/domains have a \`[name].spec.md\` file containing the global diagram (stateDiagram-v2 syntax).
|
|
57
|
+
- Micro screens or sub-rule flows have a \`[name].spec.md\` file containing the interface flow (graph LR syntax) + Decision Tables.
|
|
58
|
+
|
|
59
|
+
## 2. Connection Rule Between Existing Flows
|
|
60
|
+
Whenever you create or change a functionality using an explicit parent file:
|
|
61
|
+
1. Open the indicated parent file BEFORE drawing the new flow.
|
|
62
|
+
2. Locate the exact node from which the business bifurcation should be born.
|
|
63
|
+
3. Modify the Mermaid code of the PARENT file to make the arrow point to the newly generated state.
|
|
64
|
+
4. In the CHILD file, start the graph using an entry node that inherits the parent's context.
|
|
65
|
+
|
|
66
|
+
## 3. Strict Diagram Versioning Rule
|
|
67
|
+
- Every file has a metadata header \`\`.
|
|
68
|
+
- Whenever you change a Mermaid diagram or a decision table using the \`/md-edit\` command, you MUST increment the file's semantic version in the header before saving:
|
|
69
|
+
- Change the Patch (\`v1.0.0\` -> \`v1.0.1\`) for syntax fixes or minor adjustments to node text.
|
|
70
|
+
- Change the Minor (\`v1.0.0\` -> \`v1.1.0\`) for new states, new transitions, or new columns in the decision matrix.
|
|
71
|
+
- Never remove the version tag. It is the guarantee that the code implementation is aligned with the correct design.
|
|
72
|
+
|
|
73
|
+
** SPECIFICATION WRITING GUIDELINE: **
|
|
74
|
+
Always use Mermaid to describe business flows, architecture, or state machines. Avoid as much as possible using running text or lists to describe complex logic.
|
|
75
|
+
Specifications (.spec.md) must be living documents focused on the Current Contract, not on past audits.
|
|
76
|
+
|
|
77
|
+
If the file is the Feature Contract: Focus only on:
|
|
78
|
+
- Mermaid Diagram (Real flow).
|
|
79
|
+
- Decision Matrix (Business rules).
|
|
80
|
+
- Signature of interfaces/services (API contract).
|
|
81
|
+
- Versioning: Keep SPEC_VERSION always at the top.
|
|
82
|
+
|
|
83
|
+
** RULES: **
|
|
84
|
+
1. When generating diagrams from code, always escape or remove function name parentheses. Use double quotes (e.g., A["main()"]) if the function name needs to be preserved, or simplify the node text (e.g., A[main]) to keep the diagram clean and avoid rendering errors.
|
|
85
|
+
2. ASCII Art or manual drawings are PROHIBITED.
|
|
86
|
+
2. Every diagram must be encapsulated in markdown code blocks with the language 'mermaid'.
|
|
87
|
+
3. For architecture flows or business logic, use exclusively 'graph TD' or 'graph LR'.
|
|
88
|
+
4. For (finite) state machines, use 'stateDiagram-v2'.
|
|
89
|
+
5. Name the nodes, use specific shapes ([...], ([...]), { ... }) to indicate intent (Action, Start/End, Decision).
|
|
90
90
|
`;
|
|
91
91
|
|
|
92
92
|
fs.writeFileSync('system_prompt.md', promptContent);
|
|
93
93
|
|
|
94
|
-
// 3.
|
|
94
|
+
// 3. Skill Definitions
|
|
95
95
|
const skills = {
|
|
96
|
-
'md-new': "
|
|
97
|
-
'md-edit': "
|
|
98
|
-
'md-audit': "
|
|
99
|
-
'md-impl': "
|
|
96
|
+
'md-new': "Drawing Mode. You must run the terminal command \`md new [path_to_new_feature]\` (and include \`-p [path]\` if there is a parent). Then, assemble the Mermaid and tables within the generated file and pause to await visual approval.",
|
|
97
|
+
'md-edit': "Editing Mode. Open the specified file, apply the change to the Mermaid or tables while keeping the syntax 100% valid, and increment the header \`\`.",
|
|
98
|
+
'md-audit': "Drastic Legacy Audit Mode. Analyze the existing code file from the perspective of visual readability (MDDD):\n1. If the code is modular, cohesive, and clean: Run the terminal command \`md new [file_directory]\`. Then, map the current flow in Mermaid, fill in the decision tables, and set the initial stable version as \`\`.\n2. If the code is chaotic, coupled, or complex: YOU ARE PROHIBITED from creating a stable diagram. Instead, point out the architectural problems, suggest a REFACTORING proposal separating responsibilities, and assemble the Mermaid of how the flow SHOULD BE post-refactoring. Save this spec file with a draft status: \`\`.",
|
|
99
|
+
'md-impl': "Implementation Mode. Read the \`.spec.md\` file from the path as your only Source of Truth and write the productive code and equivalent tests."
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
Object.keys(skills).forEach(skillName => {
|
|
103
|
-
// 1.
|
|
103
|
+
// 1. Create skill folder: .agents/skills/md-new/
|
|
104
104
|
const skillFolder = path.join(skillsDir, skillName);
|
|
105
105
|
if (!fs.existsSync(skillFolder)) {
|
|
106
106
|
fs.mkdirSync(skillFolder);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// 2.
|
|
109
|
+
// 2. Create SKILL.md file inside: .agents/skills/md-new/SKILL.md
|
|
110
110
|
const skillFile = path.join(skillFolder, 'SKILL.md');
|
|
111
111
|
|
|
112
112
|
if (!fs.existsSync(skillFile)) {
|
|
113
|
-
//
|
|
113
|
+
// Adding an automatic title for better organization
|
|
114
114
|
const content = `# ${skillName.toUpperCase()}\n\n${skills[skillName]}`;
|
|
115
115
|
fs.writeFileSync(skillFile, content);
|
|
116
|
-
console.log(pc.green(`✅
|
|
116
|
+
console.log(pc.green(`✅ Encapsulated skill: ${skillFile}`));
|
|
117
117
|
}
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
-
console.log(pc.green('✅
|
|
120
|
+
console.log(pc.green('✅ Universal [system_prompt.md] file generated at the project root!'));
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
// ==========================================
|
|
124
|
-
//
|
|
124
|
+
// COMMAND: md new <targetPath>
|
|
125
125
|
// ==========================================
|
|
126
126
|
program
|
|
127
127
|
.command('new')
|
|
128
|
-
.description('
|
|
129
|
-
.argument('<targetPath>', '
|
|
130
|
-
.option('-m, --macro', '
|
|
131
|
-
.option('-p, --parent <parentFile>', '
|
|
128
|
+
.description('Creates a new co-located specification in Markdown, injects versioning, and links to the parent flow')
|
|
129
|
+
.argument('<targetPath>', 'Path to the feature directory (e.g., src/home/guest)')
|
|
130
|
+
.option('-m, --macro', 'Defines if the new file will be a module macro containing stateDiagram-v2')
|
|
131
|
+
.option('-p, --parent <parentFile>', 'Path to an existing spec (.spec.md) file to connect this new flow')
|
|
132
132
|
.action((targetPath, options) => {
|
|
133
|
+
// Ensures the base directory exists
|
|
133
134
|
if (!fs.existsSync(targetPath)) {
|
|
134
135
|
fs.mkdirSync(targetPath, { recursive: true });
|
|
135
136
|
}
|
|
136
137
|
|
|
138
|
+
// Correction: Extracts feature name for the file
|
|
139
|
+
// If targetPath ends in /routing, folderName will be 'routing'.
|
|
140
|
+
// The file will be 'routing.spec.md'.
|
|
137
141
|
const folderName = path.basename(targetPath);
|
|
138
|
-
const isMacro = options.macro;
|
|
139
|
-
|
|
140
|
-
// Extensão universal .spec.md para absolutamente tudo
|
|
141
142
|
const finalFile = path.join(targetPath, `${folderName}.spec.md`);
|
|
142
143
|
|
|
144
|
+
// Security: Verifies if the final path exists and is a directory
|
|
145
|
+
if (fs.existsSync(finalFile) && fs.lstatSync(finalFile).isDirectory()) {
|
|
146
|
+
console.log(pc.red(`❌ Error: A directory with the name ${finalFile} already exists. Cannot create spec file.`));
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
|
|
143
150
|
if (fs.existsSync(finalFile)) {
|
|
144
|
-
console.log(pc.yellow(`⚠️
|
|
151
|
+
console.log(pc.yellow(`⚠️ The specification already exists at: ${finalFile}`));
|
|
145
152
|
return;
|
|
146
153
|
}
|
|
147
154
|
|
|
148
|
-
|
|
149
|
-
let template = '';
|
|
155
|
+
const isMacro = options.macro;
|
|
150
156
|
const version = 'v1.0.0';
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
`## 2. Matriz de Decisão\n| Condição | Ação | Próximo Estado |\n| :--- | :--- | :--- |\n| | | |\n\n` +
|
|
160
|
-
`## 3. Histórico de Auditoria\n<details>\n<summary>Clique para expandir</summary>\n\n\n\n</details>\n`;
|
|
161
|
-
}
|
|
157
|
+
let template = isMacro
|
|
158
|
+
? `\n# Macro Module: ${folderName} | ${version}\n\n` +
|
|
159
|
+
`\`\`\`mermaid\n%% @spec-version ${version}\nstateDiagram-v2\n [*] --> Initial_${folderName}\n\`\`\`\n\n` +
|
|
160
|
+
`## 3. Audit History\n<details>\n<summary>Click to expand</summary>\n\n\n\n</details>\n`
|
|
161
|
+
: `\n# Specification: ${folderName} | ${version}\n\n` +
|
|
162
|
+
`## 1. Flow Contract (Mermaid)\n\`\`\`mermaid\n%% @spec-version ${version}\ngraph LR\n A([Start]) --> B[Process]\n\`\`\`\n\n` +
|
|
163
|
+
`## 2. Decision Matrix\n| Condition | Action | Next State |\n| :--- | :--- | :--- |\n| | | |\n\n` +
|
|
164
|
+
`## 3. Audit History\n<details>\n<summary>Click to expand</summary>\n\n\n\n</details>\n`;
|
|
162
165
|
|
|
163
166
|
fs.writeFileSync(finalFile, template);
|
|
164
|
-
console.log(pc.green(`✅
|
|
165
|
-
|
|
166
|
-
//
|
|
167
|
-
let macroPath = null;
|
|
168
|
-
if (options.parent) {
|
|
169
|
-
if (fs.existsSync(options.parent)) {
|
|
170
|
-
macroPath = options.parent;
|
|
171
|
-
console.log(pc.cyan('🎯 Usando o arquivo pai explícito enviado por parâmetro.'));
|
|
172
|
-
} else {
|
|
173
|
-
console.log(pc.red(`❌ O arquivo pai indicado não foi encontrado: ${options.parent}`));
|
|
174
|
-
process.exit(1);
|
|
175
|
-
}
|
|
176
|
-
} else if (!isMacro) {
|
|
177
|
-
macroPath = findClosestMacro(targetPath);
|
|
178
|
-
}
|
|
167
|
+
console.log(pc.green(`✅ New Markdown file created: ${finalFile}`));
|
|
168
|
+
|
|
169
|
+
// Linking Logic
|
|
170
|
+
let macroPath = options.parent || (!isMacro ? findClosestMacro(targetPath) : null);
|
|
179
171
|
|
|
180
172
|
if (macroPath) {
|
|
173
|
+
if (!fs.existsSync(macroPath)) {
|
|
174
|
+
console.log(pc.red(`❌ Parent file not found: ${macroPath}`));
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
181
177
|
const relativePath = path.relative(path.dirname(macroPath), finalFile);
|
|
182
|
-
const cleanLinkPath = relativePath.replace(/\\/g, '/');
|
|
183
|
-
|
|
184
|
-
// Como o pai é um arquivo Markdown, injetamos uma seção de navegação limpa no fim do documento
|
|
185
|
-
const injection = `\n\n%% Conexão automática para sub-fluxo\n- [Ir para as regras de ${folderName}](file://./${cleanLinkPath})\n`;
|
|
178
|
+
const cleanLinkPath = relativePath.replace(/\\/g, '/');
|
|
179
|
+
const injection = `\n\n%% Automatic connection for sub-flow\n- [Go to ${folderName} rules](file://./${cleanLinkPath})\n`;
|
|
186
180
|
|
|
187
181
|
fs.appendFileSync(macroPath, injection);
|
|
188
|
-
console.log(pc.blue(`🔗
|
|
189
|
-
} else if (!isMacro) {
|
|
190
|
-
console.log(pc.yellow('⚠️ Aviso: Nenhum arquivo macro (*.spec.md) acima na árvore foi encontrado para auto-vinculação.'));
|
|
182
|
+
console.log(pc.blue(`🔗 Successfully linked in parent file: ${macroPath}`));
|
|
191
183
|
}
|
|
192
184
|
});
|
|
193
185
|
|
|
194
186
|
// ==========================================
|
|
195
|
-
//
|
|
187
|
+
// COMMAND: md edit <specFilePath> <instruction>
|
|
196
188
|
// ==========================================
|
|
197
189
|
program
|
|
198
190
|
.command('edit')
|
|
199
|
-
.description('
|
|
200
|
-
.argument('<specFilePath>', '
|
|
201
|
-
.argument('<instruction...>', '
|
|
191
|
+
.description('Signals a pending change in an existing Mermaid specification file')
|
|
192
|
+
.argument('<specFilePath>', 'Path to the spec file (.spec.md)')
|
|
193
|
+
.argument('<instruction...>', 'The change instruction or flow adjustment')
|
|
202
194
|
.action((specFilePath, instruction) => {
|
|
203
195
|
if (!fs.existsSync(specFilePath)) {
|
|
204
|
-
console.log(pc.red(`❌
|
|
196
|
+
console.log(pc.red(`❌ Specification file not found: ${specFilePath}`));
|
|
205
197
|
process.exit(1);
|
|
206
198
|
}
|
|
207
199
|
|
|
208
200
|
const fullInstruction = instruction.join(' ');
|
|
209
|
-
console.log(pc.cyan(`📝
|
|
210
|
-
console.log(pc.yellow(`⚙️
|
|
211
|
-
console.log(pc.green(`\n🚀
|
|
201
|
+
console.log(pc.cyan(`📝 Requesting change to flow: "${specFilePath}"`));
|
|
202
|
+
console.log(pc.yellow(`⚙️ Evaluated instruction: ${fullInstruction}`));
|
|
203
|
+
console.log(pc.green(`\n🚀 Ready! Use the /md-edit shortcut in the chat for the AI to apply the changes and increment the version.`));
|
|
212
204
|
});
|
|
213
205
|
|
|
214
206
|
// ==========================================
|
|
215
|
-
//
|
|
207
|
+
// COMMAND: md audit <codeFilePath>
|
|
216
208
|
// ==========================================
|
|
217
209
|
program
|
|
218
210
|
.command('audit')
|
|
219
|
-
.description('
|
|
220
|
-
.argument('<codeFilePath>', '
|
|
211
|
+
.description('Audits an existing code file to create a retroactive specification or suggest refactoring')
|
|
212
|
+
.argument('<codeFilePath>', 'Path to existing code file (e.g., src/services/user.go)')
|
|
221
213
|
.action((codeFilePath) => {
|
|
222
214
|
if (!fs.existsSync(codeFilePath)) {
|
|
223
|
-
console.log(pc.red(`❌
|
|
215
|
+
console.log(pc.red(`❌ Code file not found: ${codeFilePath}`));
|
|
224
216
|
process.exit(1);
|
|
225
217
|
}
|
|
226
218
|
|
|
227
219
|
const targetDir = path.dirname(codeFilePath);
|
|
228
220
|
const fileName = path.basename(codeFilePath);
|
|
229
221
|
|
|
230
|
-
console.log(pc.cyan(`🔍
|
|
231
|
-
console.log(pc.yellow(`⚡
|
|
222
|
+
console.log(pc.cyan(`🔍 Auditing code structure for coupling in: ${fileName}...`));
|
|
223
|
+
console.log(pc.yellow(`⚡ Requesting AI to validate complexity before generating MDDD specification.`));
|
|
232
224
|
|
|
233
225
|
if (!fs.existsSync(targetDir)) {
|
|
234
226
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
235
227
|
}
|
|
236
228
|
|
|
237
|
-
console.log(pc.green(`\n🚀
|
|
229
|
+
console.log(pc.green(`\n🚀 Ready! Use the /md-audit shortcut in the chat to receive the analysis or refactoring diagram.`));
|
|
238
230
|
});
|
|
239
231
|
|
|
240
232
|
// ==========================================
|
|
241
|
-
//
|
|
233
|
+
// COMMAND: md impl <specFilePath>
|
|
242
234
|
// ==========================================
|
|
243
235
|
program
|
|
244
236
|
.command('impl')
|
|
245
|
-
.description('
|
|
246
|
-
.argument('<specFilePath>', '
|
|
237
|
+
.description('Prepares the ecosystem to implement productive code and tests based on the spec file')
|
|
238
|
+
.argument('<specFilePath>', 'Path to the specification file (.spec.md)')
|
|
247
239
|
.action((specFilePath) => {
|
|
248
240
|
if (!fs.existsSync(specFilePath)) {
|
|
249
|
-
console.log(pc.red(`❌
|
|
241
|
+
console.log(pc.red(`❌ Specification file not found: ${specFilePath}`));
|
|
250
242
|
process.exit(1);
|
|
251
243
|
}
|
|
252
244
|
|
|
253
245
|
const fileName = path.basename(specFilePath);
|
|
254
|
-
console.log(pc.cyan(`🛠️
|
|
255
|
-
console.log(pc.yellow(`🎯
|
|
256
|
-
console.log(pc.green(`\n🚀
|
|
246
|
+
console.log(pc.cyan(`🛠️ Reading business blueprint from: ${fileName}...`));
|
|
247
|
+
console.log(pc.yellow(`🎯 Establishing the signed diagram as the Single Source of Truth.`));
|
|
248
|
+
console.log(pc.green(`\n🚀 Ready! Use the /md-impl shortcut in the chat for the AI to start generating productive code and tests.`));
|
|
257
249
|
});
|
|
258
250
|
|
|
259
251
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mddd-cli",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "CLI
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "Official CLI for modular, co-located, and versioned Mermaid Diagram Driven Development (MDDD).",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
package/readme.md
CHANGED
|
@@ -36,6 +36,9 @@ No **Mermaid Diagram Driven Development**, invertemos o ciclo tradicional de des
|
|
|
36
36
|
|
|
37
37
|
## ✅ Pré-visualização dos Diagramas Mermaid
|
|
38
38
|
|
|
39
|
+
### Exemplo diagrama de inicialização de um app Flutter
|
|
40
|
+
<img width="1316" height="444" alt="image" src="https://github.com/user-attachments/assets/5cacc283-e517-4468-a8cd-d67442a75bf2" />
|
|
41
|
+
|
|
39
42
|
Para visualizar os diagramas Mermaid diretamente no seu editor durante o fluxo MDDD, você pode utilizar extensões que renderizam blocos ````mermaid```` em arquivos Markdown:
|
|
40
43
|
|
|
41
44
|
### VS Code
|
|
@@ -196,6 +199,9 @@ In **Mermaid Diagram Driven Development**, we invert the traditional AI chat-dri
|
|
|
196
199
|
|
|
197
200
|
To preview Mermaid diagrams directly in your editor during the MDDD workflow, you can use extensions that render ````mermaid```` blocks in Markdown files:
|
|
198
201
|
|
|
202
|
+
### Exemplo diagrama de inicialização de um app Flutter
|
|
203
|
+
<img width="1316" height="444" alt="image" src="https://github.com/user-attachments/assets/5cacc283-e517-4468-a8cd-d67442a75bf2" />
|
|
204
|
+
|
|
199
205
|
### VS Code
|
|
200
206
|
- **Markdown Preview Mermaid Support** — Adds Mermaid diagram support to the native Markdown preview.
|
|
201
207
|
- **Mermaid Editor** — Visual editor with side-by-side preview and export.
|
|
@@ -323,4 +329,4 @@ If you encounter any issues, open a [GitHub Issue](https://github.com/JulioCRFil
|
|
|
323
329
|
|
|
324
330
|
## 📄 License
|
|
325
331
|
|
|
326
|
-
Distributed under the MIT license. See the [LICENSE](LICENSE) file for more information.
|
|
332
|
+
Distributed under the MIT license. See the [LICENSE](LICENSE) file for more information.
|