agent-enderun 1.10.4 → 1.11.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 (183) hide show
  1. package/README.md +34 -45
  2. package/dist/framework-mcp/tests/tools/quality/check_lint.test.js +1 -1
  3. package/dist/framework-mcp/tests/tools/quality/check_lint.test.js.map +1 -1
  4. package/dist/src/cli/adapters/core.d.ts +1 -1
  5. package/dist/src/cli/adapters/core.js +0 -1
  6. package/dist/src/cli/adapters/core.js.map +1 -1
  7. package/dist/src/cli/adapters/index.d.ts +1 -0
  8. package/dist/src/cli/adapters/index.js +1 -0
  9. package/dist/src/cli/adapters/index.js.map +1 -1
  10. package/dist/src/cli/adapters/scaffold.d.ts +1 -1
  11. package/dist/src/cli/adapters/scaffold.js +8 -6
  12. package/dist/src/cli/adapters/scaffold.js.map +1 -1
  13. package/dist/src/cli/commands/init/scaffold-core.d.ts +5 -2
  14. package/dist/src/cli/commands/init/scaffold-core.js +28 -6
  15. package/dist/src/cli/commands/init/scaffold-core.js.map +1 -1
  16. package/dist/src/cli/commands/init.js +31 -4
  17. package/dist/src/cli/commands/init.js.map +1 -1
  18. package/dist/src/cli/commands/orchestrate.d.ts +6 -6
  19. package/dist/src/cli/commands/plan.d.ts +3 -1
  20. package/dist/src/cli/commands/plan.js +79 -22
  21. package/dist/src/cli/commands/plan.js.map +1 -1
  22. package/dist/src/cli/index.js +11 -15
  23. package/dist/src/cli/index.js.map +1 -1
  24. package/dist/src/cli/utils/compliance.js +0 -1
  25. package/dist/src/cli/utils/compliance.js.map +1 -1
  26. package/dist/src/cli/utils/config-schema.d.ts +7 -7
  27. package/dist/src/cli/utils/pkg.d.ts +19 -0
  28. package/dist/src/cli/utils/pkg.js +29 -5
  29. package/dist/src/cli/utils/pkg.js.map +1 -1
  30. package/dist/src/modules/agents/registry/analyst.js +1 -1
  31. package/dist/src/modules/agents/registry/analyst.js.map +1 -1
  32. package/dist/src/modules/agents/registry/backend.js +5 -4
  33. package/dist/src/modules/agents/registry/backend.js.map +1 -1
  34. package/dist/src/modules/agents/registry/database.js +2 -1
  35. package/dist/src/modules/agents/registry/database.js.map +1 -1
  36. package/dist/src/modules/agents/registry/git.js +1 -1
  37. package/dist/src/modules/agents/registry/git.js.map +1 -1
  38. package/dist/src/modules/agents/registry/manager.js +3 -2
  39. package/dist/src/modules/agents/registry/manager.js.map +1 -1
  40. package/dist/src/modules/agents/registry/native.js +1 -1
  41. package/dist/src/modules/agents/registry/native.js.map +1 -1
  42. package/dist/src/modules/agents/registry/security.js +1 -0
  43. package/dist/src/modules/agents/registry/security.js.map +1 -1
  44. package/dist/tests/approve.test.js +4 -9
  45. package/dist/tests/approve.test.js.map +1 -1
  46. package/framework-mcp/dist/constants.js +64 -0
  47. package/framework-mcp/dist/index.js +109 -0
  48. package/framework-mcp/dist/tools/control_plane/locking.js +64 -0
  49. package/framework-mcp/dist/tools/control_plane/registry.js +34 -0
  50. package/framework-mcp/dist/tools/dashboard/start_dashboard.js +29 -0
  51. package/framework-mcp/dist/tools/definitions.js +300 -0
  52. package/framework-mcp/dist/tools/file_system/batch_surgical_edit.js +59 -0
  53. package/framework-mcp/dist/tools/file_system/patch_file.js +25 -0
  54. package/framework-mcp/dist/tools/file_system/read_file.js +51 -0
  55. package/framework-mcp/dist/tools/file_system/replace_text.js +43 -0
  56. package/framework-mcp/dist/tools/file_system/write_file.js +38 -0
  57. package/framework-mcp/dist/tools/framework/audit_deps.js +41 -0
  58. package/framework-mcp/dist/tools/framework/get_status.js +5 -0
  59. package/framework-mcp/dist/tools/framework/orchestrate.js +5 -0
  60. package/framework-mcp/dist/tools/framework/run_tests.js +25 -0
  61. package/framework-mcp/dist/tools/framework/update_contract_hash.js +5 -0
  62. package/framework-mcp/dist/tools/framework/update_memory.js +8 -0
  63. package/framework-mcp/dist/tools/index.js +62 -0
  64. package/framework-mcp/dist/tools/memory/get_insights.js +34 -0
  65. package/framework-mcp/dist/tools/memory/read_memory.js +28 -0
  66. package/framework-mcp/dist/tools/messaging/log_action.js +22 -0
  67. package/framework-mcp/dist/tools/messaging/send_message.js +87 -0
  68. package/framework-mcp/dist/tools/observability/check_ports.js +26 -0
  69. package/framework-mcp/dist/tools/observability/get_health.js +19 -0
  70. package/framework-mcp/dist/tools/quality/check_lint.js +28 -0
  71. package/framework-mcp/dist/tools/search/get_gaps.js +48 -0
  72. package/framework-mcp/dist/tools/search/get_map.js +43 -0
  73. package/framework-mcp/dist/tools/search/grep_search.js +76 -0
  74. package/framework-mcp/dist/tools/search/list_dir.js +28 -0
  75. package/framework-mcp/dist/tools/shell/run_command.js +46 -0
  76. package/framework-mcp/dist/tools/types.js +1 -0
  77. package/framework-mcp/dist/utils/cli.js +20 -0
  78. package/framework-mcp/dist/utils/compliance.js +29 -0
  79. package/framework-mcp/dist/utils/fs.js +44 -0
  80. package/framework-mcp/dist/utils/metrics.js +56 -0
  81. package/framework-mcp/dist/utils/security.js +60 -0
  82. package/framework-mcp/package.json +19 -0
  83. package/framework-mcp/src/constants.ts +78 -0
  84. package/framework-mcp/src/declarations.d.ts +17 -0
  85. package/framework-mcp/src/index.ts +132 -0
  86. package/framework-mcp/src/tools/control_plane/locking.ts +71 -0
  87. package/framework-mcp/src/tools/control_plane/registry.ts +38 -0
  88. package/framework-mcp/src/tools/dashboard/start_dashboard.ts +33 -0
  89. package/framework-mcp/src/tools/definitions.ts +302 -0
  90. package/framework-mcp/src/tools/file_system/batch_surgical_edit.ts +79 -0
  91. package/framework-mcp/src/tools/file_system/patch_file.ts +33 -0
  92. package/framework-mcp/src/tools/file_system/read_file.ts +58 -0
  93. package/framework-mcp/src/tools/file_system/replace_text.ts +52 -0
  94. package/framework-mcp/src/tools/file_system/write_file.ts +45 -0
  95. package/framework-mcp/src/tools/framework/audit_deps.ts +49 -0
  96. package/framework-mcp/src/tools/framework/get_status.ts +7 -0
  97. package/framework-mcp/src/tools/framework/orchestrate.ts +7 -0
  98. package/framework-mcp/src/tools/framework/run_tests.ts +28 -0
  99. package/framework-mcp/src/tools/framework/update_contract_hash.ts +7 -0
  100. package/framework-mcp/src/tools/framework/update_memory.ts +10 -0
  101. package/framework-mcp/src/tools/index.ts +66 -0
  102. package/framework-mcp/src/tools/memory/get_insights.ts +41 -0
  103. package/framework-mcp/src/tools/memory/read_memory.ts +31 -0
  104. package/framework-mcp/src/tools/messaging/log_action.ts +28 -0
  105. package/framework-mcp/src/tools/messaging/send_message.ts +89 -0
  106. package/framework-mcp/src/tools/observability/check_ports.ts +30 -0
  107. package/framework-mcp/src/tools/observability/get_health.ts +24 -0
  108. package/framework-mcp/src/tools/quality/check_lint.ts +33 -0
  109. package/framework-mcp/src/tools/search/get_gaps.ts +54 -0
  110. package/framework-mcp/src/tools/search/get_map.ts +48 -0
  111. package/framework-mcp/src/tools/search/grep_search.ts +76 -0
  112. package/framework-mcp/src/tools/search/list_dir.ts +34 -0
  113. package/framework-mcp/src/tools/shell/run_command.ts +56 -0
  114. package/framework-mcp/src/tools/types.ts +89 -0
  115. package/framework-mcp/src/utils/cli.ts +20 -0
  116. package/framework-mcp/src/utils/compliance.ts +37 -0
  117. package/framework-mcp/src/utils/fs.ts +45 -0
  118. package/framework-mcp/src/utils/metrics.ts +73 -0
  119. package/framework-mcp/src/utils/security.ts +66 -0
  120. package/framework-mcp/tests/tools/file_system/file_system_tools.test.ts +212 -0
  121. package/framework-mcp/tests/tools/messaging/send_message.test.ts +136 -0
  122. package/framework-mcp/tests/tools/quality/check_lint.test.ts +46 -0
  123. package/framework-mcp/tests/tools/shell/run_command.test.ts +55 -0
  124. package/framework-mcp/tsconfig.json +14 -0
  125. package/package.json +5 -3
  126. package/src/cli/adapters/core.ts +2 -3
  127. package/src/cli/adapters/index.ts +1 -0
  128. package/src/cli/adapters/scaffold.ts +15 -6
  129. package/src/cli/commands/init/scaffold-core.ts +45 -6
  130. package/src/cli/commands/init.ts +31 -2
  131. package/src/cli/commands/plan.ts +89 -23
  132. package/src/cli/index.ts +14 -19
  133. package/src/cli/utils/compliance.ts +8 -9
  134. package/src/cli/utils/pkg.ts +42 -13
  135. package/src/modules/agents/registry/analyst.ts +1 -1
  136. package/src/modules/agents/registry/backend.ts +5 -4
  137. package/src/modules/agents/registry/database.ts +2 -1
  138. package/src/modules/agents/registry/git.ts +1 -1
  139. package/src/modules/agents/registry/manager.ts +3 -2
  140. package/src/modules/agents/registry/native.ts +1 -1
  141. package/src/modules/agents/registry/security.ts +1 -0
  142. package/templates/prompts/bug-fix-recipe.md +20 -0
  143. package/templates/prompts/contract-design-recipe.md +21 -0
  144. package/templates/prompts/db-management-recipe.md +25 -0
  145. package/templates/prompts/deployment-recipe.md +23 -0
  146. package/templates/prompts/new-feature-recipe.md +19 -0
  147. package/templates/prompts/performance-optimization-recipe.md +23 -0
  148. package/templates/prompts/pull-request-template.md +21 -0
  149. package/templates/prompts/refactoring-recipe.md +21 -0
  150. package/templates/prompts/security-audit-recipe.md +20 -0
  151. package/templates/standards/architecture-standards.md +23 -0
  152. package/templates/standards/auth-standards.md +125 -0
  153. package/templates/standards/crud-governance.md +21 -0
  154. package/templates/standards/deployment-standards.md +21 -0
  155. package/templates/standards/frontend-standards.md +37 -0
  156. package/templates/standards/github-actions-standards.md +43 -0
  157. package/templates/standards/i18n-standards.md +17 -0
  158. package/templates/standards/kysely-standards.md +47 -0
  159. package/templates/standards/llm-governance.md +15 -0
  160. package/templates/standards/logging-and-secrets.md +34 -0
  161. package/templates/standards/mobile-standards.md +23 -0
  162. package/templates/standards/observability-standards.md +15 -0
  163. package/templates/standards/performance-standards.md +15 -0
  164. package/templates/standards/pino-standards.md +46 -0
  165. package/templates/standards/playwright-standards.md +54 -0
  166. package/templates/standards/quality-standards.md +31 -0
  167. package/templates/standards/react-query-standards.md +72 -0
  168. package/templates/standards/react-router-standards.md +62 -0
  169. package/templates/standards/security-audit-standards.md +16 -0
  170. package/templates/standards/security-standards.md +21 -0
  171. package/templates/standards/swagger-standards.md +50 -0
  172. package/templates/standards/tailwind-standards.md +20 -0
  173. package/templates/standards/testing-standards.md +31 -0
  174. package/templates/standards/typeorm-standards.md +49 -0
  175. package/templates/standards/vitest-standards.md +110 -0
  176. package/src/cli/commands/app.ts +0 -56
  177. package/src/cli/utils/app-backend.ts +0 -257
  178. package/src/cli/utils/app-docs.ts +0 -83
  179. package/src/cli/utils/app-frontend.ts +0 -263
  180. package/src/cli/utils/app-inferrer.ts +0 -63
  181. package/src/cli/utils/app-mobile.ts +0 -113
  182. package/src/cli/utils/app-types.ts +0 -248
  183. package/src/cli/utils/app.ts +0 -6
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import { handleCheckLint } from "../../../src/tools/quality/check_lint.js";
3
+ import { exec } from "child_process";
4
+
5
+ vi.mock("child_process");
6
+
7
+ describe("handleCheckLint", () => {
8
+ const projectRoot = "/fake/project";
9
+
10
+ afterEach(() => {
11
+ vi.clearAllMocks();
12
+ });
13
+
14
+ it("should execute the lint command and return output on success", async () => {
15
+ const args = {};
16
+
17
+ vi.mocked(exec).mockImplementation((_cmd, _opts, callback) => {
18
+ // @ts-expect-error: Mock implementation callback type is complex
19
+ callback(null, "All good!", "");
20
+ return {} as any;
21
+ });
22
+
23
+ const result = await handleCheckLint(projectRoot, args);
24
+
25
+ expect(exec).toHaveBeenCalledWith("npm run lint", { cwd: projectRoot, timeout: 60000 }, expect.any(Function));
26
+ expect(result.isError).toBeUndefined();
27
+ expect(result.content[0].text).toContain("All good!");
28
+ });
29
+
30
+ it("should execute the lint command and return output on failure (lint issues found)", async () => {
31
+ const args = {};
32
+ const lintErrorOutput = "Error: 2 problems (2 errors, 0 warnings)";
33
+
34
+ vi.mocked(exec).mockImplementation((_cmd, _opts, callback) => {
35
+ // @ts-expect-error: Mock implementation callback type is complex
36
+ callback({ code: 1, message: "Lint errors found" }, lintErrorOutput, "");
37
+ return {} as any;
38
+ });
39
+
40
+ const result = await handleCheckLint(projectRoot, args);
41
+
42
+ expect(exec).toHaveBeenCalledWith("npm run lint", { cwd: projectRoot, timeout: 60000 }, expect.any(Function));
43
+ expect(result.isError).toBe(true); // Implementation returns isError: true on failure
44
+ expect(result.content[0].text).toContain(lintErrorOutput);
45
+ });
46
+ });
@@ -0,0 +1,55 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import { handleRunCommand } from "../../../src/tools/shell/run_command.js";
3
+ import { exec } from "child_process";
4
+
5
+ vi.mock("child_process");
6
+
7
+ describe("handleRunCommand", () => {
8
+ const projectRoot = "/fake/project";
9
+
10
+ afterEach(() => {
11
+ vi.clearAllMocks();
12
+ });
13
+
14
+ it("should execute an allowed command", async () => {
15
+ const args = { command: "git status" };
16
+
17
+ vi.mocked(exec).mockImplementation((_cmd, _opts, callback) => {
18
+ // @ts-expect-error: Mock implementation callback type is complex
19
+ callback(null, "On branch main", "");
20
+ return {} as any;
21
+ });
22
+
23
+ const result = await handleRunCommand(projectRoot, args);
24
+
25
+ expect(exec).toHaveBeenCalledWith("git status", { cwd: projectRoot, timeout: 30000 }, expect.any(Function));
26
+ expect(result.isError).toBeUndefined();
27
+ expect(result.content[0].text).toContain("On branch main");
28
+ });
29
+
30
+ it("should reject a disallowed command", async () => {
31
+ const args = { command: "rm -rf /" };
32
+ const result = await handleRunCommand(projectRoot, args);
33
+
34
+ expect(exec).not.toHaveBeenCalled();
35
+ expect(result.isError).toBe(true);
36
+ expect(result.content[0].text).toContain("Command not allowed");
37
+ });
38
+
39
+ it("should handle command failure", async () => {
40
+ const args = { command: "npm run build" };
41
+
42
+ vi.mocked(exec).mockImplementation((_cmd, _opts, callback) => {
43
+ // @ts-expect-error: Mock implementation callback type is complex
44
+ callback({ code: 1, message: "Build failed" }, "", "Error details");
45
+ return {} as any;
46
+ });
47
+
48
+ const result = await handleRunCommand(projectRoot, args);
49
+
50
+ expect(exec).toHaveBeenCalledWith("npm run build", { cwd: projectRoot, timeout: 30000 }, expect.any(Function));
51
+ expect(result.isError).toBe(true);
52
+ expect(result.content[0].text).toContain("Command failed with exit code 1");
53
+ expect(result.content[0].text).toContain("Error details");
54
+ });
55
+ });
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "rootDir": "src",
7
+ "outDir": "./dist",
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "esModuleInterop": true,
11
+ "types": ["node"]
12
+ },
13
+ "include": ["src/**/*.ts"]
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-enderun",
3
- "version": "1.10.4",
3
+ "version": "1.11.0",
4
4
  "description": "The Supreme AI Governance & Autonomous Orchestration Framework for Enterprise Development. Acts as a Corporate AI Management Assistant.",
