agent-enderun 0.1.9 → 0.2.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.
Files changed (103) hide show
  1. package/.enderun/BRAIN_DASHBOARD.md +43 -0
  2. package/.enderun/ENDERUN.md +203 -0
  3. package/.enderun/PROJECT_MEMORY.md +137 -36
  4. package/.enderun/agents/analyst.md +21 -10
  5. package/.enderun/agents/backend.md +12 -11
  6. package/.enderun/agents/explorer.md +10 -7
  7. package/.enderun/agents/frontend.md +9 -20
  8. package/.enderun/agents/git.md +16 -12
  9. package/.enderun/agents/manager.md +14 -15
  10. package/.enderun/agents/mobile.md +5 -5
  11. package/.enderun/agents/native.md +5 -5
  12. package/.enderun/benchmarks/.gitkeep +0 -0
  13. package/.enderun/cli-commands.json +13 -1
  14. package/.enderun/config.json +1 -1
  15. package/.enderun/docs/api/README.md +10 -9
  16. package/.enderun/docs/api/auth.md +11 -0
  17. package/.enderun/docs/api/errors.md +7 -0
  18. package/.enderun/docs/error-handling.md +12 -0
  19. package/.enderun/docs/privacy.md +3 -0
  20. package/.enderun/docs/security.md +12 -0
  21. package/.enderun/docs/tech-stack.md +1 -0
  22. package/.enderun/docs/troubleshooting.md +7 -0
  23. package/.enderun/knowledge/api_design_rules.md +6 -0
  24. package/.enderun/knowledge/async_error_handling.md +18 -0
  25. package/.enderun/knowledge/branded_types_pattern.md +1 -0
  26. package/.enderun/knowledge/code_review_checklist.md +7 -0
  27. package/.enderun/knowledge/contract_versioning.md +7 -0
  28. package/.enderun/knowledge/database_migration.md +6 -0
  29. package/.enderun/knowledge/deployment_checklist.md +7 -0
  30. package/.enderun/knowledge/git_commit_strategy.md +10 -0
  31. package/.enderun/knowledge/legacy_onboarding.md +7 -0
  32. package/.enderun/knowledge/monitoring_setup.md +5 -0
  33. package/.enderun/knowledge/performance_guidelines.md +11 -0
  34. package/.enderun/knowledge/repository_patterns.md +9 -0
  35. package/.enderun/knowledge/security_scanning.md +6 -0
  36. package/.enderun/knowledge/testing_standards.md +7 -0
  37. package/.enderun/knowledge/troubleshooting_guide.md +5 -0
  38. package/.enderun/knowledge/zero_ui_library_policy.md +1 -0
  39. package/.enderun/logs/analyst.json +1 -0
  40. package/.enderun/logs/backend.json +1 -0
  41. package/.enderun/logs/explorer.json +1 -0
  42. package/.enderun/logs/frontend.json +1 -0
  43. package/.enderun/logs/git.json +1 -0
  44. package/.enderun/logs/manager.json +363 -0
  45. package/.enderun/logs/mobile.json +1 -0
  46. package/.enderun/logs/native.json +1 -0
  47. package/.enderun/monitoring/.gitkeep +0 -0
  48. package/ENDERUN.md +8 -8
  49. package/LICENSE +21 -0
  50. package/README.md +595 -195
  51. package/bin/cli.js +306 -79
  52. package/package.json +35 -2
  53. package/packages/framework-mcp/README.md +47 -81
  54. package/packages/framework-mcp/dist/index.js +13 -971
  55. package/packages/framework-mcp/dist/schemas.js +84 -0
  56. package/packages/framework-mcp/dist/tools/academy.js +184 -0
  57. package/packages/framework-mcp/dist/tools/codebase.js +294 -0
  58. package/packages/framework-mcp/dist/tools/contract.js +95 -0
  59. package/packages/framework-mcp/dist/tools/database.js +52 -0
  60. package/packages/framework-mcp/dist/tools/framework.js +161 -0
  61. package/packages/framework-mcp/dist/tools/git.js +53 -0
  62. package/packages/framework-mcp/dist/tools/index.js +42 -0
  63. package/packages/framework-mcp/dist/tools/knowledge.js +69 -0
  64. package/packages/framework-mcp/dist/tools/memory.js +94 -0
  65. package/packages/framework-mcp/dist/tools/messages.js +71 -0
  66. package/packages/framework-mcp/dist/tools/repository.js +76 -0
  67. package/packages/framework-mcp/dist/tools/security.js +122 -0
  68. package/packages/framework-mcp/dist/utils.js +82 -0
  69. package/packages/framework-mcp/package-lock.json +1836 -0
  70. package/packages/framework-mcp/package.json +1 -1
  71. package/packages/framework-mcp/src/index.ts +20 -970
  72. package/packages/framework-mcp/src/schemas.ts +106 -0
  73. package/packages/framework-mcp/src/tools/academy.ts +178 -0
  74. package/packages/framework-mcp/src/tools/codebase.ts +284 -0
  75. package/packages/framework-mcp/src/tools/contract.ts +91 -0
  76. package/packages/framework-mcp/src/tools/database.ts +49 -0
  77. package/packages/framework-mcp/src/tools/framework.ts +157 -0
  78. package/packages/framework-mcp/src/tools/git.ts +43 -0
  79. package/packages/framework-mcp/src/tools/index.ts +45 -0
  80. package/packages/framework-mcp/src/tools/knowledge.ts +68 -0
  81. package/packages/framework-mcp/src/tools/memory.ts +88 -0
  82. package/packages/framework-mcp/src/tools/messages.ts +70 -0
  83. package/packages/framework-mcp/src/tools/repository.ts +76 -0
  84. package/packages/framework-mcp/src/tools/security.ts +122 -0
  85. package/packages/framework-mcp/src/utils.ts +90 -0
  86. package/packages/framework-mcp/tests/mcp-server.test.ts +6 -0
  87. package/packages/shared-types/README.md +28 -51
  88. package/packages/shared-types/contract.version.json +4 -4
  89. package/packages/shared-types/dist/index.d.ts +80 -48
  90. package/packages/shared-types/dist/index.d.ts.map +1 -1
  91. package/packages/shared-types/dist/index.js +5 -8
  92. package/packages/shared-types/dist/index.js.map +1 -1
  93. package/packages/shared-types/package.json +1 -1
  94. package/packages/shared-types/src/index.ts +79 -51
  95. package/CHANGELOG.md +0 -97
  96. package/CLAUDE.md +0 -7
  97. package/CODEX.md +0 -7
  98. package/CURSOR.md +0 -7
  99. package/GEMINI.md +0 -7
  100. package/docs/tech-stack.md +0 -10
  101. package/gemini-extension.json +0 -5
  102. package/panda.config.ts +0 -20
  103. /package/{docs → .enderun/docs}/project-docs.md +0 -0
