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 CHANGED
@@ -166,7 +166,7 @@ This generates `.mcp.json` with:
166
166
 
167
167
  ```
168
168
  my-project/
169
- ├── .mdan/
169
+ ├── mdan/
170
170
  │ ├── orchestrator.md
171
171
  │ ├── agents/
172
172
  │ │ ├── dev.md
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 `.mdan/orchestrator.md`
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
- ├── .mdan/
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.3.0';
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}/.mdan/agents`,
108
- `${name}/.mdan/skills`,
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}/.mdan/orchestrator.md`);
120
- fs.copyFileSync(`${MDAN_DIR}/core/universal-envelope.md`, `${name}/.mdan/universal-envelope.md`);
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}/.mdan/agents/${f}`);
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}/.mdan/skills/${skill}`;
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 .mdan/agents/\nSkills are in .mdan/skills/';
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('.mdan/agents', { recursive: true });
209
- fs.mkdirSync('.mdan/skills', { recursive: true });
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`, '.mdan/orchestrator.md');
217
- fs.copyFileSync(`${MDAN_DIR}/core/universal-envelope.md`, '.mdan/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}`, `.mdan/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, `.mdan/skills/${skill}`, { recursive: true });
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 = '.mdan/orchestrator.md';
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('.mdan/orchestrator.md')) {
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('.mdan/STATUS.md')) {
312
- console.log(fs.readFileSync('.mdan/STATUS.md', 'utf8'));
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('.mdan')) {
398
- console.log(`${colors.yellow}⚠️ No .mdan folder found. Are you in an MDAN project?${colors.nc}`);
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}`, `.mdan/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.2.0"
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}/.mdan/agents", f"{name}/.mdan/skills", f"{name}/mdan_output",
58
- f"{name}/.claude/skills", f"{name}/.github"
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}/.mdan/")
64
- shutil.copy(f"{MDAN_DIR}/core/universal-envelope.md", f"{name}/.mdan/")
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}/.mdan/agents/")
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}/.mdan/skills/{s.name}", dirs_exist_ok=True)
77
- shutil.copytree(s, f"{name}/.claude/skills/{s.name}", dirs_exist_ok=True)
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 .mdan/agents/\nSkills in .mdan/skills/"
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(f"{MDAN_DIR}/core/orchestrator.md", f"{name}/.github/copilot-instructions.md")
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(".mdan/agents").mkdir(parents=True, exist_ok=True)
98
- Path(".mdan/skills").mkdir(parents=True, exist_ok=True)
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", ".mdan/")
103
- shutil.copy(f"{MDAN_DIR}/core/universal-envelope.md", ".mdan/")
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, ".mdan/agents/")
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".mdan/skills/{s.name}", dirs_exist_ok=True)
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 += "\n\n## REBUILD MODE\nAnalyze existing code then rewrite from scratch."
128
+ cursorrules += (
129
+ "\n\n## REBUILD MODE\nAnalyze existing code then rewrite from scratch."
130
+ )
118
131
  else:
119
- cursorrules += "\n\n## EXISTING PROJECT\nAnalyze codebase before making changes."
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
- orch_file = Path(".mdan/orchestrator.md")
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("pbcopy", universal_newlines=True, input=content, check=True)
158
+ subprocess.run(
159
+ "pbcopy", universal_newlines=True, input=content, check=True
160
+ )
142
161
  elif sys.platform == "win32":
143
- subprocess.run("clip", universal_newlines=True, input=content, check=True)
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(["xclip", "-selection", "clipboard"], universal_newlines=True, input=content, check=True)
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(["wl-copy"], universal_newlines=True, input=content, check=True)
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(f"\n{YELLOW}⚠️ Could not copy to clipboard automatically. Please copy the text above.{NC}")
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(".mdan/orchestrator.md").exists():
191
+ if Path("mdan/orchestrator.md").exists():
161
192
  print(f"{GREEN}✅ MDAN is active in this project{NC}")