5
5
  "author": "Yusuf BEKAR",
6
6
  "license": "MIT",
@@ -33,6 +33,8 @@
33
33
  "bin",
34
34
  "dist",
35
35
  "src",
36
+ "templates",
37
+ "framework-mcp",
36
38
  "README.md",
37
39
  "LICENSE"
38
40
  ],
@@ -58,7 +60,7 @@
58
60
  },
59
61
  "devDependencies": {
60
62
  "@eslint/js": "^10.0.1",
61
- "@modelcontextprotocol/sdk": "^1.26.0",
63
+ "@modelcontextprotocol/sdk": "^1.29.0",
62
64
  "@pandacss/dev": "^1.11.1",
63
65
  "@types/node": "^25.9.1",
64
66
  "eslint": "^10.4.0",
@@ -69,7 +71,7 @@
69
71
  "vitest": "^3.0.0"
70
72
  },
71
73
  "enderun": {
72
- "version": "1.10.3",
74
+ "version": "1.11.0",
73
75
  "initializedAt": "2026-06-04T18:51:28.970Z",
74
76
  "frameworkDir": ".enderun"
75
77
  },
@@ -3,8 +3,8 @@ import path from "path";
3
3
  import { writeJsonFile } from "../utils/fs.js";
4
4
  import { getPackageRoot } from "../utils/pkg.js";
