agent-enderun 0.1.10 → 0.2.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.
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 +292 -79
  52. package/package.json +42 -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.json +1 -1
  70. package/packages/framework-mcp/src/index.ts +20 -970
  71. package/packages/framework-mcp/src/schemas.ts +106 -0
  72. package/packages/framework-mcp/src/tools/academy.ts +178 -0
  73. package/packages/framework-mcp/src/tools/codebase.ts +284 -0
  74. package/packages/framework-mcp/src/tools/contract.ts +91 -0
  75. package/packages/framework-mcp/src/tools/database.ts +49 -0
  76. package/packages/framework-mcp/src/tools/framework.ts +157 -0
  77. package/packages/framework-mcp/src/tools/git.ts +43 -0
  78. package/packages/framework-mcp/src/tools/index.ts +45 -0
  79. package/packages/framework-mcp/src/tools/knowledge.ts +68 -0
  80. package/packages/framework-mcp/src/tools/memory.ts +88 -0
  81. package/packages/framework-mcp/src/tools/messages.ts +70 -0
  82. package/packages/framework-mcp/src/tools/repository.ts +76 -0
  83. package/packages/framework-mcp/src/tools/security.ts +122 -0
  84. package/packages/framework-mcp/src/utils.ts +90 -0
  85. package/packages/shared-types/README.md +28 -51
  86. package/packages/shared-types/dist/index.d.ts +80 -48
  87. package/packages/shared-types/dist/index.d.ts.map +1 -1
  88. package/packages/shared-types/dist/index.js +5 -8
  89. package/packages/shared-types/dist/index.js.map +1 -1
  90. package/packages/shared-types/package.json +1 -1
  91. package/packages/shared-types/src/index.ts +79 -51
  92. package/CHANGELOG.md +0 -97
  93. package/CLAUDE.md +0 -7
  94. package/CODEX.md +0 -7
  95. package/CURSOR.md +0 -7
  96. package/GEMINI.md +0 -7
  97. package/docs/tech-stack.md +0 -10
  98. package/gemini-extension.json +0 -5
  99. package/packages/framework-mcp/tsconfig.json +0 -15
  100. package/packages/shared-types/contract.version.json +0 -9
  101. package/packages/shared-types/tsconfig.json +0 -17
  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,63 @@ 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
472
 
495
- if (!fs.existsSync(geminiDir)) {
496
- fs.mkdirSync(geminiDir, { recursive: true });
497
- }
498
-
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)
473
+ if (selectedAdapter === "gemini") {
474
+ console.log(`💎 Gemini: Adapter GEMINI.md and ${targetBase}/ folder are ready.`);
506
475
  }
507
476
 