162
- if Path(".mdan/STATUS.md").exists():
163
- print(Path(".mdan/STATUS.md").read_text())
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("pbcopy", universal_newlines=True, input=content, check=True)
228
+ subprocess.run(
229
+ "pbcopy", universal_newlines=True, input=content, check=True
230
+ )
196
231
  elif sys.platform == "win32":
197
- subprocess.run("clip", universal_newlines=True, input=content, check=True)
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(["xclip", "-selection", "clipboard"], universal_newlines=True, input=content, check=True)
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(["wl-copy"], universal_newlines=True, input=content, check=True)
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(f"\n{YELLOW}⚠️ Could not copy automatically. Please copy the text above.{NC}")
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(f"\n{YELLOW}Tip: Run '{CYAN}mdan phase {num} copy{YELLOW}' to copy this content to clipboard.{NC}")
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(args[1] if len(args) > 1 else None, args[2] if len(args) > 2 else None)
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.2.0"
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=".mdan/MDAN-KNOWLEDGE.md"
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=".mdan/MDAN-KNOWLEDGE.md"
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 .mdan already exists
219
- if [[ -d ".mdan" ]]; then
220
- echo -e "${YELLOW}⚠️ .mdan folder already exists.${NC}"
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 .mdan folder."
224
+ echo " Keeping existing mdan folder."
225
225
  else
226
- rm -rf .mdan
226
+ rm -rf mdan
227
227
  fi
228
228
  fi
229
229
 
230
- # Create .mdan directory structure
231
- mkdir -p .mdan/agents
232
- mkdir -p .mdan/artifacts
233
- mkdir -p .mdan/skills
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" .mdan/orchestrator.md
237
- cp "${MDAN_DIR}/core/universal-envelope.md" .mdan/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 .mdan/agents/
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/"* .mdan/skills/ 2>/dev/null
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 .mdan/agents/. Reference them with @file when activating agents." >> .cursorrules
252
- echo "Skills are in .mdan/skills/. Reference them for extended capabilities." >> .cursorrules
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 > .mdan/MDAN-STATE.json << EOF
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 > .mdan/MDAN-STATE.json << EOF
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 > .mdan/STATUS.md << EOF
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 > .mdan/STATUS.md << EOF
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 .mdan/orchestrator.md as system prompt
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} .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"
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 .mdan directory structure
449
- mkdir -p "${PROJECT_NAME}/.mdan/agents"
450
- mkdir -p "${PROJECT_NAME}/.mdan/artifacts"
451
- mkdir -p "${PROJECT_NAME}/.mdan/skills"
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}/.mdan/orchestrator.md"
456
- cp "${MDAN_DIR}/core/universal-envelope.md" "${PROJECT_NAME}/.mdan/universal-envelope.md"
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}/.mdan/agents/"
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}/.mdan/skills/" 2>/dev/null
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 .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"
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}/.mdan/STATUS.md" << EOF
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}/.mdan/"
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}/.mdan/skills/"
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 .mdan/orchestrator.md as your system prompt"
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=".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
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=".mdan/STATUS.md"
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 .mdan/agents/dev.md Implement the user authentication feature"
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 `.mdan/agents/` for easy reference
261
+ - Place agent files in `mdan/agents/` for easy reference
262
262
 
263
263
  ---
264
264
 
@@ -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 .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
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 .mdan/agents
37
- cp agents/*.md .mdan/agents/
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
- .mdan/
64
+ mdan/
65
65
  agents/
66
66
  product.md
67
67
  architect.md
@@ -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 `.mdan/artifacts/` for reference.
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 .mdan/agents .mdan/artifacts
33
- cp agents/*.md .mdan/agents/
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 `.mdan/artifacts/` so Cascade can reference them in context
48
+ - Save architecture documents to `mdan/artifacts/` so Cascade can reference them in context
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdan-cli",
3
- "version": "2.3.0",
3
+ "version": "2.4.1",
4
4
  "description": "Multi-Agent Development Agentic Network - A modern, adaptive, LLM-agnostic methodology for building software",
5
5
  "main": "cli/mdan.js",
6
6
  "bin": {