mddd-cli 1.0.13 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +208 -79
- package/bin/cli.spec.md +143 -213
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -15,23 +15,20 @@ function findClosestMacro(currentDir) {
|
|
|
15
15
|
while (dir !== root) {
|
|
16
16
|
try {
|
|
17
17
|
const files = fs.readdirSync(dir);
|
|
18
|
-
// Looks for any .spec.md file that is higher in the tree
|
|
19
|
-
// Ignores current directory's specification file if it already exists
|
|
20
18
|
const macroFile = files.find(f => f.endsWith('.spec.md') && f !== `${path.basename(currentDir)}.spec.md`);
|
|
21
19
|
|
|
22
20
|
if (macroFile) {
|
|
23
21
|
return path.join(dir, macroFile);
|
|
24
22
|
}
|
|
25
23
|
} catch (e) {
|
|
26
|
-
// Silences only read permission errors (EACCES/EPERM) common in system folders
|
|
27
24
|
if (e.code === 'EACCES' || e.code === 'EPERM') {
|
|
28
25
|
break;
|
|
29
26
|
}
|
|
30
|
-
throw e;
|
|
27
|
+
throw e;
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
const parent = path.dirname(dir);
|
|
34
|
-
if (parent === dir) break;
|
|
31
|
+
if (parent === dir) break;
|
|
35
32
|
dir = parent;
|
|
36
33
|
}
|
|
37
34
|
return null;
|
|
@@ -40,91 +37,237 @@ function findClosestMacro(currentDir) {
|
|
|
40
37
|
program
|
|
41
38
|
.name('md')
|
|
42
39
|
.description('Manager for co-located specifications for Mermaid Diagram Driven Development (MDDD)')
|
|
43
|
-
.version('
|
|
40
|
+
.version('2.0.0');
|
|
44
41
|
|
|
45
42
|
// ==========================================
|
|
46
43
|
// COMMAND: md init
|
|
47
44
|
// ==========================================
|
|
48
45
|
program
|
|
49
46
|
.command('init')
|
|
50
|
-
.description('Initializes the universal system prompt
|
|
47
|
+
.description('Initializes the universal system prompt and matrix-driven skills to guide the AI under the MDDD methodology')
|
|
51
48
|
.action(() => {
|
|
52
49
|
const agentsDir = '.agents';
|
|
53
50
|
const skillsDir = path.join(agentsDir, 'skills');
|
|
54
51
|
|
|
55
|
-
// 1. Creates folder structure if it doesn't exist
|
|
56
52
|
if (!fs.existsSync(agentsDir)) fs.mkdirSync(agentsDir);
|
|
57
53
|
if (!fs.existsSync(skillsDir)) fs.mkdirSync(skillsDir);
|
|
58
54
|
|
|
55
|
+
// SYSTEM PROMPT: Uso de 4 crases externas para isolar com precisão o bloco Mermaid interno
|
|
59
56
|
const promptContent = `# Mermaid Diagram Driven Development (MDDD) Protocol
|
|
60
57
|
|
|
61
|
-
You
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
##
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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.
|
|
88
107
|
`;
|
|
89
108
|
|
|
90
109
|
fs.writeFileSync('system_prompt.md', promptContent);
|
|
91
110
|
|
|
92
|
-
//
|
|
111
|
+
// SKILLS AUTOMATION: Resolvido o aninhamento de strings escapando as crases internas com barras triplas
|
|
93
112
|
const skills = {
|
|
94
113
|
'md-new': `[ROLE: ARCHITECT] [STRICT CONTRACT]
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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)
|
|
126
|
+
}
|
|
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.`,
|
|
100
148
|
|
|
101
149
|
'md-edit': `[ROLE: ARCHITECT] [STRICT CONTRACT]
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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.`,
|
|
110
184
|
|
|
111
185
|
'md-audit': `[ROLE: SECURITY & QUALITY AUDITOR] [STRICT CONTRACT]
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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.`,
|
|
121
233
|
|
|
122
234
|
'md-impl': `[ROLE: SOFTWARE ENGINEER] [STRICT CONTRACT]
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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.`
|
|
128
271
|
};
|
|
129
272
|
|
|
130
273
|
Object.keys(skills).forEach(skillName => {
|
|
@@ -134,7 +277,7 @@ Operational instructions for generating production code and unit tests:
|
|
|
134
277
|
}
|
|
135
278
|
|
|
136
279
|
const skillFile = path.join(skillFolder, 'SKILL.md');
|
|
137
|
-
const content =
|
|
280
|
+
const content = `${skills[skillName]}`;
|
|
138
281
|
|
|
139
282
|
fs.writeFileSync(skillFile, content);
|
|
140
283
|
console.log(pc.green(`✅ Skill successfully encapsulated: ${skillFile}`));
|
|
@@ -154,7 +297,6 @@ program
|
|
|
154
297
|
.option('-m, --macro', 'Defines if the new file will be a module macro containing a stateDiagram-v2')
|
|
155
298
|
.option('-p, --parent <parentFile>', 'Path to an existing specification file (.spec.md) to connect this new flow')
|
|
156
299
|
.action((targetPath, options) => {
|
|
157
|
-
// Normalizes the input path removing extra trailing slashes
|
|
158
300
|
const normalizedPath = path.normalize(targetPath).replace(/[\\/]+$/, '');
|
|
159
301
|
|
|
160
302
|
if (!fs.existsSync(normalizedPath)) {
|
|
@@ -164,13 +306,11 @@ program
|
|
|
164
306
|
const folderName = path.basename(normalizedPath);
|
|
165
307
|
const finalFile = path.join(normalizedPath, `${folderName}.spec.md`);
|
|
166
308
|
|
|
167
|
-
// Protection against structural file collisions
|
|
168
309
|
if (fs.existsSync(finalFile) && fs.lstatSync(finalFile).isDirectory()) {
|
|
169
310
|
console.log(pc.red(`❌ Error: A directory named ${finalFile} already exists. Cannot create specification file.`));
|
|
170
311
|
process.exit(1);
|
|
171
312
|
}
|
|
172
313
|
|
|
173
|
-
// Side-Effect Bug Correction: Prevents reprocessing existing files
|
|
174
314
|
if (fs.existsSync(finalFile)) {
|
|
175
315
|
console.log(pc.yellow(`⚠️ Specification already exists at: ${finalFile}. Operation aborted to avoid link duplication in the parent file.`));
|
|
176
316
|
process.exit(0);
|
|
@@ -191,7 +331,6 @@ program
|
|
|
191
331
|
fs.writeFileSync(finalFile, template);
|
|
192
332
|
console.log(pc.green(`✅ New specification file created: ${finalFile}`));
|
|
193
333
|
|
|
194
|
-
// Advanced Linking logic with loop prevention
|
|
195
334
|
let macroPath = options.parent || (!isMacro ? findClosestMacro(normalizedPath) : null);
|
|
196
335
|
|
|
197
336
|
if (macroPath) {
|
|
@@ -210,7 +349,7 @@ program
|
|
|
210
349
|
});
|
|
211
350
|
|
|
212
351
|
// ==========================================
|
|
213
|
-
//
|
|
352
|
+
// COMMANDS: md edit | md audit | md impl
|
|
214
353
|
// ==========================================
|
|
215
354
|
program
|
|
216
355
|
.command('edit')
|
|
@@ -222,16 +361,12 @@ program
|
|
|
222
361
|
console.log(pc.red(`❌ Specification file not found: ${specFilePath}`));
|
|
223
362
|
process.exit(1);
|
|
224
363
|
}
|
|
225
|
-
|
|
226
364
|
const fullInstruction = instruction.join(' ');
|
|
227
365
|
console.log(pc.cyan(`📝 Requesting alteration in flow: "${specFilePath}"`));
|
|
228
366
|
console.log(pc.yellow(`⚙️ Evaluated instruction: ${fullInstruction}`));
|
|
229
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.`));
|
|
230
368
|
});
|
|
231
369
|
|
|
232
|
-
// ==========================================
|
|
233
|
-
// COMMAND: md audit <codeFilePath>
|
|
234
|
-
// ==========================================
|
|
235
370
|
program
|
|
236
371
|
.command('audit')
|
|
237
372
|
.description('Audits an existing code file to create a retroactive specification or suggest refactoring')
|
|
@@ -247,12 +382,10 @@ program
|
|
|
247
382
|
const specFileName = `${codeBaseName}.spec.md`;
|
|
248
383
|
const specFilePath = path.join(targetDir, specFileName);
|
|
249
384
|
|
|
250
|
-
// Ensures the target directory exists
|
|
251
385
|
if (!fs.existsSync(targetDir)) {
|
|
252
386
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
253
387
|
}
|
|
254
388
|
|
|
255
|
-
// Creates the .spec.md file if it doesn't exist
|
|
256
389
|
if (!fs.existsSync(specFilePath)) {
|
|
257
390
|
const version = 'v1.0.0';
|
|
258
391
|
const template = `# Audit: ${codeBaseName} | ${version}\n\n` +
|
|
@@ -270,9 +403,6 @@ program
|
|
|
270
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.`));
|
|
271
404
|
});
|
|
272
405
|
|
|
273
|
-
// ==========================================
|
|
274
|
-
// COMMAND: md impl <specFilePath>
|
|
275
|
-
// ==========================================
|
|
276
406
|
program
|
|
277
407
|
.command('impl')
|
|
278
408
|
.description('Prepares the ecosystem to implement productive code and tests based on the specification file')
|
|
@@ -282,7 +412,6 @@ program
|
|
|
282
412
|
console.log(pc.red(`❌ Specification file not found: ${specFilePath}`));
|
|
283
413
|
process.exit(1);
|
|
284
414
|
}
|
|
285
|
-
|
|
286
415
|
const fileName = path.basename(specFilePath);
|
|
287
416
|
console.log(pc.cyan(`🛠️ Reading business blueprint from: ${fileName}...`));
|
|
288
417
|
console.log(pc.yellow(`🎯 Establishing the signed diagram as the Single Source of Truth.`));
|
package/bin/cli.spec.md
CHANGED
|
@@ -1,239 +1,169 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Audit: cli | v1.0.0
|
|
2
2
|
|
|
3
3
|
## 1. Flow Contract (Mermaid)
|
|
4
4
|
|
|
5
|
+
### 1.1 Topologia Atual (As-Is)
|
|
6
|
+
|
|
5
7
|
```mermaid
|
|
6
|
-
%% @spec-version v1.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
state ParseArgs {
|
|
12
|
-
[*] --> DetectCommand
|
|
13
|
-
DetectCommand --> CmdInit: init
|
|
14
|
-
DetectCommand --> CmdNew: new <path>
|
|
15
|
-
DetectCommand --> CmdEdit: edit <file> <instruction...>
|
|
16
|
-
DetectCommand --> CmdAudit: audit <file>
|
|
17
|
-
DetectCommand --> CmdImpl: impl <file>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
CmdInit --> MkdirDotAgents: mkdir .agents/
|
|
21
|
-
MkdirDotAgents --> MkdirSkills: mkdir .agents/skills/
|
|
22
|
-
MkdirSkills --> WriteSystemPrompt: write system_prompt.md
|
|
23
|
-
WriteSystemPrompt --> WriteSkills: write 4 SKILL.md files
|
|
24
|
-
WriteSkills --> Done: ✅ Success
|
|
25
|
-
|
|
26
|
-
CmdNew --> ProcessTarget
|
|
27
|
-
ProcessTarget --> EnsureDir: mkdir -p <targetPath>
|
|
28
|
-
EnsureDir --> CheckExists: file exists?
|
|
29
|
-
CheckExists --> Skip: yes → ⚠️ Already exists
|
|
30
|
-
CheckExists --> GenerateSpec: no → write template
|
|
31
|
-
GenerateSpec --> LinkParent: check -p or findClosestMacro
|
|
32
|
-
LinkParent --> AppendRef: link line in parent .spec.md
|
|
33
|
-
AppendRef --> Done
|
|
34
|
-
|
|
35
|
-
CmdEdit --> ValidateFile: file exists?
|
|
36
|
-
ValidateFile --> NotFound: no → ❌ Error
|
|
37
|
-
ValidateFile --> PrintInstruction: yes → 📝 log instruction
|
|
38
|
-
PrintInstruction --> Done
|
|
39
|
-
|
|
40
|
-
CmdAudit --> ValidateCodeFile: file exists?
|
|
41
|
-
ValidateCodeFile --> NotFoundAudit: no → ❌ Error
|
|
42
|
-
ValidateCodeFile --> PrepareDir: yes → ensure targetDir
|
|
43
|
-
PrepareDir --> DeriveSpecName: get codeBasename.spec.md
|
|
44
|
-
DeriveSpecName --> CheckSpecExists: spec file exists?
|
|
45
|
-
CheckSpecExists --> CreateSpec: no → write template
|
|
46
|
-
CheckSpecExists --> LogExisting: yes → 📄 Existing found
|
|
47
|
-
CreateSpec --> ReadyAudit: 🚀 Ready
|
|
48
|
-
LogExisting --> ReadyAudit: 🚀 Ready
|
|
49
|
-
|
|
50
|
-
CmdImpl --> ValidateSpecFile: file exists?
|
|
51
|
-
ValidateSpecFile --> NotFoundImpl: no → ❌ Error
|
|
52
|
-
ValidateSpecFile --> ReadyImpl: yes → 🚀 Ready
|
|
53
|
-
|
|
54
|
-
Done --> [*]
|
|
55
|
-
Skip --> [*]
|
|
56
|
-
NotFound --> [*]
|
|
57
|
-
NotFoundAudit --> [*]
|
|
58
|
-
NotFoundImpl --> [*]
|
|
59
|
-
ReadyAudit --> [*]
|
|
60
|
-
ReadyImpl --> [*]
|
|
61
|
-
```
|
|
8
|
+
%% @spec-version v1.0.0
|
|
9
|
+
graph TD
|
|
10
|
+
subgraph "CLI Entry (cli.js)"
|
|
11
|
+
A[index.js#!/usr/bin/env node] --> B[Commander: program.parse]
|
|
12
|
+
end
|
|
62
13
|
|
|
63
|
-
|
|
14
|
+
subgraph "Command Routing"
|
|
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
|
+
end
|
|
64
21
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
| `md new <path>` | `new` | Create co-located `.spec.md` at path; optional parent linking | ✅ Created / ⚠️ Exists / ❌ Error |
|
|
71
|
-
| `md edit <file> <msg>` | `edit` | Validate file, print instruction to stdout | 📝 Ready / ❌ Not found |
|
|
72
|
-
| `md audit <file>` | `audit` | Validate code file, create/co-locate `.spec.md` for audit output | 🚀 Ready / ❌ Not found |
|
|
73
|
-
| `md impl <file>` | `impl` | Validate spec file exists | 🚀 Ready / ❌ Not found |
|
|
74
|
-
|
|
75
|
-
### 2.2 `init` Command — File Generation
|
|
76
|
-
|
|
77
|
-
| Condition | Action | Next State |
|
|
78
|
-
| :--- | :--- | :--- |
|
|
79
|
-
| `./.agents` does not exist | `mkdir .agents` | Continue |
|
|
80
|
-
| `./.agents/skills` does not exist | `mkdir .agents/skills` | Continue |
|
|
81
|
-
| Always | Write `system_prompt.md` | Continue |
|
|
82
|
-
| For each skill (`md-new`, `md-edit`, `md-audit`, `md-impl`) | Create folder + `SKILL.md` | Continue → Done |
|
|
83
|
-
| Skill `SKILL.md` already exists | Overwrite silently via `fs.writeFileSync` | Replace |
|
|
84
|
-
|
|
85
|
-
### 2.3 `new` Command — Parent Linking
|
|
86
|
-
|
|
87
|
-
| Condition | Action | Next State |
|
|
88
|
-
| :--- | :--- | :--- |
|
|
89
|
-
| `--parent` provided AND file exists | Append link line to parent | ✅ Linked |
|
|
90
|
-
| `--parent` provided AND file NOT found | `process.exit(1)` with error | ❌ Fatal |
|
|
91
|
-
| `--parent` NOT provided | Auto-search via `findClosestMacro()` | ✅ Linked (if found) / No link (if none) |
|
|
92
|
-
|
|
93
|
-
### 2.4 `audit` Command — Spec File Generation
|
|
94
|
-
|
|
95
|
-
| Condition | Action | Next State |
|
|
96
|
-
| :--- | :--- | :--- |
|
|
97
|
-
| Code file does not exist | `process.exit(1)` with error | ❌ Fatal |
|
|
98
|
-
| Code file exists, target dir does not exist | `mkdir -p <targetDir>` | Continue |
|
|
99
|
-
| Code file exists, target dir exists | No action | Continue |
|
|
100
|
-
| Co-located `.spec.md` does NOT exist | Write template with `# Audit: <basename> | v1.0.0` | ⚡ Ready |
|
|
101
|
-
| Co-located `.spec.md` already exists | Log `📄 Existing specification found` | ⚡ Ready |
|
|
102
|
-
| Always after file ready | Print instruction: AI writes analysis into `<details>` in `.spec.md` | 🚀 Ready |
|
|
103
|
-
|
|
104
|
-
### 2.5 `findClosestMacro(currentDir)` — Traversal Logic
|
|
105
|
-
|
|
106
|
-
| Condition | Action | Return |
|
|
107
|
-
| :--- | :--- | :--- |
|
|
108
|
-
| Current dir contains `*.spec.md` (excluding current dir's own spec) | Return full path to that file | Path string |
|
|
109
|
-
| No matching file in current dir | Move to parent directory | Recurse |
|
|
110
|
-
| Reaches filesystem root (e.g., `/`) | Return `null` | `null` |
|
|
111
|
-
| `fs.readdirSync` throws (permission denied) | `break` out of loop | `null` |
|
|
112
|
-
|
|
113
|
-
## 3. Architecture Notes
|
|
114
|
-
|
|
115
|
-
- **Entry point**: `bin/cli.js` (referenced in `package.json` as `"bin": {"md": "bin/cli.js"}`)
|
|
116
|
-
- **Dependencies**: `commander` (argument parsing), `picocolors` (terminal coloring)
|
|
117
|
-
- **Runtime**: Node.js >= 18 (ESM — `"type": "module"`)
|
|
118
|
-
- **Pattern**: Each command is a self-contained `.action()` callback. Shared utility (`findClosestMacro`) is a module-level function with clear single responsibility.
|
|
119
|
-
- **Error handling**: Consistent pattern — validate file existence early, exit with code 1 + red message on failure, green/blue/yellow for success/warnings.
|
|
120
|
-
- **`md audit` spec generation**: The audit command derives the spec file name by stripping the code file extension and appending `.spec.md` (e.g., `user.go` → `user.spec.md`). The generated template includes a Decision Matrix, a placeholder Mermaid diagram, and an Audit History `<details>` section where the AI writes its full analysis.
|
|
121
|
-
|
|
122
|
-
## 4. Audit History
|
|
22
|
+
subgraph "md init Action"
|
|
23
|
+
C --> H[mkdir .agents/skills]
|
|
24
|
+
C --> I[Write system_prompt.md]
|
|
25
|
+
C --> J[Write 4 embedded SKILL.md files]
|
|
26
|
+
end
|
|
123
27
|
|
|
124
|
-
|
|
125
|
-
|
|
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
|
|
126
56
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
|
133
65
|
|
|
134
|
-
|
|
66
|
+
subgraph "md impl Action"
|
|
67
|
+
G --> AJ[validate file exists]
|
|
68
|
+
AJ --> AK[print placeholder message]
|
|
69
|
+
end
|
|
70
|
+
```
|
|
135
71
|
|
|
136
|
-
|
|
72
|
+
### 1.2 Topologia Refatorada Proposta (To-Be)
|
|
137
73
|
|
|
138
|
-
|
|
74
|
+
```mermaid
|
|
75
|
+
%% @spec-version v1.0.0
|
|
76
|
+
graph TD
|
|
77
|
+
subgraph "CLI Entry (cli.js)"
|
|
78
|
+
A[bin/cli.js] --> B[Commander Router]
|
|
79
|
+
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
|
+
end
|
|
139
85
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
86
|
+
subgraph "Commands Layer"
|
|
87
|
+
C --> H[InitService.createSystemPrompt]
|
|
88
|
+
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
|
+
end
|
|
150
97
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
98
|
+
subgraph "Shared Services"
|
|
99
|
+
H --> Q[FileSystemService]
|
|
100
|
+
I --> Q
|
|
101
|
+
J --> Q
|
|
102
|
+
K --> Q
|
|
103
|
+
L --> Q
|
|
104
|
+
N --> Q
|
|
105
|
+
O --> Q
|
|
106
|
+
P --> Q
|
|
107
|
+
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
|
|
158
115
|
|
|
159
|
-
|
|
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
|
+
end
|
|
122
|
+
```
|
|
160
123
|
|
|
161
|
-
|
|
124
|
+
## 2. Decision Matrix
|
|
162
125
|
|
|
163
|
-
|
|
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
|
+
| :--- | :---: | :---: | :--- | :---: | :---: |
|
|
128
|
+
| `bin/cli.js` (421 linhas) | ❌ NO | Caótico / Acoplado | Auto-gerar Spec + Mapear Lógica Atual E Proposta | ❌ **FORBIDDEN (Immutability)** | `v1.0.0` |
|
|
164
129
|
|
|
165
|
-
|
|
166
|
-
| :--- | :--- | :--- | :--- |
|
|
167
|
-
| `init` flow — directory creation | `CreateDotAgents: mkdir .agents/skills/` | Two separate conditional mkdir: `mkdir .agents/` then `mkdir .agents/skills/` | ⚠️ Minor — spec combined into one state; fixed in v1.2.0 diagram |
|
|
168
|
-
| `init` — SKILL.md overwrite | "Delete old, write new" | `fs.writeFileSync` overwrites silently, no deletion | ⚠️ Minor — wording fixed in v1.2.0 matrix |
|
|
169
|
-
| `new` — `CheckExists` guard order | CheckExists branches to Skip or GenerateSpec | Code checks `fs.existsSync(normalizedPath)` for mkdir, then checks `fs.existsSync(finalFile)` separately | ✅ Correct — diagram simplified, no semantic error |
|
|
170
|
-
| `new` — trailing slash normalization | Not mentioned | `normalizedPath` uses `.replace(/[\\/]+$/, '')` | ✅ Enhancement — documented below |
|
|
171
|
-
| `findClosestMacro` — dir exclusion | Not specified | Excludes file named `${path.basename(currentDir)}.spec.md` | ✅ Enhancement — documented in matrix |
|
|
172
|
-
| Version metadata | N/A (spec refers to v1.0.8) | Code declares `v1.0.10` | ✅ Cosmetic — spec now at v1.2.0 |
|
|
130
|
+
### Fatores Primitivos de Acoplamento
|
|
173
131
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
132
|
+
| Fator | Valor | Impacto |
|
|
133
|
+
| :--- | :---: | :--- |
|
|
134
|
+
| Arquivo único monolítico? | ✅ YES | Acoplamento extremo; todas as responsabilidades no mesmo closure |
|
|
135
|
+
| Lógica de template embutida? | ✅ YES | 4 skills + 2 templates inline no código (string templates >20KB) |
|
|
136
|
+
| Duplicação entre `new` e `audit`? | ✅ YES | Ambos criam `.spec.md` com templates semelhantes |
|
|
137
|
+
| Tratamento de erros inconsistente? | ✅ YES | `edit`/`audit`/`impl` usam `process.exit(1)`, `new` usa `process.exit(0/1)` |
|
|
138
|
+
| Sem separação CLI/Business? | ✅ YES | Comandos Commander executam lógica inline sem camada de serviço |
|
|
139
|
+
| Lógica de crawling de diretório isolada? | ❌ NO | `findClosestMacro` é função separada (bom), mas não testável isoladamente |
|
|
140
|
+
| Código testável? | ❌ NO | Sem módulos exportados; dependência direta de `fs`, `path` sem injeção |
|
|
178
141
|
|
|
179
|
-
|
|
142
|
+
## 3. Audit History
|
|
180
143
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
graph LR
|
|
184
|
-
subgraph "Entry Point"
|
|
185
|
-
CLI["bin/cli.js"]
|
|
186
|
-
end
|
|
144
|
+
<details>
|
|
145
|
+
<summary>Click to expand</summary>
|
|
187
146
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
FS[fs / path]
|
|
192
|
-
end
|
|
147
|
+
| Data | Auditor | Versão | Resumo das Mudanças |
|
|
148
|
+
| :--- | :--- | :---: | :--- |
|
|
149
|
+
| 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. |
|
|
193
150
|
|
|
194
|
-
|
|
195
|
-
FCM[findClosestMacro]
|
|
196
|
-
end
|
|
151
|
+
### Análise de Qualidade
|
|
197
152
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
IMPL[cmd: impl]
|
|
204
|
-
end
|
|
153
|
+
- **Acoplamento**: ⚠️ **ALTO** - Toda lógica em um único arquivo de 421 linhas. Dependências diretas de `fs`, `path` e `Commander` sem abstração.
|
|
154
|
+
- **Coesão**: ⚠️ **BAIXA** - O comando `init` mistura criação de sistema de arquivos, templates de sistema e escrita de skills.
|
|
155
|
+
- **Testabilidade**: ❌ **NENHUMA** - Nenhuma função é exportada; sem DI (injeção de dependência); sem mocks possíveis sem ferramentas como `proxyquire`.
|
|
156
|
+
- **Manutenibilidade**: ⚠️ **MÉDIA-BAIXA** - Templates embutidos no código dificultam manutenção; lógica de crawling de diretório é frágil (usa `readdirSync`).
|
|
157
|
+
- **Segurança**: ✅ Usa `EACCES`/`EPERM` handler no `findClosestMacro`.
|
|
205
158
|
|
|
206
|
-
|
|
207
|
-
SP[system_prompt.md]
|
|
208
|
-
SK1[.agents/skills/md-new/SKILL.md]
|
|
209
|
-
SK2[.agents/skills/md-edit/SKILL.md]
|
|
210
|
-
SK3[.agents/skills/md-audit/SKILL.md]
|
|
211
|
-
SK4[.agents/skills/md-impl/SKILL.md]
|
|
212
|
-
SPEC[targetPath/name.spec.md]
|
|
213
|
-
ASPEC[srcDir/codeBasename.spec.md]
|
|
214
|
-
end
|
|
159
|
+
### Recomendações de Refatoração
|
|
215
160
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
INIT --> SK2
|
|
224
|
-
INIT --> SK3
|
|
225
|
-
INIT --> SK4
|
|
226
|
-
|
|
227
|
-
NEW --> SPEC
|
|
228
|
-
NEW --> FCM
|
|
229
|
-
|
|
230
|
-
AUDIT --> FS
|
|
231
|
-
AUDIT --> PC
|
|
232
|
-
AUDIT --> ASPEC
|
|
233
|
-
IMPL --> FS
|
|
234
|
-
IMPL --> PC
|
|
235
|
-
EDIT --> FS
|
|
236
|
-
EDIT --> PC
|
|
237
|
-
```
|
|
161
|
+
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`
|
|
162
|
+
2. **Extrair Template Engine**: `src/services/TemplateFactory.js` com templates parametrizados
|
|
163
|
+
3. **Extrair FileSystemService**: `src/services/FileSystemService.js` com injeção de dependência para testabilidade
|
|
164
|
+
4. **Criar ParentLinker**: `src/services/ParentLinker.js` com crawler testável
|
|
165
|
+
5. **Adicionar testes unitários**: Coverage mínimo de 80% para todas as funções extraídas
|
|
166
|
+
6. **Exportar funções**: Usar `export` em vez de closures anônimas no `.action()`
|
|
167
|
+
7. **Migrar para `fs/promises`**: Substituir `readdirSync`/`writeFileSync` por `async/await` para melhor gerenciamento de concorrência
|
|
238
168
|
|
|
239
|
-
</details>
|
|
169
|
+
</details>
|