508
- if (selectedAdapter === "claude" || !selectedAdapter) {
477
+ if (selectedAdapter === "claude") {
509
478
  const mcpPath = path.join(targetDir, "packages/framework-mcp/src/index.ts");
510
479
  console.log("\n📝 Claude Code Setup:");
511
480
  console.log("To enable Agent Enderun tools in Claude Code, run this command:");
512
481
  console.log(`\x1b[36mclaude config add framework-mcp npx tsx ${mcpPath}\x1b[0m`);
513
482
  }
514
483
 
515
- if (selectedAdapter === "cursor" || !selectedAdapter) {
516
- console.log("✨ Cursor: Adapter CLAUDE.md and ENDERUN.md are ready to guide your AI.");
484
+ if (selectedAdapter === "cursor") {
485
+ const cursorRulesPath = path.join(targetDir, ".cursorrules");
486
+ const cursorMdPath = path.join(targetDir, "CURSOR.md");
487
+ if (fs.existsSync(cursorMdPath) && !fs.existsSync(cursorRulesPath)) {
488
+ fs.copyFileSync(cursorMdPath, cursorRulesPath);
489
+ console.log("🔗 Cursor: Synchronized CURSOR.md to .cursorrules");
490
+ }
517
491
  }
518
492
 
519
493
  const pkgMgr = getPackageManager();
520
- console.log(`\nℹ️ Detected package manager: ${pkgMgr}`);
521
494
  const installCmd = pkgMgr === "npm" ? "npm install" : `${pkgMgr} install`;
522
495
  const buildCmd = pkgMgr === "npm" ? "npm run enderun:build" : `${pkgMgr} run enderun:build`;
523
496
 
524
- console.log("\n✨ Framework scaffolded! (v" + FRAMEWORK_VERSION + ")");
497
+ console.log(`\n✨ Framework scaffolded! (v${FRAMEWORK_VERSION})`);
525
498
 
526
499
  try {
527
500
  const { execSync } = await import("child_process");
528
-
529
501
  console.log(`\n📦 Step 1/3: Running '${installCmd}'...`);
530
502
  execSync(installCmd, { stdio: "inherit" });
531
-
532
503
  console.log(`\n🏗️ Step 2/3: Running '${buildCmd}'...`);
533
504
  execSync(buildCmd, { stdio: "inherit" });
534
-
535
505
  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!");
506
+ checkCommand();
507
+ console.log("\n🚀 Agent Enderun is fully installed and verified!");
540
508
  } catch (error) {
541
- console.error("\n❌ Automatic installation failed. Please run manually:");
509
+ console.error("\n❌ Automatic installation failed. Run manually:");
542
510
  console.log(`👉 ${installCmd} && ${buildCmd}`);
543
511
  }
544
512
  }
@@ -593,8 +561,12 @@ function checkCommand() {
593
561
  { name: "Shared Types", path: "packages/shared-types/package.json" },
594
562
  { name: "MCP Server", path: "packages/framework-mcp/package.json" },
595
563
  { name: "Tech Stack", path: path.join(frameworkDir, "docs/tech-stack.md") },
596
- { name: "Requirements", path: "docs/project-docs.md" },
564
+ { name: "Panda CSS Config", path: "panda.config.ts" },
565
+ { name: "Requirements", path: path.join(frameworkDir, "docs/project-docs.md") },
597
566
  { name: "API Registry", path: path.join(frameworkDir, "docs/api/README.md") },
567
+ { name: "Security Policy", path: path.join(frameworkDir, "docs/security.md") },
568
+ { name: "Privacy Policy", path: path.join(frameworkDir, "docs/privacy.md") },
569
+ { name: "Brain Dashboard", path: path.join(frameworkDir, "BRAIN_DASHBOARD.md") },
598
570
  ];
599
571
 
600
572
  for (const check of checks) {
@@ -637,6 +609,7 @@ function checkCommand() {
637
609
  console.log("\n🚀 All systems green! Agent Enderun is ready for orchestration.");
638
610
  } else {
639
611
  console.log(`\n⚠️ Found ${issues} issues. Please fix them before starting.`);
612
+ process.exit(1);
640
613
  }
641
614
  }
642
615
 
@@ -835,6 +808,156 @@ function verifyContractCommand() {
835
808
  }
836
809
  }
837
810
 
