agent-enderun 1.1.10 → 1.10.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 (254) hide show
  1. package/README.md +296 -19
  2. package/bin/cli.js +7 -0
  3. package/bin/enderun-dashboard.js +16 -857
  4. package/bin/validate-agent-army.js +12 -12
  5. package/dist/framework-mcp/src/index.js +14 -2
  6. package/dist/framework-mcp/src/index.js.map +1 -1
  7. package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js +2 -1
  8. package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js.map +1 -1
  9. package/dist/framework-mcp/src/tools/file_system/replace_text.js +2 -1
  10. package/dist/framework-mcp/src/tools/file_system/replace_text.js.map +1 -1
  11. package/dist/framework-mcp/src/tools/file_system/write_file.js +3 -3
  12. package/dist/framework-mcp/src/tools/file_system/write_file.js.map +1 -1
  13. package/dist/framework-mcp/src/utils/fs.d.ts +16 -0
  14. package/dist/framework-mcp/src/utils/fs.js +45 -0
  15. package/dist/framework-mcp/src/utils/fs.js.map +1 -0
  16. package/dist/framework-mcp/src/utils/metrics.js.map +1 -1
  17. package/dist/src/cli/adapters/core.js.map +1 -1
  18. package/dist/src/cli/adapters/scaffold.js +4 -3
  19. package/dist/src/cli/adapters/scaffold.js.map +1 -1
  20. package/dist/src/cli/commands/app.js +20 -5
  21. package/dist/src/cli/commands/app.js.map +1 -1
  22. package/dist/src/cli/commands/approve.d.ts +1 -1
  23. package/dist/src/cli/commands/approve.js +7 -7
  24. package/dist/src/cli/commands/approve.js.map +1 -1
  25. package/dist/src/cli/commands/check.d.ts +1 -1
  26. package/dist/src/cli/commands/check.js +35 -4
  27. package/dist/src/cli/commands/check.js.map +1 -1
  28. package/dist/src/cli/commands/compliance.d.ts +1 -1
  29. package/dist/src/cli/commands/compliance.js +1 -1
  30. package/dist/src/cli/commands/compliance.js.map +1 -1
  31. package/dist/src/cli/commands/contract.d.ts +2 -2
  32. package/dist/src/cli/commands/contract.js +8 -14
  33. package/dist/src/cli/commands/contract.js.map +1 -1
  34. package/dist/src/cli/commands/dashboard/data-service.d.ts +33 -0
  35. package/dist/src/cli/commands/dashboard/data-service.js +120 -0
  36. package/dist/src/cli/commands/dashboard/data-service.js.map +1 -0
  37. package/dist/src/cli/commands/dashboard/html-template.d.ts +4 -0
  38. package/dist/src/cli/commands/dashboard/html-template.js +697 -0
  39. package/dist/src/cli/commands/dashboard/html-template.js.map +1 -0
  40. package/dist/src/cli/commands/dashboard/server.d.ts +2 -0
  41. package/dist/src/cli/commands/dashboard/server.js +38 -0
  42. package/dist/src/cli/commands/dashboard/server.js.map +1 -0
  43. package/dist/src/cli/commands/dashboard.d.ts +4 -0
  44. package/dist/src/cli/commands/dashboard.js +10 -0
  45. package/dist/src/cli/commands/dashboard.js.map +1 -0
  46. package/dist/src/cli/commands/explorer.d.ts +2 -2
  47. package/dist/src/cli/commands/explorer.js +2 -2
  48. package/dist/src/cli/commands/explorer.js.map +1 -1
  49. package/dist/src/cli/commands/git.d.ts +2 -2
  50. package/dist/src/cli/commands/git.js +2 -2
  51. package/dist/src/cli/commands/git.js.map +1 -1
  52. package/dist/src/cli/commands/init/scaffold-core.d.ts +4 -0
  53. package/dist/src/cli/commands/init/scaffold-core.js +65 -0
  54. package/dist/src/cli/commands/init/scaffold-core.js.map +1 -0
  55. package/dist/src/cli/commands/init/scaffold-ops.d.ts +1 -0
  56. package/dist/src/cli/commands/init/scaffold-ops.js +83 -0
  57. package/dist/src/cli/commands/init/scaffold-ops.js.map +1 -0
  58. package/dist/src/cli/commands/init/scaffold-standards.d.ts +2 -0
  59. package/dist/src/cli/commands/init/scaffold-standards.js +58 -0
  60. package/dist/src/cli/commands/init/scaffold-standards.js.map +1 -0
  61. package/dist/src/cli/commands/init.js +14 -275
  62. package/dist/src/cli/commands/init.js.map +1 -1
  63. package/dist/src/cli/commands/knowledge.d.ts +2 -2
  64. package/dist/src/cli/commands/knowledge.js +4 -3
  65. package/dist/src/cli/commands/knowledge.js.map +1 -1
  66. package/dist/src/cli/commands/lint.d.ts +1 -1
  67. package/dist/src/cli/commands/lint.js +2 -3
  68. package/dist/src/cli/commands/lint.js.map +1 -1
  69. package/dist/src/cli/commands/log.d.ts +1 -1
  70. package/dist/src/cli/commands/log.js +3 -2
  71. package/dist/src/cli/commands/log.js.map +1 -1
  72. package/dist/src/cli/commands/memory.d.ts +1 -1
  73. package/dist/src/cli/commands/memory.js +1 -1
  74. package/dist/src/cli/commands/memory.js.map +1 -1
  75. package/dist/src/cli/commands/orchestrate.js +169 -140
  76. package/dist/src/cli/commands/orchestrate.js.map +1 -1
  77. package/dist/src/cli/commands/plan.d.ts +1 -1
  78. package/dist/src/cli/commands/plan.js +1 -1
  79. package/dist/src/cli/commands/plan.js.map +1 -1
  80. package/dist/src/cli/commands/script.d.ts +1 -1
  81. package/dist/src/cli/commands/script.js +1 -1
  82. package/dist/src/cli/commands/script.js.map +1 -1
  83. package/dist/src/cli/commands/security.d.ts +1 -1
  84. package/dist/src/cli/commands/security.js +1 -1
  85. package/dist/src/cli/commands/security.js.map +1 -1
  86. package/dist/src/cli/commands/status.d.ts +1 -1
  87. package/dist/src/cli/commands/status.js +1 -1
  88. package/dist/src/cli/commands/status.js.map +1 -1
  89. package/dist/src/cli/commands/trace.d.ts +1 -1
  90. package/dist/src/cli/commands/trace.js +1 -1
  91. package/dist/src/cli/commands/trace.js.map +1 -1
  92. package/dist/src/cli/index.js +36 -21
  93. package/dist/src/cli/index.js.map +1 -1
  94. package/dist/src/cli/shims.js +6 -6
  95. package/dist/src/cli/utils/app-backend.js +7 -0
  96. package/dist/src/cli/utils/app-backend.js.map +1 -1
  97. package/dist/src/cli/utils/app-docs.js +23 -5
  98. package/dist/src/cli/utils/app-docs.js.map +1 -1
  99. package/dist/src/cli/utils/app-frontend.js +5 -0
  100. package/dist/src/cli/utils/app-frontend.js.map +1 -1
  101. package/dist/src/cli/utils/app-inferrer.d.ts +1 -0
  102. package/dist/src/cli/utils/app-inferrer.js +12 -1
  103. package/dist/src/cli/utils/app-inferrer.js.map +1 -1
  104. package/dist/src/cli/utils/app-mobile.d.ts +2 -0
  105. package/dist/src/cli/utils/app-mobile.js +106 -0
  106. package/dist/src/cli/utils/app-mobile.js.map +1 -0
  107. package/dist/src/cli/utils/app-types.js +8 -4
  108. package/dist/src/cli/utils/app-types.js.map +1 -1
  109. package/dist/src/cli/utils/app.d.ts +1 -0
  110. package/dist/src/cli/utils/app.js +1 -0
  111. package/dist/src/cli/utils/app.js.map +1 -1
  112. package/dist/src/cli/utils/claude.js +2 -1
  113. package/dist/src/cli/utils/claude.js.map +1 -1
  114. package/dist/src/cli/utils/compliance.js +37 -6
  115. package/dist/src/cli/utils/compliance.js.map +1 -1
  116. package/dist/src/cli/utils/config-schema.d.ts +3 -3
  117. package/dist/src/cli/utils/config-schema.js +3 -3
  118. package/dist/src/cli/utils/config-schema.js.map +1 -1
  119. package/dist/src/cli/utils/fs.d.ts +2 -2
  120. package/dist/src/cli/utils/fs.js +9 -13
  121. package/dist/src/cli/utils/fs.js.map +1 -1
  122. package/dist/src/cli/utils/memory.d.ts +9 -2
  123. package/dist/src/cli/utils/memory.js +87 -16
  124. package/dist/src/cli/utils/memory.js.map +1 -1
  125. package/dist/src/cli/utils/pkg.js +14 -13
  126. package/dist/src/cli/utils/pkg.js.map +1 -1
  127. package/dist/src/cli/utils/string.js +1 -1
  128. package/dist/src/cli/utils/string.js.map +1 -1
  129. package/dist/src/cli/utils/ui.d.ts +1 -1
  130. package/dist/src/cli/utils/ui.js +1 -1
  131. package/dist/src/modules/adapters/shared.js +7 -7
  132. package/dist/src/modules/adapters/shared.js.map +1 -1
  133. package/dist/src/modules/agents/definitions.d.ts +3 -34
  134. package/dist/src/modules/agents/definitions.js +35 -511
  135. package/dist/src/modules/agents/definitions.js.map +1 -1
  136. package/dist/src/modules/agents/registry/analyst.d.ts +2 -0
  137. package/dist/src/modules/agents/registry/analyst.js +36 -0
  138. package/dist/src/modules/agents/registry/analyst.js.map +1 -0
  139. package/dist/src/modules/agents/registry/architect.d.ts +2 -0
  140. package/dist/src/modules/agents/registry/architect.js +42 -0
  141. package/dist/src/modules/agents/registry/architect.js.map +1 -0
  142. package/dist/src/modules/agents/registry/backend.d.ts +2 -0
  143. package/dist/src/modules/agents/registry/backend.js +43 -0
  144. package/dist/src/modules/agents/registry/backend.js.map +1 -0
  145. package/dist/src/modules/agents/registry/database.d.ts +2 -0
  146. package/dist/src/modules/agents/registry/database.js +38 -0
  147. package/dist/src/modules/agents/registry/database.js.map +1 -0
  148. package/dist/src/modules/agents/registry/devops.d.ts +2 -0
  149. package/dist/src/modules/agents/registry/devops.js +38 -0
  150. package/dist/src/modules/agents/registry/devops.js.map +1 -0
  151. package/dist/src/modules/agents/registry/explorer.d.ts +2 -0
  152. package/dist/src/modules/agents/registry/explorer.js +36 -0
  153. package/dist/src/modules/agents/registry/explorer.js.map +1 -0
  154. package/dist/src/modules/agents/registry/frontend.d.ts +2 -0
  155. package/dist/src/modules/agents/registry/frontend.js +44 -0
  156. package/dist/src/modules/agents/registry/frontend.js.map +1 -0
  157. package/dist/src/modules/agents/registry/git.d.ts +2 -0
  158. package/dist/src/modules/agents/registry/git.js +35 -0
  159. package/dist/src/modules/agents/registry/git.js.map +1 -0
  160. package/dist/src/modules/agents/registry/manager.d.ts +2 -0
  161. package/dist/src/modules/agents/registry/manager.js +49 -0
  162. package/dist/src/modules/agents/registry/manager.js.map +1 -0
  163. package/dist/src/modules/agents/registry/mobile.d.ts +2 -0
  164. package/dist/src/modules/agents/registry/mobile.js +40 -0
  165. package/dist/src/modules/agents/registry/mobile.js.map +1 -0
  166. package/dist/src/modules/agents/registry/native.d.ts +2 -0
  167. package/dist/src/modules/agents/registry/native.js +36 -0
  168. package/dist/src/modules/agents/registry/native.js.map +1 -0
  169. package/dist/src/modules/agents/registry/quality.d.ts +2 -0
  170. package/dist/src/modules/agents/registry/quality.js +41 -0
  171. package/dist/src/modules/agents/registry/quality.js.map +1 -0
  172. package/dist/src/modules/agents/registry/security.d.ts +2 -0
  173. package/dist/src/modules/agents/registry/security.js +37 -0
  174. package/dist/src/modules/agents/registry/security.js.map +1 -0
  175. package/dist/src/modules/agents/types.d.ts +31 -0
  176. package/dist/src/modules/agents/types.js +2 -0
  177. package/dist/src/modules/agents/types.js.map +1 -0
  178. package/dist/src/modules/skills/definitions.d.ts +1 -1
  179. package/dist/src/modules/skills/definitions.js +1 -1
  180. package/dist/src/shared/errors.d.ts +8 -6
  181. package/dist/src/shared/errors.js +13 -10
  182. package/dist/src/shared/errors.js.map +1 -1
  183. package/dist/src/shared/fs.d.ts +4 -0
  184. package/dist/src/shared/fs.js +17 -2
  185. package/dist/src/shared/fs.js.map +1 -1
  186. package/dist/src/shared/types.d.ts +19 -0
  187. package/dist/src/shared/types.js +13 -0
  188. package/dist/src/shared/types.js.map +1 -0
  189. package/package.json +3 -6
  190. package/src/cli/adapters/core.ts +0 -1
  191. package/src/cli/adapters/scaffold.ts +4 -3
  192. package/src/cli/commands/app.ts +23 -5
  193. package/src/cli/commands/approve.ts +15 -7
  194. package/src/cli/commands/check.ts +38 -5
  195. package/src/cli/commands/compliance.ts +1 -1
  196. package/src/cli/commands/contract.ts +20 -14
  197. package/src/cli/commands/dashboard/data-service.ts +119 -0
  198. package/src/cli/commands/dashboard/html-template.ts +696 -0
  199. package/src/cli/commands/dashboard/server.ts +43 -0
  200. package/src/cli/commands/dashboard.ts +11 -0
  201. package/src/cli/commands/explorer.ts +2 -2
  202. package/src/cli/commands/git.ts +2 -2
  203. package/src/cli/commands/init/scaffold-core.ts +71 -0
  204. package/src/cli/commands/init/scaffold-ops.ts +86 -0
  205. package/src/cli/commands/init/scaffold-standards.ts +59 -0
  206. package/src/cli/commands/init.ts +21 -292
  207. package/src/cli/commands/knowledge.ts +5 -3
  208. package/src/cli/commands/lint.ts +2 -4
  209. package/src/cli/commands/log.ts +4 -2
  210. package/src/cli/commands/memory.ts +1 -1
  211. package/src/cli/commands/orchestrate.ts +177 -142
  212. package/src/cli/commands/plan.ts +1 -1
  213. package/src/cli/commands/script.ts +1 -1
  214. package/src/cli/commands/security.ts +1 -1
  215. package/src/cli/commands/status.ts +1 -1
  216. package/src/cli/commands/trace.ts +1 -1
  217. package/src/cli/index.ts +37 -21
  218. package/src/cli/shims.ts +6 -6
  219. package/src/cli/utils/app-backend.ts +8 -0
  220. package/src/cli/utils/app-docs.ts +23 -5
  221. package/src/cli/utils/app-frontend.ts +6 -0
  222. package/src/cli/utils/app-inferrer.ts +11 -1
  223. package/src/cli/utils/app-mobile.ts +113 -0
  224. package/src/cli/utils/app-types.ts +9 -4
  225. package/src/cli/utils/app.ts +1 -0
  226. package/src/cli/utils/claude.ts +2 -1
  227. package/src/cli/utils/compliance.ts +38 -7
  228. package/src/cli/utils/config-schema.ts +4 -4
  229. package/src/cli/utils/fs.ts +9 -14
  230. package/src/cli/utils/memory.ts +103 -20
  231. package/src/cli/utils/pkg.ts +14 -13
  232. package/src/cli/utils/string.ts +1 -1
  233. package/src/cli/utils/ui.ts +1 -1
  234. package/src/modules/adapters/shared.ts +7 -7
  235. package/src/modules/agents/definitions.ts +39 -598
  236. package/src/modules/agents/registry/analyst.ts +40 -0
  237. package/src/modules/agents/registry/architect.ts +46 -0
  238. package/src/modules/agents/registry/backend.ts +47 -0
  239. package/src/modules/agents/registry/database.ts +42 -0
  240. package/src/modules/agents/registry/devops.ts +42 -0
  241. package/src/modules/agents/registry/explorer.ts +40 -0
  242. package/src/modules/agents/registry/frontend.ts +48 -0
  243. package/src/modules/agents/registry/git.ts +39 -0
  244. package/src/modules/agents/registry/manager.ts +53 -0
  245. package/src/modules/agents/registry/mobile.ts +44 -0
  246. package/src/modules/agents/registry/native.ts +40 -0
  247. package/src/modules/agents/registry/quality.ts +45 -0
  248. package/src/modules/agents/registry/security.ts +41 -0
  249. package/src/modules/agents/types.ts +37 -0
  250. package/src/modules/skills/definitions.ts +1 -1
  251. package/src/shared/errors.ts +13 -10
  252. package/src/shared/fs.ts +17 -2
  253. package/src/shared/types.ts +20 -0
  254. package/bin/utils/docgen.ts +0 -24
