mdan-cli 2.3.0 → 2.4.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/AGENTS.md +1 -1
- package/README.md +2 -2
- package/cli/mdan.js +21 -21
- package/cli/mdan.py +111 -54
- package/cli/mdan.sh +43 -43
- package/integrations/all-integrations.md +2 -2
- package/integrations/cursor.md +11 -11
- package/integrations/windsurf.md +4 -4
- package/package.json +1 -1
package/AGENTS.md
CHANGED
package/README.md
CHANGED
|
@@ -156,7 +156,7 @@ pour tout réécrire from scratch.
|
|
|
156
156
|
- **Windsurf** — `.windsurfrules` auto-généré
|
|
157
157
|
- **Claude Code** — `.claude/skills/` auto-généré
|
|
158
158
|
- **GitHub Copilot** — `.github/copilot-instructions.md` auto-généré
|
|
159
|
-
- **Claude Web** — Copier
|
|
159
|
+
- **Claude Web** — Copier `mdan/orchestrator.md`
|
|
160
160
|
|
|
161
161
|
---
|
|
162
162
|
|
|
@@ -164,7 +164,7 @@ pour tout réécrire from scratch.
|
|
|
164
164
|
|
|
165
165
|
```
|
|
166
166
|
projet/
|
|
167
|
-
├──
|
|
167
|
+
├── mdan/
|
|
168
168
|
│ ├── orchestrator.md # System prompt
|
|
169
169
|
│ ├── agents/ # Prompts des agents
|
|
170
170
|
│ ├── skills/ # Skills installés
|
package/cli/mdan.js
CHANGED
|
@@ -6,7 +6,7 @@ const { execSync } = require('child_process');
|
|
|
6
6
|
const { intro, text, select, isCancel, cancel, outro, spinner } = require('@clack/prompts');
|
|
7
7
|
const pc = require('picocolors');
|
|
8
8
|
|
|
9
|
-
const VERSION = '2.
|
|
9
|
+
const VERSION = '2.4.1';
|
|
10
10
|
const MDAN_DIR = path.resolve(__dirname, '..');
|
|
11
11
|
|
|
12
12
|
// Colors
|
|
@@ -104,8 +104,8 @@ async function cmdInit(initialName) {
|
|
|
104
104
|
s.start(`Creating ${name} project structure...`);
|
|
105
105
|
|
|
106
106
|
const dirs = [
|
|
107
|
-
`${name}
|
|
108
|
-
`${name}
|
|
107
|
+
`${name}/mdan/agents`,
|
|
108
|
+
`${name}/mdan/skills`,
|
|
109
109
|
`${name}/mdan_output`,
|
|
110
110
|
`${name}/.claude/skills`,
|
|
111
111
|
`${name}/.github`,
|
|
@@ -116,11 +116,11 @@ async function cmdInit(initialName) {
|
|
|
116
116
|
|
|
117
117
|
dirs.forEach(dir => fs.mkdirSync(dir, { recursive: true }));
|
|
118
118
|
|
|
119
|
-
fs.copyFileSync(`${MDAN_DIR}/core/orchestrator.md`, `${name}
|
|
120
|
-
fs.copyFileSync(`${MDAN_DIR}/core/universal-envelope.md`, `${name}
|
|
119
|
+
fs.copyFileSync(`${MDAN_DIR}/core/orchestrator.md`, `${name}/mdan/orchestrator.md`);
|
|
120
|
+
fs.copyFileSync(`${MDAN_DIR}/core/universal-envelope.md`, `${name}/mdan/universal-envelope.md`);
|
|
121
121
|
|
|
122
122
|
fs.readdirSync(`${MDAN_DIR}/agents`).filter(f => f.endsWith('.md')).forEach(f => {
|
|
123
|
-
fs.copyFileSync(`${MDAN_DIR}/agents/${f}`, `${name}
|
|
123
|
+
fs.copyFileSync(`${MDAN_DIR}/agents/${f}`, `${name}/mdan/agents/${f}`);
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
fs.readdirSync(`${MDAN_DIR}/templates`).filter(f => f.endsWith('.md')).forEach(f => {
|
|
@@ -132,7 +132,7 @@ async function cmdInit(initialName) {
|
|
|
132
132
|
if (fs.existsSync(skillsDir)) {
|
|
133
133
|
fs.readdirSync(skillsDir).forEach(skill => {
|
|
134
134
|
const src = `${skillsDir}/${skill}`;
|
|
135
|
-
const dest1 = `${name}
|
|
135
|
+
const dest1 = `${name}/mdan/skills/${skill}`;
|
|
136
136
|
const dest2 = `${name}/.claude/skills/${skill}`;
|
|
137
137
|
if (fs.statSync(src).isDirectory()) {
|
|
138
138
|
fs.cpSync(src, dest1, { recursive: true });
|
|
@@ -143,7 +143,7 @@ async function cmdInit(initialName) {
|
|
|
143
143
|
|
|
144
144
|
// Create .cursorrules
|
|
145
145
|
let cursorrules = fs.readFileSync(`${MDAN_DIR}/core/orchestrator.md`, 'utf8');
|
|
146
|
-
cursorrules += '\n\n## CURSOR INSTRUCTIONS\nAgent files are in
|
|
146
|
+
cursorrules += '\n\n## CURSOR INSTRUCTIONS\nAgent files are in mdan/agents/\nSkills are in mdan/skills/';
|
|
147
147
|
fs.writeFileSync(`${name}/.cursorrules`, cursorrules);
|
|
148
148
|
fs.copyFileSync(`${name}/.cursorrules`, `${name}/.windsurfrules`);
|
|
149
149
|
fs.copyFileSync(`${MDAN_DIR}/core/orchestrator.md`, `${name}/.github/copilot-instructions.md`);
|
|
@@ -205,19 +205,19 @@ async function cmdAttach(rebuildMode) {
|
|
|
205
205
|
? `Preparing REBUILD environment for ${projectName}...`
|
|
206
206
|
: `Attaching MDAN to ${projectName}...`);
|
|
207
207
|
|
|
208
|
-
fs.mkdirSync('
|
|
209
|
-
fs.mkdirSync('
|
|
208
|
+
fs.mkdirSync('mdan/agents', { recursive: true });
|
|
209
|
+
fs.mkdirSync('mdan/skills', { recursive: true });
|
|
210
210
|
fs.mkdirSync('.claude/skills', { recursive: true });
|
|
211
211
|
fs.mkdirSync('.github', { recursive: true });
|
|
212
212
|
fs.mkdirSync('tests/scenarios', { recursive: true });
|
|
213
213
|
fs.mkdirSync('tests/evaluations', { recursive: true });
|
|
214
214
|
fs.mkdirSync('templates/prompts', { recursive: true });
|
|
215
215
|
|
|
216
|
-
fs.copyFileSync(`${MDAN_DIR}/core/orchestrator.md`, '
|
|
217
|
-
fs.copyFileSync(`${MDAN_DIR}/core/universal-envelope.md`, '
|
|
216
|
+
fs.copyFileSync(`${MDAN_DIR}/core/orchestrator.md`, 'mdan/orchestrator.md');
|
|
217
|
+
fs.copyFileSync(`${MDAN_DIR}/core/universal-envelope.md`, 'mdan/universal-envelope.md');
|
|
218
218
|
|
|
219
219
|
fs.readdirSync(`${MDAN_DIR}/agents`).filter(f => f.endsWith('.md')).forEach(f => {
|
|
220
|
-
fs.copyFileSync(`${MDAN_DIR}/agents/${f}`,
|
|
220
|
+
fs.copyFileSync(`${MDAN_DIR}/agents/${f}`, `mdan/agents/${f}`);
|
|
221
221
|
});
|
|
222
222
|
|
|
223
223
|
// Copy skills
|
|
@@ -226,7 +226,7 @@ async function cmdAttach(rebuildMode) {
|
|
|
226
226
|
fs.readdirSync(skillsDir).forEach(skill => {
|
|
227
227
|
const src = `${skillsDir}/${skill}`;
|
|
228
228
|
if (fs.statSync(src).isDirectory()) {
|
|
229
|
-
fs.cpSync(src,
|
|
229
|
+
fs.cpSync(src, `mdan/skills/${skill}`, { recursive: true });
|
|
230
230
|
fs.cpSync(src, `.claude/skills/${skill}`, { recursive: true });
|
|
231
231
|
}
|
|
232
232
|
});
|
|
@@ -273,7 +273,7 @@ async function cmdAttach(rebuildMode) {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
function cmdOc() {
|
|
276
|
-
let orchFile = '
|
|
276
|
+
let orchFile = 'mdan/orchestrator.md';
|
|
277
277
|
if (!fs.existsSync(orchFile)) {
|
|
278
278
|
orchFile = `${MDAN_DIR}/core/orchestrator.md`;
|
|
279
279
|
}
|
|
@@ -306,10 +306,10 @@ function cmdOc() {
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
function cmdStatus() {
|
|
309
|
-
if (fs.existsSync('
|
|
309
|
+
if (fs.existsSync('mdan/orchestrator.md')) {
|
|
310
310
|
console.log(`${colors.green}✅ MDAN is active in this project${colors.nc}`);
|
|
311
|
-
if (fs.existsSync('
|
|
312
|
-
console.log(fs.readFileSync('
|
|
311
|
+
if (fs.existsSync('mdan/STATUS.md')) {
|
|
312
|
+
console.log(fs.readFileSync('mdan/STATUS.md', 'utf8'));
|
|
313
313
|
}
|
|
314
314
|
} else {
|
|
315
315
|
console.log(`${colors.yellow}No MDAN project here.${colors.nc}`);
|
|
@@ -394,15 +394,15 @@ function cmdModule(action, name) {
|
|
|
394
394
|
|
|
395
395
|
console.log(`${colors.cyan}📦 Installing module: ${colors.bold}${name}${colors.nc}`);
|
|
396
396
|
|
|
397
|
-
if (!fs.existsSync('
|
|
398
|
-
console.log(`${colors.yellow}⚠️ No
|
|
397
|
+
if (!fs.existsSync('mdan')) {
|
|
398
|
+
console.log(`${colors.yellow}⚠️ No mdan folder found. Are you in an MDAN project?${colors.nc}`);
|
|
399
399
|
return;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
402
|
// Copy agents
|
|
403
403
|
if (fs.existsSync(`${moduleDir}/agents`)) {
|
|
404
404
|
fs.readdirSync(`${moduleDir}/agents`).forEach(f => {
|
|
405
|
-
fs.copyFileSync(`${moduleDir}/agents/${f}`,
|
|
405
|
+
fs.copyFileSync(`${moduleDir}/agents/${f}`, `mdan/agents/${f}`);
|
|
406
406
|
console.log(`${colors.green} Added agent:${colors.nc} ${f}`);
|
|
407
407
|
});
|
|
408
408
|
}
|
package/cli/mdan.py
CHANGED
|
@@ -7,7 +7,7 @@ import shutil
|
|
|
7
7
|
import json
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
|
-
VERSION = "2.
|
|
10
|
+
VERSION = "2.4.1"
|
|
11
11
|
MDAN_DIR = Path(__file__).parent.parent
|
|
12
12
|
|
|
13
13
|
# Colors
|
|
@@ -19,6 +19,7 @@ MAGENTA = "\033[0;35m"
|
|
|
19
19
|
BOLD = "\033[1m"
|
|
20
20
|
NC = "\033[0m"
|
|
21
21
|
|
|
22
|
+
|
|
22
23
|
def banner():
|
|
23
24
|
print(f"{CYAN}")
|
|
24
25
|
print(" ███╗ ███╗██████╗ █████╗ ███╗ ██╗")
|
|
@@ -30,6 +31,7 @@ def banner():
|
|
|
30
31
|
print(f"{NC}")
|
|
31
32
|
print(f" {BOLD}Multi-Agent Development Agentic Network{NC} v{VERSION}\n")
|
|
32
33
|
|
|
34
|
+
|
|
33
35
|
def show_help():
|
|
34
36
|
banner()
|
|
35
37
|
print(f"{BOLD}USAGE{NC}")
|
|
@@ -50,77 +52,90 @@ def show_help():
|
|
|
50
52
|
print(f"{BOLD}AGENTS{NC}")
|
|
51
53
|
print(" product, architect, ux, dev, test, security, devops, doc")
|
|
52
54
|
|
|
55
|
+
|
|
53
56
|
def cmd_init(name="my-project"):
|
|
54
57
|
print(f"{CYAN}🚀 Creating: {BOLD}{name}{NC}")
|
|
55
|
-
|
|
58
|
+
|
|
56
59
|
dirs = [
|
|
57
|
-
f"{name}
|
|
58
|
-
f"{name}
|
|
60
|
+
f"{name}/mdan/agents",
|
|
61
|
+
f"{name}/mdan/skills",
|
|
62
|
+
f"{name}/mdan_output",
|
|
63
|
+
f"{name}/.claude/skills",
|
|
64
|
+
f"{name}/.github",
|
|
59
65
|
]
|
|
60
66
|
for d in dirs:
|
|
61
67
|
Path(d).mkdir(parents=True, exist_ok=True)
|
|
62
|
-
|
|
63
|
-
shutil.copy(f"{MDAN_DIR}/core/orchestrator.md", f"{name}
|
|
64
|
-
shutil.copy(f"{MDAN_DIR}/core/universal-envelope.md", f"{name}
|
|
65
|
-
|
|
68
|
+
|
|
69
|
+
shutil.copy(f"{MDAN_DIR}/core/orchestrator.md", f"{name}/mdan/")
|
|
70
|
+
shutil.copy(f"{MDAN_DIR}/core/universal-envelope.md", f"{name}/mdan/")
|
|
71
|
+
|
|
66
72
|
for f in Path(f"{MDAN_DIR}/agents").glob("*.md"):
|
|
67
|
-
shutil.copy(f, f"{name}
|
|
68
|
-
|
|
73
|
+
shutil.copy(f, f"{name}/mdan/agents/")
|
|
74
|
+
|
|
69
75
|
for f in Path(f"{MDAN_DIR}/templates").glob("*.md"):
|
|
70
76
|
shutil.copy(f, f"{name}/mdan_output/")
|
|
71
|
-
|
|
77
|
+
|
|
72
78
|
skills_dir = Path(f"{MDAN_DIR}/skills")
|
|
73
79
|
if skills_dir.exists():
|
|
74
80
|
for s in skills_dir.iterdir():
|
|
75
81
|
if s.is_dir():
|
|
76
|
-
shutil.copytree(s, f"{name}
|
|
77
|
-
shutil.copytree(
|
|
78
|
-
|
|
82
|
+
shutil.copytree(s, f"{name}/mdan/skills/{s.name}", dirs_exist_ok=True)
|
|
83
|
+
shutil.copytree(
|
|
84
|
+
s, f"{name}/.claude/skills/{s.name}", dirs_exist_ok=True
|
|
85
|
+
)
|
|
86
|
+
|
|
79
87
|
cursorrules = Path(f"{MDAN_DIR}/core/orchestrator.md").read_text()
|
|
80
|
-
cursorrules += "\n\n## CURSOR INSTRUCTIONS\nAgent files in
|
|
88
|
+
cursorrules += "\n\n## CURSOR INSTRUCTIONS\nAgent files in mdan/agents/\nSkills in mdan/skills/"
|
|
81
89
|
Path(f"{name}/.cursorrules").write_text(cursorrules)
|
|
82
90
|
shutil.copy(f"{name}/.cursorrules", f"{name}/.windsurfrules")
|
|
83
|
-
shutil.copy(
|
|
91
|
+
shutil.copy(
|
|
92
|
+
f"{MDAN_DIR}/core/orchestrator.md", f"{name}/.github/copilot-instructions.md"
|
|
93
|
+
)
|
|
84
94
|
Path(f"{name}/README.md").write_text(f"# {name}\n\n> Built with MDAN\n")
|
|
85
|
-
|
|
95
|
+
|
|
86
96
|
print(f"{GREEN}✅ Created {name}/{NC}\n")
|
|
87
97
|
print(f" {BOLD}Next:{NC} cursor {name}")
|
|
88
98
|
|
|
99
|
+
|
|
89
100
|
def cmd_attach(rebuild=None):
|
|
90
101
|
project = Path.cwd().name
|
|
91
|
-
|
|
102
|
+
|
|
92
103
|
if rebuild == "--rebuild":
|
|
93
104
|
print(f"{MAGENTA}🔄 REBUILD MODE: {BOLD}{project}{NC}")
|
|
94
105
|
else:
|
|
95
106
|
print(f"{CYAN}🔗 Attaching to: {BOLD}{project}{NC}")
|
|
96
|
-
|
|
97
|
-
Path("
|
|
98
|
-
Path("
|
|
107
|
+
|
|
108
|
+
Path("mdan/agents").mkdir(parents=True, exist_ok=True)
|
|
109
|
+
Path("mdan/skills").mkdir(parents=True, exist_ok=True)
|
|
99
110
|
Path(".claude/skills").mkdir(parents=True, exist_ok=True)
|
|
100
111
|
Path(".github").mkdir(parents=True, exist_ok=True)
|
|
101
|
-
|
|
102
|
-
shutil.copy(f"{MDAN_DIR}/core/orchestrator.md", "
|
|
103
|
-
shutil.copy(f"{MDAN_DIR}/core/universal-envelope.md", "
|
|
104
|
-
|
|
112
|
+
|
|
113
|
+
shutil.copy(f"{MDAN_DIR}/core/orchestrator.md", "mdan/")
|
|
114
|
+
shutil.copy(f"{MDAN_DIR}/core/universal-envelope.md", "mdan/")
|
|
115
|
+
|
|
105
116
|
for f in Path(f"{MDAN_DIR}/agents").glob("*.md"):
|
|
106
|
-
shutil.copy(f, "
|
|
107
|
-
|
|
117
|
+
shutil.copy(f, "mdan/agents/")
|
|
118
|
+
|
|
108
119
|
skills_dir = Path(f"{MDAN_DIR}/skills")
|
|
109
120
|
if skills_dir.exists():
|
|
110
121
|
for s in skills_dir.iterdir():
|
|
111
122
|
if s.is_dir():
|
|
112
|
-
shutil.copytree(s, f"
|
|
123
|
+
shutil.copytree(s, f"mdan/skills/{s.name}", dirs_exist_ok=True)
|
|
113
124
|
shutil.copytree(s, f".claude/skills/{s.name}", dirs_exist_ok=True)
|
|
114
|
-
|
|
125
|
+
|
|
115
126
|
cursorrules = Path(f"{MDAN_DIR}/core/orchestrator.md").read_text()
|
|
116
127
|
if rebuild == "--rebuild":
|
|
117
|
-
cursorrules +=
|
|
128
|
+
cursorrules += (
|
|
129
|
+
"\n\n## REBUILD MODE\nAnalyze existing code then rewrite from scratch."
|
|
130
|
+
)
|
|
118
131
|
else:
|
|
119
|
-
cursorrules +=
|
|
132
|
+
cursorrules += (
|
|
133
|
+
"\n\n## EXISTING PROJECT\nAnalyze codebase before making changes."
|
|
134
|
+
)
|
|
120
135
|
Path(".cursorrules").write_text(cursorrules)
|
|
121
136
|
shutil.copy(".cursorrules", ".windsurfrules")
|
|
122
137
|
shutil.copy(f"{MDAN_DIR}/core/orchestrator.md", ".github/copilot-instructions.md")
|
|
123
|
-
|
|
138
|
+
|
|
124
139
|
print(f"{GREEN}✅ MDAN ready!{NC}\n")
|
|
125
140
|
print(f" {BOLD}Next:{NC} Run {CYAN}mdan oc{NC} to copy prompt")
|
|
126
141
|
if rebuild == "--rebuild":
|
|
@@ -128,45 +143,63 @@ def cmd_attach(rebuild=None):
|
|
|
128
143
|
else:
|
|
129
144
|
print(f" Start: {CYAN}MDAN: Analyze this project{NC}")
|
|
130
145
|
|
|
146
|
+
|
|
131
147
|
def cmd_oc():
|
|
132
148
|
import subprocess
|
|
133
|
-
|
|
149
|
+
|
|
150
|
+
orch_file = Path("mdan/orchestrator.md")
|
|
134
151
|
if not orch_file.exists():
|
|
135
152
|
orch_file = Path(f"{MDAN_DIR}/core/orchestrator.md")
|
|
136
|
-
|
|
153
|
+
|
|
137
154
|
if orch_file.exists():
|
|
138
155
|
content = orch_file.read_text()
|
|
139
156
|
try:
|
|
140
157
|
if sys.platform == "darwin":
|
|
141
|
-
subprocess.run(
|
|
158
|
+
subprocess.run(
|
|
159
|
+
"pbcopy", universal_newlines=True, input=content, check=True
|
|
160
|
+
)
|
|
142
161
|
elif sys.platform == "win32":
|
|
143
|
-
subprocess.run(
|
|
162
|
+
subprocess.run(
|
|
163
|
+
"clip", universal_newlines=True, input=content, check=True
|
|
164
|
+
)
|
|
144
165
|
elif sys.platform == "linux":
|
|
145
166
|
if shutil.which("xclip"):
|
|
146
|
-
subprocess.run(
|
|
167
|
+
subprocess.run(
|
|
168
|
+
["xclip", "-selection", "clipboard"],
|
|
169
|
+
universal_newlines=True,
|
|
170
|
+
input=content,
|
|
171
|
+
check=True,
|
|
172
|
+
)
|
|
147
173
|
elif shutil.which("wl-copy"):
|
|
148
|
-
subprocess.run(
|
|
174
|
+
subprocess.run(
|
|
175
|
+
["wl-copy"], universal_newlines=True, input=content, check=True
|
|
176
|
+
)
|
|
149
177
|
else:
|
|
150
178
|
raise Exception("No clipboard tool found")
|
|
151
179
|
print(f"{GREEN}✅ Orchestrator prompt copied to clipboard!{NC}")
|
|
152
180
|
print(" Paste it into Claude, ChatGPT, or your favorite LLM.")
|
|
153
181
|
except Exception:
|
|
154
182
|
print(content)
|
|
155
|
-
print(
|
|
183
|
+
print(
|
|
184
|
+
f"\n{YELLOW}⚠️ Could not copy to clipboard automatically. Please copy the text above.{NC}"
|
|
185
|
+
)
|
|
156
186
|
else:
|
|
157
187
|
print(f"{RED}Orchestrator file not found.{NC}")
|
|
158
188
|
|
|
189
|
+
|
|
159
190
|
def cmd_status():
|
|
160
|
-
if Path("
|
|
191
|
+
if Path("mdan/orchestrator.md").exists():
|
|
161
192
|
print(f"{GREEN}✅ MDAN is active in this project{NC}")
|
|
162
|
-
if Path("
|
|
163
|
-
print(Path("
|
|
193
|
+
if Path("mdan/STATUS.md").exists():
|
|
194
|
+
print(Path("mdan/STATUS.md").read_text())
|
|
164
195
|
else:
|
|
165
196
|
print(f"{YELLOW}No MDAN project here.{NC}")
|
|
166
197
|
print(" Run: mdan init [name] or mdan attach")
|
|
167
198
|
|
|
199
|
+
|
|
168
200
|
def cmd_phase(num, action=None):
|
|
169
201
|
import subprocess
|
|
202
|
+
|
|
170
203
|
phases = {
|
|
171
204
|
"1": ("01-discover.md", "DISCOVER"),
|
|
172
205
|
"discover": ("01-discover.md", "DISCOVER"),
|
|
@@ -177,43 +210,62 @@ def cmd_phase(num, action=None):
|
|
|
177
210
|
"4": ("04-verify.md", "VERIFY"),
|
|
178
211
|
"verify": ("04-verify.md", "VERIFY"),
|
|
179
212
|
"5": ("05-ship.md", "SHIP"),
|
|
180
|
-
"ship": ("05-ship.md", "SHIP")
|
|
213
|
+
"ship": ("05-ship.md", "SHIP"),
|
|
181
214
|
}
|
|
182
|
-
|
|
215
|
+
|
|
183
216
|
if num not in phases:
|
|
184
217
|
print("Usage: mdan phase [1-5|name] [copy]")
|
|
185
218
|
return
|
|
186
|
-
|
|
219
|
+
|
|
187
220
|
file, name = phases[num]
|
|
188
221
|
phase_file = Path(f"{MDAN_DIR}/phases/{file}")
|
|
189
|
-
|
|
222
|
+
|
|
190
223
|
if phase_file.exists():
|
|
191
224
|
content = phase_file.read_text()
|
|
192
225
|
if action in ["copy", "-c"]:
|
|
193
226
|
try:
|
|
194
227
|
if sys.platform == "darwin":
|
|
195
|
-
subprocess.run(
|
|
228
|
+
subprocess.run(
|
|
229
|
+
"pbcopy", universal_newlines=True, input=content, check=True
|
|
230
|
+
)
|
|
196
231
|
elif sys.platform == "win32":
|
|
197
|
-
subprocess.run(
|
|
232
|
+
subprocess.run(
|
|
233
|
+
"clip", universal_newlines=True, input=content, check=True
|
|
234
|
+
)
|
|
198
235
|
elif sys.platform == "linux":
|
|
199
236
|
if shutil.which("xclip"):
|
|
200
|
-
subprocess.run(
|
|
237
|
+
subprocess.run(
|
|
238
|
+
["xclip", "-selection", "clipboard"],
|
|
239
|
+
universal_newlines=True,
|
|
240
|
+
input=content,
|
|
241
|
+
check=True,
|
|
242
|
+
)
|
|
201
243
|
elif shutil.which("wl-copy"):
|
|
202
|
-
subprocess.run(
|
|
244
|
+
subprocess.run(
|
|
245
|
+
["wl-copy"],
|
|
246
|
+
universal_newlines=True,
|
|
247
|
+
input=content,
|
|
248
|
+
check=True,
|
|
249
|
+
)
|
|
203
250
|
else:
|
|
204
251
|
raise Exception("No clipboard tool found")
|
|
205
252
|
print(f"{GREEN}✅ Phase {name} prompt copied to clipboard!{NC}")
|
|
206
253
|
print(" Paste it into your LLM to start the phase.")
|
|
207
254
|
except Exception:
|
|
208
255
|
print(content)
|
|
209
|
-
print(
|
|
256
|
+
print(
|
|
257
|
+
f"\n{YELLOW}⚠️ Could not copy automatically. Please copy the text above.{NC}"
|
|
258
|
+
)
|
|
210
259
|
else:
|
|
211
260
|
print(f"{CYAN}{BOLD}Phase {name}{NC}")
|
|
212
261
|
print(content)
|
|
213
|
-
print(
|
|
262
|
+
print(
|
|
263
|
+
f"\n{YELLOW}Tip: Run '{CYAN}mdan phase {num} copy{YELLOW}' to copy this content to clipboard.{NC}"
|
|
264
|
+
)
|
|
214
265
|
else:
|
|
215
266
|
print(f"Phase file not found: {file}")
|
|
216
267
|
|
|
268
|
+
|
|
217
269
|
def cmd_agent(name):
|
|
218
270
|
file = Path(f"{MDAN_DIR}/agents/{name}.md")
|
|
219
271
|
if file.exists():
|
|
@@ -221,6 +273,7 @@ def cmd_agent(name):
|
|
|
221
273
|
else:
|
|
222
274
|
print("Agents: product, architect, ux, dev, test, security, devops, doc")
|
|
223
275
|
|
|
276
|
+
|
|
224
277
|
def cmd_skills():
|
|
225
278
|
print(f"{CYAN}Skills:{NC}")
|
|
226
279
|
skills_dir = Path(f"{MDAN_DIR}/skills")
|
|
@@ -230,10 +283,11 @@ def cmd_skills():
|
|
|
230
283
|
else:
|
|
231
284
|
print(" No skills installed")
|
|
232
285
|
|
|
286
|
+
|
|
233
287
|
def main():
|
|
234
288
|
args = sys.argv[1:]
|
|
235
289
|
cmd = args[0] if args else "help"
|
|
236
|
-
|
|
290
|
+
|
|
237
291
|
if cmd in ["help", "--help", "-h", None]:
|
|
238
292
|
show_help()
|
|
239
293
|
elif cmd == "init":
|
|
@@ -245,7 +299,9 @@ def main():
|
|
|
245
299
|
elif cmd == "status":
|
|
246
300
|
cmd_status()
|
|
247
301
|
elif cmd == "phase":
|
|
248
|
-
cmd_phase(
|
|
302
|
+
cmd_phase(
|
|
303
|
+
args[1] if len(args) > 1 else None, args[2] if len(args) > 2 else None
|
|
304
|
+
)
|
|
249
305
|
elif cmd == "agent":
|
|
250
306
|
cmd_agent(args[1] if len(args) > 1 else None)
|
|
251
307
|
elif cmd == "skills":
|
|
@@ -255,5 +311,6 @@ def main():
|
|
|
255
311
|
else:
|
|
256
312
|
print(f"Unknown: {cmd}. Run: mdan help")
|
|
257
313
|
|
|
314
|
+
|
|
258
315
|
if __name__ == "__main__":
|
|
259
316
|
main()
|
package/cli/mdan.sh
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Multi-Agent Development Agentic Network
|
|
6
6
|
# ============================================================
|
|
7
7
|
|
|
8
|
-
VERSION="2.
|
|
8
|
+
VERSION="2.4.1"
|
|
9
9
|
MDAN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
10
10
|
|
|
11
11
|
# Colors
|
|
@@ -110,7 +110,7 @@ cmd_learn() {
|
|
|
110
110
|
echo "---"
|
|
111
111
|
;;
|
|
112
112
|
--list)
|
|
113
|
-
KNOWLEDGE_FILE="
|
|
113
|
+
KNOWLEDGE_FILE="mdan/MDAN-KNOWLEDGE.md"
|
|
114
114
|
if [[ -f "${KNOWLEDGE_FILE}" ]]; then
|
|
115
115
|
cat "${KNOWLEDGE_FILE}"
|
|
116
116
|
else
|
|
@@ -120,7 +120,7 @@ cmd_learn() {
|
|
|
120
120
|
--capsule)
|
|
121
121
|
AGENT="${1}"
|
|
122
122
|
echo -e "${CYAN}Capsule for agent: ${BOLD}${AGENT}${NC}"
|
|
123
|
-
KNOWLEDGE_FILE="
|
|
123
|
+
KNOWLEDGE_FILE="mdan/MDAN-KNOWLEDGE.md"
|
|
124
124
|
if [[ -f "${KNOWLEDGE_FILE}" ]]; then
|
|
125
125
|
grep -A 20 "### ${AGENT^} Agent" "${KNOWLEDGE_FILE}" | head -25
|
|
126
126
|
else
|
|
@@ -215,41 +215,41 @@ cmd_attach() {
|
|
|
215
215
|
echo ""
|
|
216
216
|
fi
|
|
217
217
|
|
|
218
|
-
# Check if
|
|
219
|
-
if [[ -d "
|
|
220
|
-
echo -e "${YELLOW}⚠️
|
|
218
|
+
# Check if mdan already exists
|
|
219
|
+
if [[ -d "mdan" ]]; then
|
|
220
|
+
echo -e "${YELLOW}⚠️ mdan folder already exists.${NC}"
|
|
221
221
|
read -p " Overwrite? (y/n) " -n 1 -r
|
|
222
222
|
echo
|
|
223
223
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
224
|
-
echo " Keeping existing
|
|
224
|
+
echo " Keeping existing mdan folder."
|
|
225
225
|
else
|
|
226
|
-
rm -rf
|
|
226
|
+
rm -rf mdan
|
|
227
227
|
fi
|
|
228
228
|
fi
|
|
229
229
|
|
|
230
|
-
# Create
|
|
231
|
-
mkdir -p
|
|
232
|
-
mkdir -p
|
|
233
|
-
mkdir -p
|
|
230
|
+
# Create mdan directory structure
|
|
231
|
+
mkdir -p mdan/agents
|
|
232
|
+
mkdir -p mdan/artifacts
|
|
233
|
+
mkdir -p mdan/skills
|
|
234
234
|
|
|
235
235
|
# Copy core files
|
|
236
|
-
cp "${MDAN_DIR}/core/orchestrator.md"
|
|
237
|
-
cp "${MDAN_DIR}/core/universal-envelope.md"
|
|
236
|
+
cp "${MDAN_DIR}/core/orchestrator.md" mdan/orchestrator.md
|
|
237
|
+
cp "${MDAN_DIR}/core/universal-envelope.md" mdan/universal-envelope.md
|
|
238
238
|
|
|
239
239
|
# Copy all agents
|
|
240
|
-
cp "${MDAN_DIR}/agents/"*.md
|
|
240
|
+
cp "${MDAN_DIR}/agents/"*.md mdan/agents/
|
|
241
241
|
|
|
242
242
|
# Copy skills if available
|
|
243
243
|
if [[ -d "${MDAN_DIR}/skills" ]]; then
|
|
244
|
-
cp -r "${MDAN_DIR}/skills/"*
|
|
244
|
+
cp -r "${MDAN_DIR}/skills/"* mdan/skills/ 2>/dev/null
|
|
245
245
|
fi
|
|
246
246
|
|
|
247
247
|
# Create .cursorrules
|
|
248
248
|
cat "${MDAN_DIR}/core/orchestrator.md" > .cursorrules
|
|
249
249
|
echo "" >> .cursorrules
|
|
250
250
|
echo "## CURSOR INSTRUCTIONS" >> .cursorrules
|
|
251
|
-
echo "Agent files are in
|
|
252
|
-
echo "Skills are in
|
|
251
|
+
echo "Agent files are in mdan/agents/. Reference them with @file when activating agents." >> .cursorrules
|
|
252
|
+
echo "Skills are in mdan/skills/. Reference them for extended capabilities." >> .cursorrules
|
|
253
253
|
echo "" >> .cursorrules
|
|
254
254
|
|
|
255
255
|
if [[ "$REBUILD_MODE" == true ]]; then
|
|
@@ -283,7 +283,7 @@ cmd_attach() {
|
|
|
283
283
|
|
|
284
284
|
# Create MDAN-STATE.json
|
|
285
285
|
if [[ "$REBUILD_MODE" == true ]]; then
|
|
286
|
-
cat >
|
|
286
|
+
cat > mdan/MDAN-STATE.json << EOF
|
|
287
287
|
{
|
|
288
288
|
"user": {
|
|
289
289
|
"name": null
|
|
@@ -313,7 +313,7 @@ cmd_attach() {
|
|
|
313
313
|
}
|
|
314
314
|
EOF
|
|
315
315
|
else
|
|
316
|
-
cat >
|
|
316
|
+
cat > mdan/MDAN-STATE.json << EOF
|
|
317
317
|
{
|
|
318
318
|
"user": {
|
|
319
319
|
"name": null
|
|
@@ -345,7 +345,7 @@ EOF
|
|
|
345
345
|
|
|
346
346
|
# Create STATUS.md
|
|
347
347
|
if [[ "$REBUILD_MODE" == true ]]; then
|
|
348
|
-
cat >
|
|
348
|
+
cat > mdan/STATUS.md << EOF
|
|
349
349
|
# MDAN Project Status — REBUILD MODE
|
|
350
350
|
|
|
351
351
|
**Project:** ${PROJECT_NAME}
|
|
@@ -375,7 +375,7 @@ Rewrite the entire project from scratch with a modern architecture.
|
|
|
375
375
|
2. Start with: "MDAN REBUILD: Begin DISCOVER phase. Analyze this entire codebase."
|
|
376
376
|
EOF
|
|
377
377
|
else
|
|
378
|
-
cat >
|
|
378
|
+
cat > mdan/STATUS.md << EOF
|
|
379
379
|
# MDAN Project Status
|
|
380
380
|
|
|
381
381
|
**Project:** ${PROJECT_NAME} (existing)
|
|
@@ -396,17 +396,17 @@ EOF
|
|
|
396
396
|
|
|
397
397
|
## Commands to Start
|
|
398
398
|
1. Open Claude/Cursor with this project
|
|
399
|
-
2. Paste
|
|
399
|
+
2. Paste mdan/orchestrator.md as system prompt
|
|
400
400
|
3. Start with: "MDAN: Analyze this existing project and help me [goal]"
|
|
401
401
|
EOF
|
|
402
402
|
fi
|
|
403
403
|
|
|
404
404
|
echo -e "${GREEN}✅ MDAN attached to ${PROJECT_NAME}!${NC}"
|
|
405
405
|
echo ""
|
|
406
|
-
echo -e " ${BOLD}MDAN files:${NC}
|
|
407
|
-
echo -e " ${BOLD}Agents:${NC}
|
|
408
|
-
echo -e " ${BOLD}Skills:${NC}
|
|
409
|
-
echo -e " ${BOLD}State:${NC}
|
|
406
|
+
echo -e " ${BOLD}MDAN files:${NC} mdan/"
|
|
407
|
+
echo -e " ${BOLD}Agents:${NC} mdan/agents/"
|
|
408
|
+
echo -e " ${BOLD}Skills:${NC} mdan/skills/"
|
|
409
|
+
echo -e " ${BOLD}State:${NC} mdan/MDAN-STATE.json"
|
|
410
410
|
echo ""
|
|
411
411
|
|
|
412
412
|
if [[ "$REBUILD_MODE" == true ]]; then
|
|
@@ -445,33 +445,33 @@ cmd_init() {
|
|
|
445
445
|
echo -e "${CYAN}🚀 Initializing MDAN project: ${BOLD}${PROJECT_NAME}${NC}"
|
|
446
446
|
echo ""
|
|
447
447
|
|
|
448
|
-
# Create
|
|
449
|
-
mkdir -p "${PROJECT_NAME}
|
|
450
|
-
mkdir -p "${PROJECT_NAME}
|
|
451
|
-
mkdir -p "${PROJECT_NAME}
|
|
448
|
+
# Create mdan directory structure
|
|
449
|
+
mkdir -p "${PROJECT_NAME}/mdan/agents"
|
|
450
|
+
mkdir -p "${PROJECT_NAME}/mdan/artifacts"
|
|
451
|
+
mkdir -p "${PROJECT_NAME}/mdan/skills"
|
|
452
452
|
mkdir -p "${PROJECT_NAME}/mdan_output"
|
|
453
453
|
|
|
454
454
|
# Copy core files
|
|
455
|
-
cp "${MDAN_DIR}/core/orchestrator.md" "${PROJECT_NAME}
|
|
456
|
-
cp "${MDAN_DIR}/core/universal-envelope.md" "${PROJECT_NAME}
|
|
455
|
+
cp "${MDAN_DIR}/core/orchestrator.md" "${PROJECT_NAME}/mdan/orchestrator.md"
|
|
456
|
+
cp "${MDAN_DIR}/core/universal-envelope.md" "${PROJECT_NAME}/mdan/universal-envelope.md"
|
|
457
457
|
|
|
458
458
|
# Copy all agents
|
|
459
|
-
cp "${MDAN_DIR}/agents/"*.md "${PROJECT_NAME}
|
|
459
|
+
cp "${MDAN_DIR}/agents/"*.md "${PROJECT_NAME}/mdan/agents/"
|
|
460
460
|
|
|
461
461
|
# Copy templates
|
|
462
462
|
cp "${MDAN_DIR}/templates/"*.md "${PROJECT_NAME}/mdan_output/"
|
|
463
463
|
|
|
464
464
|
# Copy skills if available
|
|
465
465
|
if [[ -d "${MDAN_DIR}/skills" ]]; then
|
|
466
|
-
cp -r "${MDAN_DIR}/skills/"* "${PROJECT_NAME}
|
|
466
|
+
cp -r "${MDAN_DIR}/skills/"* "${PROJECT_NAME}/mdan/skills/" 2>/dev/null
|
|
467
467
|
fi
|
|
468
468
|
|
|
469
469
|
# Create .cursorrules
|
|
470
470
|
cat "${MDAN_DIR}/core/orchestrator.md" > "${PROJECT_NAME}/.cursorrules"
|
|
471
471
|
echo "" >> "${PROJECT_NAME}/.cursorrules"
|
|
472
472
|
echo "## CURSOR INSTRUCTIONS" >> "${PROJECT_NAME}/.cursorrules"
|
|
473
|
-
echo "Agent files are in
|
|
474
|
-
echo "Skills are in
|
|
473
|
+
echo "Agent files are in mdan/agents/. Reference them with @file when activating agents." >> "${PROJECT_NAME}/.cursorrules"
|
|
474
|
+
echo "Skills are in mdan/skills/. Reference them for extended capabilities." >> "${PROJECT_NAME}/.cursorrules"
|
|
475
475
|
|
|
476
476
|
# Create .windsurfrules
|
|
477
477
|
cp "${PROJECT_NAME}/.cursorrules" "${PROJECT_NAME}/.windsurfrules"
|
|
@@ -487,7 +487,7 @@ cmd_init() {
|
|
|
487
487
|
cp "${MDAN_DIR}/core/orchestrator.md" "${PROJECT_NAME}/.github/copilot-instructions.md"
|
|
488
488
|
|
|
489
489
|
# Create STATUS.md
|
|
490
|
-
cat > "${PROJECT_NAME}
|
|
490
|
+
cat > "${PROJECT_NAME}/mdan/STATUS.md" << EOF
|
|
491
491
|
# MDAN Project Status
|
|
492
492
|
|
|
493
493
|
**Project:** ${PROJECT_NAME}
|
|
@@ -520,13 +520,13 @@ EOF
|
|
|
520
520
|
echo -e "${GREEN}✅ MDAN project initialized successfully!${NC}"
|
|
521
521
|
echo ""
|
|
522
522
|
echo -e " ${BOLD}Project:${NC} ${PROJECT_NAME}/"
|
|
523
|
-
echo -e " ${BOLD}MDAN files:${NC} ${PROJECT_NAME}
|
|
523
|
+
echo -e " ${BOLD}MDAN files:${NC} ${PROJECT_NAME}/mdan/"
|
|
524
524
|
echo -e " ${BOLD}Templates:${NC} ${PROJECT_NAME}/mdan_output/"
|
|
525
|
-
echo -e " ${BOLD}Skills:${NC} ${PROJECT_NAME}
|
|
525
|
+
echo -e " ${BOLD}Skills:${NC} ${PROJECT_NAME}/mdan/skills/"
|
|
526
526
|
echo ""
|
|
527
527
|
echo -e "${YELLOW}Next steps:${NC}"
|
|
528
528
|
echo " 1. Open your chosen LLM"
|
|
529
|
-
echo " 2. Paste
|
|
529
|
+
echo " 2. Paste mdan/orchestrator.md as your system prompt"
|
|
530
530
|
echo " 3. Start with: 'MDAN: I want to build ${PROJECT_NAME}'"
|
|
531
531
|
echo ""
|
|
532
532
|
echo -e " Or for Cursor/Windsurf: open the ${PROJECT_NAME}/ folder — .cursorrules is ready"
|
|
@@ -654,9 +654,9 @@ cmd_prompt() {
|
|
|
654
654
|
# STATUS
|
|
655
655
|
# ============================================================
|
|
656
656
|
|
|
657
|
-
# ============================================================n# OC (Orchestrator)n# ============================================================nncmd_oc() {n ORCH_FILE="
|
|
657
|
+
# ============================================================n# OC (Orchestrator)n# ============================================================nncmd_oc() {n ORCH_FILE="mdan/orchestrator.md"n if [[ ! -f "$ORCH_FILE" ]]; thenn ORCH_FILE="${MDAN_DIR}/core/orchestrator.md"n fin n if [[ -f "$ORCH_FILE" ]]; thenn if command -v pbcopy &> /dev/null; thenn cat "$ORCH_FILE" | pbcopyn echo -e "${GREEN}✅ Orchestrator prompt copied to clipboard!${NC}"n echo " Paste it into Claude, ChatGPT, or your favorite LLM."n elif command -v xclip &> /dev/null; thenn cat "$ORCH_FILE" | xclip -selection clipboardn echo -e "${GREEN}✅ Orchestrator prompt copied to clipboard!${NC}"n echo " Paste it into Claude, ChatGPT, or your favorite LLM."n elif command -v wl-copy &> /dev/null; thenn cat "$ORCH_FILE" | wl-copyn echo -e "${GREEN}✅ Orchestrator prompt copied to clipboard!${NC}"n echo " Paste it into Claude, ChatGPT, or your favorite LLM."n elsen cat "$ORCH_FILE"n echo -e "\n${YELLOW}⚠️ Could not copy to clipboard automatically. Please copy the text above.${NC}"n fin elsen echo -e "${RED}Orchestrator file not found.${NC}"n fin}nn
|
|
658
658
|
cmd_status() {
|
|
659
|
-
STATUS_FILE="
|
|
659
|
+
STATUS_FILE="mdan/STATUS.md"
|
|
660
660
|
if [[ -f "${STATUS_FILE}" ]]; then
|
|
661
661
|
cat "${STATUS_FILE}"
|
|
662
662
|
else
|
|
@@ -251,14 +251,14 @@ opencode
|
|
|
251
251
|
opencode "I want to build [your project idea]"
|
|
252
252
|
|
|
253
253
|
# Reference agent prompts
|
|
254
|
-
opencode "@file
|
|
254
|
+
opencode "@file mdan/agents/dev.md Implement the user authentication feature"
|
|
255
255
|
```
|
|
256
256
|
|
|
257
257
|
## Notes for Opencode
|
|
258
258
|
|
|
259
259
|
- Opencode excels in the BUILD phase — it can directly edit files
|
|
260
260
|
- Use MDAN feature briefs as opencode tasks
|
|
261
|
-
- Place agent files in
|
|
261
|
+
- Place agent files in `mdan/agents/` for easy reference
|
|
262
262
|
|
|
263
263
|
---
|
|
264
264
|
|
package/integrations/cursor.md
CHANGED
|
@@ -20,21 +20,21 @@ You are operating inside Cursor IDE. In addition to your MDAN orchestration role
|
|
|
20
20
|
- When the Doc Agent produces documentation, write it to the mdan_output/ folder
|
|
21
21
|
|
|
22
22
|
### Agent File References
|
|
23
|
-
- Product Agent: @file
|
|
24
|
-
- Architect Agent: @file
|
|
25
|
-
- UX Agent: @file
|
|
26
|
-
- Dev Agent: @file
|
|
27
|
-
- Test Agent: @file
|
|
28
|
-
- Security Agent: @file
|
|
29
|
-
- DevOps Agent: @file
|
|
30
|
-
- Doc Agent: @file
|
|
23
|
+
- Product Agent: @file mdan/agents/product.md
|
|
24
|
+
- Architect Agent: @file mdan/agents/architect.md
|
|
25
|
+
- UX Agent: @file mdan/agents/ux.md
|
|
26
|
+
- Dev Agent: @file mdan/agents/dev.md
|
|
27
|
+
- Test Agent: @file mdan/agents/test.md
|
|
28
|
+
- Security Agent: @file mdan/agents/security.md
|
|
29
|
+
- DevOps Agent: @file mdan/agents/devops.md
|
|
30
|
+
- Doc Agent: @file mdan/agents/doc.md
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
### Step 2: Copy agents to project
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
mkdir -p
|
|
37
|
-
cp agents/*.md
|
|
36
|
+
mkdir -p mdan/agents
|
|
37
|
+
cp agents/*.md mdan/agents/
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
### Step 3: Start using MDAN in Cursor
|
|
@@ -61,7 +61,7 @@ Enable Agent mode for autonomous implementation. MDAN Core will orchestrate, and
|
|
|
61
61
|
|
|
62
62
|
```
|
|
63
63
|
.cursorrules ← MDAN Core orchestrator prompt
|
|
64
|
-
|
|
64
|
+
mdan/
|
|
65
65
|
agents/
|
|
66
66
|
product.md
|
|
67
67
|
architect.md
|
package/integrations/windsurf.md
CHANGED
|
@@ -23,14 +23,14 @@ You are operating inside Windsurf IDE with Cascade AI.
|
|
|
23
23
|
- Use Cascade's flow awareness to maintain MDAN phase context across sessions
|
|
24
24
|
|
|
25
25
|
### File Organization
|
|
26
|
-
All MDAN artifacts should be saved to
|
|
26
|
+
All MDAN artifacts should be saved to `mdan/artifacts/` for reference.
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
### Step 2: Copy agents
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
mkdir -p
|
|
33
|
-
cp agents/*.md
|
|
32
|
+
mkdir -p mdan/agents mdan/artifacts
|
|
33
|
+
cp agents/*.md mdan/agents/
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
### Step 3: Using MDAN with Cascade
|
|
@@ -45,4 +45,4 @@ Cascade's multi-step reasoning pairs well with MDAN's structured phases. When st
|
|
|
45
45
|
|
|
46
46
|
- Windsurf's Cascade is excellent for the BUILD phase — it can implement entire features autonomously
|
|
47
47
|
- Use MDAN's Feature Briefs as Cascade tasks for predictable, structured implementation
|
|
48
|
-
- Save architecture documents to
|
|
48
|
+
- Save architecture documents to `mdan/artifacts/` so Cascade can reference them in context
|