mddd-cli 2.0.0 → 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/bin/cli.js +92 -393
- package/bin/cli.spec.md +6 -4
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,421 +1,120 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
|
-
import fs from 'fs';
|
|
5
|
-
import path from 'path';
|
|
6
4
|
import pc from 'picocolors';
|
|
7
|
-
|
|
5
|
+
import { FileSystemService } from '../src/services/FileSystemService.js';
|
|
6
|
+
import { ParentLinker } from '../src/services/ParentLinker.js';
|
|
7
|
+
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
|
+
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
|
+
|
|
19
|
+
// ─── Services ────────────────────────────────────────────────────────────────
|
|
20
|
+
const fs = new FileSystemService();
|
|
21
|
+
const parentLinker = new ParentLinker(fs);
|
|
22
|
+
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
|
+
|
|
29
|
+
// ─── CLI Setup ───────────────────────────────────────────────────────────────
|
|
8
30
|
const program = new Command();
|
|
9
31
|
|
|
10
|
-
// Searches for the closest macro (*.spec.md) by recursively traversing the directory tree
|
|
11
|
-
function findClosestMacro(currentDir) {
|
|
12
|
-
let dir = path.resolve(currentDir);
|
|
13
|
-
const root = path.parse(dir).root;
|
|
14
|
-
|
|
15
|
-
while (dir !== root) {
|
|
16
|
-
try {
|
|
17
|
-
const files = fs.readdirSync(dir);
|
|
18
|
-
const macroFile = files.find(f => f.endsWith('.spec.md') && f !== `${path.basename(currentDir)}.spec.md`);
|
|
19
|
-
|
|
20
|
-
if (macroFile) {
|
|
21
|
-
return path.join(dir, macroFile);
|
|
22
|
-
}
|
|
23
|
-
} catch (e) {
|
|
24
|
-
if (e.code === 'EACCES' || e.code === 'EPERM') {
|
|
25
|
-
break;
|
|
26
|
-
}
|
|
27
|
-
throw e;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const parent = path.dirname(dir);
|
|
31
|
-
if (parent === dir) break;
|
|
32
|
-
dir = parent;
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
32
|
program
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
.name('md')
|
|
34
|
+
.description('Manager for co-located specifications for Mermaid Diagram Driven Development (MDDD)')
|
|
35
|
+
.version('2.1.1');
|
|
41
36
|
|
|
42
37
|
// ==========================================
|
|
43
38
|
// COMMAND: md init
|
|
44
39
|
// ==========================================
|
|
45
40
|
program
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// SYSTEM PROMPT: Uso de 4 crases externas para isolar com precisão o bloco Mermaid interno
|
|
56
|
-
const promptContent = `# Mermaid Diagram Driven Development (MDDD) Protocol
|
|
57
|
-
|
|
58
|
-
You are an engineering agent operating strictly under MDDD. Your cognitive processing is guided by visual topologies and truth tables, completely eliminating text-based specification ambiguity.
|
|
59
|
-
|
|
60
|
-
\`\`\`mermaid
|
|
61
|
-
%% @spec-version v1.0.0
|
|
62
|
-
stateDiagram-v2
|
|
63
|
-
[*] --> ReadSpecification: User Trigger Fired
|
|
64
|
-
ReadSpecification --> CheckDecisionMatrix: Evaluate Primitive Factors
|
|
65
|
-
CheckDecisionMatrix --> HaltWithConflict: Constraint Violation / Feature Creep
|
|
66
|
-
CheckDecisionMatrix --> ExecuteAction: Strict Match Confirmed
|
|
67
|
-
ExecuteAction --> MutateState: Apply File/Code Changes
|
|
68
|
-
MutateState --> UpdateVersionHeader: Apply Semantic Version Rules
|
|
69
|
-
UpdateVersionHeader --> [*]
|
|
70
|
-
\`\`\`
|
|
71
|
-
|
|
72
|
-
## 1. Co-location Architecture Tree
|
|
73
|
-
|
|
74
|
-
src/
|
|
75
|
-
└── [domain]/
|
|
76
|
-
├── [domain_name].spec.md # 🌎 Macro Module Domain
|
|
77
|
-
└── [feature_name]/
|
|
78
|
-
├── [feature_name].spec.md # 🔬 Micro Flow Contract + Decision Matrix
|
|
79
|
-
└── [feature_name].* # 💻 Target Production Code File (Any Extension)
|
|
80
|
-
|
|
81
|
-
## 2. Parent Interaction Logic
|
|
82
|
-
|
|
83
|
-
\`\`\`mermaid
|
|
84
|
-
graph TD
|
|
85
|
-
A[Create/Change Sub-Feature] --> B[Open Indicated Parent File]
|
|
86
|
-
B --> C[Locate Bifurcation Node in Parent Mermaid]
|
|
87
|
-
C --> D[Modify Parent Graph: Point Arrow to New State]
|
|
88
|
-
D --> E[Child File: Inherit Parent Context in Entry Node]
|
|
89
|
-
\`\`\`
|
|
90
|
-
|
|
91
|
-
## 3. Core Behavioral Framework Matrix
|
|
92
|
-
|
|
93
|
-
| User Context | Target Spec Header | Human Request Path | Diagram Change Impact | AI Core Rule / Mandate / Ironclad Clause |
|
|
94
|
-
| :---: | :---: | :---: | :---: | :--- |
|
|
95
|
-
| - | **MISSING** | - | - | Never remove, omit, or bypass the version tag from files. |
|
|
96
|
-
| Code Change Needed | **SIGNED** | Contradicts Matrix | - | 🛑 **HALT**: Refuse code generation. Demand \`md edit\` to align design first. |
|
|
97
|
-
| Feature Writing | - | Continuous Text Block | - | 📊 **STRUCTURE**: Convert text into tables of primitive factors (yes/no/rigid values). |
|
|
98
|
-
| Command Executed | \`SPEC_VERSION\` | - | Typo / Label Only | Increment Patch (\`X.Y.Z\` -> \`X.Y.Z+1\`) |
|
|
99
|
-
| Command Executed | \`SPEC_VERSION\` | - | New State / Arrow / Matrix Column | Increment Minor (\`X.Y.Z\` -> \`X.Y+1.0\`) |
|
|
100
|
-
| Command Executed | \`SPEC_VERSION\` | - | Structural Breaking / Flow Overhaul | Increment Major (\`X.Y.Z\` -> \`X+1.0.0\`) |
|
|
101
|
-
|
|
102
|
-
## 4. Anti-Hallucination Guardrails
|
|
103
|
-
1. **No Spec, No Code:** You are strictly forbidden from writing a single line of production code or unit tests if the corresponding \`.spec.md\` file does not exist or does not contain a populated Decision Matrix.
|
|
104
|
-
2. **Implicit Logic Ban:** If a business condition, validation check, or outcome branch is not explicitly listed as a row or column in the Decision Matrix, it does not exist. Do not assume, extrapolate, or invent fallback behaviors.
|
|
105
|
-
3. **Strict State Isolation:** When handling a micro feature, you cannot introduce global states or modify sibling domains unless instructed via explicit macro architectural mapping updates.
|
|
106
|
-
4. **Idempotent Full-File Output Mandate:** You are completely forbidden from using code placeholders, truncating files, or emitting partial snippets (e.g., "// rest of class unchanged", "/* TODO */"). Every code generation action must output the entire, clean, compile-ready file from scratch, ensuring perfect context preservation.
|
|
107
|
-
`;
|
|
108
|
-
|
|
109
|
-
fs.writeFileSync('system_prompt.md', promptContent);
|
|
110
|
-
|
|
111
|
-
// SKILLS AUTOMATION: Resolvido o aninhamento de strings escapando as crases internas com barras triplas
|
|
112
|
-
const skills = {
|
|
113
|
-
'md-new': `[ROLE: ARCHITECT] [STRICT CONTRACT]
|
|
114
|
-
|
|
115
|
-
\`\`\`mermaid
|
|
116
|
-
%% @spec-version v1.1.0
|
|
117
|
-
stateDiagram-v2
|
|
118
|
-
[*] --> TargetVerification
|
|
119
|
-
TargetVerification --> StopAndSwitchToEdit: .spec.md File Already Exists
|
|
120
|
-
TargetVerification --> EvaluateContext: File Does Not Exist
|
|
121
|
-
|
|
122
|
-
state EvaluateContext {
|
|
123
|
-
[*] --> CheckDirectoryDepth
|
|
124
|
-
CheckDirectoryDepth --> InferMacro: Target is Domain Root (e.g., src/domain)
|
|
125
|
-
CheckDirectoryDepth --> InferMicro: Target is Sub-Feature (e.g., src/domain/feature)
|
|
41
|
+
.command('init')
|
|
42
|
+
.description('Initializes the universal system prompt and matrix-driven skills to guide the AI under the MDDD methodology')
|
|
43
|
+
.action(async () => {
|
|
44
|
+
try {
|
|
45
|
+
await initCmd.execute(initService);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.error(pc.red(`❌ ${err.message}`));
|
|
48
|
+
process.exit(1);
|
|
126
49
|
}
|
|
127
|
-
|
|
128
|
-
InferMacro --> ExecCliNew: Apply stateDiagram-v2 Template
|
|
129
|
-
InferMicro --> ExecCliNew: Apply graph LR + Matrix Template
|
|
130
|
-
|
|
131
|
-
ExecCliNew --> AwaitHumanReview: Run "md new [path]" & Populate Blueprint
|
|
132
|
-
AwaitHumanReview --> [*]: Pause Code & Test Generation
|
|
133
|
-
\`\`\`
|
|
134
|
-
|
|
135
|
-
### Operational Execution Matrix
|
|
136
|
-
|
|
137
|
-
| File Exists? | Path Depth Type | Parent Indicated? | CLI Execution Syntax | Target Payload Blueprint | Next AI Action |
|
|
138
|
-
| :---: | :---: | :---: | :--- | :--- | :---: |
|
|
139
|
-
| ✅ YES | - | - | *None* (Aborted) | *None* | 🛑 **STOP** (Call md-edit instead) |
|
|
140
|
-
| ❌ NO | Domain Root | ❌ NO | \`md new [domain_path]\` | \`stateDiagram-v2\` Placeholder Domain Map | ⏳ **AWAIT_VISUAL_APPROVAL** |
|
|
141
|
-
| ❌ NO | Sub-Feature | ❌ NO | \`md new [feature_path]\` | \`graph LR\` + Auto-scanned parent link reference | ⏳ **AWAIT_VISUAL_APPROVAL** |
|
|
142
|
-
| ❌ NO | Sub-Feature | ✅ YES | \`md new [feature_path] -p[parent]\` | \`graph LR\` + Explicit link injected to designated Parent | ⏳ **AWAIT_VISUAL_APPROVAL** |
|
|
143
|
-
|
|
144
|
-
### Automation & Inference Ironclad Rules
|
|
145
|
-
1. **Deterministic Inference:** You must strictly follow the directory depth. If the target path is a top-level domain folder inside your source root, treat it as a Module Macro. If it is nested inside a domain, it is a Micro Feature. Never ask the user to declare this.
|
|
146
|
-
2. **Implicit Parent Binding:** When creating a Sub-Feature without an explicit \`-p\` parameter, acknowledge that the CLI tool will automatically scan and mutate the nearest parent macro file via recursive climbing. You must read the updated parent immediately after execution to synchronize your internal context map.
|
|
147
|
-
3. Agnostic Blueprint Initialization: When generating the initial blueprint files, you must scan the neighboring files in the target domain directory to identify the current programming language and framework conventions. Adapt your placeholder references to strictly pair with the localized file architecture.`,
|
|
148
|
-
|
|
149
|
-
'md-edit': `[ROLE: ARCHITECT] [STRICT CONTRACT]
|
|
150
|
-
|
|
151
|
-
\`\`\`mermaid
|
|
152
|
-
%% @spec-version v1.1.0
|
|
153
|
-
graph LR
|
|
154
|
-
A[Read Target .spec.md] --> B[Parse Current SPEC_VERSION]
|
|
155
|
-
B --> C[Apply Mermaid/Matrix Adjustments]
|
|
156
|
-
C --> D{Evaluate Mutation Scope}
|
|
157
|
-
|
|
158
|
-
D -->|Typo / Label Fix| E[Increment Patch: Bump Z in X.Y.Z]
|
|
159
|
-
D -->|New Node / Flow Path / Factor| F[Increment Minor: Bump Y in X.Y.Z]
|
|
160
|
-
D -->|Breaking Overhaul / Restructure| G[Increment Major: Bump X in X.Y.Z]
|
|
161
|
-
|
|
162
|
-
E --> H[Validate Mermaid Syntax]
|
|
163
|
-
F --> H
|
|
164
|
-
G --> H
|
|
165
|
-
|
|
166
|
-
H -->|Syntax Valid| I[Save Contract & Halt]
|
|
167
|
-
H -->|Syntax Invalid| J[🛑 HALT: Abort & Ask Human]
|
|
168
|
-
\`\`\`
|
|
169
|
-
|
|
170
|
-
### Evolution Versioning Matrix
|
|
171
|
-
|
|
172
|
-
| Structural Change Type | Adds Factor Column? | Adds Transition Node/Arrow? | Label / Typo Corrections Only? | Semantic Version Modification | Target AI State |
|
|
173
|
-
| :--- | :---: | :---: | :---: | :---: | :---: |
|
|
174
|
-
| Complete Business Overhaul | - | - | - | **MAJOR Mutation (X.Y.Z -> X+1.0.0)** | ⏳ **AWAIT_USER_VALIDATION** |
|
|
175
|
-
| New Context Conditional Branch | ✅ YES | - | - | **MINOR Mutation (X.Y.Z -> X.Y+1.0)** | ⏳ **AWAIT_USER_VALIDATION** |
|
|
176
|
-
| New UI Flow Step / Lifecycle State | ❌ NO | ✅ YES | - | **MINOR Mutation (X.Y.Z -> X.Y+1.0)** | ⏳ **AWAIT_USER_VALIDATION** |
|
|
177
|
-
| Visual Spacing / Text Refinement | ❌ NO | ❌ NO | ✅ YES | **PATCH Mutation (X.Y.Z -> X.Y.Z+1)** | ⏳ **AWAIT_USER_VALIDATION** |
|
|
178
|
-
|
|
179
|
-
### Mutation Integrity Ironclad Rules
|
|
180
|
-
1. **Incremental SemVer Locking:** You must read the existing \`SPEC_VERSION\` from the file header before modifying it. Never reset, guess, or overwrite the version to a lower state. Bumping Minor explicitly drops the patch version to zero (\`X.Y.Z\` -> \`X.Y+1.0\`). Bumping Major explicitly drops both minor and patch to zero (\`X.Y.Z\` -> \`X+1.0.0\`).
|
|
181
|
-
2. **Strict Syntax Guard:** Before writing the modifications to disk, execute an internal mental compilation of the Mermaid syntax. If any arrow (\`-->\`), state connector, or label syntax breaks the official Mermaid spec, immediately halt execution and report the error to the user without modifying the file.
|
|
182
|
-
3. **Audit History Log Requirement:** Every time you perform an edit, you must append a new row to the markdown table inside the \`<details><summary>Click to expand</summary>...</details>\` block at the bottom of the file, containing the current date, your agent identity, the new version number, and a concise summary of the changes made.
|
|
183
|
-
4. **Node ID Immutability:** When adding new transitions or nodes to an existing graph, you are strictly forbidden from altering, renaming, or refactoring the identifiers (IDs) of existing states/nodes unless explicitly requested by the user.`,
|
|
184
|
-
|
|
185
|
-
'md-audit': `[ROLE: SECURITY & QUALITY AUDITOR] [STRICT CONTRACT]
|
|
186
|
-
|
|
187
|
-
\`\`\`mermaid
|
|
188
|
-
%% @spec-version v1.1.0
|
|
189
|
-
stateDiagram-v2
|
|
190
|
-
[*] --> AnalyzeLegacyCode: Evaluate Coupling & Scope Leaks
|
|
191
|
-
AnalyzeLegacyCode --> FileSystemCheck
|
|
192
|
-
|
|
193
|
-
state FileSystemCheck {
|
|
194
|
-
[*] --> CheckCoLocation
|
|
195
|
-
CheckCoLocation --> CreateMissingSpec: Target Co-located .spec.md Missing
|
|
196
|
-
CheckCoLocation --> AppendToExisting: Target Co-located .spec.md Exists
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
CreateMissingSpec --> RenderTopology: Initialize New .spec.md
|
|
200
|
-
AppendToExisting --> InjectAuditBlock: Target Existing File Preservation Map
|
|
201
|
-
|
|
202
|
-
state RenderTopology {
|
|
203
|
-
[*] --> CodeIsClean: Map exact architecture as-is (v1.0.0)
|
|
204
|
-
[*] --> CodeIsChaotic: Draw BOTH current real logic AND ideal target refactored graph
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
RenderTopology --> WriteToAuditTag: Inject payloads inside <details> block
|
|
208
|
-
InjectAuditBlock --> WriteToAuditTag: Append to existing <details> block without overwriting business specs
|
|
209
|
-
WriteToAuditTag --> EnforceImmutability: Lock Production Code File
|
|
210
|
-
EnforceImmutability --> [*]
|
|
211
|
-
\`\`\`
|
|
212
|
-
|
|
213
|
-
### Reverse Engineering & Auto-Repair Decision Matrix
|
|
214
|
-
|
|
215
|
-
| Source File State | Co-located .spec.md Exists? | Code Design Assessment | Target Output Destination | Code File Manipulation Allowed? | Initial Compiled Version |
|
|
216
|
-
| :--- | :---: | :---: | :--- | :---: | :---: |
|
|
217
|
-
| Legacy Code Active | ✅ YES | Clean / Modular | Append to existing \`<details><summary>Audit History</summary>\` | ❌ **FORBIDDEN (Immutability)** | Retain Current |
|
|
218
|
-
| Legacy Code Active | ✅ YES | Chaotic / Coupled | Append to existing \`<details><summary>Audit History</summary>\` | ❌ **FORBIDDEN (Immutability)** | Retain Current |
|
|
219
|
-
| Legacy Code Active | ❌ NO | Clean / Modular | Auto-generate Spec File + Map Current Logic | ❌ **FORBIDDEN (Immutability)** | \`v1.0.0\` |
|
|
220
|
-
| Legacy Code Active | ❌ NO | Chaotic / Coupled | Auto-generate Spec File + Map Current AND Proposed Logic | ❌ **FORBIDDEN (Immutability)** | \`v1.0.0\` |
|
|
221
|
-
|
|
222
|
-
### Missing Spec Auto-Repair Blueprint Requirements
|
|
223
|
-
* **Enforce Section Injections:** Every auto-generated specification file must structurally enforce:
|
|
224
|
-
1. \`SPEC_VERSION: v1.0.0\` metadata header at the very top.
|
|
225
|
-
2. \`stateDiagram-v2\` or \`graph LR\` derived exactly from code logic behaviors.
|
|
226
|
-
3. \`Decision Matrix\` tables filled if the code contains conditional execution branches.
|
|
227
|
-
4. An isolated \`<details><summary>Audit History</summary>...</details>\` block at the bottom containing the specific code review analytics.
|
|
228
|
-
|
|
229
|
-
### Quality Assurance & Immutability Ironclad Rules
|
|
230
|
-
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.
|
|
231
|
-
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.
|
|
232
|
-
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.`,
|
|
233
|
-
|
|
234
|
-
'md-impl': `[ROLE: SOFTWARE ENGINEER] [STRICT CONTRACT]
|
|
235
|
-
|
|
236
|
-
\`\`\`mermaid
|
|
237
|
-
%% @spec-version v1.1.0
|
|
238
|
-
graph TD
|
|
239
|
-
A[Ingest Signed .spec.md] --> B[Parse Matrix Rows & Version Header]
|
|
240
|
-
B --> C{Verify Code/Chat Request}
|
|
241
|
-
|
|
242
|
-
C -->|Matches Decision Matrix Rows 100%| D[Check File Target State]
|
|
243
|
-
C -->|Human Asks to Skip/Add Extraneous Scope| E[Trigger Prompt Injection Defense]
|
|
244
|
-
|
|
245
|
-
D -->|New File| F[Generate Full Structural Code from Scratch]
|
|
246
|
-
D -->|Existing File| G[Idempotent Overwrite: Read & Output Full File]
|
|
247
|
-
|
|
248
|
-
F --> H[Generate Truth-Table Unit Tests]
|
|
249
|
-
G --> H
|
|
250
|
-
|
|
251
|
-
H --> I[Verify 100% Branch Coverage Alignment]
|
|
252
|
-
I --> [*]
|
|
253
|
-
|
|
254
|
-
E --> J[Refuse Coding & Demand Spec Refinement via md-edit]
|
|
255
|
-
J --> [*]
|
|
256
|
-
\`\`\`
|
|
257
|
-
|
|
258
|
-
### Injection Defense & Execution Guard Matrix
|
|
259
|
-
|
|
260
|
-
| Spec Contract Signed? | Chat Prompt Code Alignment | Human Requests Bypassing Spec Matrix? | Core AI Action Authorized | Error Response Pattern |
|
|
261
|
-
| :---: | :---: | :---: | :--- | :--- |
|
|
262
|
-
| ❌ NO | - | - | ❌ **DENY GENERATION** | Demand invocation of \`md-new\` or \`md-audit\` |
|
|
263
|
-
| ✅ YES | ❌ Out-of-bounds | - | ❌ **DENY GENERATION** | "Please use the md-edit command to update the diagram..." |
|
|
264
|
-
| ✅ YES | - | ✅ YES (Feature Creep) | ❌ **DENY GENERATION** | "Please use the md-edit command to update the diagram..." |
|
|
265
|
-
| ✅ YES | ✅ 100% Rigid Match| ❌ NO | ✅ **ALLOW SOLID CODEGEN** | Complete compliance code + 100% matrix row unit tests |
|
|
266
|
-
|
|
267
|
-
### Production Implementation & Codegen Ironclad Rules
|
|
268
|
-
1. **The Matrix Test Alignment Mandate:** Your unit test suite must match the Decision Matrix row by row. For every single row present in the specification's truth table, you are strictly required to build at least one explicit, dedicated unit test case mapping those precise primitive factors to that exact outcome.
|
|
269
|
-
2. **Anti-Placeholder Clause:** You are absolutely forbidden from generating incomplete code structures, omitting code sections, or using placeholders like \`// TODO\`, \`// implementation goes here\`, or \`// rest of the class remains unchanged\`. You must always output the complete, compile-ready, and production-grade file layout.
|
|
270
|
-
3. **Strict SOLID Compliance:** Every piece of logic generated under this cycle must follow strict Clean Architecture principles and SOLID patterns. If the specification implies a new conditional branch, you must implement it using polymorphism or structured strategies rather than compounding nested \`if-else\` or pattern-matching anti-patterns unless explicitly dictated by the diagram topology.`
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
Object.keys(skills).forEach(skillName => {
|
|
274
|
-
const skillFolder = path.join(skillsDir, skillName);
|
|
275
|
-
if (!fs.existsSync(skillFolder)) {
|
|
276
|
-
fs.mkdirSync(skillFolder);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const skillFile = path.join(skillFolder, 'SKILL.md');
|
|
280
|
-
const content = `${skills[skillName]}`;
|
|
281
|
-
|
|
282
|
-
fs.writeFileSync(skillFile, content);
|
|
283
|
-
console.log(pc.green(`✅ Skill successfully encapsulated: ${skillFile}`));
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
console.log(pc.green('\n🚀 Universal [system_prompt.md] and SKILLS generated successfully in the project root!'));
|
|
287
|
-
console.log(pc.green('Run the "md init" command whenever you update the MDDD-CLI NPM package.'));
|
|
288
|
-
});
|
|
50
|
+
});
|
|
289
51
|
|
|
290
52
|
// ==========================================
|
|
291
53
|
// COMMAND: md new <targetPath>
|
|
292
54
|
// ==========================================
|
|
293
55
|
program
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
const finalFile = path.join(normalizedPath, `${folderName}.spec.md`);
|
|
308
|
-
|
|
309
|
-
if (fs.existsSync(finalFile) && fs.lstatSync(finalFile).isDirectory()) {
|
|
310
|
-
console.log(pc.red(`❌ Error: A directory named ${finalFile} already exists. Cannot create specification file.`));
|
|
311
|
-
process.exit(1);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (fs.existsSync(finalFile)) {
|
|
315
|
-
console.log(pc.yellow(`⚠️ Specification already exists at: ${finalFile}. Operation aborted to avoid link duplication in the parent file.`));
|
|
316
|
-
process.exit(0);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const isMacro = options.macro;
|
|
320
|
-
const version = 'v1.0.0';
|
|
321
|
-
|
|
322
|
-
let template = isMacro
|
|
323
|
-
? `\n# Macro Module: ${folderName} | ${version}\n\n` +
|
|
324
|
-
`\`\`\`mermaid\n%% @spec-version ${version}\nstateDiagram-v2\n [*] --> Initial_${folderName}\n\`\`\`\n\n` +
|
|
325
|
-
`## 3. Audit History\n<details>\n<summary>Click to expand</summary>\n\n\n\n</details>\n`
|
|
326
|
-
: `\n# Specification: ${folderName} | ${version}\n\n` +
|
|
327
|
-
`## 1. Flow Contract (Mermaid)\n\`\`\`mermaid\n%% @spec-version ${version}\ngraph LR\n A([Start]) --> B[Process]\n\`\`\`\n\n` +
|
|
328
|
-
`## 2. Decision Matrix\n| Factor A? | Factor B? | Proposed Action | Decision (Outcome) | Transition State (New Status) |\n| :---: | :---: | :--- | :---: | :---: |\n| | | | | |\n\n` +
|
|
329
|
-
`## 3. Audit History\n<details>\n<summary>Click to expand</summary>\n\n\n\n</details>\n`;
|
|
330
|
-
|
|
331
|
-
fs.writeFileSync(finalFile, template);
|
|
332
|
-
console.log(pc.green(`✅ New specification file created: ${finalFile}`));
|
|
333
|
-
|
|
334
|
-
let macroPath = options.parent || (!isMacro ? findClosestMacro(normalizedPath) : null);
|
|
335
|
-
|
|
336
|
-
if (macroPath) {
|
|
337
|
-
if (!fs.existsSync(macroPath)) {
|
|
338
|
-
console.log(pc.red(`❌ Specified parent file not found: ${macroPath}`));
|
|
339
|
-
process.exit(1);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const relativePath = path.relative(path.dirname(macroPath), finalFile);
|
|
343
|
-
const cleanLinkPath = relativePath.replace(/\\/g, '/');
|
|
344
|
-
const injection = `\n\n%% Automatic connection for sub-flow\n- [Go to ${folderName} rules](file://./${cleanLinkPath})\n`;
|
|
345
|
-
|
|
346
|
-
fs.appendFileSync(macroPath, injection);
|
|
347
|
-
console.log(pc.blue(`🔗 Successfully linked into parent flow: ${macroPath}`));
|
|
348
|
-
}
|
|
349
|
-
});
|
|
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
|
+
});
|
|
350
69
|
|
|
351
70
|
// ==========================================
|
|
352
|
-
//
|
|
71
|
+
// COMMAND: md edit <specFilePath> <instruction...>
|
|
353
72
|
// ==========================================
|
|
354
73
|
program
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
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.`));
|
|
368
|
-
});
|
|
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
|
+
});
|
|
369
86
|
|
|
87
|
+
// ==========================================
|
|
88
|
+
// COMMAND: md audit <codeFilePath>
|
|
89
|
+
// ==========================================
|
|
370
90
|
program
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
const specFileName = `${codeBaseName}.spec.md`;
|
|
383
|
-
const specFilePath = path.join(targetDir, specFileName);
|
|
384
|
-
|
|
385
|
-
if (!fs.existsSync(targetDir)) {
|
|
386
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
if (!fs.existsSync(specFilePath)) {
|
|
390
|
-
const version = 'v1.0.0';
|
|
391
|
-
const template = `# Audit: ${codeBaseName} | ${version}\n\n` +
|
|
392
|
-
`## 1. Flow Contract (Mermaid)\n\`\`\`mermaid\n%% @spec-version ${version}\ngraph LR\n A([Start]) --> B[Process]\n\`\`\`\n\n` +
|
|
393
|
-
`## 2. Decision Matrix\n| Condition | Action | Next State |\n| :---: | :--- | :---: |\n| | | |\n\n` +
|
|
394
|
-
`## 3. Audit History\n<details>\n<summary>Click to expand</summary>\n\n\n\n</details>\n`;
|
|
395
|
-
fs.writeFileSync(specFilePath, template);
|
|
396
|
-
console.log(pc.green(`✅ Co-located specification file created: ${specFilePath}`));
|
|
397
|
-
} else {
|
|
398
|
-
console.log(pc.blue(`📄 Existing specification found: ${specFilePath}`));
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
console.log(pc.cyan(`🔍 Auditing code structure for coupling in: ${path.basename(codeFilePath)}...`));
|
|
402
|
-
console.log(pc.yellow(`⚡ The AI will validate complexity and write the analysis to: ${specFilePath}`));
|
|
403
|
-
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.`));
|
|
404
|
-
});
|
|
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
|
+
});
|
|
405
102
|
|
|
103
|
+
// ==========================================
|
|
104
|
+
// COMMAND: md impl <specFilePath>
|
|
105
|
+
// ==========================================
|
|
406
106
|
program
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
console.log(pc.green(`\n🚀 Ready! Use the /md-impl shortcut in chat for the AI to start generating productive code and tests.`));
|
|
419
|
-
});
|
|
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
|
+
});
|
|
420
118
|
|
|
119
|
+
// ─── Parse ───────────────────────────────────────────────────────────────────
|
|
421
120
|
program.parse(process.argv);
|
package/bin/cli.spec.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Refactoring Plan: cli | v2.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 v2.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]
|
|
@@ -69,10 +69,10 @@ graph TD
|
|
|
69
69
|
end
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
### 1.2 Topologia
|
|
72
|
+
### 1.2 Topologia Aprovada (To-Be → Refactoring Target)
|
|
73
73
|
|
|
74
74
|
```mermaid
|
|
75
|
-
%% @spec-version
|
|
75
|
+
%% @spec-version v2.0.0
|
|
76
76
|
graph TD
|
|
77
77
|
subgraph "CLI Entry (cli.js)"
|
|
78
78
|
A[bin/cli.js] --> B[Commander Router]
|
|
@@ -126,6 +126,7 @@ graph TD
|
|
|
126
126
|
| Código Atual | Co-located .spec.md Exists? | Design Assessment | Ação de Auditoria | Manipulação de Código Permitida? | Versão Inicial |
|
|
127
127
|
| :--- | :---: | :---: | :--- | :---: | :---: |
|
|
128
128
|
| `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/*.js` + `src/services/*.js` (refatorado) | ✅ YES (this spec) | Refatorado / Modular | Aprovado com diagrama To-Be como alvo de implementação | ✅ **ALLOW (Refactoring)** | `v2.0.0` |
|
|
129
130
|
|
|
130
131
|
### Fatores Primitivos de Acoplamento
|
|
131
132
|
|
|
@@ -147,6 +148,7 @@ graph TD
|
|
|
147
148
|
| Data | Auditor | Versão | Resumo das Mudanças |
|
|
148
149
|
| :--- | :--- | :---: | :--- |
|
|
149
150
|
| 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
|
+
| 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. |
|
|
150
152
|
|
|
151
153
|
### Análise de Qualidade
|
|
152
154
|
|