@@ -1,866 +1,25 @@
1
1
  #!/usr/bin/env node
2
+ import { spawn } from "node:child_process";
3
+ import { fileURLToPath } from "node:url";
4
+ import { dirname, join } from "node:path";
5
+ import fs from "node:fs";
2
6
 
3
- import http from "http";
4
- import fs from "fs";
5
- import path from "path";
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
6
9
 
7
- const PORT = process.env.PORT || 5858;
8
- const projectRoot = process.cwd();
10
+ const cliPath = join(__dirname, "../dist/src/cli/index.js");
9
11
 
10
- // Helper to find .enderun path
11
- function getEnderunDir() {
12
- const p1 = path.join(projectRoot, ".enderun");
13
- if (fs.existsSync(p1)) return p1;
14
- return null;
12
+ if (!fs.existsSync(cliPath)) {
13
+ process.stderr.write("\n❌ Error: Compiled CLI not found at 'dist/src/cli/index.js'\n");
14
+ process.stderr.write("💡 Solution Tip: Run 'npm run build' to compile the project first.\n\n");
15
+ process.exit(1);
15
16
  }
16
17
 
17
- // Parses PROJECT_MEMORY.md into JSON
18
- function parseProjectMemory() {
19
- const enderunDir = getEnderunDir();
20
- if (!enderunDir) return { error: "No framework directory found. Run init." };
21
-
22
- const memPath = path.join(enderunDir, "memory/PROJECT_MEMORY.md");
23
- if (!fs.existsSync(memPath)) return { error: "PROJECT_MEMORY.md not found" };
24
-
25
- try {
26
- const content = fs.readFileSync(memPath, "utf8");
27
-
28
- // Parse Phase & Trace ID
29
- const phaseMatch = content.match(/Phase:\s*([^\n\r]+)/i);
30
- const traceMatch = content.match(/Trace ID:\s*([^\n\r]+)/i);
31
- const managerMatch = content.match(/@manager state:\s*([^\n\r]+)/i);
32
-
33
- // Parse Active Tasks Table
34
- const tasks = [];
35
- const lines = content.split("\n");
36
- let inTaskTable = false;
37
-
38
- for (const line of lines) {
39
- if (line.includes("| Trace ID | Task |")) {
40
- inTaskTable = true;
41
- continue;
42
- }
43
- if (inTaskTable && line.trim() === "") {
44
- inTaskTable = false;
45
- continue;
46
- }
47
- if (inTaskTable && line.startsWith("|") && !line.includes(":---")) {
48
- const cols = line.split("|").map(c => c.trim()).filter(Boolean);
49
- if (cols.length >= 5) {
50
- tasks.push({
51
- traceId: cols[0],
52
- task: cols[1],
53
- agent: cols[2],
54
- priority: cols[3],
55
- status: cols[4]
56
- });
57
- }
58
- }
59
- }
60
-
61
- // Parse History Section
62
- const history = [];
63
- const historyParts = content.split(/##\s+HISTORY/i);
64
- if (historyParts[1]) {
65
- const histLines = historyParts[1].split("\n");
66
- let currentItem = null;
67
- for (const line of histLines) {
68
- if (line.startsWith("###")) {
69
- if (currentItem) history.push(currentItem);
70
- currentItem = { title: line.replace("###", "").trim(), body: [] };
71
- } else if (currentItem && line.trim() !== "") {
72
- currentItem.body.push(line.trim());
73
- }
74
- }
75
- if (currentItem) history.push(currentItem);
76
- }
77
-
78
- return {
79
- phase: phaseMatch ? phaseMatch[1].trim() : "PHASE_0",
80
- traceId: traceMatch ? traceMatch[1].trim() : "N/A",
81
- managerState: managerMatch ? managerMatch[1].trim() : "ACTIVE",
82
- tasks,
83
- history: history.slice(0, 15) // Return last 15 entries
84
- };
85
- } catch (e) {
86
- return { error: e.message };
87
- }
88
- }
89
-
90
- // Reads manager.json logs
91
- function readManagerLogs() {
92
- const enderunDir = getEnderunDir();
93
- if (!enderunDir) return [];
94
-
95
- const logsPath = path.join(enderunDir, "logs/manager.json");
96
- if (!fs.existsSync(logsPath)) return [];
97
-
98
- try {
99
- const raw = fs.readFileSync(logsPath, "utf8");
100
- // Handle both json array format and jsonl format
101
- if (raw.trim().startsWith("[")) {
102
- return JSON.parse(raw);
103
- } else {
104
- return raw.split("\n").filter(Boolean).map(line => JSON.parse(line));
105
- }
106
- } catch {
107
- return [];
108
- }
109
- }
110
-
111
- // Lists agents in .enderun/agents
112
- function listAgents() {
113
- const enderunDir = getEnderunDir();
114
- if (!enderunDir) return [];
115
- const agentsPath = path.join(enderunDir, "agents");
116
- if (!fs.existsSync(agentsPath)) return [];
117
-
118
- try {
119
- const files = fs.readdirSync(agentsPath).filter(f => f.endsWith(".json") && f !== "agent_army_schema.json");
120
- return files.map(file => {
121
- const content = JSON.parse(fs.readFileSync(path.join(agentsPath, file), "utf8"));
122
- return {
123
- name: content.name,
124
- displayName: content.displayName || content.name,
125
- description: content.description,
126
- role: content.role,
127
- capability: content.capability,
128
- tags: content.tags || []
129
- };
130
- });
131
- } catch {
132
- return [];
133
- }
134
- }
135
-
136
- // HTML Dashboard Template
137
- const HTML_CONTENT = `
138
- <!DOCTYPE html>
139
- <html lang="en">
140
- <head>
141
- <meta charset="UTF-8">
142
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
143
- <title>Agent Enderun — Live Dashboard</title>
144
- <style>
145
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Fira+Code:wght@400;500&display=swap');
146
-
147
- * {
148
- box-sizing: border-box;
149
- margin: 0;
150
- padding: 0;
151
- }
152
-
153
- body {
154
- background-color: #0b0c10;
155
- color: #c5c6c7;
156
- font-family: 'Inter', sans-serif;
157
- overflow-x: hidden;
158
- height: 100vh;
159
- display: flex;
160
- flex-direction: column;
161
- }
162
-
163
- /* Gradient background glows */
164
- body::before {
165
- content: '';
166
- position: absolute;
167
- width: 300px;
168
- height: 300px;
169
- background: radial-gradient(circle, rgba(139, 92, 246, 0.15) 0%, rgba(0,0,0,0) 70%);
170
- top: 10%;
171
- left: 5%;
172
- z-index: -1;
173
- pointer-events: none;
174
- }
175
-
176
- body::after {
177
- content: '';
178
- position: absolute;
179
- width: 400px;
180
- height: 400px;
181
- background: radial-gradient(circle, rgba(6, 182, 212, 0.1) 0%, rgba(0,0,0,0) 70%);
182
- bottom: 10%;
183
- right: 5%;
184
- z-index: -1;
185
- pointer-events: none;
186
- }
187
-
188
- header {
189
- display: flex;
190
- justify-content: space-between;
191
- align-items: center;
192
- padding: 1.5rem 2rem;
193
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
194
- background: rgba(15, 17, 23, 0.7);
195
- backdrop-filter: blur(12px);
196
- }
197
-
198
- .logo-container {
199
- display: flex;
200
- align-items: center;
201
- gap: 0.75rem;
202
- }
203
-
204
- .logo-icon {
205
- width: 32px;
206
- height: 32px;
207
- background: linear-gradient(135deg, #8b5cf6, #06b6d4);
208
- border-radius: 8px;
209
- box-shadow: 0 0 15px rgba(139, 92, 246, 0.5);
210
- display: flex;
211
- align-items: center;
212
- justify-content: center;
213
- font-weight: 700;
214
- color: #fff;
215
- font-size: 1.1rem;
216
- }
217
-
218
- .logo-text {
219
- font-size: 1.25rem;
220
- font-weight: 700;
221
- background: linear-gradient(to right, #ffffff, #a5b4fc);
222
- -webkit-background-clip: text;
223
- -webkit-text-fill-color: transparent;
224
- }
225
-
226
- .system-status {
227
- display: flex;
228
- align-items: center;
229
- gap: 1.5rem;
230
- font-size: 0.875rem;
231
- }
232
-
233
- .status-badge {
234
- display: flex;
235
- align-items: center;
236
- gap: 0.5rem;
237
- background: rgba(16, 185, 129, 0.1);
238
- color: #10b981;
239
- padding: 0.35rem 0.75rem;
240
- border-radius: 9999px;
241
- border: 1px solid rgba(16, 185, 129, 0.2);
242
- font-weight: 500;
243
- }
244
-
245
- .status-dot {
246
- width: 8px;
247
- height: 8px;
248
- background-color: #10b981;
249
- border-radius: 50%;
250
- box-shadow: 0 0 8px #10b981;
251
- animation: pulse 1.8s infinite;
252
- }
253
-
254
- @keyframes pulse {
255
- 0% { transform: scale(0.9); opacity: 0.6; }
256
- 50% { transform: scale(1.1); opacity: 1; box-shadow: 0 0 12px #10b981; }
257
- 100% { transform: scale(0.9); opacity: 0.6; }
258
- }
259
-
260
- .main-layout {
261
- display: flex;
262
- flex: 1;
263
- padding: 1.5rem;
264
- gap: 1.5rem;
265
- height: calc(100vh - 80px);
266
- overflow: hidden;
267
- }
268
-
269
- /* Card panels */
270
- .panel {
271
- background: rgba(18, 20, 29, 0.6);
272
- border: 1px solid rgba(255, 255, 255, 0.05);
273
- border-radius: 16px;
274
- backdrop-filter: blur(16px);
275
- display: flex;
276
- flex-direction: column;
277
- overflow: hidden;
278
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
279
- }
280
-
281
- .panel-header {
282
- padding: 1rem 1.25rem;
283
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
284
- display: flex;
285
- justify-content: space-between;
286
- align-items: center;
287
- font-weight: 600;
288
- font-size: 0.95rem;
289
- color: #ffffff;
290
- letter-spacing: 0.05em;
291
- text-transform: uppercase;
292
- }
293
-
294
- /* Left Panel - Agents list */
295
- .agents-panel {
296
- width: 300px;
297
- flex-shrink: 0;
298
- }
299
-
300
- .agent-list {
301
- padding: 1rem;
302
- display: flex;
303
- flex-direction: column;
304
- gap: 0.75rem;
305
- overflow-y: auto;
306
- flex: 1;
307
- }
308
-
309
- .agent-card {
310
- background: rgba(255, 255, 255, 0.02);
311
- border: 1px solid rgba(255, 255, 255, 0.03);
312
- border-radius: 10px;
313
- padding: 0.75rem 1rem;
314
- display: flex;
315
- align-items: center;
316
- justify-content: space-between;
317
- transition: all 0.25s ease;
318
- }
319
-
320
- .agent-card:hover {
321
- background: rgba(255, 255, 255, 0.04);
322
- border-color: rgba(139, 92, 246, 0.3);
323
- transform: translateX(4px);
324
- }
325
-
326
- .agent-info {
327
- display: flex;
328
- flex-direction: column;
329
- gap: 0.25rem;
330
- }
331
-
332
- .agent-name {
333
- font-weight: 600;
334
- color: #e2e8f0;
335
- font-size: 0.9rem;
336
- }
337
-
338
- .agent-role {
339
- font-size: 0.75rem;
340
- color: #64748b;
341
- }
342
-
343
- .agent-state {
344
- display: flex;
345
- align-items: center;
346
- gap: 0.4rem;
347
- font-size: 0.75rem;
348
- font-weight: 600;
349
- padding: 0.25rem 0.5rem;
350
- border-radius: 6px;
351
- }
352
-
353
- .state-active { color: #10b981; background: rgba(16, 185, 129, 0.1); }
354
- .state-working { color: #f59e0b; background: rgba(245, 158, 11, 0.1); }
355
- .state-idle { color: #94a3b8; background: rgba(148, 163, 184, 0.1); }
356
-
357
- /* Middle Panel - Terminal Screen */
358
- .terminal-panel {
359
- flex: 1;
360
- display: flex;
361
- flex-direction: column;
362
- }
363
-
364
- .terminal-header-controls {
365
- display: flex;
366
- gap: 0.4rem;
367
- }
368
-
369
- .dot {
370
- width: 12px;
371
- height: 12px;
372
- border-radius: 50%;
373
- }
374
- .dot-red { background-color: #ef4444; }
375
- .dot-yellow { background-color: #f59e0b; }
376
- .dot-green { background-color: #10b981; }
377
-
378
- .terminal-screen {
379
- flex: 1;
380
- background: #050508;
381
- font-family: 'Fira Code', monospace;
382
- padding: 1.25rem;
383
- overflow-y: auto;
384
- font-size: 0.85rem;
385
- line-height: 1.6;
386
- color: #a7f3d0;
387
- display: flex;
388
- flex-direction: column;
389
- gap: 0.5rem;
390
- }
391
-
392
- .terminal-line {
393
- display: flex;
394
- gap: 0.5rem;
395
- align-items: flex-start;
396
- border-left: 2px solid transparent;
397
- padding-left: 0.5rem;
398
- }
399
-
400
- .line-timestamp {
401
- color: #64748b;
402
- flex-shrink: 0;
403
- font-size: 0.75rem;
404
- }
405
-
406
- .line-trace {
407
- color: #8b5cf6;
408
- font-weight: 600;
409
- flex-shrink: 0;
410
- font-size: 0.75rem;
411
- }
412
-
413
- .line-agent {
414
- color: #06b6d4;
415
- font-weight: 600;
416
- flex-shrink: 0;
417
- }
418
-
419
- .line-content {
420
- color: #e2e8f0;
421
- word-break: break-all;
422
- }
423
-
424
- .line-status-success {
425
- color: #10b981;
426
- font-weight: bold;
427
- }
428
-
429
- .line-status-failure {
430
- color: #ef4444;
431
- font-weight: bold;
432
- }
433
-
434
- /* Right Panel - Tasks & Metadata */
435
- .meta-panel {
436
- width: 320px;
437
- flex-shrink: 0;
438
- display: flex;
439
- flex-direction: column;
440
- gap: 1.5rem;
441
- background: transparent;
442
- border: none;
443
- box-shadow: none;
444
- overflow: visible;
445
- }
446
-
447
- .meta-card {
448
- background: rgba(18, 20, 29, 0.6);
449
- border: 1px solid rgba(255, 255, 255, 0.05);
450
- border-radius: 16px;
451
- backdrop-filter: blur(16px);
452
- padding: 1.25rem;
453
- display: flex;
454
- flex-direction: column;
455
- gap: 1rem;
456
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
457
- }
458
-
459
- .meta-card-title {
460
- font-size: 0.85rem;
461
- font-weight: 600;
462
- color: #ffffff;
463
- letter-spacing: 0.05em;
464
- text-transform: uppercase;
465
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
466
- padding-bottom: 0.5rem;
467
- }
468
-
469
- /* Task layout */
470
- .task-list {
471
- display: flex;
472
- flex-direction: column;
473
- gap: 0.75rem;
474
- }
475
-
476
- .task-item {
477
- background: rgba(255, 255, 255, 0.02);
478
- border: 1px solid rgba(255, 255, 255, 0.03);
479
- border-radius: 8px;
480
- padding: 0.75rem;
481
- display: flex;
482
- flex-direction: column;
483
- gap: 0.5rem;
484
- }
485
-
486
- .task-meta-top {
487
- display: flex;
488
- justify-content: space-between;
489
- align-items: center;
490
- font-size: 0.75rem;
491
- }
492
-
493
- .task-title {
494
- font-size: 0.825rem;
495
- font-weight: 500;
496
- color: #e2e8f0;
497
- }
498
-
499
- .task-agent-badge {
500
- color: #06b6d4;
501
- font-weight: 600;
502
- }
503
-
504
- .task-status-badge {
505
- font-size: 0.7rem;
506
- font-weight: bold;
507
- padding: 0.15rem 0.4rem;
508
- border-radius: 4px;
509
- text-transform: uppercase;
510
- }
511
-
512
- .status-inprogress { color: #3b82f6; background: rgba(59, 130, 246, 0.1); }
513
- .status-pending { color: #f59e0b; background: rgba(245, 158, 11, 0.1); }
514
- .status-completed { color: #10b981; background: rgba(16, 185, 129, 0.1); }
515
-
516
- /* Memory metrics */
517
- .metric-row {
518
- display: flex;
519
- flex-direction: column;
520
- gap: 0.4rem;
521
- }
522
-
523
- .metric-label-container {
524
- display: flex;
525
- justify-content: space-between;
526
- font-size: 0.8rem;
527
- color: #94a3b8;
528
- }
529
-
530
- .metric-bar-bg {
531
- height: 8px;
532
- background: rgba(255, 255, 255, 0.05);
533
- border-radius: 9999px;
534
- overflow: hidden;
535
- }
536
-
537
- .metric-bar-fill {
538
- height: 100%;
539
- background: linear-gradient(to right, #8b5cf6, #06b6d4);
540
- border-radius: 9999px;
541
- width: 0%;
542
- transition: width 0.5s ease;
543
- }
544
-
545
- /* Scrollbar styles */
546
- ::-webkit-scrollbar {
547
- width: 6px;
548
- }
549
- ::-webkit-scrollbar-track {
550
- background: transparent;
551
- }
552
- ::-webkit-scrollbar-thumb {
553
- background: rgba(255, 255, 255, 0.1);
554
- border-radius: 9999px;
555
- }
556
- ::-webkit-scrollbar-thumb:hover {
557
- background: rgba(255, 255, 255, 0.2);
558
- }
559
-
560
- </style>
561
- </head>
562
- <body>
563
-
564
- <header>
565
- <div class="logo-container">
566
- <div class="logo-icon">E</div>
567
- <div class="logo-text">Agent Enderun Live Monitor</div>
568
- </div>
569
- <div class="system-status">
570
- <div>Active Phase: <span id="system-phase" style="color:#ffffff; font-weight:600;">PHASE_0</span></div>
571
- <div>Trace ID: <span id="system-trace" style="color:#8b5cf6; font-weight:600; font-family:'Fira Code',monospace;">N/A</span></div>
572
- <div class="status-badge">
573
- <span class="status-dot"></span>
574
- <span>Live Connection</span>
575
- </div>
576
- </div>
577
- </header>
578
-
579
- <div class="main-layout">
580
-
581
- <!-- Left Panel: Agents -->
582
- <div class="panel agents-panel">
583
- <div class="panel-header">
584
- <span>Army Agents</span>
585
- <span id="agents-online-count" style="color: #10b981; font-size: 0.8rem;">12 Online</span>
586
- </div>
587
- <div class="agent-list" id="agent-list-container">
588
- <!-- Dynamic Agents -->
589
- <div style="color:#64748b; font-size:0.875rem; text-align:center; padding:2rem;">Loading...</div>
590
- </div>
591
- </div>
592
-
593
- <!-- Middle Panel: Terminal -->
594
- <div class="panel terminal-panel">
595
- <div class="panel-header">
596
- <span>Live Orchestration Logs</span>
597
- <div class="terminal-header-controls">
598
- <span class="dot dot-red"></span>
599
- <span class="dot dot-yellow"></span>
600
- <span class="dot dot-green"></span>
601
- </div>
602
- </div>
603
- <div class="terminal-screen" id="terminal-screen-container">
604
- <div class="terminal-line">
605
- <span class="line-content">> Initializing Agent Enderun orchestrator...</span>
606
- </div>
607
- </div>
608
- </div>
609
-
610
- <!-- Right Panel: Tasks & System Status -->
611
- <div class="meta-panel">
612
-
613
- <!-- Active Tasks -->
614
- <div class="meta-card">
615
- <div class="meta-card-title">Active Tasks</div>
616
- <div class="task-list" id="task-list-container">
617
- <div style="color:#64748b; font-size:0.825rem; text-align:center; padding:1rem;">No active tasks</div>
618
- </div>
619
- </div>
620
-
621
- <!-- Project Memory State -->
622
- <div class="meta-card">
623
- <div class="meta-card-title">Project Memory State</div>
624
- <div class="metric-row">
625
- <div class="metric-label-container">
626
- <span>Agent Compliance</span>
627
- <span id="metric-compliance">100%</span>
628
- </div>
629
- <div class="metric-bar-bg">
630
- <div class="metric-bar-fill" id="compliance-bar" style="width: 100%;"></div>
631
- </div>
632
- </div>
633
- <div class="metric-row">
634
- <div class="metric-label-container">
635
- <span>Completed Tasks</span>
636
- <span id="metric-tasks-done">100%</span>
637
- </div>
638
- <div class="metric-bar-bg">
639
- <div class="metric-bar-fill" id="tasks-done-bar" style="width: 100%; background: linear-gradient(to right, #10b981, #059669);"></div>
640
- </div>
641
- </div>
642
- </div>
643
-
644
- </div>
645
-
646
- </div>
647
-
648
- <script>
649
- const API_STATUS = '/api/status';
650
- const API_AGENTS = '/api/agents';
651
-
652
- // Predefined list of Enderun core agents to ensure we display all 12 correctly
653
- const CORE_AGENTS = [
654
- { name: "manager", role: "CTO / Orchestrator", status: "state-active", stateLabel: "Active" },
655
- { name: "backend", role: "Logic & API Specialist", status: "state-idle", stateLabel: "Idle" },
656
- { name: "frontend", role: "UI & UX Specialist", status: "state-idle", stateLabel: "Idle" },
657
- { name: "database", role: "SQL & Migration Specialist", status: "state-idle", stateLabel: "Idle" },
658
- { name: "quality", role: "QA & Compliance Specialist", status: "state-idle", stateLabel: "Idle" },
659
- { name: "devops", role: "CI/CD & Deploy Specialist", status: "state-idle", stateLabel: "Idle" },
660
- { name: "security", role: "Crypt & RLS Specialist", status: "state-idle", stateLabel: "Idle" },
661
- { name: "explorer", role: "Code Discovery Specialist", status: "state-idle", stateLabel: "Idle" },
662
- { name: "git", role: "Version Control Specialist", status: "state-idle", stateLabel: "Idle" },
663
- { name: "analyst", role: "Specs Verification Specialist", status: "state-idle", stateLabel: "Idle" },
664
- { name: "mobile", role: "Mobile Specialist", status: "state-idle", stateLabel: "Idle" },
665
- { name: "native", role: "Desktop wrapper Specialist", status: "state-idle", stateLabel: "Idle" }
666
- ];
667
-
668
- let loadedAgents = [];
669
-
670
- async function fetchAgents() {
671
- try {
672
- const res = await fetch(API_AGENTS);
673
- loadedAgents = await res.json();
674
- renderAgents();
675
- } catch (e) {
676
- console.error("Agents fetch error", e);
677
- renderAgents(); // Fallback to core agents list
678
- }
679
- }
680
-
681
- function renderAgents(activeAgentName = null) {
682
- const container = document.getElementById('agent-list-container');
683
- container.innerHTML = '';
684
-
685
- const displayList = CORE_AGENTS.map(core => {
686
- const found = loadedAgents.find(l => l.name === core.name);
687
- return {
688
- name: core.name,
689
- role: found ? found.role : core.role,
690
- displayName: found ? found.displayName : core.name.toUpperCase()
691
- };
692
- });
693
-
694
- displayList.forEach(agent => {
695
- let stateClass = 'state-idle';
696
- let stateLabel = 'Idle';
697
-
698
- if (agent.name === 'manager') {
699
- stateClass = 'state-active';
700
- stateLabel = 'Active';
701
- }
702
-
703
- if (activeAgentName && agent.name === activeAgentName.replace('@', '').toLowerCase()) {
704
- stateClass = 'state-working';
705
- stateLabel = 'Working';
706
- }
707
-
708
- const card = document.createElement('div');
709
- card.className = 'agent-card';
710
- card.innerHTML = \`
711
- <div class="agent-info">
712
- <span class="agent-name">@\${agent.name}</span>
713
- <span class="agent-role">\${agent.role}</span>
714
- </div>
715
- <span class="agent-state \${stateClass}">\${stateLabel}</span>
716
- \`;
717
- container.appendChild(card);
718
- });
719
-
720
- document.getElementById('agents-online-count').innerText = \`\${displayList.length} Online\`;
721
- }
722
-
723
- let renderedLogTimestamps = new Set();
724
-
725
- async function fetchStatus() {
726
- try {
727
- const res = await fetch(API_STATUS);
728
- const data = await res.json();
729
-
730
- if (data.error) {
731
- console.error("API error", data.error);
732
- return;
733
- }
734
-
735
- // Update Header Status
736
- document.getElementById('system-phase').innerText = data.phase || 'PHASE_0';
737
- document.getElementById('system-trace').innerText = data.traceId || 'N/A';
738
-
739
- // Update Active Tasks
740
- const taskContainer = document.getElementById('task-list-container');
741
- if (data.tasks && data.tasks.length > 0) {
742
- taskContainer.innerHTML = '';
743
- data.tasks.forEach(task => {
744
- const statusClass = task.status.toLowerCase().includes('progress') ? 'status-inprogress'
745
- : task.status.toLowerCase().includes('pending') ? 'status-pending'
746
- : 'status-completed';
747
- const item = document.createElement('div');
748
- item.className = 'task-item';
749
- item.innerHTML = \`
750
- <div class="task-meta-top">
751
- <span class="task-agent-badge">\${task.agent}</span>
752
- <span class="task-status-badge \${statusClass}">\${task.status}</span>
753
- </div>
754
- <span class="task-title">\${task.task}</span>
755
- \`;
756
- taskContainer.appendChild(item);
757
- });
758
- } else {
759
- taskContainer.innerHTML = '<div style="color:#64748b; font-size:0.825rem; text-align:center; padding:1rem;">No active tasks</div>';
760
- }
761
-
762
- // Update Terminal logs dynamically with manager.json
763
- const terminal = document.getElementById('terminal-screen-container');
764
-
765
- if (data.logs && data.logs.length > 0) {
766
- // Filter and append new logs
767
- let activeAgent = null;
768
- data.logs.forEach(log => {
769
- const uniqueKey = log.timestamp + '-' + log.action;
770
- if (!renderedLogTimestamps.has(uniqueKey)) {
771
- renderedLogTimestamps.add(uniqueKey);
772
-
773
- const line = document.createElement('div');
774
- line.className = 'terminal-line';
775
-
776
- const cleanTime = new Date(log.timestamp).toLocaleTimeString();
777
- const cleanTrace = log.requestId ? log.requestId.slice(0, 8) : 'T-000';
778
-
779
- const statusColorClass = log.status === 'SUCCESS' ? 'line-status-success' : 'line-status-failure';
780
-
781
- line.innerHTML = \`
782
- <span class="line-timestamp">[\${cleanTime}]</span>
783
- <span class="line-trace">[TR-\${cleanTrace}]</span>
784
- <span class="line-agent">\${log.agent}:</span>
785
- <span class="line-content">\${log.summary} <span class="\${statusColorClass}">[\${log.status}]</span></span>
786
- \`;
787
- terminal.appendChild(line);
788
- terminal.scrollTop = terminal.scrollHeight;
789
-
790
- activeAgent = log.agent;
791
- }
792
- });
793
-
794
- if (activeAgent) {
795
- renderAgents(activeAgent);
796
- }
797
- } else if (data.history && data.history.length > 0) {
798
- // Fallback to parsed project memory history
799
- data.history.forEach(hist => {
800
- const uniqueKey = hist.title;
801
- if (!renderedLogTimestamps.has(uniqueKey)) {
802
- renderedLogTimestamps.add(uniqueKey);
803
-
804
- const line = document.createElement('div');
805
- line.className = 'terminal-line';
806
- line.innerHTML = \`
807
- <span class="line-timestamp">[MEMORY]</span>
808
- <span class="line-agent">✏️ \${hist.title}:</span>
809
- <span class="line-content">\${hist.body.join(' ')}</span>
810
- \`;
811
- terminal.appendChild(line);
812
- terminal.scrollTop = terminal.scrollHeight;
813
- }
814
- });
815
- }
816
- } catch (e) {
817
- console.error("Status fetch error", e);
818
- }
819
- }
820
-
821
- // Initialize and Start Polling
822
- fetchAgents().then(() => {
823
- fetchStatus();
824
- setInterval(fetchStatus, 2000);
825
- });
826
- </script>
827
- </body>
828
- </html>
829
- `;
830
-
831
- // Start simple HTTP Server
832
- const server = http.createServer((req, res) => {
833
- // API: Status
834
- if (req.url === "/api/status") {
835
- const mem = parseProjectMemory();
836
- const logs = readManagerLogs();
837
- res.writeHead(200, { "Content-Type": "application/json" });
838
- res.end(JSON.stringify({ ...mem, logs }));
839
- return;
840
- }
841
-
842
- // API: Agents list
843
- if (req.url === "/api/agents") {
844
- const list = listAgents();
845
- res.writeHead(200, { "Content-Type": "application/json" });
846
- res.end(JSON.stringify(list));
847
- return;
848
- }
849
-
850
- // Static HTML Serve
851
- if (req.url === "/" || req.url === "/index.html") {
852
- res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8" });
853
- res.end(HTML_CONTENT);
854
- return;
855
- }
856
-
857
- // Fallback 404
858
- res.writeHead(404, { "Content-Type": "text/plain" });
859
- res.end("Not Found");
18
+ const child = spawn("node", [cliPath, "dashboard", ...process.argv.slice(2)], {
19
+ stdio: "inherit",
20
+ shell: false
860
21
  });
861
22
 
862
- server.listen(PORT, () => {
863
- console.log("================================================================================");
864
- console.log(`🖥️ AGENT ENDERUN LIVE MONITOR SERVED AT: http://localhost:${PORT}`);
865
- console.log("================================================================================");
23
+ child.on("exit", (code) => {
24
+ process.exit(code ?? 0);
866
25
  });