package/bin/cli.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- console.log("🤖 Agent Enderun CLI — Initializing...");
3
2
 
4
3
  import fs from "fs";
5
4
  import path from "path";
@@ -177,12 +176,12 @@ function mergePackageJson(targetPath, sourcePath) {
177
176
  function updateGitIgnore(targetPath, frameworkDir = ".enderun") {
178
177
  const IGNORE_LINES = [
179
178
  "# AI-Enderun",
180
- ".gemini/logs/*.json",
179
+ ".enderun/logs/*.json",
181
180
  ".claude/logs/*.json",
182
181
  ".cursor/logs/*.json",
183
182
  ".codex/logs/*.json",
184
183
  ".enderun/logs/*.json",
185
- ".gemini/*.lock",
184
+ ".enderun/*.lock",
186
185
  ".claude/*.lock",
187
186
  ".cursor/*.lock",
188
187
  ".codex/*.lock",
@@ -312,35 +311,37 @@ async function initCommand(selectedAdapter) {
312
311
  };
313
312
 
314
313
  const targetBase = selectedAdapter ? `.${selectedAdapter}` : ".enderun";
314
+
315
315
  const targetFrameworkDir = path.join(targetDir, targetBase);
316
316
 
317
317
  const CORE_FILES = [
318
318
  ".enderun",
319
- "docs",
319
+
320
320
  "mcp.json",
321
321
  ".env.example",
322
322
  "ENDERUN.md",
323
- ".enderun/cli-commands.json",
324
- ".enderun/config.json",
325
- ".enderun/STATUS.md",
323
+ "package.json",
326
324
  "packages/framework-mcp",
327
325
  "packages/shared-types",
328
- "panda.config.ts",
329
326
  ];
330
327
 
331
328
  const DIRS_TO_CREATE = [
329
+ targetBase,
332
330
  `${targetBase}/agents`,
333
331
  `${targetBase}/docs/api`,
332
+ `${targetBase}/knowledge`,
333
+ `${targetBase}/benchmarks`,
334
+ `${targetBase}/monitoring`,
334
335
  `${targetBase}/logs`,
335
336
  `${targetBase}/messages`,
336
337
  "apps/web",
337
338
  "apps/backend",
338
- "docs",
339
+
339
340
  "packages/shared-types",
340
341
  "packages/framework-mcp",
341
342
  ];
342
343
 
343
- console.log("🚀 Installing Agent Enderun (Smart Mode)...");
344
+ console.log(`🚀 Installing Agent Enderun (Adapter: ${selectedAdapter || "all"})...`);
344
345
 
345
346
  // Ensure target framework base exists
346
347
  if (!fs.existsSync(targetFrameworkDir)) {
@@ -357,13 +358,12 @@ async function initCommand(selectedAdapter) {
357
358
  }
358
359
 
359
360
  let filesToProcess = [...CORE_FILES];
360
-
361
361
  if (selectedAdapter) {
362
362
  if (!ADAPTERS[selectedAdapter]) {
363
363
  console.error(`❌ Invalid adapter: ${selectedAdapter}. Available: gemini, claude, cursor, codex`);
364
364
  process.exit(1);
365
365
  }
366
- filesToProcess = [...CORE_FILES, ...ADAPTERS[selectedAdapter]];
366
+ filesToProcess.push(...ADAPTERS[selectedAdapter]);
367
367
  } else {
368
368
  Object.values(ADAPTERS).forEach(list => filesToProcess.push(...list));
369
369
  }
@@ -387,7 +387,7 @@ async function initCommand(selectedAdapter) {
387
387
  let dest = path.join(targetDir, item);
388
388
 
389
389
  // FORCED CLEANUP: Delete existing framework directories in target before copying
390
- if (["packages/framework-mcp", "packages/shared-types", ".enderun", ".gemini", ".claude"].includes(item)) {
390
+ if (["packages/framework-mcp", "packages/shared-types", ".enderun", ".enderun", ".claude", ".cursor", ".codex"].includes(item)) {
391
391
  if (fs.existsSync(dest)) {
392
392
  try {
393
393
  fs.rmSync(dest, { recursive: true, force: true });
@@ -397,38 +397,27 @@ async function initCommand(selectedAdapter) {
397
397
  }
398
398
  }
399
399
 
400
- // Clean up existing lockfiles in target
401
- if (fs.existsSync(dest)) {
402
- const lockFile = path.join(dest, "package-lock.json");
403
- if (fs.existsSync(lockFile)) {
404
- fs.unlinkSync(lockFile);
405
- }
406
- }
407
-
408
400
  // Remap core framework files to targetBase
409
401
  if (item === ".enderun" || item.startsWith(".enderun/")) {
410
402
  dest = path.join(targetDir, item.replace(".enderun", targetBase));
411
403
  }
412
404
  if (item === "ENDERUN.md") dest = path.join(targetFrameworkDir, "ENDERUN.md");
413
- if (ADAPTERS[selectedAdapter]?.includes(item)) {
414
- dest = path.join(targetDir, item); // Keep adapter linker files in root
405
+
406
+ // Check if item is an adapter pointer file
407
+ const isAdapterPointer = Object.values(ADAPTERS).flat().includes(item);
408
+ if (isAdapterPointer) {
409
+ dest = path.join(targetDir, item);
415
410
  }
416
411
 
417
412
  if (fs.existsSync(src)) {
418
413
  if (fs.lstatSync(src).isDirectory()) {
419
- // When copying framework dir, skip logs and project-specific state
420
- const skipFiles = (item === ".enderun") ? ["logs", "PROJECT_MEMORY.md", "BRAIN_DASHBOARD.md", "PROJECT_MEMORY.lock"] : [];
414
+ const skipFiles = (item === ".enderun") ? ["logs", "PROJECT_MEMORY.md", "PROJECT_MEMORY.lock"] : [];
421
415
  const isDocs = item === "docs";
422
416
  copyDir(src, dest, new Set(skipFiles), isDocs, targetBase, targetScope);
423
417
  } else {
424
- // Special files handling
425
- if (item === "package.json") continue;
426
- if (item === "ENDERUN.md" && fs.existsSync(dest)) {
427
- console.log(`ℹ️ Skipping ENDERUN.md (already exists in ${targetBase}).`);
428
- continue;
429
- }
418
+ if (item === "package.json") continue; // We merge it later
430
419
 
431
- if (fs.existsSync(dest)) {
420
+ if (fs.existsSync(dest) && !isAdapterPointer) {
432
421
  console.log(`ℹ️ Skipping existing file: ${item}`);
433
422
  continue;
434
423
  }
@@ -440,16 +429,16 @@ async function initCommand(selectedAdapter) {
440
429
  content = content.replace(/\{\{FRAMEWORK_DIR\}\}/g, targetBase);
441
430
  content = content.replace(/\{\{ADAPTER\}\}/g, selectedAdapter || "enderun");
442
431
 
443
- // Sanitize workspace: protocol in all text files
444
432
  if (ext === ".json") {
445
433
  try {
446
434
  const json = JSON.parse(content);
447
435
  content = JSON.stringify(sanitizeJson(json, targetScope), null, 2);
436
+ // Ensure variable replacement even inside JSON strings if any
437
+ content = content.replace(/\{\{FRAMEWORK_DIR\}\}/g, targetBase);
438
+ content = content.replace(/\{\{ADAPTER\}\}/g, selectedAdapter || "enderun");
448
439
  } catch (e) {
449
440
  content = content.replace(/workspace:[^"'\s]*/g, "*");
450
441
  }
451
- } else {
452
- content = content.replace(/workspace:[^"'\s]*/g, "*");
453
442
  }
454
443
 
455
444
  fs.writeFileSync(dest, content);
@@ -461,84 +450,78 @@ async function initCommand(selectedAdapter) {
461
450
  }
462
451
  }
463
452
 
464
- // Smart setup
453
+ // Merge Package JSON
465
454
  mergePackageJson(path.join(targetDir, "package.json"), path.join(sourceDir, "package.json"));
466
455
  updateGitIgnore(path.join(targetDir, ".gitignore"), targetBase);
467
456
 
468
457
  const finalMemoryPath = path.join(targetDir, targetBase, "PROJECT_MEMORY.md");
469
458
  initializeMemory(finalMemoryPath, targetBase);
470
459
 
471
- // Deep clean ALL package.json files in target directory (removes workspace: and unocss)
472
460
  deepCleanProtocols(targetDir, targetScope);
473
461
 
474
- // Initialize git if missing
475
462
  if (!fs.existsSync(path.join(targetDir, ".git"))) {
476
463
  try {
477
464
  const { execSync } = await import("child_process");
478
465
  execSync("git init", { cwd: targetDir, stdio: "ignore" });
479
466
  console.log("✅ Git repository initialized.");
480
- } catch (e) {
481
- console.warn("⚠️ Could not initialize git automatically. Please run 'git init' manually.");
482
- }
467
+ } catch (e) {}
483
468
  }
484
469
 
485
- // --- Post-Install Hooks (Smart Setup) ---
486
-
487
470
  console.log("\n🛠️ Running smart configuration for adapters...");
488
471
 
489
- // Universal Gemini Compatibility (Symlink)
490
- try {
491
- const geminiDir = path.join(targetDir, ".gemini");
492
- const geminiAgentsDir = path.join(geminiDir, "agents");
493
- const frameworkAgentsDir = path.join(targetDir, targetBase, "agents");
494
-
495
- if (!fs.existsSync(geminiDir)) {
496
- fs.mkdirSync(geminiDir, { recursive: true });
497
- }
472
+ // Universal Symlink for Gemini compatibility
473
+ if (targetBase !== ".enderun") {
474
+ try {
475
+ const geminiDir = path.join(targetDir, ".enderun");
476
+ if (!fs.existsSync(geminiDir)) fs.mkdirSync(geminiDir, { recursive: true });
477
+
478
+ const geminiAgentsDir = path.join(geminiDir, "agents");
479
+ const frameworkAgentsDir = path.join(targetDir, targetBase, "agents");
480
+ if (!fs.existsSync(geminiAgentsDir)) {
481
+ const relativePath = path.relative(geminiDir, frameworkAgentsDir);
482
+ fs.symlinkSync(relativePath, geminiAgentsDir, "dir");
483
+ console.log(`🔗 Created symlink: .enderun/agents -> ${targetBase}/agents`);
484
+ }
485
+ } catch (e) {}
486
+ }
498
487
 
499
- if (targetBase !== ".gemini" && !fs.existsSync(geminiAgentsDir)) {
500
- const relativePath = path.relative(geminiDir, frameworkAgentsDir);
501
- fs.symlinkSync(relativePath, geminiAgentsDir, "dir");
502
- console.log(`🔗 Omni-Agent: Created symlink from .gemini/agents to ${targetBase}/agents`);
503
- }
504
- } catch (err) {
505
- // Silently ignore if symlink fails (e.g. on non-compatible OS)
488
+ if (selectedAdapter === "gemini") {
489
+ console.log(`💎 Gemini: Adapter GEMINI.md and ${targetBase}/ folder are ready.`);
506
490
  }
507
491
 
508
- if (selectedAdapter === "claude" || !selectedAdapter) {
492
+ if (selectedAdapter === "claude") {
509
493
  const mcpPath = path.join(targetDir, "packages/framework-mcp/src/index.ts");
510
494
  console.log("\n📝 Claude Code Setup:");
511
495
  console.log("To enable Agent Enderun tools in Claude Code, run this command:");
512
496
  console.log(`\x1b[36mclaude config add framework-mcp npx tsx ${mcpPath}\x1b[0m`);
513
497
  }
514
498
 
515
- if (selectedAdapter === "cursor" || !selectedAdapter) {
516
- console.log("✨ Cursor: Adapter CLAUDE.md and ENDERUN.md are ready to guide your AI.");
499
+ if (selectedAdapter === "cursor") {
500
+ const cursorRulesPath = path.join(targetDir, ".cursorrules");
501
+ const cursorMdPath = path.join(targetDir, "CURSOR.md");
502
+ if (fs.existsSync(cursorMdPath) && !fs.existsSync(cursorRulesPath)) {
503
+ fs.copyFileSync(cursorMdPath, cursorRulesPath);
504
+ console.log("🔗 Cursor: Synchronized CURSOR.md to .cursorrules");
505
+ }
517
506
  }
518
507
 
519
508
  const pkgMgr = getPackageManager();
520
- console.log(`\nℹ️ Detected package manager: ${pkgMgr}`);
521
509
  const installCmd = pkgMgr === "npm" ? "npm install" : `${pkgMgr} install`;
522
510
  const buildCmd = pkgMgr === "npm" ? "npm run enderun:build" : `${pkgMgr} run enderun:build`;
523
511
 
524
- console.log("\n✨ Framework scaffolded! (v" + FRAMEWORK_VERSION + ")");
512
+ console.log(`\n✨ Framework scaffolded! (v${FRAMEWORK_VERSION})`);
525
513
 
526
514
  try {
527
515
  const { execSync } = await import("child_process");
528
-
529
516
  console.log(`\n📦 Step 1/3: Running '${installCmd}'...`);
530
517
  execSync(installCmd, { stdio: "inherit" });
531
-
532
518
  console.log(`\n🏗️ Step 2/3: Running '${buildCmd}'...`);
533
519
  execSync(buildCmd, { stdio: "inherit" });
534
-
535
520
  console.log(`\n🔍 Step 3/3: Running 'agent-enderun check'...`);
536
- // Run the health check logic directly
537
- await checkHealth();
538
-
539
- console.log("\n🚀 Agent Enderun is fully installed, built and verified!");
521
+ checkCommand();
522
+ console.log("\n🚀 Agent Enderun is fully installed and verified!");
540
523
  } catch (error) {
541
- console.error("\n❌ Automatic installation failed. Please run manually:");
524
+ console.error("\n❌ Automatic installation failed. Run manually:");
542
525
  console.log(`👉 ${installCmd} && ${buildCmd}`);
543
526
  }
544
527
  }
@@ -593,8 +576,12 @@ function checkCommand() {
593
576
  { name: "Shared Types", path: "packages/shared-types/package.json" },
594
577
  { name: "MCP Server", path: "packages/framework-mcp/package.json" },
595
578
  { name: "Tech Stack", path: path.join(frameworkDir, "docs/tech-stack.md") },
596
- { name: "Requirements", path: "docs/project-docs.md" },
579
+ { name: "Panda CSS Config", path: "panda.config.ts" },
580
+ { name: "Requirements", path: path.join(frameworkDir, "docs/project-docs.md") },
597
581
  { name: "API Registry", path: path.join(frameworkDir, "docs/api/README.md") },
582
+ { name: "Security Policy", path: path.join(frameworkDir, "docs/security.md") },
583
+ { name: "Privacy Policy", path: path.join(frameworkDir, "docs/privacy.md") },
584
+ { name: "Brain Dashboard", path: path.join(frameworkDir, "BRAIN_DASHBOARD.md") },
598
585
  ];
599
586
 
600
587
  for (const check of checks) {
@@ -835,6 +822,156 @@ function verifyContractCommand() {
835
822
  }
836
823
  }
837
824
 
825
+ function securityAuditCommand(targetPath) {
826
+ console.log(`🔍 Running Advanced Security Audit on: ${targetPath}...`);
827
+ const scanRules = [
828
+ { pattern: /sql`/, message: "Potential Raw SQL usage detected", severity: "HIGH" },
829
+ { pattern: /(password|secret|api_?key)\s*[:=]\s*['"][^'"]+['"]/i, message: "Potential hardcoded secret detected", severity: "CRITICAL" },
830
+ { pattern: /:\s*any(?!\w)/, message: "Usage of 'any' type detected", severity: "MEDIUM" },
831
+ { pattern: /\.innerHTML\s*=/, message: "Unsafe innerHTML assignment detected", severity: "MEDIUM" },
832
+ ];
833
+ const issues = [];
834
+ const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx", ".js", ".jsx"]);
835
+ files.forEach(f => {
836
+ const content = fs.readFileSync(f, "utf8");
837
+ const lines = content.split("\n");
838
+ lines.forEach((line, i) => {
839
+ scanRules.forEach(rule => {
840
+ if (rule.pattern.test(line)) {
841
+ issues.push(`[${rule.severity}] ${rule.message} in ${path.relative(targetDir, f)}:${i+1}`);
842
+ }
843
+ });
844
+ });
845
+ });
846
+ if (issues.length === 0) {
847
+ console.log("✅ No security issues detected.");
848
+ } else {
849
+ issues.forEach(issue => console.log(`⚠️ ${issue}`));
850
+ }
851
+ }
852
+
853
+ function complianceCheckCommand(targetPath) {
854
+ console.log(`📜 Checking Constitution Compliance: ${targetPath}...`);
855
+ const violations = [];
856
+ const forbidden = ["@shadcn", "mui", "@chakra-ui", "tailwindcss"];
857
+ const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx", ".js", ".jsx", ".md"]);
858
+ files.forEach(f => {
859
+ const content = fs.readFileSync(f, "utf8");
860
+ forbidden.forEach(lib => {
861
+ if (content.includes(lib)) violations.push(`${path.relative(targetDir, f)}: Forbidden library '${lib}' found.`);
862
+ });
863
+ if (f.endsWith(".ts") && content.includes("interface") && content.match(/ID\s*:\s*string/)) {
864
+ violations.push(`${path.relative(targetDir, f)}: Potential Branded Types violation (ID typed as string).`);
865
+ }
866
+ });
867
+ if (violations.length === 0) {
868
+ console.log("✅ All systems compliant with ENDERUN.md.");
869
+ } else {
870
+ violations.forEach(v => console.log(`❌ ${v}`));
871
+ }
872
+ }
873
+
874
+ function gitCommitCommand(traceId) {
875
+ try {
876
+ const diff = cp.execSync("git diff --staged", { encoding: "utf8" });
877
+ if (!diff) {
878
+ console.log("ℹ️ No staged changes found. Use 'git add' first.");
879
+ return;
880
+ }
881
+ const files = cp.execSync("git diff --staged --name-only", { encoding: "utf8" }).split("\n").filter(Boolean);
882
+ let type = "feat", scope = "code";
883
+ if (files.some(f => f.includes(".md"))) type = "docs";
884
+ else if (files.some(f => f.includes("shared-types"))) type = "arch";
885
+ else if (files.some(f => f.includes("bin/cli.js"))) type = "fix";
886
+
887
+ const summary = files.length === 1 ? `update ${path.basename(files[0])}` : `update ${files.length} files`;
888
+ console.log(`\n### SUGGESTED COMMIT MESSAGE ###\n\n[${traceId}] ${type}(${scope}): ${summary}\n`);
889
+ } catch (e) {
890
+ console.log("❌ Git command failed.");
891
+ }
892
+ }
893
+
894
+ function explorerGraphCommand(targetPath) {
895
+ console.log(`🗺️ Generating Dependency Graph for: ${targetPath}...`);
896
+ const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx"]);
897
+ const edges = [];
898
+ files.forEach(f => {
899
+ const content = fs.readFileSync(f, "utf8");
900
+ const name = path.basename(f, path.extname(f));
901
+ const imports = content.match(/from\s+['"]\.\.?\/[^'"]+['"]/g) || [];
902
+ imports.forEach(imp => {
903
+ const target = path.basename(imp.split(/['"]/)[1]);
904
+ edges.push(`${name} --> ${target}`);
905
+ });
906
+ });
907
+ if (edges.length === 0) {
908
+ console.log("ℹ️ No internal dependencies found.");
909
+ } else {
910
+ console.log("\n```mermaid\ngraph TD\n" + Array.from(new Set(edges)).join("\n") + "\n```\n");
911
+ }
912
+ }
913
+
914
+ function explorerAuditCommand(targetPath) {
915
+ console.log(`🧠 Codebase Intelligence Scan: ${targetPath}...`);
916
+ const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx"]);
917
+ const complexity = [];
918
+ files.forEach(f => {
919
+ const content = fs.readFileSync(f, "utf8");
920
+ const lines = content.split("\n").length;
921
+ if (lines > 300) complexity.push(`${path.relative(targetDir, f)} (${lines} lines)`);
922
+ });
923
+ if (complexity.length > 0) {
924
+ console.log("\n⚠️ Complexity Spikes:");
925
+ complexity.forEach(c => console.log(`- ${c}`));
926
+ } else {
927
+ console.log("✅ Codebase structure looks clean.");
928
+ }
929
+ }
930
+
931
+ function collectFiles(dir, extensions) {
932
+ let results = [];
933
+ if (!fs.existsSync(dir)) return results;
934
+ const list = fs.readdirSync(dir);
935
+ list.forEach(file => {
936
+ file = path.join(dir, file);
937
+ const stat = fs.statSync(file);
938
+ if (stat && stat.isDirectory()) {
939
+ if (!file.includes("node_modules") && !file.includes(".git")) {
940
+ results = results.concat(collectFiles(file, extensions));
941
+ }
942
+ } else {
943
+ if (extensions.includes(path.extname(file))) {
944
+ results.push(file);
945
+ }
946
+ }
947
+ });
948
+ return results;
949
+ }
950
+
951
+ function runScriptCommand(script, projectPath) {
952
+ const fullPath = path.join(targetDir, projectPath);
953
+ if (!fs.existsSync(fullPath)) {
954
+ console.log(`❌ Project path not found: ${projectPath}`);
955
+ return;
956
+ }
957
+ console.log(`🚀 Running 'npm run ${script}' in ${projectPath}...`);
958
+ try {
959
+ cp.spawnSync("npm", ["run", script], { cwd: fullPath, stdio: "inherit", shell: true });
960
+ } catch (e) {
961
+ console.log(`❌ Failed to run script: ${e.message}`);
962
+ }
963
+ }
964
+
965
+ function gitSyncCommand() {
966
+ console.log("🔄 Syncing with remote repository...");
967
+ try {
968
+ cp.execSync("git pull origin main --rebase", { stdio: "inherit" });
969
+ console.log("✅ Successfully synced and rebased.");
970
+ } catch (e) {
971
+ console.log("❌ Sync failed. Please resolve conflicts manually.");
972
+ }
973
+ }
974
+
838
975
  function logAgentActionCommand(data) {
839
976
  const frameworkDir = getFrameworkDir();
840
977
  const logsDir = path.join(targetDir, frameworkDir, "logs");
@@ -921,6 +1058,11 @@ function updateProjectMemoryCommand(section, content) {
921
1058
  async function main() {
922
1059
  const [command, ...args] = process.argv.slice(2);
923
1060
 
1061
+ // Skip header for version and mcp commands to keep output clean
1062
+ if (command !== "version" && command !== "-v" && command !== "--version" && command !== "mcp") {
1063
+ console.log("🤖 Agent Enderun CLI — Initializing...");
1064
+ }
1065
+
924
1066
  switch (command) {
925
1067
  case "init":
926
1068
  await initCommand(args[0]);
@@ -938,6 +1080,19 @@ async function main() {
938
1080
  case "verify-contract":
939
1081
  verifyContractCommand();
940
1082
  break;
1083
+ case "mcp": {
1084
+ const mcpServerPath = path.join(sourceDir, "packages/framework-mcp/dist/index.js");
1085
+ if (fs.existsSync(mcpServerPath)) {
1086
+ const { spawn } = await import("child_process");
1087
+ // Use node to execute the built MCP server
1088
+ const child = spawn("node", [mcpServerPath], { stdio: "inherit" });
1089
+ child.on("exit", (code) => process.exit(code || 0));
1090
+ } else {
1091
+ console.error("❌ MCP Server not built. Run 'npm run enderun:build' first.");
1092
+ process.exit(1);
1093
+ }
1094
+ break;
1095
+ }
941
1096
  case "log_agent_action": {
942
1097
  // Handle both structured JSON and positional args
943
1098
  let data = {};
@@ -978,9 +1133,75 @@ async function main() {
978
1133
  updateProjectMemoryCommand(section, content);
979
1134
  break;
980
1135
  }
1136
+ case "update_knowledge_base": {
1137
+ const topic = args[0];
1138
+ const content = args.slice(1).join(" ");
1139
+ if (!topic || !content) {
1140
+ console.error("❌ Usage: agent-enderun update_knowledge_base <topic> <content>");
1141
+ process.exit(1);
1142
+ }
1143
+ const frameworkDir = getFrameworkDir();
1144
+ const kbDir = path.join(targetDir, frameworkDir, "knowledge");
1145
+ if (!fs.existsSync(kbDir)) fs.mkdirSync(kbDir, { recursive: true });
1146
+ const fileName = topic.replace(/[^a-z0-9]/gi, "_").toLowerCase() + ".md";
1147
+ fs.writeFileSync(path.join(kbDir, fileName), content);
1148
+ console.log(`✅ Knowledge base updated: ${topic}`);
1149
+ break;
1150
+ }
1151
+ case "search_knowledge_base": {
1152
+ const query = args[0];
1153
+ if (!query) {
1154
+ console.error("❌ Usage: agent-enderun search_knowledge_base <query>");
1155
+ process.exit(1);
1156
+ }
1157
+ const frameworkDir = getFrameworkDir();
1158
+ const kbDir = path.join(targetDir, frameworkDir, "knowledge");
1159
+ if (!fs.existsSync(kbDir)) {
1160
+ console.log("ℹ️ Knowledge base is empty.");
1161
+ break;
1162
+ }
1163
+ const files = fs.readdirSync(kbDir).filter(f => f.endsWith(".md"));
1164
+ let found = false;
1165
+ for (const file of files) {
1166
+ const content = fs.readFileSync(path.join(kbDir, file), "utf-8");
1167
+ if (content.toLowerCase().includes(query.toLowerCase()) || file.toLowerCase().includes(query.toLowerCase())) {
1168
+ console.log(`\n### ${file.replace(".md", "")}\n${content.slice(0, 300)}...`);
1169
+ found = true;
1170
+ }
1171
+ }
1172
+ if (!found) console.log("ℹ️ No matching entries found.");
1173
+ break;
1174
+ }
981
1175
  case "check":
982
1176
  checkCommand();
983
1177
  break;
1178
+ case "check:security":
1179
+ securityAuditCommand(args[0] || ".");
1180
+ break;
1181
+ case "check:compliance":
1182
+ complianceCheckCommand(args[0] || ".");
1183
+ break;
1184
+ case "git:commit":
1185
+ gitCommitCommand(args[0] || "TRACE-ID-MISSING");
1186
+ break;
1187
+ case "explorer:graph":
1188
+ explorerGraphCommand(args[0] || ".");
1189
+ break;
1190
+ case "explorer:audit":
1191
+ explorerAuditCommand(args[0] || ".");
1192
+ break;
1193
+ case "frontend:dev":
1194
+ runScriptCommand("dev", "apps/web");
1195
+ break;
1196
+ case "frontend:build":
1197
+ runScriptCommand("build", "apps/web");
1198
+ break;
1199
+ case "mobile:dev":
1200
+ runScriptCommand("start", "apps/mobile");
1201
+ break;
1202
+ case "git:sync":
1203
+ gitSyncCommand();
1204
+ break;
984
1205
  case "version":
985
1206
  case "-v":
986
1207
  case "--version":
@@ -991,12 +1212,18 @@ async function main() {
991
1212
  🤖 Agent Enderun CLI (v${FRAMEWORK_VERSION})
992
1213
 
993
1214
  Available Commands:
994
- init [adapter] Initialize the framework (gemini, claude, cursor, codex)
995
- check Verify framework health and MCP server status
996
- status Show current phase and task status
997
- trace:new <desc> Generate a new Trace ID and add the task to memory
998
- verify-contract Check if shared types match the stored hash
999
- version Show version information
1215
+ init [adapter] Initialize the framework (gemini, claude, cursor, codex)
1216
+ check Full health check
1217
+ check:security Run security audit scan
1218
+ check:compliance Run constitution compliance check
1219
+ status Show current phase and task status
1220
+ trace:new <desc> Generate a new Trace ID
1221
+ verify-contract Check shared types integrity
1222
+ explorer:graph Generate dependency graph
1223
+ explorer:audit Codebase intelligence scan
1224
+ git:commit <id> Suggest semantic commit message
1225
+ mcp Start the MCP server
1226
+ version Show version information
1000
1227
 
1001
1228
  Example:
1002
1229
  agent-enderun trace:new "Auth module design" backend P1
package/package.json CHANGED
@@ -1,23 +1,56 @@
1
1
  {
2
2
  "name": "agent-enderun",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
+ "description": "The Supreme AI Governance & Orchestration Framework for Enterprise Development",
5
+ "author": "Yusuf BEKAR",
6
+ "license": "MIT",
4
7
  "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/ysf-bkr/Agent-Enderun.git"
11
+ },
12
+ "homepage": "https://github.com/ysf-bkr/Agent-Enderun#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/ysf-bkr/Agent-Enderun/issues"
15
+ },
16
+ "keywords": [
17
+ "ai",
18
+ "governance",
19
+ "orchestration",
20
+ "agents",
21
+ "mcp",
22
+ "typescript",
23
+ "framework"
24
+ ],
5
25
  "workspaces": [
6
26
  "packages/*"
7
27
  ],
8
28
  "bin": {
9
29
  "agent-enderun": "bin/cli.js"
10
30
  },
31
+ "files": [
32
+ "bin",
33
+ "packages",
34
+ ".enderun",
35
+ "ENDERUN.md",
36
+ "README.md",
37
+ "LICENSE",
38
+ "mcp.json",
39
+ ".env.example"
40
+ ],
11
41
  "scripts": {
12
42
  "enderun:build": "npm run build --prefix packages/shared-types && npm run build --prefix packages/framework-mcp",
13
43
  "enderun:status": "agent-enderun status",
14
44
  "enderun:trace": "agent-enderun trace:new",
15
45
  "enderun:verify": "agent-enderun verify-contract"
16
46
  },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
17
50
  "dependencies": {},
18
51
  "devDependencies": {},
19
52
  "enderun": {
20
- "version": "0.1.9",
53
+ "version": "0.2.0",
21
54
  "initializedAt": "2026-05-09T13:24:27.472Z"
22
55
  }
23
56
  }