811
+ function securityAuditCommand(targetPath) {
812
+ console.log(`🔍 Running Advanced Security Audit on: ${targetPath}...`);
813
+ const scanRules = [
814
+ { pattern: /sql`/, message: "Potential Raw SQL usage detected", severity: "HIGH" },
815
+ { pattern: /(password|secret|api_?key)\s*[:=]\s*['"][^'"]+['"]/i, message: "Potential hardcoded secret detected", severity: "CRITICAL" },
816
+ { pattern: /:\s*any(?!\w)/, message: "Usage of 'any' type detected", severity: "MEDIUM" },
817
+ { pattern: /\.innerHTML\s*=/, message: "Unsafe innerHTML assignment detected", severity: "MEDIUM" },
818
+ ];
819
+ const issues = [];
820
+ const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx", ".js", ".jsx"]);
821
+ files.forEach(f => {
822
+ const content = fs.readFileSync(f, "utf8");
823
+ const lines = content.split("\n");
824
+ lines.forEach((line, i) => {
825
+ scanRules.forEach(rule => {
826
+ if (rule.pattern.test(line)) {
827
+ issues.push(`[${rule.severity}] ${rule.message} in ${path.relative(targetDir, f)}:${i+1}`);
828
+ }
829
+ });
830
+ });
831
+ });
832
+ if (issues.length === 0) {
833
+ console.log("✅ No security issues detected.");
834
+ } else {
835
+ issues.forEach(issue => console.log(`⚠️ ${issue}`));
836
+ }
837
+ }
838
+
839
+ function complianceCheckCommand(targetPath) {
840
+ console.log(`📜 Checking Constitution Compliance: ${targetPath}...`);
841
+ const violations = [];
842
+ const forbidden = ["@shadcn", "mui", "@chakra-ui", "tailwindcss"];
843
+ const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx", ".js", ".jsx", ".md"]);
844
+ files.forEach(f => {
845
+ const content = fs.readFileSync(f, "utf8");
846
+ forbidden.forEach(lib => {
847
+ if (content.includes(lib)) violations.push(`${path.relative(targetDir, f)}: Forbidden library '${lib}' found.`);
848
+ });
849
+ if (f.endsWith(".ts") && content.includes("interface") && content.match(/ID\s*:\s*string/)) {
850
+ violations.push(`${path.relative(targetDir, f)}: Potential Branded Types violation (ID typed as string).`);
851
+ }
852
+ });
853
+ if (violations.length === 0) {
854
+ console.log("✅ All systems compliant with ENDERUN.md.");
855
+ } else {
856
+ violations.forEach(v => console.log(`❌ ${v}`));
857
+ }
858
+ }
859
+
860
+ function gitCommitCommand(traceId) {
861
+ try {
862
+ const diff = cp.execSync("git diff --staged", { encoding: "utf8" });
863
+ if (!diff) {
864
+ console.log("ℹ️ No staged changes found. Use 'git add' first.");
865
+ return;
866
+ }
867
+ const files = cp.execSync("git diff --staged --name-only", { encoding: "utf8" }).split("\n").filter(Boolean);
868
+ let type = "feat", scope = "code";
869
+ if (files.some(f => f.includes(".md"))) type = "docs";
870
+ else if (files.some(f => f.includes("shared-types"))) type = "arch";
871
+ else if (files.some(f => f.includes("bin/cli.js"))) type = "fix";
872
+
873
+ const summary = files.length === 1 ? `update ${path.basename(files[0])}` : `update ${files.length} files`;
874
+ console.log(`\n### SUGGESTED COMMIT MESSAGE ###\n\n[${traceId}] ${type}(${scope}): ${summary}\n`);
875
+ } catch (e) {
876
+ console.log("❌ Git command failed.");
877
+ }
878
+ }
879
+
880
+ function explorerGraphCommand(targetPath) {
881
+ console.log(`🗺️ Generating Dependency Graph for: ${targetPath}...`);
882
+ const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx"]);
883
+ const edges = [];
884
+ files.forEach(f => {
885
+ const content = fs.readFileSync(f, "utf8");
886
+ const name = path.basename(f, path.extname(f));
887
+ const imports = content.match(/from\s+['"]\.\.?\/[^'"]+['"]/g) || [];
888
+ imports.forEach(imp => {
889
+ const target = path.basename(imp.split(/['"]/)[1]);
890
+ edges.push(`${name} --> ${target}`);
891
+ });
892
+ });
893
+ if (edges.length === 0) {
894
+ console.log("ℹ️ No internal dependencies found.");
895
+ } else {
896
+ console.log("\n```mermaid\ngraph TD\n" + Array.from(new Set(edges)).join("\n") + "\n```\n");
897
+ }
898
+ }
899
+
900
+ function explorerAuditCommand(targetPath) {
901
+ console.log(`🧠 Codebase Intelligence Scan: ${targetPath}...`);
902
+ const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx"]);
903
+ const complexity = [];
904
+ files.forEach(f => {
905
+ const content = fs.readFileSync(f, "utf8");
906
+ const lines = content.split("\n").length;
907
+ if (lines > 300) complexity.push(`${path.relative(targetDir, f)} (${lines} lines)`);
908
+ });
909
+ if (complexity.length > 0) {
910
+ console.log("\n⚠️ Complexity Spikes:");
911
+ complexity.forEach(c => console.log(`- ${c}`));
912
+ } else {
913
+ console.log("✅ Codebase structure looks clean.");
914
+ }
915
+ }
916
+
917
+ function collectFiles(dir, extensions) {
918
+ let results = [];
919
+ if (!fs.existsSync(dir)) return results;
920
+ const list = fs.readdirSync(dir);
921
+ list.forEach(file => {
922
+ file = path.join(dir, file);
923
+ const stat = fs.statSync(file);
924
+ if (stat && stat.isDirectory()) {
925
+ if (!file.includes("node_modules") && !file.includes(".git")) {
926
+ results = results.concat(collectFiles(file, extensions));
927
+ }
928
+ } else {
929
+ if (extensions.includes(path.extname(file))) {
930
+ results.push(file);
931
+ }
932
+ }
933
+ });
934
+ return results;
935
+ }
936
+
937
+ function runScriptCommand(script, projectPath) {
938
+ const fullPath = path.join(targetDir, projectPath);
939
+ if (!fs.existsSync(fullPath)) {
940
+ console.log(`❌ Project path not found: ${projectPath}`);
941
+ return;
942
+ }
943
+ console.log(`🚀 Running 'npm run ${script}' in ${projectPath}...`);
944
+ try {
945
+ cp.spawnSync("npm", ["run", script], { cwd: fullPath, stdio: "inherit", shell: true });
946
+ } catch (e) {
947
+ console.log(`❌ Failed to run script: ${e.message}`);
948
+ }
949
+ }
950
+
951
+ function gitSyncCommand() {
952
+ console.log("🔄 Syncing with remote repository...");
953
+ try {
954
+ cp.execSync("git pull origin main --rebase", { stdio: "inherit" });
955
+ console.log("✅ Successfully synced and rebased.");
956
+ } catch (e) {
957
+ console.log("❌ Sync failed. Please resolve conflicts manually.");
958
+ }
959
+ }
960
+
838
961
  function logAgentActionCommand(data) {
839
962
  const frameworkDir = getFrameworkDir();
840
963
  const logsDir = path.join(targetDir, frameworkDir, "logs");
@@ -921,6 +1044,11 @@ function updateProjectMemoryCommand(section, content) {
921
1044
  async function main() {
922
1045
  const [command, ...args] = process.argv.slice(2);
923
1046
 
1047
+ // Skip header for version and mcp commands to keep output clean
1048
+ if (command !== "version" && command !== "-v" && command !== "--version" && command !== "mcp") {
1049
+ console.log("🤖 Agent Enderun CLI — Initializing...");
1050
+ }
1051
+
924
1052
  switch (command) {
925
1053
  case "init":
926
1054
  await initCommand(args[0]);
@@ -938,6 +1066,19 @@ async function main() {
938
1066
  case "verify-contract":
939
1067
  verifyContractCommand();
940
1068
  break;
1069
+ case "mcp": {
1070
+ const mcpServerPath = path.join(sourceDir, "packages/framework-mcp/dist/index.js");
1071
+ if (fs.existsSync(mcpServerPath)) {
1072
+ const { spawn } = await import("child_process");
1073
+ // Use node to execute the built MCP server
1074
+ const child = spawn("node", [mcpServerPath], { stdio: "inherit" });
1075
+ child.on("exit", (code) => process.exit(code || 0));
1076
+ } else {
1077
+ console.error("❌ MCP Server not built. Run 'npm run enderun:build' first.");
1078
+ process.exit(1);
1079
+ }
1080
+ break;
1081
+ }
941
1082
  case "log_agent_action": {
942
1083
  // Handle both structured JSON and positional args
943
1084
  let data = {};
@@ -978,9 +1119,75 @@ async function main() {
978
1119
  updateProjectMemoryCommand(section, content);
979
1120
  break;
980
1121
  }
1122
+ case "update_knowledge_base": {
1123
+ const topic = args[0];
1124
+ const content = args.slice(1).join(" ");
1125
+ if (!topic || !content) {
1126
+ console.error("❌ Usage: agent-enderun update_knowledge_base <topic> <content>");
1127
+ process.exit(1);
1128
+ }
1129
+ const frameworkDir = getFrameworkDir();
1130
+ const kbDir = path.join(targetDir, frameworkDir, "knowledge");
1131
+ if (!fs.existsSync(kbDir)) fs.mkdirSync(kbDir, { recursive: true });
1132
+ const fileName = topic.replace(/[^a-z0-9]/gi, "_").toLowerCase() + ".md";
1133
+ fs.writeFileSync(path.join(kbDir, fileName), content);
1134
+ console.log(`✅ Knowledge base updated: ${topic}`);
1135
+ break;
1136
+ }
1137
+ case "search_knowledge_base": {
1138
+ const query = args[0];
1139
+ if (!query) {
1140
+ console.error("❌ Usage: agent-enderun search_knowledge_base <query>");
1141
+ process.exit(1);
1142
+ }
1143
+ const frameworkDir = getFrameworkDir();
1144
+ const kbDir = path.join(targetDir, frameworkDir, "knowledge");
1145
+ if (!fs.existsSync(kbDir)) {
1146
+ console.log("ℹ️ Knowledge base is empty.");
1147
+ break;
1148
+ }
1149
+ const files = fs.readdirSync(kbDir).filter(f => f.endsWith(".md"));
1150
+ let found = false;
1151
+ for (const file of files) {
1152
+ const content = fs.readFileSync(path.join(kbDir, file), "utf-8");
1153
+ if (content.toLowerCase().includes(query.toLowerCase()) || file.toLowerCase().includes(query.toLowerCase())) {
1154
+ console.log(`\n### ${file.replace(".md", "")}\n${content.slice(0, 300)}...`);
1155
+ found = true;
1156
+ }
1157
+ }
1158
+ if (!found) console.log("ℹ️ No matching entries found.");
1159
+ break;
1160
+ }
981
1161
  case "check":
982
1162
  checkCommand();
983
1163
  break;
1164
+ case "check:security":
1165
+ securityAuditCommand(args[0] || ".");
1166
+ break;
1167
+ case "check:compliance":
1168
+ complianceCheckCommand(args[0] || ".");
1169
+ break;
1170
+ case "git:commit":
1171
+ gitCommitCommand(args[0] || "TRACE-ID-MISSING");
1172
+ break;
1173
+ case "explorer:graph":
1174
+ explorerGraphCommand(args[0] || ".");
1175
+ break;
1176
+ case "explorer:audit":
1177
+ explorerAuditCommand(args[0] || ".");
1178
+ break;
1179
+ case "frontend:dev":
1180
+ runScriptCommand("dev", "apps/web");
1181
+ break;
1182
+ case "frontend:build":
1183
+ runScriptCommand("build", "apps/web");
1184
+ break;
1185
+ case "mobile:dev":
1186
+ runScriptCommand("start", "apps/mobile");
1187
+ break;
1188
+ case "git:sync":
1189
+ gitSyncCommand();
1190
+ break;
984
1191
  case "version":
985
1192
  case "-v":
986
1193
  case "--version":
@@ -991,12 +1198,18 @@ async function main() {
991
1198
  🤖 Agent Enderun CLI (v${FRAMEWORK_VERSION})
992
1199
 
993
1200
  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
1201
+ init [adapter] Initialize the framework (gemini, claude, cursor, codex)
1202
+ check Full health check
1203
+ check:security Run security audit scan
1204
+ check:compliance Run constitution compliance check
1205
+ status Show current phase and task status
1206
+ trace:new <desc> Generate a new Trace ID
1207
+ verify-contract Check shared types integrity
1208
+ explorer:graph Generate dependency graph
1209
+ explorer:audit Codebase intelligence scan
1210
+ git:commit <id> Suggest semantic commit message
1211
+ mcp Start the MCP server
1212
+ version Show version information
1000
1213
 
1001
1214
  Example:
1002
1215
  agent-enderun trace:new "Auth module design" backend P1
package/package.json CHANGED
@@ -1,23 +1,63 @@
1
1
  {
2
2
  "name": "agent-enderun",
3
- "version": "0.1.10",
3
+ "version": "0.2.1",
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/shared-types/dist",
34
+ "packages/shared-types/src",
35
+ "packages/shared-types/package.json",
36
+ "packages/shared-types/README.md",
37
+ "packages/framework-mcp/dist",
38
+ "packages/framework-mcp/src",
39
+ "packages/framework-mcp/package.json",
40
+ "packages/framework-mcp/README.md",
41
+ ".enderun",
42
+ "ENDERUN.md",
43
+ "README.md",
44
+ "LICENSE",
45
+ "mcp.json",
46
+ ".env.example"
47
+ ],
11
48
  "scripts": {
12
49
  "enderun:build": "npm run build --prefix packages/shared-types && npm run build --prefix packages/framework-mcp",
13
50
  "enderun:status": "agent-enderun status",
14
51
  "enderun:trace": "agent-enderun trace:new",
15
52
  "enderun:verify": "agent-enderun verify-contract"
16
53
  },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
17
57
  "dependencies": {},
18
58
  "devDependencies": {},
19
59
  "enderun": {
20
- "version": "0.1.10",
60
+ "version": "0.2.1",
21
61
  "initializedAt": "2026-05-09T13:24:27.472Z"
22
62
  }
23
63
  }