5
5
 
6
- import type { AdapterConfig, AdapterId } from "../../modules/adapters/types.js";
7
6
  import { ADAPTER_CONFIGS, POST_INIT_HANDLERS } from "../../modules/adapters/definitions.js";
7
+ import type { AdapterConfig, AdapterId } from "../../modules/adapters/types.js";
8
8
 
9
9
  export const ADAPTERS: Record<AdapterId, AdapterConfig> = ADAPTER_CONFIGS;
10
10
 
@@ -16,7 +16,6 @@ export const FRAMEWORK_DIR_CANDIDATES = [
16
16
  ".claude",
17
17
  ".github",
18
18
  ".grok",
19
- ".windsurf",
20
19
  ".antigravity",
21
20
  ".agent",
22
21
  ".gemini/antigravity-cli",
@@ -28,7 +27,7 @@ export const FRAMEWORK_DIR_CANDIDATES = [
28
27
  export function buildMcpServerEntry(projectRoot: string) {
29
28
  const packageRoot = getPackageRoot();
30
29
  const mcpServerPath = path.join(packageRoot, "framework-mcp/dist/index.js");
31
-
30
+
32
31
  if (!fs.existsSync(mcpServerPath)) {
33
32
  console.warn(`āš ļø MCP Server not found at ${mcpServerPath}. Did you run 'npm run build'?`);
34
33
  }
@@ -2,3 +2,4 @@ export { ADAPTER_IDS, type AdapterConfig, type AdapterId, type AdapterRole } fro
2
2
  export { ADAPTERS, FRAMEWORK_DIR_CANDIDATES, runAdapterPostInit, buildMcpServerEntry } from "./core.js";
3
3
  export { resolveAdapter, isAdapterShimFile, remapFrameworkContent } from "./utils.js";
4
4
  export { scaffoldAgents } from "./scaffold.js";
5
+ export { resolveAgentsDir, mirrorUnifiedAgentsToNative } from "./paths.js";
@@ -14,12 +14,22 @@ import {
14
14
  import type { AdapterId } from "../../modules/adapters/types.js";
15
15
  import { ADAPTERS } from "./core.js";
16
16
 
17
- export function scaffoldAgents(projectRoot: string, adapterId: AdapterId, dryRun: boolean, agentsToScaffold?: string[]): void {
17
+ export function scaffoldAgents(
18
+ projectRoot: string,
19
+ adapterId: AdapterId,
20
+ dryRun: boolean,
21
+ agentsToScaffold?: string[],
22
+ explicitDestDir?: string,
23
+ explicitExt?: string
24
+ ): void {
18
25
  const adapter = ADAPTERS[adapterId];
19
- if (!adapter || !adapter.agentsDir || !adapter.agentsExt) return;
26
+ if (!adapter) return;
20
27
 
21
28
  const allowedAgents = agentsToScaffold ? new Set(agentsToScaffold) : undefined;
22
- const destAgentsDir = path.join(projectRoot, adapter.agentsDir);
29
+ const destAgentsDir = explicitDestDir ? path.join(projectRoot, explicitDestDir) : (adapter.agentsDir ? path.join(projectRoot, adapter.agentsDir) : null);
30
+ const extension = explicitExt || adapter.agentsExt || ".md";
31
+
32
+ if (!destAgentsDir) return;
23
33
 
24
34
  const baseKnowledgeDir = path.join(getPackageRoot(), "templates/standards");
25
35
 
@@ -30,7 +40,7 @@ export function scaffoldAgents(projectRoot: string, adapterId: AdapterId, dryRun
30
40
  if (allowedAgents && !allowedAgents.has(agent.name)) continue;
31
41
 
32
42
  let content = "";
33
- let fileName = `${agent.name}${adapter.agentsExt}`;
43
+ let fileName = `${agent.name}${extension}`;
34
44
  let secondaryContent: string | null = null;
35
45
  let secondaryFileName: string | null = null;
36
46
 
@@ -72,8 +82,7 @@ export function scaffoldAgents(projectRoot: string, adapterId: AdapterId, dryRun
72
82
  }
73
83
  }
74
84
  }
75
- console.warn(`āœ… Generated ${allowedAgents ? allowedAgents.size : ALL_AGENTS.length} Agent/Rule definitions under ${path.relative(projectRoot, destAgentsDir)}/`);
76
85
  } catch (e) {
77
- console.warn(`āš ļø Failed to scaffold agents: ${e}`);
86
+ console.warn(`āš ļø Failed to scaffold agents for ${adapterId}: ${e}`);
78
87
  }
79
88
  }
@@ -3,7 +3,8 @@ import path from "path";
3
3
  import {
4
4
  remapFrameworkContent,
5
5
  type AdapterConfig,
6
- type AdapterId
6
+ type AdapterId,
7
+ ADAPTERS
7
8
  } from "../../adapters/index.js";
8
9
  import { SHIM_TEMPLATES } from "../../shims.js";
9
10
  import { writeJsonFile, writeTextFile } from "../../utils/fs.js";
@@ -38,7 +39,14 @@ export function scaffoldConstitution(targetDir: string, frameworkDir: string, ad
38
39
  console.warn(`āœ… Constitution file created inside: ${frameworkDir}/ENDERUN.md${readSuccess ? "" : " (default template)"}`);
39
40
  }
40
41
 
41
- export function scaffoldFrameworkConfigs(targetDir: string, fDir: string, adapter: AdapterConfig, dryRun: boolean, selectedPalette: string) {
42
+ export function scaffoldFrameworkConfigs(
43
+ targetDir: string,
44
+ fDir: string,
45
+ adapter: AdapterConfig,
46
+ dryRun: boolean,
47
+ selectedPalette: string,
48
+ options?: { unified?: boolean; adapters?: string[] }
49
+ ) {
42
50
  if (dryRun) return;
43
51
  const frameworkDir = path.join(targetDir, fDir);
44
52
  const palette = COLOR_PALETTES[selectedPalette as keyof typeof COLOR_PALETTES] || COLOR_PALETTES["Modern Blue"];
@@ -46,12 +54,28 @@ export function scaffoldFrameworkConfigs(targetDir: string, fDir: string, adapte
46
54
  const config = {
47
55
  name: FRAMEWORK_NAME,
48
56
  version: getPackageVersion(),
57
+ unified: options?.unified || false,
58
+ adapters: options?.adapters || [adapter.id],
49
59
  theme: {
50
60
  palette: selectedPalette,
51
61
  colors: palette
52
62
  }
53
63
  };
54
64
  writeJsonFile(path.join(frameworkDir, "config.json"), config, dryRun);
65
+
66
+ // Scaffold shared-facts.json in memory-graph
67
+ const graphDir = path.join(frameworkDir, "memory-graph");
68
+ if (!fs.existsSync(graphDir)) fs.mkdirSync(graphDir, { recursive: true });
69
+ const sharedFactsPath = path.join(graphDir, "shared-facts.json");
70
+ if (!fs.existsSync(sharedFactsPath)) {
71
+ writeJsonFile(sharedFactsPath, {
72
+ project: FRAMEWORK_NAME,
73
+ initializedAt: new Date().toISOString(),
74
+ stack: [],
75
+ policies: []
76
+ }, dryRun);
77
+ }
78
+
55
79
  let statusContent = "# šŸŽ–ļø Status\n\n| Agent | State | Active Task | Last Updated | Notes | Extra | Backup |\n|---|---|---|---|---|---|---|\n";
56
80
  for (const ag of ALL_AGENTS) {
57
81
  statusContent += "| @" + ag.name + " | READY | Idle | - | - | - | - |\n";
@@ -59,13 +83,28 @@ export function scaffoldFrameworkConfigs(targetDir: string, fDir: string, adapte
59
83
  writeTextFile(path.join(frameworkDir, "STATUS.md"), statusContent);
60
84
  }
61
85
 
62
- export function scaffoldShims(projectRoot: string, coreDir: string, adapterId: AdapterId, adapter: AdapterConfig, dryRun: boolean) {
86
+ export function scaffoldShims(
87
+ projectRoot: string,
88
+ coreDir: string,
89
+ adapterId: AdapterId,
90
+ adapter: AdapterConfig,
91
+ dryRun: boolean,
92
+ unified: boolean = false
93
+ ) {
63
94
  for (const [name, content] of Object.entries(SHIM_TEMPLATES)) {
64
- if (name.toLowerCase() === adapterId.split("-")[0] || name === adapterId) {
95
+ const isSelectedAdapter = name.toLowerCase() === adapterId.split("-")[0] || name === adapterId;
96
+
97
+ if (unified || isSelectedAdapter) {
65
98
  const shimContent = remapFrameworkContent(content, coreDir, adapterId);
66
- const shimFileName = adapter.shimFile || `${name.toUpperCase()}.md`;
99
+ const shimAdapter = ADAPTERS[name as AdapterId] || adapter;
100
+ const shimFileName = (unified && !isSelectedAdapter) ? (shimAdapter.shimFile || `${name.toUpperCase()}.md`) : (adapter.shimFile || `${name.toUpperCase()}.md`);
101
+
67
102
  if (!dryRun) writeTextFile(path.join(projectRoot, shimFileName), shimContent);
68
- console.warn(`āœ… Platform shim created: ${shimFileName}`);
103
+ if (isSelectedAdapter) {
104
+ console.warn(`āœ… Platform shim created: ${shimFileName}`);
105
+ } else if (unified) {
106
+ console.warn(`āœ… Unified platform shim added: ${shimFileName}`);
107
+ }
69
108
  }
70
109
  }
71
110
  }
@@ -5,6 +5,9 @@ import {
5
5
  resolveAdapter,
6
6
  runAdapterPostInit,
7
7
  scaffoldAgents,
8
+ resolveAgentsDir,
9
+ mirrorUnifiedAgentsToNative,
10
+ ADAPTER_IDS,
8
11
  type AdapterId,
9
12
  } from "../adapters/index.js";
10
13
  import { ensureDir } from "../utils/fs.js";
@@ -112,15 +115,41 @@ export async function initCommand(adapterName: string, options: { unified?: bool
112
115
  }
113
116
 
114
117
  scaffoldConstitution(projectRoot, coreDir, adapterId, dryRun);
118
+ scaffoldFrameworkConfigs(projectRoot, coreDir, adapter, dryRun, selectedPalette, {
119
+ unified: isUnified,
120
+ adapters: isUnified ? [...ADAPTER_IDS] : [adapterId]
121
+ });
115
122
 
116
123
  scaffoldStandards(path.join(projectRoot, coreDir), dryRun);
117
- scaffoldAgents(projectRoot, adapterId, dryRun, selectedAgents);
124
+
125
+ if (isUnified) {
126
+ // Scaffold ALL agents for ALL adapters under unified hub
127
+ for (const id of ADAPTER_IDS) {
128
+ const dest = resolveAgentsDir(id, true, aiToolDir);
129
+ scaffoldAgents(projectRoot, id, dryRun, selectedAgents, dest.agentsDir, dest.agentsExt);
130
+ if (!dryRun) mirrorUnifiedAgentsToNative(projectRoot, id);
131
+ }
132
+ UI.success(`āœ… Scaffolding complete for all adapters under ${aiToolDir}/ with native mirrors.`);
133
+ } else {
134
+ // Standard single-adapter scaffold
135
+ const dest = resolveAgentsDir(adapterId, false);
136
+ scaffoldAgents(projectRoot, adapterId, dryRun, selectedAgents, dest.agentsDir, dest.agentsExt);
137
+ UI.success(`āœ… Generated agent definitions under ${dest.agentsDir}/`);
138
+ }
118
139
 
119
140
  const skillsBaseDir = path.join(projectRoot, aiToolDir, "skills");
120
141
  scaffoldSkills(skillsBaseDir, dryRun);
121
142
  scaffoldOps(path.join(projectRoot, coreDir), dryRun);
122
- scaffoldShims(projectRoot, coreDir, adapterId, adapter, dryRun);
143
+ scaffoldShims(projectRoot, coreDir, adapterId, adapter, dryRun, isUnified);
144
+
145
+ // Initialize runtime directories
146
+ if (!dryRun) {
147
+ ensureDir(path.join(projectRoot, coreDir, "messages"));
148
+ ensureDir(path.join(projectRoot, coreDir, "logs"));
149
+ ensureDir(path.join(projectRoot, coreDir, "memory-graph"));
150
+ }
123
151
 
152
+ initializeMemory(path.join(projectRoot, coreDir), dryRun);
124
153
  runAdapterPostInit(adapter, projectRoot);
125
154
 
126
155
  UI.success(`\nšŸš€ ${FRAMEWORK_NAME} (v${getPackageVersion()}) initialized successfully!`);
@@ -1,47 +1,113 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { updateDocumentStore } from "../utils/memory.js";
4
3
  import { generateULID } from "../utils/time.js";
5
4
  import { UI } from "../utils/ui.js";
6
5
 
7
6
  /**
8
- * Parses docs/user/roadmap.md and injects tasks into the Document Store.
7
+ * Reads ALL markdown files from the docs/ directory and creates
8
+ * planning tasks from them. Agents will use this to understand
9
+ * project requirements and generate code accordingly.
9
10
  */
10
11
  export async function planCommand() {
11
12
  const projectRoot = process.cwd();
12
- const roadmapPath = path.join(projectRoot, "docs/user/roadmap.md");
13
+ const docsDir = path.join(projectRoot, "docs");
13
14
 
14
- if (!fs.existsSync(roadmapPath)) {
15
- UI.error("Roadmap file not found at docs/user/roadmap.md");
15
+ if (!fs.existsSync(docsDir)) {
16
+ UI.error("Docs directory not found at docs/");
17
+ console.warn("šŸ’” Create a docs/ folder with your project requirements in .md files.");
16
18
  return;
17
19
  }
18
20
 
19
- const content = fs.readFileSync(roadmapPath, "utf8");
20
- const taskRegex = /- \[ \] (.*) \| (.*) \| (.*)/g;
21
- let match;
22
- let count = 0;
21
+ const entries = fs.readdirSync(docsDir, { withFileTypes: true });
22
+ const mdFiles = entries.filter(e => e.isFile() && e.name.endsWith(".md"));
23
23
 
24
- UI.intent("Planning Engine", "Parsing roadmap.md and injecting tasks into Document Store...");
24
+ if (mdFiles.length === 0) {
25
+ UI.warning("No markdown files found in docs/ directory.");
26
+ console.warn("šŸ’” Add .md files to docs/ with your project requirements.");
27
+ return;
28
+ }
25
29
 
26
- while ((match = taskRegex.exec(content)) !== null) {
27
- const description = match[1];
28
- const priority = match[2];
29
- const agent = match[3];
30
+ UI.intent("Planning Engine", `Reading ${mdFiles.length} document(s) from docs/...`);
31
+
32
+ // Discover available template standards
33
+ const templatesDir = path.join(projectRoot, "templates");
34
+ const standards: string[] = [];
35
+ if (fs.existsSync(templatesDir)) {
36
+ const templateFiles = fs.readdirSync(templatesDir);
37
+ standards.push(...templateFiles.filter(f => f.endsWith("-standards.md")).map(f => `templates/${f}`));
38
+ if (standards.length > 0) {
39
+ UI.success(`Found ${standards.length} standard templates available for code generation.`);
40
+ }
41
+ }
42
+
43
+ let totalTasks = 0;
44
+
45
+ for (const file of mdFiles) {
46
+ const filePath = path.join(docsDir, file.name);
47
+ const content = fs.readFileSync(filePath, "utf8");
48
+ const lines = content.split("\n");
30
49
  const traceId = generateULID();
31
-
50
+
51
+ UI.success(`šŸ“„ docs/${file.name} (${lines.length} lines) → Trace: ${traceId}`);
52
+
53
+ console.warn(` Content preview: ${content.substring(0, 200).replace(/\n/g, " ")}...`);
54
+
55
+ // Extract headings as task descriptions
56
+ const headingRegex = /^#{2,4}\s+(.+)$/gm;
57
+ let headingMatch;
58
+ let headingCount = 0;
59
+ while ((headingMatch = headingRegex.exec(content)) !== null) {
60
+ headingCount++;
61
+ totalTasks++;
62
+ }
63
+
64
+ // Extract checklist items
65
+ const taskRegex = /- \[ \]\s+(.+)/g;
66
+ let taskMatch;
67
+ let taskCount = 0;
68
+ while ((taskMatch = taskRegex.exec(content)) !== null) {
69
+ if (taskMatch[1].trim().length >= 3) {
70
+ taskCount++;
71
+ totalTasks++;
72
+ }
73
+ }
74
+
75
+ console.warn(` šŸ“‹ ${headingCount} sections, ${taskCount} actionable tasks detected`);
76
+
77
+ // Store in project memory-compatible format
78
+ const memoryDir = path.join(projectRoot, ".enderun", "memory", "tasks");
79
+ if (!fs.existsSync(memoryDir)) {
80
+ fs.mkdirSync(memoryDir, { recursive: true });
81
+ }
82
+
83
+ const taskFile = path.join(memoryDir, `${traceId}.json`);
32
84
  const taskData = {
33
85
  traceId,
34
- description: description.trim(),
35
- priority: priority.trim(),
36
- agent: agent.trim().replace("@", ""),
86
+ source: `docs/${file.name}`,
87
+ description: `Process requirements from docs/${file.name}`,
37
88
  status: "PENDING",
38
- createdAt: new Date().toISOString()
89
+ createdAt: new Date().toISOString(),
90
+ standards,
91
+ headings: headingCount,
92
+ tasks: taskCount,
93
+ preview: content.substring(0, 500),
39
94
  };
95
+ fs.writeFileSync(taskFile, JSON.stringify(taskData, null, 2));
96
+ }
40
97
 
41
- updateDocumentStore("task", taskData, traceId);
42
- UI.success(`Injected task: ${taskData.description} (Agent: ${taskData.agent})`);
43
- count++;
98
+ // Log available standards
99
+ if (standards.length > 0) {
100
+ console.warn("");
101
+ UI.divider();
102
+ console.warn("šŸ“š Available Enterprise Standards:");
103
+ standards.forEach(s => console.warn(` - ${s}`));
104
+ UI.divider();
44
105
  }
45
106
 
46
- UI.success(`Plan complete: ${count} tasks injected into Document Store.`);
107
+ UI.success(`\nāœ… Planning complete: ${totalTasks} tasks identified from ${mdFiles.length} document(s).`);
108
+ console.warn("\nšŸ“‹ Next steps:");
109
+ console.warn(" 1. Run 'agent-enderun status' to see project state");
110
+ console.warn(" 2. AI agents (Claude, Gemini, Grok, etc.) will read docs/ and templates/");
111
+ console.warn(" 3. Agents generate enterprise-standard code based on requirements");
112
+ console.warn(" 4. Use @agent delegation for specific tasks: agent-enderun @backend \"...\"");
47
113
  }
package/src/cli/index.ts CHANGED
@@ -1,17 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from "fs";
3
- import { getPackageVersion, getValidatorPath } from "./utils/pkg.js";
4
- import { getMemoryPath, readActiveTraceId } from "./utils/memory.js";
5
- import { planCommand } from "./commands/plan.js";
6
- import { initCommand } from "./commands/init.js";
3
+ import { approveCommand } from "./commands/approve.js";
7
4
  import { checkCommand } from "./commands/check.js";
8
- import { statusCommand } from "./commands/status.js";
9
- import { traceNewCommand } from "./commands/trace.js";
5
+ import { updateApiContractCommand, verifyApiContractCommand } from "./commands/contract.js";
6
+ import { initCommand } from "./commands/init.js";
10
7
  import { updateProjectMemoryCommand } from "./commands/memory.js";
11
- import { createAppCommand } from "./commands/app.js";
12
- import { verifyApiContractCommand, updateApiContractCommand } from "./commands/contract.js";
13
8
  import { orchestrateCommand, sendMessage } from "./commands/orchestrate.js";
14
- import { approveCommand } from "./commands/approve.js";
9
+ import { planCommand } from "./commands/plan.js";
10
+ import { statusCommand } from "./commands/status.js";
11
+ import { traceNewCommand } from "./commands/trace.js";
12
+ import { getMemoryPath, readActiveTraceId } from "./utils/memory.js";
13
+ import { getPackageVersion, getValidatorPath } from "./utils/pkg.js";
15
14
 
16
15
  /**
17
16
  * Main CLI entry point.
@@ -21,8 +20,8 @@ async function main() {
21
20
  const command = args[0];
22
21
 
23
22
  const KNOWN_COMMANDS = [
24
- "init", "check", "status", "trace:new", "update_project_memory",
25
- "create-app", "orchestrate", "loop", "verify-contract", "update-contract",
23
+ "init", "check", "status", "trace:new", "update_project_memory",
24
+ "plan", "orchestrate", "loop", "verify-contract", "update-contract",
26
25
  "validate", "validate-army", "check:al", "version", "-v", "--version", "help", "-h", "--help",
27
26
  "git:commit", "git:sync", "check:compliance", "explorer:graph", "explorer:audit",
28
27
  "knowledge:update", "knowledge:search", "log:action", "run-script", "security:audit", "check:lint", "approve"
@@ -77,6 +76,7 @@ async function main() {
77
76
  case "plan":
78
77
  await planCommand();
79
78
  break;
79
+
80
80
  case "status":
81
81
  await statusCommand();
82
82
  break;
@@ -100,10 +100,6 @@ async function main() {
100
100
  break;
101
101
  }
102
102
 
103
- case "create-app":
104
- await createAppCommand(args.slice(1));
105
- break;
106
-
107
103
  case "dashboard": {
108
104
  const { dashboardCommand } = await import("./commands/dashboard.js");
109
105
  await dashboardCommand(args.slice(1));
@@ -128,7 +124,7 @@ async function main() {
128
124
  case "verify-contract":
129
125
  await verifyApiContractCommand();
130
126
  break;
131
-
127
+
132
128
  case "update-contract":
133
129
  await updateApiContractCommand();
134
130
  break;
@@ -287,7 +283,7 @@ Commands:
287
283
  check Perform an enterprise-grade system health check
288
284
  status Show active phase, trace ID, and agent statuses
289
285
  trace:new <desc> Start a new task chain with a unique Trace ID
290
- create-app <idea> Generate a new full-stack app from natural language
286
+ plan Read all docs/ files and create planning tasks
291
287
  orchestrate Start the dynamic Hermes agent orchestration loop
292
288
  verify-contract Validate type alignment between backend and frontend
293
289
  update-contract Generate and synchronize a new contract hash
@@ -314,8 +310,8 @@ Example:
314
310
  `);
315
311
  }
316
312
 
317
- import { logger } from "../shared/logger.js";
318
313
  import { EnderunBaseError } from "../shared/errors.js";
314
+ import { logger } from "../shared/logger.js";
319
315
 
320
316
  main().catch((err) => {
321
317
  if (err instanceof EnderunBaseError) {
@@ -330,4 +326,3 @@ main().catch((err) => {
330
326
  logger.fatal("Fatal exception during CLI execution", err);
331
327
  process.exit(1);
332
328
  });
333
-
@@ -14,12 +14,11 @@ export function scanProjectCompliance(): ComplianceIssue[] {
14
14
 
15
15
  for (const file of files) {
16
16
  // Absolute skip for the scanner itself to avoid recursion/self-flagging
17
- if (file.includes("compliance") ||
17
+ if (file.includes("compliance") ||
18
18
  file.includes("definitions") ||
19
19
  file.includes("agents/registry") || // Skip agent definitions
20
- file.includes("app-backend.ts") || // Template generator
21
20
  file.includes("scaffold-ops.ts") || // Template generator
22
- file.includes("logger") ||
21
+ file.includes("logger") ||
23
22
  file.includes("errors") ||
24
23
  file.includes("shared/fs")) continue;
25
24
 
@@ -31,8 +30,8 @@ export function scanProjectCompliance(): ComplianceIssue[] {
31
30
  const trimmedLine = line.trim();
32
31
 
33
32
  // Skip comments and common doc string patterns
34
- if (trimmedLine.startsWith("//") ||
35
- trimmedLine.startsWith("*") ||
33
+ if (trimmedLine.startsWith("//") ||
34
+ trimmedLine.startsWith("*") ||
36
35
  trimmedLine.startsWith("-") ||
37
36
  trimmedLine.includes("\": \"") || // Ignore JSON-like values
38
37
  trimmedLine.includes("default: ") || // Ignore default template values
@@ -48,9 +47,9 @@ export function scanProjectCompliance(): ComplianceIssue[] {
48
47
  }
49
48
 
50
49
  // 2. Secret check (Regex for simple API keys/assignments) - skip UI messages and templates
51
- if (/(API_KEY|SECRET|PASSWORD)\s*[:=]/i.test(line) &&
52
- !file.includes(".env") &&
53
- !isUIMessage &&
50
+ if (/(API_KEY|SECRET|PASSWORD)\s*[:=]/i.test(line) &&
51
+ !file.includes(".env") &&
52
+ !isUIMessage &&
54
53
  !trimmedLine.includes(".env.example") && // Skip template lines
55
54
  !trimmedLine.includes("your_secret_key_here") && // Skip common placeholders
56
55
  !trimmedLine.includes("pattern:")) {
@@ -68,7 +67,7 @@ export function scanProjectCompliance(): ComplianceIssue[] {
68
67
  }
69
68
 
70
69
  // 5. Raw fs write check (Atomic safety enforcement)
71
- if ((line.includes("fs.writeFileSync") || line.includes("fs.appendFileSync")) &&
70
+ if ((line.includes("fs.writeFileSync") || line.includes("fs.appendFileSync")) &&
72
71
  !file.includes("src/shared/fs.ts") && // Ignore the utility itself
73
72
  !line.includes(".lock") && // Allow lock files
74
73
  !line.includes("lockPath") && // Allow lock path variables