mddd-cli 2.1.4 → 3.0.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/bin/cli.js +1 -84
- package/bin/cli.spec.md +13 -100
- package/package.json +1 -1
- package/readme.md +43 -112
- package/src/commands/init.js +11 -8
- package/src/commands/audit.js +0 -22
- package/src/commands/edit.js +0 -19
- package/src/commands/impl.js +0 -16
- package/src/commands/new.js +0 -56
- package/src/services/AuditService.js +0 -41
- package/src/services/ImplValidator.js +0 -27
- package/src/services/ParentLinker.js +0 -70
- package/src/services/SpecEditor.js +0 -37
- package/src/services/SpecGenerator.js +0 -58
- package/src/services/SpecValidator.js +0 -27
- package/src/services/TemplateFactory.js +0 -80
package/bin/cli.js
CHANGED
|
@@ -3,28 +3,12 @@
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import pc from 'picocolors';
|
|
5
5
|
import { FileSystemService } from '../src/services/FileSystemService.js';
|
|
6
|
-
import { ParentLinker } from '../src/services/ParentLinker.js';
|
|
7
6
|
import { InitService } from '../src/services/InitService.js';
|
|
8
|
-
import { SpecGenerator } from '../src/services/SpecGenerator.js';
|
|
9
|
-
import { SpecValidator } from '../src/services/SpecValidator.js';
|
|
10
|
-
import { SpecEditor } from '../src/services/SpecEditor.js';
|
|
11
|
-
import { AuditService } from '../src/services/AuditService.js';
|
|
12
|
-
import { ImplValidator } from '../src/services/ImplValidator.js';
|
|
13
7
|
import * as initCmd from '../src/commands/init.js';
|
|
14
|
-
import * as newCmd from '../src/commands/new.js';
|
|
15
|
-
import * as editCmd from '../src/commands/edit.js';
|
|
16
|
-
import * as auditCmd from '../src/commands/audit.js';
|
|
17
|
-
import * as implCmd from '../src/commands/impl.js';
|
|
18
8
|
|
|
19
9
|
// ─── Services ────────────────────────────────────────────────────────────────
|
|
20
10
|
const fs = new FileSystemService();
|
|
21
|
-
const parentLinker = new ParentLinker(fs);
|
|
22
11
|
const initService = new InitService(fs);
|
|
23
|
-
const specGenerator = new SpecGenerator(fs);
|
|
24
|
-
const specValidator = new SpecValidator(fs);
|
|
25
|
-
const specEditor = new SpecEditor(fs);
|
|
26
|
-
const auditService = new AuditService(fs);
|
|
27
|
-
const implValidator = new ImplValidator(fs);
|
|
28
12
|
|
|
29
13
|
// ─── CLI Setup ───────────────────────────────────────────────────────────────
|
|
30
14
|
const program = new Command();
|
|
@@ -32,7 +16,7 @@ const program = new Command();
|
|
|
32
16
|
program
|
|
33
17
|
.name('md')
|
|
34
18
|
.description('Manager for co-located specifications for Mermaid Diagram Driven Development (MDDD)')
|
|
35
|
-
.version('
|
|
19
|
+
.version('3.0.1');
|
|
36
20
|
|
|
37
21
|
// ==========================================
|
|
38
22
|
// COMMAND: md init
|
|
@@ -49,72 +33,5 @@ program
|
|
|
49
33
|
}
|
|
50
34
|
});
|
|
51
35
|
|
|
52
|
-
// ==========================================
|
|
53
|
-
// COMMAND: md new <targetPath>
|
|
54
|
-
// ==========================================
|
|
55
|
-
program
|
|
56
|
-
.command('new')
|
|
57
|
-
.description('Creates a new co-located specification in Markdown, injects the version header, and links to the parent flow')
|
|
58
|
-
.argument('<targetPath>', 'Path to the feature directory (e.g., src/home/guest)')
|
|
59
|
-
.option('-m, --macro', 'Defines if the new file will be a module macro containing a stateDiagram-v2')
|
|
60
|
-
.option('-p, --parent <parentFile>', 'Path to an existing specification file (.spec.md) to connect this new flow')
|
|
61
|
-
.action(async (targetPath, options) => {
|
|
62
|
-
try {
|
|
63
|
-
await newCmd.execute(specGenerator, parentLinker, fs, targetPath, options);
|
|
64
|
-
} catch (err) {
|
|
65
|
-
console.error(pc.red(`❌ ${err.message}`));
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// ==========================================
|
|
71
|
-
// COMMAND: md edit <specFilePath> <instruction...>
|
|
72
|
-
// ==========================================
|
|
73
|
-
program
|
|
74
|
-
.command('edit')
|
|
75
|
-
.description('Signals a pending change in an existing Mermaid specification file')
|
|
76
|
-
.argument('<specFilePath>', 'Path to the specification file (.spec.md)')
|
|
77
|
-
.argument('<instruction...>', 'The change instruction or flow adjustment')
|
|
78
|
-
.action(async (specFilePath, instruction) => {
|
|
79
|
-
try {
|
|
80
|
-
await editCmd.execute(specEditor, specFilePath, instruction);
|
|
81
|
-
} catch (err) {
|
|
82
|
-
console.error(pc.red(`❌ ${err.message}`));
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
// ==========================================
|
|
88
|
-
// COMMAND: md audit <codeFilePath>
|
|
89
|
-
// ==========================================
|
|
90
|
-
program
|
|
91
|
-
.command('audit')
|
|
92
|
-
.description('Audits an existing code file to create a retroactive specification or suggest refactoring')
|
|
93
|
-
.argument('<codeFilePath>', 'Path to the existing code file (e.g., src/services/user.go)')
|
|
94
|
-
.action(async (codeFilePath) => {
|
|
95
|
-
try {
|
|
96
|
-
await auditCmd.execute(auditService, specGenerator, codeFilePath);
|
|
97
|
-
} catch (err) {
|
|
98
|
-
console.error(pc.red(`❌ ${err.message}`));
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// ==========================================
|
|
104
|
-
// COMMAND: md impl <specFilePath>
|
|
105
|
-
// ==========================================
|
|
106
|
-
program
|
|
107
|
-
.command('impl')
|
|
108
|
-
.description('Prepares the ecosystem to implement productive code and tests based on the specification file')
|
|
109
|
-
.argument('<specFilePath>', 'Path to the specification file (.spec.md)')
|
|
110
|
-
.action(async (specFilePath) => {
|
|
111
|
-
try {
|
|
112
|
-
await implCmd.execute(implValidator, specFilePath);
|
|
113
|
-
} catch (err) {
|
|
114
|
-
console.error(pc.red(`❌ ${err.message}`));
|
|
115
|
-
process.exit(1);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
36
|
// ─── Parse ───────────────────────────────────────────────────────────────────
|
|
120
37
|
program.parse(process.argv);
|
package/bin/cli.spec.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Refactoring Plan: cli |
|
|
1
|
+
# Refactoring Plan: cli | v3.0.0
|
|
2
2
|
|
|
3
3
|
## 1. Flow Contract (Mermaid)
|
|
4
4
|
|
|
5
5
|
### 1.1 Topologia Atual (As-Is)
|
|
6
6
|
|
|
7
7
|
```mermaid
|
|
8
|
-
%% @spec-version
|
|
8
|
+
%% @spec-version v3.0.0
|
|
9
9
|
graph TD
|
|
10
10
|
subgraph "CLI Entry (cli.js)"
|
|
11
11
|
A[index.js#!/usr/bin/env node] --> B[Commander: program.parse]
|
|
@@ -13,10 +13,6 @@ graph TD
|
|
|
13
13
|
|
|
14
14
|
subgraph "Command Routing"
|
|
15
15
|
B --> C[md init]
|
|
16
|
-
B --> D[md new <path>]
|
|
17
|
-
B --> E[md edit <spec> <instruction>]
|
|
18
|
-
B --> F[md audit <codeFile>]
|
|
19
|
-
B --> G[md impl <spec>]
|
|
20
16
|
end
|
|
21
17
|
|
|
22
18
|
subgraph "md init Action"
|
|
@@ -24,100 +20,27 @@ graph TD
|
|
|
24
20
|
C --> I[Write system_prompt.md]
|
|
25
21
|
C --> J[Write 4 embedded SKILL.md files]
|
|
26
22
|
end
|
|
27
|
-
|
|
28
|
-
subgraph "md new Action"
|
|
29
|
-
D --> K[Normalize path]
|
|
30
|
-
K --> L{folder exists?}
|
|
31
|
-
L -->|NO| M[mkdir -p]
|
|
32
|
-
L -->|YES| N[skip mkdir]
|
|
33
|
-
M --> O[Build .spec.md template]
|
|
34
|
-
N --> O
|
|
35
|
-
O --> P{--macro flag?}
|
|
36
|
-
P -->|YES| Q[stateDiagram-v2 template]
|
|
37
|
-
P -->|NO| R[graph LR + Decision Matrix template]
|
|
38
|
-
Q --> S[Write file]
|
|
39
|
-
R --> S
|
|
40
|
-
S --> T{--parent or findClosestMacro?}
|
|
41
|
-
T -->|Found| U[Append link to parent .spec.md]
|
|
42
|
-
T -->|Not Found| V[Done]
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
subgraph "Utility Functions"
|
|
46
|
-
X[findClosestMacro] --> Y[walk dir up]
|
|
47
|
-
Y --> Z{find *.spec.md?}
|
|
48
|
-
Z -->|Found| AA[return path]
|
|
49
|
-
Z -->|Not Found| AB[return null]
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
subgraph "md edit Action"
|
|
53
|
-
E --> AC[validate file exists]
|
|
54
|
-
AC --> AD[print placeholder message]
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
subgraph "md audit Action"
|
|
58
|
-
F --> AE[validate file exists]
|
|
59
|
-
AE --> AF{spec exists?}
|
|
60
|
-
AF -->|NO| AG[write template spec]
|
|
61
|
-
AF -->|YES| AH[print found message]
|
|
62
|
-
AG --> AI[print 'AI will analyze' message]
|
|
63
|
-
AH --> AI
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
subgraph "md impl Action"
|
|
67
|
-
G --> AJ[validate file exists]
|
|
68
|
-
AJ --> AK[print placeholder message]
|
|
69
|
-
end
|
|
70
23
|
```
|
|
71
24
|
|
|
72
25
|
### 1.2 Topologia Aprovada (To-Be → Refactoring Target)
|
|
73
26
|
|
|
74
27
|
```mermaid
|
|
75
|
-
%% @spec-version
|
|
28
|
+
%% @spec-version v3.0.0
|
|
76
29
|
graph TD
|
|
77
30
|
subgraph "CLI Entry (cli.js)"
|
|
78
31
|
A[bin/cli.js] --> B[Commander Router]
|
|
79
32
|
B --> C[delegate to ./commands/init.js]
|
|
80
|
-
B --> D[delegate to ./commands/new.js]
|
|
81
|
-
B --> E[delegate to ./commands/edit.js]
|
|
82
|
-
B --> F[delegate to ./commands/audit.js]
|
|
83
|
-
B --> G[delegate to ./commands/impl.js]
|
|
84
33
|
end
|
|
85
34
|
|
|
86
35
|
subgraph "Commands Layer"
|
|
87
36
|
C --> H[InitService.createSystemPrompt]
|
|
88
37
|
C --> I[InitService.createSkills]
|
|
89
|
-
D --> J[SpecGenerator.create]
|
|
90
|
-
D --> K[ParentLinker.link]
|
|
91
|
-
E --> L[SpecValidator.validate]
|
|
92
|
-
E --> M[SpecEditor.prepareInstruction]
|
|
93
|
-
F --> N[AuditService.run]
|
|
94
|
-
F --> O[SpecGenerator.createIfMissing]
|
|
95
|
-
G --> P[ImplValidator.validate]
|
|
96
38
|
end
|
|
97
39
|
|
|
98
40
|
subgraph "Shared Services"
|
|
99
41
|
H --> Q[FileSystemService]
|
|
100
42
|
I --> Q
|
|
101
|
-
J --> Q
|
|
102
|
-
K --> Q
|
|
103
|
-
L --> Q
|
|
104
|
-
N --> Q
|
|
105
|
-
O --> Q
|
|
106
|
-
P --> Q
|
|
107
43
|
Q --> R[fs/promises]
|
|
108
|
-
|
|
109
|
-
subgraph "Template Engine"
|
|
110
|
-
S[TemplateFactory] --> T[MacroTemplate: stateDiagram-v2]
|
|
111
|
-
S --> U[MicroTemplate: graph LR + DecisionMatrix]
|
|
112
|
-
S --> V[AuditTemplate: graph LR + AuditHistory]
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
subgraph "Tests (Unit)"
|
|
117
|
-
W[SpecGenerator.test.js]
|
|
118
|
-
X[ParentLinker.test.js]
|
|
119
|
-
Y[AuditService.test.js]
|
|
120
|
-
Z[TemplateFactory.test.js]
|
|
121
44
|
end
|
|
122
45
|
```
|
|
123
46
|
|
|
@@ -126,7 +49,7 @@ graph TD
|
|
|
126
49
|
| Código Atual | Co-located .spec.md Exists? | Design Assessment | Ação de Auditoria | Manipulação de Código Permitida? | Versão Inicial |
|
|
127
50
|
| :--- | :---: | :---: | :--- | :---: | :---: |
|
|
128
51
|
| `bin/cli.js` (421 linhas) | ❌ NO | Caótico / Acoplado | Auto-gerar Spec + Mapear Lógica Atual E Proposta | ❌ **FORBIDDEN (Immutability)** | `v1.0.0` |
|
|
129
|
-
| `src/commands
|
|
52
|
+
| `src/commands/init.js` + `src/services/InitService.js` + `src/services/FileSystemService.js` (refatorado) | ✅ YES (this spec) | Refatorado / Modular | Aprovado com diagrama To-Be como alvo de implementação | ✅ **ALLOW (Refactoring)** | `v3.0.0` |
|
|
130
53
|
|
|
131
54
|
### Fatores Primitivos de Acoplamento
|
|
132
55
|
|
|
@@ -134,10 +57,10 @@ graph TD
|
|
|
134
57
|
| :--- | :---: | :--- |
|
|
135
58
|
| Arquivo único monolítico? | ✅ YES | Acoplamento extremo; todas as responsabilidades no mesmo closure |
|
|
136
59
|
| Lógica de template embutida? | ✅ YES | 4 skills + 2 templates inline no código (string templates >20KB) |
|
|
137
|
-
| Duplicação entre `new` e `audit`? |
|
|
138
|
-
| Tratamento de erros inconsistente? |
|
|
139
|
-
| Sem separação CLI/Business? |
|
|
140
|
-
| Lógica de crawling de diretório isolada? | ❌
|
|
60
|
+
| Duplicação entre `new` e `audit`? | ❌ N/A (removido) | Comandos `new`, `edit`, `audit` e `impl` foram removidos do escopo |
|
|
61
|
+
| Tratamento de erros inconsistente? | ❌ N/A (removido) | Comandos `edit`/`audit`/`impl` removidos |
|
|
62
|
+
| Sem separação CLI/Business? | ❌ NO | `init` permanece com separação CLI/Business via `src/commands/init.js` |
|
|
63
|
+
| Lógica de crawling de diretório isolada? | ❌ N/A (removido) | `findClosestMacro` removido junto com comando `new` |
|
|
141
64
|
| Código testável? | ❌ NO | Sem módulos exportados; dependência direta de `fs`, `path` sem injeção |
|
|
142
65
|
|
|
143
66
|
## 3. Audit History
|
|
@@ -149,23 +72,13 @@ graph TD
|
|
|
149
72
|
| :--- | :--- | :---: | :--- |
|
|
150
73
|
| 2026-05-27 | MDDD-Audit Agent (Cline) | v1.0.0 | Auditoria inicial. Código classificado como **Caótico/Acoplado**. Diagrama As-Is documenta a topologia real (monolítica). Diagrama To-Be propõe separação em Commands Layer + Shared Services + Template Engine + Testes. Decisão de imutabilidade: código de produção não foi modificado. |
|
|
151
74
|
| 2026-05-27 | Cline (Agent-Actor) | v2.0.0 | **MAJOR Mutation (v1.0.0 → v2.0.0):** Aprovada refatoração estrutural do monolito `bin/cli.js` (421 linhas) para arquitetura modular: Commands Layer (`src/commands/*.js`) + Shared Services (`src/services/*.js`) + Template Engine (`src/services/TemplateFactory.js`) + Unit Tests. Removida restrição FORBIDDEN (Immutability). Diagrama To-Be promovido a alvo de implementação oficial. |
|
|
75
|
+
| 2026-05-27 | Cline (Agent-Actor) | v3.0.0 | **MAJOR Mutation (v2.0.0 → v3.0.0):** Removidos comandos `new`, `edit`, `audit` e `impl` do escopo do CLI. Diagramas As-Is e To-Be simplificados para refletir apenas o comando `init` restante. Matriz de decisão e fatores de acoplamento atualizados. |
|
|
152
76
|
|
|
153
77
|
### Análise de Qualidade
|
|
154
78
|
|
|
155
|
-
- **Acoplamento**: ⚠️ **
|
|
156
|
-
- **Coesão**:
|
|
157
|
-
- **Testabilidade**:
|
|
158
|
-
- **Manutenibilidade**:
|
|
159
|
-
- **Segurança**: ✅ Usa `EACCES`/`EPERM` handler no `findClosestMacro`.
|
|
160
|
-
|
|
161
|
-
### Recomendações de Refatoração
|
|
162
|
-
|
|
163
|
-
1. **Separar em módulos**: `src/commands/init.js`, `src/commands/new.js`, `src/commands/edit.js`, `src/commands/audit.js`, `src/commands/impl.js`
|
|
164
|
-
2. **Extrair Template Engine**: `src/services/TemplateFactory.js` com templates parametrizados
|
|
165
|
-
3. **Extrair FileSystemService**: `src/services/FileSystemService.js` com injeção de dependência para testabilidade
|
|
166
|
-
4. **Criar ParentLinker**: `src/services/ParentLinker.js` com crawler testável
|
|
167
|
-
5. **Adicionar testes unitários**: Coverage mínimo de 80% para todas as funções extraídas
|
|
168
|
-
6. **Exportar funções**: Usar `export` em vez de closures anônimas no `.action()`
|
|
169
|
-
7. **Migrar para `fs/promises`**: Substituir `readdirSync`/`writeFileSync` por `async/await` para melhor gerenciamento de concorrência
|
|
79
|
+
- **Acoplamento**: ⚠️ **MÉDIO** - O comando `init` restante ainda reside em `bin/cli.js` mas delega para `src/commands/init.js`.
|
|
80
|
+
- **Coesão**: ✅ **ALTA** - Escopo reduzido a apenas inicialização do ambiente MDDD.
|
|
81
|
+
- **Testabilidade**: ⚠️ **MÉDIA** - Serviços são injetados via construtor, mas `bin/cli.js` não exporta funções para teste unitário isolado.
|
|
82
|
+
- **Manutenibilidade**: ✅ **ALTA** - Código simplificado com apenas um comando e clara separação de responsabilidades.
|
|
170
83
|
|
|
171
84
|
</details>
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -57,11 +57,11 @@ Unlike traditional specification frameworks that generate dozens of text files a
|
|
|
57
57
|
|
|
58
58
|
| Phase | Actor | Action / Trigger | What Happens |
|
|
59
59
|
| :--- | :--- | :--- | :--- |
|
|
60
|
-
| **1. Input** | Human |
|
|
60
|
+
| **1. Input** | Human | Feature Request | The user proposes a feature using natural language, points the AI directly to a Jira/GitHub Issue/Task, or asks AI to audit a legacy file. |
|
|
61
61
|
| **2. Conception** | AI | Autogeneration | The AI assesses the scope and builds the `.spec.md` file complete with flowcharts, lifecycles, and required **Decision Matrices**. |
|
|
62
62
|
| **3. Alignment** | Human | Interactive Review | The user reviews the specification within the editor. Refinements are handled iteratively by chatting with the AI. |
|
|
63
63
|
| **4. Planning** | AI | Task Breakdown | Once the spec is approved, the AI extracts a granular, atomic checklist of development steps directly within the file. |
|
|
64
|
-
| **5. Execution** |
|
|
64
|
+
| **5. Execution** | AI | Code Generation | The AI implements production code and tests strictly adhering to the specs, updating the semantic versioning on completion. |
|
|
65
65
|
|
|
66
66
|
---
|
|
67
67
|
|
|
@@ -69,7 +69,7 @@ Unlike traditional specification frameworks that generate dozens of text files a
|
|
|
69
69
|
|
|
70
70
|
To preview Mermaid diagrams directly in your editor during the MDDD workflow, you can use extensions that render ````mermaid```` blocks in Markdown files:
|
|
71
71
|
|
|
72
|
-
### Architectural Diagram
|
|
72
|
+
### Architectural Diagram Example
|
|
73
73
|
|
|
74
74
|
```mermaid
|
|
75
75
|
sequenceDiagram
|
|
@@ -114,7 +114,7 @@ sequenceDiagram
|
|
|
114
114
|
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
### Micro-App Runtime & Lifecycle Decision Matrix
|
|
117
|
+
### Micro-App Runtime & Lifecycle Decision Matrix Example
|
|
118
118
|
|
|
119
119
|
| Active Tenant? | Premium App? | Active Billing Tier? | User Has Role Admin? | App Whitelisted? | Global Kill Switch? | Proposed Action | Decision (Outcome) | Transition State (New Status) |
|
|
120
120
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
@@ -130,7 +130,7 @@ sequenceDiagram
|
|
|
130
130
|
|
|
131
131
|
---
|
|
132
132
|
|
|
133
|
-
### VS Code
|
|
133
|
+
### VS Code and derivated
|
|
134
134
|
|
|
135
135
|
* **Markdown Preview Mermaid Support** — Adds Mermaid diagram support to the native Markdown preview.
|
|
136
136
|
* **Mermaid Editor** — Visual editor with side-by-side preview and export.
|
|
@@ -166,7 +166,7 @@ npm install -g mddd-cli
|
|
|
166
166
|
|
|
167
167
|
## 🚀 Quick Start Guide
|
|
168
168
|
|
|
169
|
-
The MDDD workflow is based on
|
|
169
|
+
The MDDD workflow is based on skills to orchestrate the AI in the chat.
|
|
170
170
|
|
|
171
171
|
### 1. Initialize your project
|
|
172
172
|
|
|
@@ -177,31 +177,22 @@ md init
|
|
|
177
177
|
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
This will create the `system_prompt.md` and `SKILL.md` files in the root directory, containing the global instructions that will guide the AI in understanding the MDDD methodology and interacting with Git logs.
|
|
180
|
+
This will create the `system_prompt.md` and `SKILL.md` files in the root directory, containing the global instructions that will guide the AI in understanding the MDDD methodology and interacting with Git logs. You can rename `system_prompt.md` to any .rules file you need (.cursorrules, .clinerules, etc.).
|
|
181
181
|
|
|
182
|
-
### 2.
|
|
182
|
+
### 2. Audit legacy files or make new ones.
|
|
183
183
|
|
|
184
|
-
|
|
184
|
+
- Tell AI to `md-audit` the file you want to review. If it's clean and concise, AI will create the spec based on it. If it's not, then AI will propose a refactoring with the "to-be" spec.
|
|
185
185
|
|
|
186
|
-
|
|
187
|
-
# For a single feature
|
|
188
|
-
md new path/feature-name
|
|
189
|
-
|
|
190
|
-
# For a feature connecting to an existing flow
|
|
191
|
-
md new path/feature-name --parent path/to/parent
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
This will generate the `feature-name.spec.md` file containing the semantic version structure, Mermaid placeholders, Decision Matrix matrices, and the implementation checklist.
|
|
186
|
+
- Tell AI to `md-new` a specification you need, connect to a Jira/Task, to a Figma/Design or simple tell AI what you need.
|
|
196
187
|
|
|
197
|
-
### 3.
|
|
188
|
+
### 3. Implement the specification.
|
|
198
189
|
|
|
199
|
-
|
|
190
|
+
Tell AI to `md-impl` pointing to a .spec file. It will read all the specification, create the task list and start working on it.
|
|
200
191
|
|
|
201
|
-
|
|
202
|
-
md audit path/to/legacy-file
|
|
192
|
+
### 4. Edit existing specifications.
|
|
203
193
|
|
|
204
|
-
|
|
194
|
+
If you need to add a new feature or modify an existing one, just tell AI to `md-edit` the .spec file with the modifications you want.
|
|
195
|
+
Review it until you get exactly the specification you need and then tell AI to `md-impl` it.
|
|
205
196
|
|
|
206
197
|
---
|
|
207
198
|
|
|
@@ -241,12 +232,6 @@ src/
|
|
|
241
232
|
| Command | Description |
|
|
242
233
|
| --- | --- |
|
|
243
234
|
| `md init` | Configures the `system_prompt.md` file and the SKILL.md files which instructs the AI how to behave. Run this everytime you update MDDD-CLI NPM Package. |
|
|
244
|
-
| `md new <targetPath>` | Creates a new `.spec.md` file at the target directory. Supports `--macro` for module-level specs and `--parent` for explicit parent linking. |
|
|
245
|
-
| `md edit <specFilePath> <instruction...>` | Signals a pending change to an existing `.spec.md` file. The AI then applies the changes and increments semantic version. |
|
|
246
|
-
| `md audit <codeFilePath>` | Audits a code file to create a retroactive `.spec.md` or suggest refactoring. |
|
|
247
|
-
| `md impl <specFilePath>` | Prepares the ecosystem to implement production code and tests based on a signed `.spec.md`. |
|
|
248
|
-
|
|
249
|
-
> **💡 Note for AI agents:** These commands are designed to be invoked by AI tools (Cursor, Windsurf, Claude Code, GitHub Copilot). As a human, simply tell the AI which skill to use and the target file.
|
|
250
235
|
|
|
251
236
|
### Project Architecture
|
|
252
237
|
|
|
@@ -254,36 +239,17 @@ The CLI codebase follows a clean modular architecture, as documented in `bin/cli
|
|
|
254
239
|
|
|
255
240
|
```
|
|
256
241
|
bin/
|
|
257
|
-
├── cli.js # Thin Commander router (<
|
|
258
|
-
└── cli.spec.md # Co-located spec (
|
|
242
|
+
├── cli.js # Thin Commander router (< 30 lines)
|
|
243
|
+
└── cli.spec.md # Co-located spec (v3.0.0)
|
|
259
244
|
|
|
260
245
|
src/
|
|
261
|
-
├── commands/ # Command layer
|
|
262
|
-
│
|
|
263
|
-
│ ├── new.js
|
|
264
|
-
│ ├── edit.js
|
|
265
|
-
│ ├── audit.js
|
|
266
|
-
│ └── impl.js
|
|
246
|
+
├── commands/ # Command layer
|
|
247
|
+
│ └── init.js
|
|
267
248
|
└── services/ # Shared services with DI
|
|
268
249
|
├── FileSystemService.js
|
|
269
|
-
|
|
270
|
-
├── ParentLinker.js
|
|
271
|
-
├── InitService.js
|
|
272
|
-
├── SpecGenerator.js
|
|
273
|
-
├── SpecValidator.js
|
|
274
|
-
├── SpecEditor.js
|
|
275
|
-
├── AuditService.js
|
|
276
|
-
└── ImplValidator.js
|
|
277
|
-
|
|
278
|
-
tests/ # Unit tests
|
|
279
|
-
├── SpecGenerator.test.js
|
|
280
|
-
├── ParentLinker.test.js
|
|
281
|
-
├── AuditService.test.js
|
|
282
|
-
└── TemplateFactory.test.js
|
|
250
|
+
└── InitService.js
|
|
283
251
|
```
|
|
284
252
|
|
|
285
|
-
All 21 unit tests pass with mocked file system (zero real I/O), ensuring full coverage of the core services.
|
|
286
|
-
|
|
287
253
|
---
|
|
288
254
|
|
|
289
255
|
## 🧪 Technologies
|
|
@@ -313,7 +279,7 @@ Distributed under the MIT license. See the [LICENSE](https://www.google.com/sear
|
|
|
313
279
|
|
|
314
280
|
Uma CLI agnóstica, ultra-leve e cirúrgica para implementar **MDDD (Mermaid Diagram Driven Development)** de forma modular, colocalizada e estritamente versionada.
|
|
315
281
|
|
|
316
|
-
Esta ferramenta automatiza a criação e a conexão de arquivos de especificação visual (Markdown + Mermaid + Matrizes de Decisão)
|
|
282
|
+
Esta ferramenta automatiza a criação e a conexão de arquivos de especificação visual (Markdown + Mermaid + Matrizes de Decisão) através do comando `md init`. O objetivo é envelopar as regras de negócio em arquivos `.spec.md` para que qualquer ferramenta de IA (**Cursor, Windsurf, Claude Code, GitHub Copilot**, etc.) use esses assets como a **Fonte Única da Verdade** antes de tocar no código produtivo.
|
|
317
283
|
|
|
318
284
|
---
|
|
319
285
|
|
|
@@ -352,11 +318,11 @@ Ao contrário de frameworks tradicionais de especificação que geram dezenas de
|
|
|
352
318
|
|
|
353
319
|
| Etapa | Ator | Ação / Gatilho | O que acontece |
|
|
354
320
|
| --- | --- | --- | --- |
|
|
355
|
-
| **1. Entrada** | Humano |
|
|
321
|
+
| **1. Entrada** | Humano | Solicitação de Funcionalidade | O usuário propõe uma funcionalidade em linguagem natural, aponta a IA diretamente para uma Issue/Task do Jira ou GitHub, ou pede para a IA auditar um arquivo legado. |
|
|
356
322
|
| **2. Concepção** | IA | Autogeração | A IA avalia o escopo e constrói o arquivo `.spec.md` completo com diagramas de fluxo, ciclos de vida e as **Matrizes de Decisão** necessárias. |
|
|
357
323
|
| **3. Alinhamento** | Humano | Revisão Interativa | O usuário revisa a especificação dentro do editor. Os refinamentos são feitos de forma iterativa conversando com a IA. |
|
|
358
324
|
| **4. Planning** | IA | Quebra de Tarefas | Com a spec aprovada, a IA extrai um checklist granular e atômico dos passos de desenvolvimento diretamente dentro do arquivo. |
|
|
359
|
-
| **5. Execução** |
|
|
325
|
+
| **5. Execução** | IA | Geração de Código | A IA implementa o código produtivo e os testes baseando-se estritamente nas specs, atualizando o versionamento semântico ao concluir. |
|
|
360
326
|
|
|
361
327
|
---
|
|
362
328
|
|
|
@@ -364,7 +330,7 @@ Ao contrário de frameworks tradicionais de especificação que geram dezenas de
|
|
|
364
330
|
|
|
365
331
|
Para visualizar diagramas Mermaid diretamente no seu editor durante o fluxo MDDD, você pode usar extensões que renderizam blocos `mermaid` em arquivos Markdown:
|
|
366
332
|
|
|
367
|
-
### Diagrama Arquitetural
|
|
333
|
+
### Exemplo de Diagrama Arquitetural
|
|
368
334
|
|
|
369
335
|
```mermaid
|
|
370
336
|
sequenceDiagram
|
|
@@ -409,7 +375,7 @@ sequenceDiagram
|
|
|
409
375
|
|
|
410
376
|
```
|
|
411
377
|
|
|
412
|
-
### Matriz de Decisão de Ciclo de Vida & Runtime de Micro-Apps
|
|
378
|
+
### Exemplo de Matriz de Decisão de Ciclo de Vida & Runtime de Micro-Apps
|
|
413
379
|
|
|
414
380
|
| Tenant Ativo? | App Premium? | Tier de Faturamento Ativo? | Usuário é Admin? | App em White-list? | Kill Switch Global Ativo? | Ação Proposta | Decisão (Resultado) | Estado de Transição (Novo Status) |
|
|
415
381
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
@@ -425,7 +391,7 @@ sequenceDiagram
|
|
|
425
391
|
|
|
426
392
|
---
|
|
427
393
|
|
|
428
|
-
### VS Code
|
|
394
|
+
### VS Code e derivados
|
|
429
395
|
|
|
430
396
|
* **Markdown Preview Mermaid Support** — Adiciona suporte a diagramas Mermaid no preview nativo do Markdown.
|
|
431
397
|
* **Mermaid Editor** — Editor visual com preview lado a lado e exportação.
|
|
@@ -461,9 +427,9 @@ npm install -g mddd-cli
|
|
|
461
427
|
|
|
462
428
|
## 🚀 Guia de Uso Rápido
|
|
463
429
|
|
|
464
|
-
O fluxo MDDD é baseado em
|
|
430
|
+
O fluxo MDDD é baseado em skills para orquestrar a IA no chat.
|
|
465
431
|
|
|
466
|
-
### 1.
|
|
432
|
+
### 1. Inicialize seu projeto
|
|
467
433
|
|
|
468
434
|
Na raiz do seu projeto, execute:
|
|
469
435
|
|
|
@@ -472,31 +438,21 @@ md init
|
|
|
472
438
|
|
|
473
439
|
```
|
|
474
440
|
|
|
475
|
-
Isso criará os arquivos `system_prompt.md` e `SKILL.md` no diretório raiz, contendo as instruções globais que guiarão a IA
|
|
441
|
+
Isso criará os arquivos `system_prompt.md` e `SKILL.md` no diretório raiz, contendo as instruções globais que guiarão a IA na compreensão da metodologia MDDD e na interação com os logs do Git. Você pode renomear `system_prompt.md` para qualquer arquivo .rules que precisar (.cursorrules, .clinerules, etc.).
|
|
476
442
|
|
|
477
|
-
### 2.
|
|
443
|
+
### 2. Auditar arquivos legados ou criar novos.
|
|
478
444
|
|
|
479
|
-
|
|
445
|
+
* Diga à IA para executar `md-audit` no arquivo que você deseja revisar. Se ele estiver limpo e conciso, a IA criará a especificação com base nele. Caso contrário, a IA proporá uma refatoração com a especificação ideal ("to-be").
|
|
446
|
+
* Diga à IA para executar `md-new` para uma especificação que você precisa, conectar a um Jira/Tarefa, a um Figma/Design ou simplesmente diga à IA o que você precisa.
|
|
480
447
|
|
|
481
|
-
|
|
482
|
-
# Para uma funcionalidade única
|
|
483
|
-
md new caminho/nome-da-feature
|
|
484
|
-
|
|
485
|
-
# Para uma funcionalidade conectando a um fluxo existente
|
|
486
|
-
md new caminho/nome-da-feature --parent caminho/para/pai
|
|
487
|
-
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
Isso gerará o arquivo `nome-da-feature.spec.md` contendo a estrutura de versão semântica, placeholders do Mermaid, tabelas de Matrizes de Decisão e o checklist de tarefas de implementação.
|
|
448
|
+
### 3. Implementar a especificação.
|
|
491
449
|
|
|
492
|
-
|
|
450
|
+
Diga à IA para executar `md-impl` apontando para um arquivo .spec. Ela lerá toda a especificação, criará a lista de tarefas e começará a trabalhar nela.
|
|
493
451
|
|
|
494
|
-
|
|
452
|
+
### 4. Editar especificações existentes.
|
|
495
453
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
```
|
|
454
|
+
Se você precisar adicionar uma nova funcionalidade ou modificar uma existente, basta dizer à IA para executar `md-edit` no arquivo .spec com as modificações desejadas.
|
|
455
|
+
Revise até obter exatamente a especificação de que precisa e, em seguida, diga à IA para executá-lo com `md-impl`.
|
|
500
456
|
|
|
501
457
|
---
|
|
502
458
|
|
|
@@ -536,12 +492,6 @@ src/
|
|
|
536
492
|
| Comando | Descrição |
|
|
537
493
|
| --- | --- |
|
|
538
494
|
| `md init` | Configura os arquivos `system_prompt.md` e `SKILL.md` que instruem a IA sobre como se comportar. Execute isto sempre que atualizar o pacote NPM do MDDD-CLI. |
|
|
539
|
-
| `md new <targetPath>` | Cria um novo arquivo `.spec.md` no diretório alvo. Suporta `--macro` para specs de módulo e `--parent` para vinculação explícita ao pai. |
|
|
540
|
-
| `md edit <specFilePath> <instruction...>` | Sinaliza uma alteração pendente em um `.spec.md` existente. A IA então aplica as mudanças e incrementa a versão semântica. |
|
|
541
|
-
| `md audit <codeFilePath>` | Audita um arquivo de código para criar um `.spec.md` retroativo ou sugerir refatoração. |
|
|
542
|
-
| `md impl <specFilePath>` | Prepara o ecossistema para implementar código produtivo e testes com base em um `.spec.md` assinado. |
|
|
543
|
-
|
|
544
|
-
> **💡 Nota para agentes de IA:** Estes comandos foram projetados para serem invocados por ferramentas de IA (Cursor, Windsurf, Claude Code, GitHub Copilot). Como humano, basta dizer à IA qual skill usar e o arquivo de destino.
|
|
545
495
|
|
|
546
496
|
### Arquitetura do Projeto
|
|
547
497
|
|
|
@@ -549,36 +499,17 @@ O código-fonte da CLI segue uma arquitetura modular limpa, conforme documentado
|
|
|
549
499
|
|
|
550
500
|
```
|
|
551
501
|
bin/
|
|
552
|
-
├── cli.js # Router Commander enxuto (<
|
|
553
|
-
└── cli.spec.md # Spec colocalizada (
|
|
502
|
+
├── cli.js # Router Commander enxuto (< 30 linhas)
|
|
503
|
+
└── cli.spec.md # Spec colocalizada (v3.0.0)
|
|
554
504
|
|
|
555
505
|
src/
|
|
556
|
-
├── commands/ # Camada de comandos
|
|
557
|
-
│
|
|
558
|
-
│ ├── new.js
|
|
559
|
-
│ ├── edit.js
|
|
560
|
-
│ ├── audit.js
|
|
561
|
-
│ └── impl.js
|
|
506
|
+
├── commands/ # Camada de comandos
|
|
507
|
+
│ └── init.js
|
|
562
508
|
└── services/ # Serviços compartilhados com DI
|
|
563
509
|
├── FileSystemService.js
|
|
564
|
-
|
|
565
|
-
├── ParentLinker.js
|
|
566
|
-
├── InitService.js
|
|
567
|
-
├── SpecGenerator.js
|
|
568
|
-
├── SpecValidator.js
|
|
569
|
-
├── SpecEditor.js
|
|
570
|
-
├── AuditService.js
|
|
571
|
-
└── ImplValidator.js
|
|
572
|
-
|
|
573
|
-
tests/ # Testes unitários
|
|
574
|
-
├── SpecGenerator.test.js
|
|
575
|
-
├── ParentLinker.test.js
|
|
576
|
-
├── AuditService.test.js
|
|
577
|
-
└── TemplateFactory.test.js
|
|
510
|
+
└── InitService.js
|
|
578
511
|
```
|
|
579
512
|
|
|
580
|
-
Todos os 21 testes unitários passam com sistema de arquivos mockado (zero I/O real), garantindo cobertura total dos serviços principais.
|
|
581
|
-
|
|
582
513
|
---
|
|
583
514
|
|
|
584
515
|
## 🧪 Tecnologias
|
|
@@ -599,4 +530,4 @@ Se encontrar qualquer problema, abra uma [Issue no GitHub](https://github.com/Ju
|
|
|
599
530
|
|
|
600
531
|
## 📄 Licença
|
|
601
532
|
|
|
602
|
-
Distribuído sob a licença MIT. Veja o arquivo [LICENSE](https://www.google.com/search?q=LICENSE) para mais informações.
|
|
533
|
+
Distribuído sob a licença MIT. Veja o arquivo [LICENSE](https://www.google.com/search?q=LICENSE) para mais informações.
|
package/src/commands/init.js
CHANGED
|
@@ -137,7 +137,7 @@ graph LR
|
|
|
137
137
|
\`\`\`mermaid
|
|
138
138
|
%% @spec-version v1.1.0
|
|
139
139
|
stateDiagram-v2
|
|
140
|
-
[*] --> AnalyzeLegacyCode: Evaluate
|
|
140
|
+
[*] --> AnalyzeLegacyCode: Evaluate code quality, conciseness, and coupling
|
|
141
141
|
AnalyzeLegacyCode --> FileSystemCheck
|
|
142
142
|
|
|
143
143
|
state FileSystemCheck {
|
|
@@ -146,12 +146,12 @@ stateDiagram-v2
|
|
|
146
146
|
CheckCoLocation --> AppendToExisting: Target Co-located .spec.md Exists
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
CreateMissingSpec --> RenderTopology:
|
|
149
|
+
CreateMissingSpec --> RenderTopology: Create new colocated .spec.md
|
|
150
150
|
AppendToExisting --> InjectAuditBlock: Target Existing File Preservation Map
|
|
151
151
|
|
|
152
152
|
state RenderTopology {
|
|
153
|
-
[*] --> CodeIsClean: Map exact architecture as-is (v1.0.0)
|
|
154
|
-
[*] --> CodeIsChaotic: Draw BOTH current real logic AND ideal target refactored graph
|
|
153
|
+
[*] --> CodeIsClean: Map exact architecture as-is (v1.0.0 - stable)
|
|
154
|
+
[*] --> CodeIsChaotic: Draw BOTH current real logic AND ideal target refactored graph (v1.0.0 - draft)
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
RenderTopology --> WriteToAuditTag: Inject payloads inside <details> block
|
|
@@ -166,11 +166,11 @@ stateDiagram-v2
|
|
|
166
166
|
| :--- | :---: | :---: | :--- | :---: | :---: |
|
|
167
167
|
| Legacy Code Active | ✅ YES | Clean / Modular | Append to existing \`<details><summary>Audit History</summary>\` | ❌ **FORBIDDEN (Immutability)** | Retain Current |
|
|
168
168
|
| Legacy Code Active | ✅ YES | Chaotic / Coupled | Append to existing \`<details><summary>Audit History</summary>\` | ❌ **FORBIDDEN (Immutability)** | Retain Current |
|
|
169
|
-
| Legacy Code Active | ❌ NO | Clean / Modular |
|
|
170
|
-
| Legacy Code Active | ❌ NO | Chaotic / Coupled |
|
|
169
|
+
| Legacy Code Active | ❌ NO | Clean / Modular | Generate Spec File + Map Current Logic | ❌ **FORBIDDEN (Immutability)** | \`v1.0.0 - stable\` |
|
|
170
|
+
| Legacy Code Active | ❌ NO | Chaotic / Coupled | Generate Spec File + Map Current Logic AND Proposed Refactoring | ❌ **FORBIDDEN (Immutability)** | \`v1.0.0 - draft\` |
|
|
171
171
|
|
|
172
172
|
### Missing Spec Auto-Repair Blueprint Requirements
|
|
173
|
-
* **Enforce Section Injections:** Every
|
|
173
|
+
* **Enforce Section Injections:** Every generated specification file must structurally enforce:
|
|
174
174
|
1. \`SPEC_VERSION: v1.0.0\` metadata header at the very top.
|
|
175
175
|
2. \`stateDiagram-v2\` or \`graph LR\` derived exactly from code logic behaviors.
|
|
176
176
|
3. \`Decision Matrix\` tables filled if the code contains conditional execution branches.
|
|
@@ -179,7 +179,10 @@ stateDiagram-v2
|
|
|
179
179
|
### Quality Assurance & Immutability Ironclad Rules
|
|
180
180
|
1. **Absolute Immutability Command:** Under no circumstances are you allowed to patch, alter, or modify the target production code file during the \`md-audit\` cycle. Your execution scope is strictly limited to observation and documentation within the Markdown specification file.
|
|
181
181
|
2. **Preservation Guarantee:** When appending an audit report to an existing \`.spec.md\` file, you must read the file completely and guarantee that the business requirements, main diagrams, and current decision matrices are left untouched. You are only allowed to inject rows inside the \`<details>\` audit history block.
|
|
182
|
-
3. **Chaotic Code Double-Mapping:** If you evaluate the legacy code as chaotic or highly coupled, you must not replace the current reality with your ideal version. You are required to draw the current graph (flawed as it is) to serve as a baseline, and then provide a separate, clearly labeled Mermaid graph showing the suggested refactored topology
|
|
182
|
+
3. **Chaotic Code Double-Mapping:** If you evaluate the legacy code as chaotic or highly coupled, you must not replace the current reality with your ideal version. You are required to draw the current graph (flawed as it is) to serve as a baseline, and then provide a separate, clearly labeled Mermaid graph showing the suggested refactored topology.
|
|
183
|
+
|
|
184
|
+
**Rule:** ALWAYS GENERATE THE .SPEC.MD FILE OR UPDATE THE EXISTING ONE.
|
|
185
|
+
`,
|
|
183
186
|
|
|
184
187
|
'md-impl': `[ROLE: SOFTWARE ENGINEER] [STRICT CONTRACT]
|
|
185
188
|
|
package/src/commands/audit.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import pc from 'picocolors';
|
|
2
|
-
import { SpecGenerator } from '../services/SpecGenerator.js';
|
|
3
|
-
import { AuditService } from '../services/AuditService.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Executes the `md audit <codeFilePath>` command.
|
|
7
|
-
* @param {AuditService} auditService
|
|
8
|
-
* @param {SpecGenerator} specGenerator
|
|
9
|
-
* @param {string} codeFilePath
|
|
10
|
-
* @returns {Promise<void>}
|
|
11
|
-
*/
|
|
12
|
-
export async function execute(auditService, specGenerator, codeFilePath) {
|
|
13
|
-
auditService.validateCodeFile(codeFilePath);
|
|
14
|
-
|
|
15
|
-
const { specFilePath: finalSpecPath } = await specGenerator.createIfMissing(codeFilePath);
|
|
16
|
-
const result = auditService.run(codeFilePath, finalSpecPath);
|
|
17
|
-
|
|
18
|
-
console.log(pc.blue(`📄 Existing specification: ${finalSpecPath}`));
|
|
19
|
-
console.log(pc.cyan(`🔍 Auditing code structure for coupling in: ${result.codeBasename}...`));
|
|
20
|
-
console.log(pc.yellow(`⚡ The AI will validate complexity and write the analysis to: ${finalSpecPath}`));
|
|
21
|
-
console.log(pc.green(`\n🚀 Ready! Use the /md-audit shortcut in chat for the AI to write the analysis and structural refactoring diagram into the co-located spec file.`));
|
|
22
|
-
}
|
package/src/commands/edit.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import pc from 'picocolors';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Executes the `md edit <specFilePath>` command.
|
|
5
|
-
* @param {import('../services/SpecEditor.js').SpecEditor} specEditor
|
|
6
|
-
* @param {string} specFilePath
|
|
7
|
-
* @param {string[]} instructionParts
|
|
8
|
-
* @returns {void}
|
|
9
|
-
*/
|
|
10
|
-
export function execute(specEditor, specFilePath, instructionParts) {
|
|
11
|
-
specEditor.validateSpec(specFilePath);
|
|
12
|
-
|
|
13
|
-
const fullInstruction = instructionParts.join(' ');
|
|
14
|
-
const prepared = specEditor.prepareInstruction(specFilePath, fullInstruction);
|
|
15
|
-
|
|
16
|
-
console.log(pc.cyan(`📝 Requesting alteration in flow: "${prepared.specFilePath}"`));
|
|
17
|
-
console.log(pc.yellow(`⚙️ Evaluated instruction: ${prepared.instruction}`));
|
|
18
|
-
console.log(pc.green(`\n🚀 Ready! Use the /md-edit shortcut in chat for the AI to apply changes to the diagram and increment the version.`));
|
|
19
|
-
}
|
package/src/commands/impl.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import pc from 'picocolors';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Executes the `md impl <specFilePath>` command.
|
|
5
|
-
* @param {import('../services/ImplValidator.js').ImplValidator} implValidator
|
|
6
|
-
* @param {string} specFilePath
|
|
7
|
-
* @returns {void}
|
|
8
|
-
*/
|
|
9
|
-
export function execute(implValidator, specFilePath) {
|
|
10
|
-
implValidator.validate(specFilePath);
|
|
11
|
-
|
|
12
|
-
const fileName = specFilePath.split('/').pop() || specFilePath.split('\\').pop();
|
|
13
|
-
console.log(pc.cyan(`🛠️ Reading business blueprint from: ${fileName}...`));
|
|
14
|
-
console.log(pc.yellow(`🎯 Establishing the signed diagram as the Single Source of Truth.`));
|
|
15
|
-
console.log(pc.green(`\n🚀 Ready! Use the /md-impl shortcut in chat for the AI to start generating productive code and tests.`));
|
|
16
|
-
}
|
package/src/commands/new.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import pc from 'picocolors';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Executes the `md new <targetPath>` command.
|
|
6
|
-
* @param {import('../services/SpecGenerator.js').SpecGenerator} specGenerator
|
|
7
|
-
* @param {import('../services/ParentLinker.js').ParentLinker} parentLinker
|
|
8
|
-
* @param {import('../services/FileSystemService.js').FileSystemService} fs
|
|
9
|
-
* @param {string} targetPath
|
|
10
|
-
* @param {{ macro?: boolean, parent?: string }} options
|
|
11
|
-
* @returns {Promise<void>}
|
|
12
|
-
*/
|
|
13
|
-
export async function execute(specGenerator, parentLinker, fs, targetPath, options) {
|
|
14
|
-
const normalizedPath = path.normalize(targetPath).replace(/[\\/]+$/, '');
|
|
15
|
-
|
|
16
|
-
fs.ensureDir(normalizedPath);
|
|
17
|
-
|
|
18
|
-
const folderName = path.basename(normalizedPath);
|
|
19
|
-
const finalFile = path.join(normalizedPath, `${folderName}.spec.md`);
|
|
20
|
-
|
|
21
|
-
if (fs.existsSync(finalFile)) {
|
|
22
|
-
// Check if it's a directory (edge case)
|
|
23
|
-
try {
|
|
24
|
-
const stats = await fs.getRaw().stat?.(finalFile);
|
|
25
|
-
if (stats?.isDirectory()) {
|
|
26
|
-
console.log(pc.red(`❌ Error: A directory named ${finalFile} already exists. Cannot create specification file.`));
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
29
|
-
} catch {
|
|
30
|
-
// stat not available in mock, fall through to normal check
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (fs.existsSync(finalFile)) {
|
|
35
|
-
console.log(pc.yellow(`⚠️ Specification already exists at: ${finalFile}. Operation aborted to avoid link duplication in the parent file.`));
|
|
36
|
-
process.exit(0);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const isMacro = options.macro || false;
|
|
40
|
-
const version = 'v1.0.0';
|
|
41
|
-
|
|
42
|
-
const { filePath } = await specGenerator.create(normalizedPath, isMacro, version);
|
|
43
|
-
console.log(pc.green(`✅ New specification file created: ${filePath}`));
|
|
44
|
-
|
|
45
|
-
let macroPath = options.parent || (!isMacro ? parentLinker.findClosestMacro(normalizedPath) : null);
|
|
46
|
-
|
|
47
|
-
if (macroPath) {
|
|
48
|
-
if (!fs.existsSync(macroPath)) {
|
|
49
|
-
console.log(pc.red(`❌ Specified parent file not found: ${macroPath}`));
|
|
50
|
-
process.exit(1);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
await parentLinker.linkToParent(macroPath, filePath, folderName);
|
|
54
|
-
console.log(pc.blue(`🔗 Successfully linked into parent flow: ${macroPath}`));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Handles the `md audit` command business logic.
|
|
3
|
-
*/
|
|
4
|
-
export class AuditService {
|
|
5
|
-
/** @type {import('./FileSystemService.js').FileSystemService} */
|
|
6
|
-
#fs;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @param {import('./FileSystemService.js').FileSystemService} fsService
|
|
10
|
-
*/
|
|
11
|
-
constructor(fsService) {
|
|
12
|
-
this.#fs = fsService;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Validates that a code file exists.
|
|
17
|
-
* @param {string} codeFilePath
|
|
18
|
-
* @returns {boolean}
|
|
19
|
-
* @throws {Error} if not found
|
|
20
|
-
*/
|
|
21
|
-
validateCodeFile(codeFilePath) {
|
|
22
|
-
if (!this.#fs.existsSync(codeFilePath)) {
|
|
23
|
-
throw new Error(`Code file not found: ${codeFilePath}`);
|
|
24
|
-
}
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Runs audit placeholders (actual AI analysis happens in chat via /md-audit skill).
|
|
30
|
-
* @param {string} codeFilePath
|
|
31
|
-
* @param {string} specFilePath
|
|
32
|
-
* @returns {{ codeBasename: string, specFilePath: string }}
|
|
33
|
-
*/
|
|
34
|
-
run(codeFilePath, specFilePath) {
|
|
35
|
-
const basename = codeFilePath.split('/').pop() || codeFilePath.split('\\').pop();
|
|
36
|
-
return {
|
|
37
|
-
codeBasename: basename,
|
|
38
|
-
specFilePath,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validates prerequisites for the `md impl` command.
|
|
3
|
-
*/
|
|
4
|
-
export class ImplValidator {
|
|
5
|
-
/** @type {import('./FileSystemService.js').FileSystemService} */
|
|
6
|
-
#fs;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @param {import('./FileSystemService.js').FileSystemService} fsService
|
|
10
|
-
*/
|
|
11
|
-
constructor(fsService) {
|
|
12
|
-
this.#fs = fsService;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Validates that a spec file exists before implementation.
|
|
17
|
-
* @param {string} specFilePath
|
|
18
|
-
* @returns {boolean}
|
|
19
|
-
* @throws {Error} if not found
|
|
20
|
-
*/
|
|
21
|
-
validate(specFilePath) {
|
|
22
|
-
if (!this.#fs.existsSync(specFilePath)) {
|
|
23
|
-
throw new Error(`Specification file not found: ${specFilePath}`);
|
|
24
|
-
}
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Crawls directories upward to find the nearest parent macro .spec.md file.
|
|
5
|
-
*/
|
|
6
|
-
export class ParentLinker {
|
|
7
|
-
/** @type {import('./FileSystemService.js').FileSystemService} */
|
|
8
|
-
#fs;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @param {import('./FileSystemService.js').FileSystemService} fsService
|
|
12
|
-
*/
|
|
13
|
-
constructor(fsService) {
|
|
14
|
-
this.#fs = fsService;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Searches for the closest macro (*.spec.md) by recursively traversing the directory tree upward.
|
|
19
|
-
* Skips the spec file that matches the current folder name to avoid self-linking.
|
|
20
|
-
* @param {string} currentDir - Absolute path of the feature directory
|
|
21
|
-
* @returns {string|null} Path to the parent .spec.md, or null if not found
|
|
22
|
-
*/
|
|
23
|
-
findClosestMacro(currentDir) {
|
|
24
|
-
let dir = path.resolve(currentDir);
|
|
25
|
-
const root = path.parse(dir).root;
|
|
26
|
-
|
|
27
|
-
while (dir !== root) {
|
|
28
|
-
try {
|
|
29
|
-
const files = this.#fs.readdirSync(dir);
|
|
30
|
-
const macroFile = files.find(
|
|
31
|
-
(f) => f.endsWith('.spec.md') && f !== `${path.basename(currentDir)}.spec.md`
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
if (macroFile) {
|
|
35
|
-
return path.join(dir, macroFile);
|
|
36
|
-
}
|
|
37
|
-
} catch (e) {
|
|
38
|
-
// Permission errors: stop climbing and return null
|
|
39
|
-
if (e.code === 'EACCES' || e.code === 'EPERM') {
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
throw e;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const parent = path.dirname(dir);
|
|
46
|
-
if (parent === dir) break;
|
|
47
|
-
dir = parent;
|
|
48
|
-
}
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Appends a markdown link to the child spec into the parent spec file.
|
|
54
|
-
* @param {string} parentSpecPath - Path to the parent .spec.md
|
|
55
|
-
* @param {string} childSpecPath - Path to the child .spec.md
|
|
56
|
-
* @param {string} folderName - Name of the child feature folder
|
|
57
|
-
* @returns {Promise<void>}\n */
|
|
58
|
-
async linkToParent(parentSpecPath, childSpecPath, folderName) {
|
|
59
|
-
const relativePath = path
|
|
60
|
-
.relative(path.dirname(parentSpecPath), childSpecPath)
|
|
61
|
-
.replace(/\\/g, '/'); // Garante compatibilidade de paths no estilo POSIX para o Markdown
|
|
62
|
-
|
|
63
|
-
const parentContent = await this.#fs.readFile(parentSpecPath);
|
|
64
|
-
|
|
65
|
-
// Injeta o link logo após o fim do bloco do Mermaid ou no topo do arquivo estruturado
|
|
66
|
-
const linkAddition = `\n\n- [Micro Feature: ${folderName}](${relativePath})`;
|
|
67
|
-
|
|
68
|
-
await this.#fs.writeFile(parentSpecPath, parentContent + linkAddition);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Handles the `md edit` command business logic.
|
|
3
|
-
*/
|
|
4
|
-
export class SpecEditor {
|
|
5
|
-
/** @type {import('./FileSystemService.js').FileSystemService} */
|
|
6
|
-
#fs;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @param {import('./FileSystemService.js').FileSystemService} fsService
|
|
10
|
-
*/
|
|
11
|
-
constructor(fsService) {
|
|
12
|
-
this.#fs = fsService;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Validates that a spec file exists.
|
|
17
|
-
* @param {string} specFilePath
|
|
18
|
-
* @returns {boolean}
|
|
19
|
-
* @throws {Error} if not found
|
|
20
|
-
*/
|
|
21
|
-
validateSpec(specFilePath) {
|
|
22
|
-
if (!this.#fs.existsSync(specFilePath)) {
|
|
23
|
-
throw new Error(`Specification file not found: ${specFilePath}`);
|
|
24
|
-
}
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Prepares the edit instruction message (placeholder — actual logic applied by AI agent).
|
|
30
|
-
* @param {string} specFilePath
|
|
31
|
-
* @param {string} instruction
|
|
32
|
-
* @returns {{ specFilePath: string, instruction: string }}
|
|
33
|
-
*/
|
|
34
|
-
prepareInstruction(specFilePath, instruction) {
|
|
35
|
-
return { specFilePath, instruction };
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { TemplateFactory } from './TemplateFactory.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Handles .spec.md file generation for `md new` and `md audit` commands.
|
|
6
|
-
*/
|
|
7
|
-
export class SpecGenerator {
|
|
8
|
-
/** @type {import('./FileSystemService.js').FileSystemService} */
|
|
9
|
-
#fs;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @param {import('./FileSystemService.js').FileSystemService} fsService
|
|
13
|
-
*/
|
|
14
|
-
constructor(fsService) {
|
|
15
|
-
this.#fs = fsService;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates a new .spec.md file for a feature (macro or micro).
|
|
20
|
-
* @param {string} targetPath - Normalized target directory path
|
|
21
|
-
* @param {boolean} isMacro - Whether to generate a macro template
|
|
22
|
-
* @param {string} version - Semantic version string (e.g. 'v1.0.0')
|
|
23
|
-
* @returns {Promise<{filePath: string, folderName: string}>}
|
|
24
|
-
*/
|
|
25
|
-
async create(targetPath, isMacro, version) {
|
|
26
|
-
const folderName = path.basename(targetPath);
|
|
27
|
-
const finalFile = path.join(targetPath, `${folderName}.spec.md`);
|
|
28
|
-
|
|
29
|
-
const template = isMacro
|
|
30
|
-
? TemplateFactory.macroTemplate(folderName, version)
|
|
31
|
-
: TemplateFactory.microTemplate(folderName, version);
|
|
32
|
-
|
|
33
|
-
await this.#fs.writeFile(finalFile, template);
|
|
34
|
-
|
|
35
|
-
return { filePath: finalFile, folderName };
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Creates a missing .spec.md file for audit purposes.
|
|
40
|
-
* @param {string} codeFilePath - Path to the code file being audited
|
|
41
|
-
* @returns {Promise<{specFilePath: string, codeBaseName: string}>}
|
|
42
|
-
*/
|
|
43
|
-
async createIfMissing(codeFilePath) {
|
|
44
|
-
const targetDir = path.dirname(codeFilePath);
|
|
45
|
-
const ext = path.extname(codeFilePath);
|
|
46
|
-
const codeBaseName = path.basename(codeFilePath, ext);
|
|
47
|
-
const specFileName = `${codeBaseName}.spec.md`;
|
|
48
|
-
const specFilePath = path.join(targetDir, specFileName);
|
|
49
|
-
|
|
50
|
-
if (!this.#fs.existsSync(specFilePath)) {
|
|
51
|
-
const version = 'v1.0.0';
|
|
52
|
-
const template = TemplateFactory.auditTemplate(codeBaseName, version);
|
|
53
|
-
await this.#fs.writeFile(specFilePath, template);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return { specFilePath, codeBaseName };
|
|
57
|
-
}
|
|
58
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validates that a .spec.md file exists before processing.
|
|
3
|
-
*/
|
|
4
|
-
export class SpecValidator {
|
|
5
|
-
/** @type {import('./FileSystemService.js').FileSystemService} */
|
|
6
|
-
#fs;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @param {import('./FileSystemService.js').FileSystemService} fsService
|
|
10
|
-
*/
|
|
11
|
-
constructor(fsService) {
|
|
12
|
-
this.#fs = fsService;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Validates that a spec file path exists.
|
|
17
|
-
* @param {string} specFilePath
|
|
18
|
-
* @returns {boolean} true if valid
|
|
19
|
-
* @throws {Error} if file does not exist
|
|
20
|
-
*/
|
|
21
|
-
validate(specFilePath) {
|
|
22
|
-
if (!this.#fs.existsSync(specFilePath)) {
|
|
23
|
-
throw new Error(`Specification file not found: ${specFilePath}`);
|
|
24
|
-
}
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template engine for generating .spec.md file blueprints.
|
|
3
|
-
*/
|
|
4
|
-
export class TemplateFactory {
|
|
5
|
-
/**
|
|
6
|
-
* Generates a macro module template (stateDiagram-v2).
|
|
7
|
-
* @param {string} folderName
|
|
8
|
-
* @param {string} version
|
|
9
|
-
* @returns {string}
|
|
10
|
-
*/
|
|
11
|
-
static macroTemplate(folderName, version) {
|
|
12
|
-
return (
|
|
13
|
-
`\n# Macro Module: ${folderName} | ${version}\n\n` +
|
|
14
|
-
'```mermaid\n' +
|
|
15
|
-
`%% @spec-version ${version}\n` +
|
|
16
|
-
'stateDiagram-v2\n' +
|
|
17
|
-
` [*] --> Initial_${folderName}\n` +
|
|
18
|
-
'```\n\n' +
|
|
19
|
-
'## 3. Audit History\n' +
|
|
20
|
-
'<details>\n' +
|
|
21
|
-
'<summary>Click to expand</summary>\n' +
|
|
22
|
-
'\n\n\n' +
|
|
23
|
-
'</details>\n'
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Generates a micro feature template (graph LR + Decision Matrix).
|
|
29
|
-
* @param {string} folderName
|
|
30
|
-
* @param {string} version
|
|
31
|
-
* @returns {string}
|
|
32
|
-
*/
|
|
33
|
-
static microTemplate(folderName, version) {
|
|
34
|
-
return (
|
|
35
|
-
`\n# Specification: ${folderName} | ${version}\n\n` +
|
|
36
|
-
'## 1. Flow Contract (Mermaid)\n' +
|
|
37
|
-
'```mermaid\n' +
|
|
38
|
-
`%% @spec-version ${version}\n` +
|
|
39
|
-
'graph LR\n' +
|
|
40
|
-
' A([Start]) --> B[Process]\n' +
|
|
41
|
-
'```\n\n' +
|
|
42
|
-
'## 2. Decision Matrix\n' +
|
|
43
|
-
'| Factor A? | Factor B? | Proposed Action | Decision (Outcome) | Transition State (New Status) |\n' +
|
|
44
|
-
'| :---: | :---: | :--- | :---: | :---: |\n' +
|
|
45
|
-
'| | | | | |\n\n' +
|
|
46
|
-
'## 3. Audit History\n' +
|
|
47
|
-
'<details>\n' +
|
|
48
|
-
'<summary>Click to expand</summary>\n' +
|
|
49
|
-
'\n\n\n' +
|
|
50
|
-
'</details>\n'
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Generates an audit template (graph LR + AuditHistory).
|
|
56
|
-
* @param {string} codeBaseName
|
|
57
|
-
* @param {string} version
|
|
58
|
-
* @returns {string}
|
|
59
|
-
*/
|
|
60
|
-
static auditTemplate(codeBaseName, version) {
|
|
61
|
-
return (
|
|
62
|
-
`# Audit: ${codeBaseName} | ${version}\n\n` +
|
|
63
|
-
'## 1. Flow Contract (Mermaid)\n' +
|
|
64
|
-
'```mermaid\n' +
|
|
65
|
-
`%% @spec-version ${version}\n` +
|
|
66
|
-
'graph LR\n' +
|
|
67
|
-
' A([Start]) --> B[Process]\n' +
|
|
68
|
-
'```\n\n' +
|
|
69
|
-
'## 2. Decision Matrix\n' +
|
|
70
|
-
'| Condition | Action | Next State |\n' +
|
|
71
|
-
'| :---: | :--- | :---: |\n' +
|
|
72
|
-
'| | | |\n\n' +
|
|
73
|
-
'## 3. Audit History\n' +
|
|
74
|
-
'<details>\n' +
|
|
75
|
-
'<summary>Click to expand</summary>\n' +
|
|
76
|
-
'\n\n\n' +
|
|
77
|
-
'</details>\n'
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
}
|