agent-enderun 1.0.7 → 1.0.9

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 (312) hide show
  1. package/.enderun/ARCHITECTURE.md +1 -0
  2. package/.enderun/BRAIN_DASHBOARD.md +1 -1
  3. package/.enderun/ENDERUN.md +2 -2
  4. package/.enderun/SECURITY.md +1 -0
  5. package/.enderun/STATUS.md +5 -6
  6. package/.enderun/agents/agent_army_schema.json +71 -77
  7. package/.enderun/agents/analyst.json +32 -0
  8. package/.enderun/agents/backend.json +32 -0
  9. package/.enderun/agents/database.json +32 -0
  10. package/.enderun/agents/devops.json +32 -0
  11. package/.enderun/agents/explorer.json +32 -0
  12. package/.enderun/agents/frontend.json +32 -0
  13. package/.enderun/agents/git.json +32 -0
  14. package/.enderun/agents/manager.json +32 -0
  15. package/.enderun/agents/mobile.json +32 -0
  16. package/.enderun/agents/native.json +32 -0
  17. package/.enderun/agents/quality.json +32 -0
  18. package/.enderun/agents/schema/agent-lifecycle-schema.json +35 -80
  19. package/.enderun/agents/security.json +32 -0
  20. package/.enderun/cli-commands.json +7 -5
  21. package/.enderun/config.json +1 -1
  22. package/.enderun/knowledge/ARCHITECTURE.md +1 -0
  23. package/.enderun/knowledge/SECURITY.md +1 -0
  24. package/.enderun/knowledge/SHIM_TEMPLATE.md +12 -1
  25. package/.enderun/knowledge/evaluation_engine.md +11 -0
  26. package/.enderun/knowledge/legacy_onboarding.md +11 -0
  27. package/.enderun/knowledge/project_scaffold_guidelines.md +11 -0
  28. package/.enderun/knowledge/reference_application_guidelines.md +11 -0
  29. package/.enderun/logs/manager.json +52 -23
  30. package/.enderun/memory/PROJECT_MEMORY.md +14 -12
  31. package/.enderun/observability/README.md +19 -0
  32. package/README.md +38 -101
  33. package/agent.md +1 -1
  34. package/bin/hermes-sandbox.js +9 -0
  35. package/bin/init-check.js +9 -0
  36. package/bin/validate-agent-army.js +34 -92
  37. package/dist/apps/backend/src/types/index.d.ts +9 -0
  38. package/dist/apps/backend/src/types/index.js +5 -0
  39. package/dist/apps/backend/src/types/index.js.map +1 -0
  40. package/dist/apps/web/src/main.d.ts +1 -0
  41. package/dist/apps/web/src/main.js +9 -0
  42. package/dist/apps/web/src/main.js.map +1 -0
  43. package/dist/apps/web/vite.config.d.ts +2 -0
  44. package/dist/apps/web/vite.config.js +6 -0
  45. package/dist/apps/web/vite.config.js.map +1 -0
  46. package/dist/framework-mcp/src/index.d.ts +1 -0
  47. package/dist/framework-mcp/src/index.js +71 -0
  48. package/dist/framework-mcp/src/index.js.map +1 -0
  49. package/dist/framework-mcp/src/tools/definitions.d.ts +2 -0
  50. package/dist/framework-mcp/src/tools/definitions.js +111 -0
  51. package/dist/framework-mcp/src/tools/definitions.js.map +1 -0
  52. package/dist/framework-mcp/src/tools/file_system/patch_file.d.ts +2 -0
  53. package/dist/framework-mcp/src/tools/file_system/patch_file.js +19 -0
  54. package/dist/framework-mcp/src/tools/file_system/patch_file.js.map +1 -0
  55. package/dist/framework-mcp/src/tools/file_system/read_file.d.ts +2 -0
  56. package/dist/framework-mcp/src/tools/file_system/read_file.js +8 -0
  57. package/dist/framework-mcp/src/tools/file_system/read_file.js.map +1 -0
  58. package/dist/framework-mcp/src/tools/file_system/replace_text.d.ts +2 -0
  59. package/dist/framework-mcp/src/tools/file_system/replace_text.js +32 -0
  60. package/dist/framework-mcp/src/tools/file_system/replace_text.js.map +1 -0
  61. package/dist/framework-mcp/src/tools/file_system/write_file.d.ts +2 -0
  62. package/dist/framework-mcp/src/tools/file_system/write_file.js +10 -0
  63. package/dist/framework-mcp/src/tools/file_system/write_file.js.map +1 -0
  64. package/dist/framework-mcp/src/tools/framework/get_status.d.ts +2 -0
  65. package/dist/framework-mcp/src/tools/framework/get_status.js +6 -0
  66. package/dist/framework-mcp/src/tools/framework/get_status.js.map +1 -0
  67. package/dist/framework-mcp/src/tools/framework/orchestrate.d.ts +2 -0
  68. package/dist/framework-mcp/src/tools/framework/orchestrate.js +6 -0
  69. package/dist/framework-mcp/src/tools/framework/orchestrate.js.map +1 -0
  70. package/dist/framework-mcp/src/tools/framework/update_contract_hash.d.ts +2 -0
  71. package/dist/framework-mcp/src/tools/framework/update_contract_hash.js +6 -0
  72. package/dist/framework-mcp/src/tools/framework/update_contract_hash.js.map +1 -0
  73. package/dist/framework-mcp/src/tools/framework/update_memory.d.ts +2 -0
  74. package/dist/framework-mcp/src/tools/framework/update_memory.js +9 -0
  75. package/dist/framework-mcp/src/tools/framework/update_memory.js.map +1 -0
  76. package/dist/framework-mcp/src/tools/index.d.ts +5 -0
  77. package/dist/framework-mcp/src/tools/index.js +26 -0
  78. package/dist/framework-mcp/src/tools/index.js.map +1 -0
  79. package/dist/framework-mcp/src/tools/messaging/log_action.d.ts +2 -0
  80. package/dist/framework-mcp/src/tools/messaging/log_action.js +23 -0
  81. package/dist/framework-mcp/src/tools/messaging/log_action.js.map +1 -0
  82. package/dist/framework-mcp/src/tools/messaging/send_message.d.ts +2 -0
  83. package/dist/framework-mcp/src/tools/messaging/send_message.js +24 -0
  84. package/dist/framework-mcp/src/tools/messaging/send_message.js.map +1 -0
  85. package/dist/framework-mcp/src/tools/types.d.ts +47 -0
  86. package/dist/framework-mcp/src/tools/types.js +2 -0
  87. package/dist/framework-mcp/src/tools/types.js.map +1 -0
  88. package/dist/framework-mcp/src/utils/cli.d.ts +5 -0
  89. package/dist/framework-mcp/src/utils/cli.js +21 -0
  90. package/dist/framework-mcp/src/utils/cli.js.map +1 -0
  91. package/dist/framework-mcp/src/utils/security.d.ts +12 -0
  92. package/dist/framework-mcp/src/utils/security.js +54 -0
  93. package/dist/framework-mcp/src/utils/security.js.map +1 -0
  94. package/dist/src/cli/adapters.d.ts +32 -0
  95. package/dist/src/cli/adapters.js +264 -0
  96. package/dist/src/cli/adapters.js.map +1 -0
  97. package/dist/src/cli/commands/app.d.ts +4 -0
  98. package/dist/src/cli/commands/app.js +32 -0
  99. package/dist/src/cli/commands/app.js.map +1 -0
  100. package/dist/src/cli/commands/check.d.ts +6 -0
  101. package/dist/src/cli/commands/check.js +110 -0
  102. package/dist/src/cli/commands/check.js.map +1 -0
  103. package/dist/src/cli/commands/compliance.d.ts +1 -0
  104. package/dist/src/cli/commands/compliance.js +51 -0
  105. package/dist/src/cli/commands/compliance.js.map +1 -0
  106. package/dist/src/cli/commands/contract.d.ts +8 -0
  107. package/dist/src/cli/commands/contract.js +73 -0
  108. package/dist/src/cli/commands/contract.js.map +1 -0
  109. package/dist/src/cli/commands/explorer.d.ts +2 -0
  110. package/dist/src/cli/commands/explorer.js +43 -0
  111. package/dist/src/cli/commands/explorer.js.map +1 -0
  112. package/dist/src/cli/commands/git.d.ts +2 -0
  113. package/dist/src/cli/commands/git.js +41 -0
  114. package/dist/src/cli/commands/git.js.map +1 -0
  115. package/dist/src/cli/commands/init.d.ts +1 -0
  116. package/dist/src/cli/commands/init.js +338 -0
  117. package/dist/src/cli/commands/init.js.map +1 -0
  118. package/dist/src/cli/commands/knowledge.d.ts +2 -0
  119. package/dist/src/cli/commands/knowledge.js +43 -0
  120. package/dist/src/cli/commands/knowledge.js.map +1 -0
  121. package/dist/src/cli/commands/lint.d.ts +4 -0
  122. package/dist/src/cli/commands/lint.js +24 -0
  123. package/dist/src/cli/commands/lint.js.map +1 -0
  124. package/dist/src/cli/commands/log.d.ts +9 -0
  125. package/dist/src/cli/commands/log.js +33 -0
  126. package/dist/src/cli/commands/log.js.map +1 -0
  127. package/dist/src/cli/commands/memory.d.ts +1 -0
  128. package/dist/src/cli/commands/memory.js +72 -0
  129. package/dist/src/cli/commands/memory.js.map +1 -0
  130. package/dist/src/cli/commands/orchestrate.d.ts +1 -0
  131. package/dist/src/cli/commands/orchestrate.js +111 -0
  132. package/dist/src/cli/commands/orchestrate.js.map +1 -0
  133. package/dist/src/cli/commands/script.d.ts +1 -0
  134. package/dist/src/cli/commands/script.js +20 -0
  135. package/dist/src/cli/commands/script.js.map +1 -0
  136. package/dist/src/cli/commands/security.d.ts +1 -0
  137. package/dist/src/cli/commands/security.js +37 -0
  138. package/dist/src/cli/commands/security.js.map +1 -0
  139. package/dist/src/cli/commands/status.d.ts +4 -0
  140. package/dist/src/cli/commands/status.js +56 -0
  141. package/dist/src/cli/commands/status.js.map +1 -0
  142. package/dist/src/cli/commands/trace.d.ts +4 -0
  143. package/dist/src/cli/commands/trace.js +42 -0
  144. package/dist/src/cli/commands/trace.js.map +1 -0
  145. package/dist/src/cli/index.d.ts +2 -0
  146. package/dist/src/cli/index.js +117 -0
  147. package/dist/src/cli/index.js.map +1 -0
  148. package/dist/src/cli/utils/app.d.ts +33 -0
  149. package/dist/src/cli/utils/app.js +710 -0
  150. package/dist/src/cli/utils/app.js.map +1 -0
  151. package/dist/src/cli/utils/claude.d.ts +8 -0
  152. package/dist/src/cli/utils/claude.js +56 -0
  153. package/dist/src/cli/utils/claude.js.map +1 -0
  154. package/dist/src/cli/utils/fs.d.ts +11 -0
  155. package/dist/src/cli/utils/fs.js +144 -0
  156. package/dist/src/cli/utils/fs.js.map +1 -0
  157. package/dist/src/cli/utils/memory.d.ts +14 -0
  158. package/dist/src/cli/utils/memory.js +173 -0
  159. package/dist/src/cli/utils/memory.js.map +1 -0
  160. package/dist/src/cli/utils/pkg.d.ts +24 -0
  161. package/dist/src/cli/utils/pkg.js +254 -0
  162. package/dist/src/cli/utils/pkg.js.map +1 -0
  163. package/dist/src/cli/utils/string.d.ts +6 -0
  164. package/dist/src/cli/utils/string.js +44 -0
  165. package/dist/src/cli/utils/string.js.map +1 -0
  166. package/dist/src/cli/utils/time.d.ts +2 -0
  167. package/dist/src/cli/utils/time.js +28 -0
  168. package/dist/src/cli/utils/time.js.map +1 -0
  169. package/dist/tests/adapter.test.d.ts +1 -0
  170. package/dist/tests/adapter.test.js +80 -0
  171. package/dist/tests/adapter.test.js.map +1 -0
  172. package/dist/tests/framework-init-test/framework-mcp/src/index.d.ts +1 -0
  173. package/dist/tests/framework-init-test/framework-mcp/src/index.js +71 -0
  174. package/dist/tests/framework-init-test/framework-mcp/src/index.js.map +1 -0
  175. package/dist/tests/framework-init-test/framework-mcp/src/tools/definitions.d.ts +2 -0
  176. package/dist/tests/framework-init-test/framework-mcp/src/tools/definitions.js +111 -0
  177. package/dist/tests/framework-init-test/framework-mcp/src/tools/definitions.js.map +1 -0
  178. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/patch_file.d.ts +2 -0
  179. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/patch_file.js +19 -0
  180. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/patch_file.js.map +1 -0
  181. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/read_file.d.ts +2 -0
  182. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/read_file.js +8 -0
  183. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/read_file.js.map +1 -0
  184. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/replace_text.d.ts +2 -0
  185. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/replace_text.js +32 -0
  186. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/replace_text.js.map +1 -0
  187. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/write_file.d.ts +2 -0
  188. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/write_file.js +10 -0
  189. package/dist/tests/framework-init-test/framework-mcp/src/tools/file_system/write_file.js.map +1 -0
  190. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/get_status.d.ts +2 -0
  191. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/get_status.js +6 -0
  192. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/get_status.js.map +1 -0
  193. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/orchestrate.d.ts +2 -0
  194. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/orchestrate.js +6 -0
  195. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/orchestrate.js.map +1 -0
  196. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/update_contract_hash.d.ts +2 -0
  197. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/update_contract_hash.js +6 -0
  198. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/update_contract_hash.js.map +1 -0
  199. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/update_memory.d.ts +2 -0
  200. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/update_memory.js +9 -0
  201. package/dist/tests/framework-init-test/framework-mcp/src/tools/framework/update_memory.js.map +1 -0
  202. package/dist/tests/framework-init-test/framework-mcp/src/tools/index.d.ts +5 -0
  203. package/dist/tests/framework-init-test/framework-mcp/src/tools/index.js +26 -0
  204. package/dist/tests/framework-init-test/framework-mcp/src/tools/index.js.map +1 -0
  205. package/dist/tests/framework-init-test/framework-mcp/src/tools/messaging/log_action.d.ts +2 -0
  206. package/dist/tests/framework-init-test/framework-mcp/src/tools/messaging/log_action.js +23 -0
  207. package/dist/tests/framework-init-test/framework-mcp/src/tools/messaging/log_action.js.map +1 -0
  208. package/dist/tests/framework-init-test/framework-mcp/src/tools/messaging/send_message.d.ts +2 -0
  209. package/dist/tests/framework-init-test/framework-mcp/src/tools/messaging/send_message.js +24 -0
  210. package/dist/tests/framework-init-test/framework-mcp/src/tools/messaging/send_message.js.map +1 -0
  211. package/dist/tests/framework-init-test/framework-mcp/src/tools/types.d.ts +47 -0
  212. package/dist/tests/framework-init-test/framework-mcp/src/tools/types.js +2 -0
  213. package/dist/tests/framework-init-test/framework-mcp/src/tools/types.js.map +1 -0
  214. package/dist/tests/framework-init-test/framework-mcp/src/utils/cli.d.ts +5 -0
  215. package/dist/tests/framework-init-test/framework-mcp/src/utils/cli.js +21 -0
  216. package/dist/tests/framework-init-test/framework-mcp/src/utils/cli.js.map +1 -0
  217. package/dist/tests/framework-init-test/framework-mcp/src/utils/security.d.ts +12 -0
  218. package/dist/tests/framework-init-test/framework-mcp/src/utils/security.js +54 -0
  219. package/dist/tests/framework-init-test/framework-mcp/src/utils/security.js.map +1 -0
  220. package/dist/tests/framework-init-test/framework-mcp/tests/tools/file_system/replace_text.test.d.ts +1 -0
  221. package/dist/tests/framework-init-test/framework-mcp/tests/tools/file_system/replace_text.test.js +69 -0
  222. package/dist/tests/framework-init-test/framework-mcp/tests/tools/file_system/replace_text.test.js.map +1 -0
  223. package/dist/tests/framework-init-test/panda.config.d.ts +4 -0
  224. package/dist/tests/framework-init-test/panda.config.js +95 -0
  225. package/dist/tests/framework-init-test/panda.config.js.map +1 -0
  226. package/dist/tests/framework-init-test/vitest.config.d.ts +2 -0
  227. package/dist/tests/framework-init-test/vitest.config.js +19 -0
  228. package/dist/tests/framework-init-test/vitest.config.js.map +1 -0
  229. package/dist/tests/gemini.test.d.ts +1 -0
  230. package/dist/tests/gemini.test.js +38 -0
  231. package/dist/tests/gemini.test.js.map +1 -0
  232. package/dist/tests/initial.test.d.ts +1 -0
  233. package/dist/tests/initial.test.js +7 -0
  234. package/dist/tests/initial.test.js.map +1 -0
  235. package/dist/vitest.config.d.ts +2 -0
  236. package/dist/vitest.config.js +19 -0
  237. package/dist/vitest.config.js.map +1 -0
  238. package/docs/getting-started.md +4 -4
  239. package/eslint.config.js +1 -1
  240. package/framework-mcp/dist/index.js +2 -2
  241. package/framework-mcp/dist/src/index.js +70 -0
  242. package/framework-mcp/dist/src/tools/definitions.js +110 -0
  243. package/framework-mcp/dist/src/tools/file_system/patch_file.js +18 -0
  244. package/framework-mcp/dist/src/tools/file_system/read_file.js +7 -0
  245. package/framework-mcp/dist/src/tools/file_system/replace_text.js +31 -0
  246. package/framework-mcp/dist/src/tools/file_system/write_file.js +9 -0
  247. package/framework-mcp/dist/src/tools/framework/get_status.js +5 -0
  248. package/framework-mcp/dist/src/tools/framework/orchestrate.js +5 -0
  249. package/framework-mcp/dist/src/tools/framework/update_contract_hash.js +5 -0
  250. package/framework-mcp/dist/src/tools/framework/update_memory.js +8 -0
  251. package/framework-mcp/dist/src/tools/index.js +25 -0
  252. package/framework-mcp/dist/src/tools/messaging/log_action.js +22 -0
  253. package/framework-mcp/dist/src/tools/messaging/send_message.js +23 -0
  254. package/framework-mcp/dist/src/tools/types.js +1 -0
  255. package/framework-mcp/dist/src/utils/cli.js +20 -0
  256. package/framework-mcp/dist/src/utils/security.js +53 -0
  257. package/framework-mcp/dist/tests/tools/file_system/replace_text.test.js +68 -0
  258. package/framework-mcp/dist/tools/definitions.js +1 -0
  259. package/framework-mcp/dist/tools/file_system/replace_text.js +18 -1
  260. package/framework-mcp/dist/tools/framework/get_status.js +2 -2
  261. package/framework-mcp/dist/tools/framework/orchestrate.js +2 -2
  262. package/framework-mcp/dist/tools/framework/update_contract_hash.js +2 -2
  263. package/framework-mcp/dist/tools/framework/update_memory.js +1 -1
  264. package/framework-mcp/dist/tools/messaging/send_message.js +4 -2
  265. package/framework-mcp/dist/utils/cli.js +2 -2
  266. package/framework-mcp/dist/utils/security.js +23 -5
  267. package/framework-mcp/package.json +3 -3
  268. package/framework-mcp/src/index.ts +2 -2
  269. package/framework-mcp/src/tools/definitions.ts +1 -0
  270. package/framework-mcp/src/tools/file_system/replace_text.ts +21 -1
  271. package/framework-mcp/src/tools/framework/get_status.ts +3 -3
  272. package/framework-mcp/src/tools/framework/orchestrate.ts +3 -3
  273. package/framework-mcp/src/tools/framework/update_contract_hash.ts +3 -3
  274. package/framework-mcp/src/tools/framework/update_memory.ts +1 -1
  275. package/framework-mcp/src/tools/messaging/send_message.ts +5 -2
  276. package/framework-mcp/src/tools/types.ts +3 -0
  277. package/framework-mcp/src/utils/cli.ts +2 -2
  278. package/framework-mcp/src/utils/security.ts +23 -5
  279. package/framework-mcp/tests/tools/file_system/replace_text.test.js +68 -0
  280. package/framework-mcp/tests/tools/file_system/replace_text.test.ts +77 -0
  281. package/framework-mcp/tsconfig.json +1 -2
  282. package/mcp.json +4 -4
  283. package/package.json +4 -3
  284. package/src/cli/adapters.ts +16 -9
  285. package/src/cli/commands/check.ts +8 -5
  286. package/src/cli/commands/contract.ts +2 -2
  287. package/src/cli/commands/init.ts +213 -433
  288. package/src/cli/commands/memory.ts +5 -0
  289. package/src/cli/index.ts +12 -9
  290. package/src/cli/utils/app.ts +19 -16
  291. package/src/cli/utils/claude.ts +2 -1
  292. package/src/cli/utils/fs.ts +2 -1
  293. package/src/cli/utils/memory.ts +2 -2
  294. package/src/cli/utils/pkg.ts +72 -5
  295. package/.enderun/agents/analyst.md +0 -32
  296. package/.enderun/agents/backend.md +0 -49
  297. package/.enderun/agents/database.md +0 -41
  298. package/.enderun/agents/devops.md +0 -41
  299. package/.enderun/agents/explorer.md +0 -40
  300. package/.enderun/agents/frontend.md +0 -48
  301. package/.enderun/agents/git.md +0 -41
  302. package/.enderun/agents/manager.md +0 -43
  303. package/.enderun/agents/mobile.md +0 -42
  304. package/.enderun/agents/native.md +0 -41
  305. package/.enderun/agents/quality.md +0 -40
  306. package/.enderun/agents/security.md +0 -32
  307. package/docs/api-referans.md +0 -1137
  308. package/docs/is_akislari.md +0 -902
  309. package/docs/mimari.md +0 -926
  310. package/docs/moduller.md +0 -294
  311. package/docs/proje.md +0 -521
  312. package/docs/yap/304/261.md +0 -2150
@@ -0,0 +1,710 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import crypto from "crypto";
4
+ import { ensureDir, writeTextFile, writeJsonFile } from "../utils/fs.js";
5
+ import { updateProjectMemoryCommand } from "../commands/memory.js";
6
+ import { slugifyName, titleCase } from "../utils/string.js";
7
+ import { getConfiguredPaths, getMemoryPath } from "./memory.js";
8
+ import { getDependencyVersions } from "./pkg.js";
9
+ const targetDir = process.cwd(); // Assuming targetDir is process.cwd() in the CLI context
10
+ export function inferAppSpec(description) {
11
+ const normalized = String(description || "").toLowerCase();
12
+ const isCrm = /\bcrm\b|customer|musteri|müşteri/.test(normalized);
13
+ const hasAuth = /auth|login|giris|giriş|signin|sign in|user|kullanici|kullanıcı|role|rol/.test(normalized);
14
+ const hasRoles = /role|rol|permission|yetki|admin/.test(normalized);
15
+ const hasReports = /report|rapor|analytics|dashboard|chart|metric/.test(normalized);
16
+ const appName = isCrm ? "crm-dashboard" : slugifyName(description).split("-").slice(0, 4).join("-");
17
+ return {
18
+ rawDescription: description,
19
+ appName,
20
+ title: isCrm ? "CRM Dashboard" : titleCase(appName),
21
+ domain: isCrm ? "CRM" : "Business",
22
+ modules: {
23
+ auth: hasAuth || isCrm,
24
+ users: hasAuth || hasRoles || isCrm,
25
+ roles: hasRoles || isCrm,
26
+ reports: hasReports || isCrm,
27
+ },
28
+ };
29
+ }
30
+ export function buildSharedTypesContent(existingContent) {
31
+ const marker = "// --- Generated Application Contract ---";
32
+ const generated = [
33
+ marker,
34
+ "export type RoleID = Brand<string, \"RoleID\">;",
35
+ "export type ReportID = Brand<string, \"ReportID\">;",
36
+ "export type CustomerID = Brand<string, \"CustomerID\">;",
37
+ "",
38
+ "export interface AuthSession {",
39
+ " user: User;",
40
+ " token: string;",
41
+ " expiresAt: string;",
42
+ "}",
43
+ "",
44
+ "export interface Role {",
45
+ " id: RoleID;",
46
+ " name: string;",
47
+ " permissions: string[];",
48
+ "}",
49
+ "",
50
+ "export interface Customer {",
51
+ " id: CustomerID;",
52
+ " name: string;",
53
+ " ownerId: UserID;",
54
+ " status: \"LEAD\" | \"ACTIVE\" | \"AT_RISK\";", // Using backticks for inner double quotes
55
+ " annualValue: number;",
56
+ " createdAt: string;",
57
+ "}",
58
+ "",
59
+ "export interface ReportMetric {",
60
+ " id: ReportID;",
61
+ " label: string;",
62
+ " value: number;",
63
+ " trend: \"UP\" | \"DOWN\" | \"FLAT\";", // Using backticks for inner double quotes
64
+ "}",
65
+ "",
66
+ "export interface DashboardSummary {",
67
+ " customers: Customer[];",
68
+ " users: User[];",
69
+ " roles: Role[];",
70
+ " reports: ReportMetric[];",
71
+ "}",
72
+ ].join("\n");
73
+ if (existingContent.includes(marker))
74
+ return existingContent;
75
+ return `${existingContent.trim()}\n\n${generated}\n`;
76
+ }
77
+ export function updateContractHashFile() {
78
+ const pathsMap = getConfiguredPaths();
79
+ const sharedDir = path.join(targetDir, pathsMap.backend, "src/types");
80
+ const contractPath = path.join(targetDir, pathsMap.backend, "contract.version.json");
81
+ if (!fs.existsSync(sharedDir) || !fs.existsSync(contractPath))
82
+ return;
83
+ const walk = (dir) => fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
84
+ const fullPath = path.join(dir, entry.name);
85
+ return entry.isDirectory() ? walk(fullPath) : (entry.name.endsWith(".ts") ? [fullPath] : []);
86
+ });
87
+ const hash = crypto.createHash("sha256");
88
+ for (const filePath of walk(sharedDir).sort()) {
89
+ hash.update(path.relative(targetDir, filePath));
90
+ hash.update("\0");
91
+ hash.update(fs.readFileSync(filePath));
92
+ hash.update("\0");
93
+ }
94
+ const contract = JSON.parse(fs.readFileSync(contractPath, "utf8"));
95
+ contract.contract_hash = hash.digest("hex");
96
+ contract.last_updated = new Date().toISOString();
97
+ fs.writeFileSync(contractPath, JSON.stringify(contract, null, 2));
98
+ }
99
+ export function createBaseTypeFiles(baseDir) {
100
+ const typesDir = path.join(baseDir, "types");
101
+ ensureDir(typesDir);
102
+ writeTextFile(path.join(typesDir, "api.ts"), `import { TraceID } from "./brands.js";
103
+
104
+ /**
105
+ * API Response Wrappers
106
+ */
107
+ export interface ApiResponse<T> {
108
+ data: T;
109
+ meta?: {
110
+ requestId: TraceID;
111
+ timestamp: string;
112
+ };
113
+ }
114
+
115
+ export interface ApiError {
116
+ error: {
117
+ code: string;
118
+ message: string;
119
+ details?: unknown;
120
+ };
121
+ }
122
+ `);
123
+ writeTextFile(path.join(typesDir, "brands.ts"), `/**
124
+ * Branded Type Utility
125
+ */
126
+ export type Brand<K, T> = K & { __brand: T };
127
+
128
+ /**
129
+ * Entity IDs (Branded)
130
+ */
131
+ export type TraceID = Brand<string, "TraceID">;
132
+ export type AgentID = Brand<string, "AgentID">;
133
+ export type ProjectID = Brand<string, "ProjectID">;
134
+ export type UserID = Brand<string, "UserID">;
135
+ `);
136
+ writeTextFile(path.join(typesDir, "constants.ts"), `import { TraceID } from "./brands.js";
137
+
138
+ /**
139
+ * Project Phases
140
+ */
141
+ export const PROJECT_PHASES = ["PHASE_0", "PHASE_1", "PHASE_2", "PHASE_3", "PHASE_4"] as const;
142
+ export type ProjectPhase = (typeof PROJECT_PHASES)[number];
143
+
144
+ /**
145
+ * Execution Profiles
146
+ */
147
+ export const EXECUTION_PROFILES = ["Lightweight", "Full"] as const;
148
+ export type ExecutionProfile = (typeof EXECUTION_PROFILES)[number];
149
+
150
+ /**
151
+ * Task Priorities
152
+ */
153
+ export const TASK_PRIORITIES = ["P0", "P1", "P2", "P3"] as const;
154
+ export type TaskPriority = (typeof TASK_PRIORITIES)[number];
155
+
156
+ /**
157
+ * Task Statuses
158
+ */
159
+ export const TASK_STATUSES = ["PENDING", "IN_PROGRESS", "BLOCKED", "COMPLETED", "FAILED"] as const;
160
+ export type TaskStatus = (typeof TASK_STATUSES)[number];
161
+
162
+ /**
163
+ * Action Types & Status
164
+ */
165
+ export const ACTION_TYPES = ["CREATE", "MODIFY", "DELETE", "RESEARCH", "ORCHESTRATE"] as const;
166
+ export type ActionType = (typeof ACTION_TYPES)[number];
167
+
168
+ export const ACTION_STATUSES = ["SUCCESS", "FAILURE", "WAITING"] as const;
169
+ export type ActionStatus = (typeof ACTION_STATUSES)[number];
170
+ `);
171
+ writeTextFile(path.join(typesDir, "index.ts"), `/**
172
+ * Agent Enderun — App-Local Types (Modular)
173
+ */
174
+
175
+ export * from "./brands.js";
176
+ export * from "./constants.js";
177
+ export * from "./models.js";
178
+ export * from "./api.js";
179
+ export * from "./logs.js";
180
+ `);
181
+ writeTextFile(path.join(typesDir, "logs.ts"), `import { TraceID, AgentID } from "./brands.js";
182
+ import { ActionType, ActionStatus } from "./constants.js";
183
+
184
+ /**
185
+ * Audit & Agent Logging Types
186
+ */
187
+ export interface AgentActionLog {
188
+ timestamp: string;
189
+ agent: AgentID;
190
+ action: ActionType;
191
+ requestId: TraceID | "—";
192
+ status: ActionStatus;
193
+ summary: string;
194
+ files?: string[];
195
+ details?: Record<string, unknown>;
196
+ }
197
+ `);
198
+ writeTextFile(path.join(typesDir, "models.ts"), `import { UserID, TraceID, AgentID } from "./brands.js";
199
+ import { ProjectPhase, ExecutionProfile, TaskPriority, TaskStatus } from "./constants.js";
200
+
201
+ /**
202
+ * Base Entity Fields
203
+ */
204
+ export interface BaseEntity {
205
+ id: string; // Usually ULID
206
+ createdAt: string;
207
+ updatedAt: string;
208
+ deletedAt?: string | null;
209
+ }
210
+
211
+ /**
212
+ * Audit Log Model
213
+ */
214
+ export interface AuditLog extends BaseEntity {
215
+ entityName: string;
216
+ entityId: string;
217
+ action: "CREATE" | "UPDATE" | "DELETE" | "RESTORE";
218
+ userId: UserID;
219
+ previousState?: Record<string, unknown> | null;
220
+ newState?: Record<string, unknown> | null;
221
+ traceId: TraceID;
222
+ }
223
+
224
+ /**
225
+ * User Model
226
+ */
227
+ export interface User extends BaseEntity {
228
+ id: UserID;
229
+ email: string;
230
+ fullName: string;
231
+ role: "ADMIN" | "DEVELOPER" | "VIEWER";
232
+ }
233
+
234
+ export interface UserProfile extends User {
235
+ avatarUrl?: string;
236
+ bio?: string;
237
+ preferences: Record<string, unknown>;
238
+ }
239
+
240
+ /**
241
+ * Project Status
242
+ */
243
+ export interface ProjectStatus {
244
+ phase: ProjectPhase;
245
+ profile: ExecutionProfile;
246
+ lastUpdate: string;
247
+ activeTraceId: TraceID | null;
248
+ blockers: string[];
249
+ }
250
+
251
+ /**
252
+ * Task Model
253
+ */
254
+ export interface Task {
255
+ id: TraceID;
256
+ description: string;
257
+ agent: AgentID;
258
+ priority: TaskPriority;
259
+ status: TaskStatus;
260
+ createdAt: string;
261
+ updatedAt: string;
262
+ }
263
+ `);
264
+ console.warn(`✅ Base types created in ${path.relative(targetDir, typesDir)}`);
265
+ }
266
+ export function createBackendFiles(spec) {
267
+ const pathsMap = getConfiguredPaths();
268
+ const backendDir = pathsMap.backend;
269
+ const { fastify, "@fastify/cors": fastifyCors, zod, "@types/node": typesNode, tsx, typescript, "vitest-backend": vitest } = getDependencyVersions();
270
+ createBaseTypeFiles(path.join(targetDir, backendDir, "src"));
271
+ writeJsonFile(path.join(targetDir, backendDir, "contract.version.json"), {
272
+ "contract_hash": "initial_hash_placeholder",
273
+ "last_updated": new Date().toISOString()
274
+ });
275
+ writeJsonFile(path.join(targetDir, backendDir, "package.json"), {
276
+ name: "@agent-enderun/backend",
277
+ version: "0.1.0",
278
+ private: true,
279
+ type: "module",
280
+ scripts: {
281
+ dev: "tsx src/server.ts",
282
+ build: "tsc -p tsconfig.json",
283
+ start: "node dist/server.js",
284
+ test: "vitest run",
285
+ },
286
+ dependencies: {
287
+ "@fastify/cors": fastifyCors,
288
+ fastify: fastify,
289
+ zod: zod,
290
+ },
291
+ devDependencies: {
292
+ "@types/node": typesNode,
293
+ tsx: tsx,
294
+ typescript: typescript,
295
+ vitest: vitest,
296
+ },
297
+ });
298
+ writeJsonFile(path.join(targetDir, backendDir, "tsconfig.json"), {
299
+ extends: "../../tsconfig.json",
300
+ compilerOptions: {
301
+ outDir: "dist",
302
+ rootDir: "src",
303
+ module: "NodeNext",
304
+ moduleResolution: "NodeNext",
305
+ target: "ES2022",
306
+ strict: true,
307
+ skipLibCheck: true,
308
+ },
309
+ include: ["src/**/*.ts"],
310
+ });
311
+ writeTextFile(path.join(targetDir, backendDir, "src/data.ts"), [
312
+ "import type { Customer, DashboardSummary, ReportMetric, Role, User } from \"./types/index.js\";",
313
+ "",
314
+ "const now = new Date().toISOString();",
315
+ "",
316
+ "export const roles: Role[] = [",
317
+ " { id: \"role_admin\" as Role[\"id\"], name: \"Admin\", permissions: [\"users:manage\", \"reports:view\", \"customers:manage\"] },",
318
+ " { id: \"role_manager\" as Role[\"id\"], name: \"Manager\", permissions: [\"reports:view\", \"customers:manage\"] },",
319
+ " { id: \"role_viewer\" as Role[\"id\"], name: \"Viewer\", permissions: [\"reports:view\"] },",
320
+ "];",
321
+ "",
322
+ "export const users: User[] = [",
323
+ " { id: \"user_1\" as User[\"id\"], email: \"admin@example.com\", fullName: \"Admin User\", role: \"ADMIN\", createdAt: now },",
324
+ " { id: \"user_2\" as User[\"id\"], email: \"manager@example.com\", fullName: \"Sales Manager\", role: \"DEVELOPER\", createdAt: now },",
325
+ "];",
326
+ "",
327
+ "export const customers: Customer[] = [",
328
+ " { id: \"customer_1\" as Customer[\"id\"], name: \"Northwind\", ownerId: users[1].id, status: \"ACTIVE\", annualValue: 125000, createdAt: now },",
329
+ " { id: \"customer_2\" as Customer[\"id\"], name: \"Acme Corp\", ownerId: users[1].id, status: \"LEAD\", annualValue: 82000, createdAt: now },",
330
+ " { id: \"customer_3\" as Customer[\"id\"], name: \"Globex\", ownerId: users[0].id, status: \"AT_RISK\", annualValue: 54000, createdAt: now },",
331
+ "];",
332
+ "",
333
+ "export const reports: ReportMetric[] = [",
334
+ " { id: \"report_pipeline\" as ReportMetric[\"id\"], label: \"Pipeline\", value: 261000, trend: \"UP\" },",
335
+ " { id: \"report_active_customers\" as ReportMetric[\"id\"], label: \"Active Customers\", value: 1, trend: \"FLAT\" },",
336
+ " { id: \"report_risk\" as ReportMetric[\"id\"], label: \"At Risk\", value: 1, trend: \"DOWN\" },",
337
+ "];",
338
+ "",
339
+ "export function getDashboardSummary(): DashboardSummary {",
340
+ " return { customers, users, roles, reports };",
341
+ "}",
342
+ ].join("\n"));
343
+ writeTextFile(path.join(targetDir, backendDir, "src/server.ts"), [
344
+ "import Fastify from \"fastify\";",
345
+ "import cors from \"@fastify/cors\";",
346
+ "import { z } from \"zod\";",
347
+ "import { customers, getDashboardSummary, reports, roles, users } from \"./data.js\";",
348
+ "",
349
+ "const app = Fastify({ logger: true });",
350
+ "await app.register(cors, { origin: true });",
351
+ "",
352
+ "app.get(\"/health\", async () => ({ ok: true, service: \"agent-enderun-backend\" }));",
353
+ "app.get(\"/api/v1/dashboard\", async () => ({ data: getDashboardSummary() }));",
354
+ "app.get(\"/api/v1/users\", async () => ({ data: users }));",
355
+ "app.get(\"/api/v1/roles\", async () => ({ data: roles }));",
356
+ "app.get(\"/api/v1/customers\", async () => ({ data: customers }));",
357
+ "app.get(\"/api/v1/reports\", async (request, reply) => {",
358
+ " interface QueryParams {",
359
+ " page?: number;",
360
+ " limit?: number;",
361
+ " }",
362
+ " const { page = 1, limit = 10 } = request.query as QueryParams;",
363
+ " const startIndex = (Number(page) - 1) * Number(limit);",
364
+ " const endIndex = startIndex + Number(limit);",
365
+ " const paginatedReports = reports.slice(startIndex, endIndex);",
366
+ " reply.send({",
367
+ " data: paginatedReports,",
368
+ " meta: {",
369
+ " total: reports.length,",
370
+ " page: Number(page),",
371
+ " limit: Number(limit),",
372
+ " },",
373
+ " });",
374
+ "});",
375
+ "",
376
+ "app.post(\"/api/v1/auth/login\", async (request, reply) => {",
377
+ " const body = z.object({ email: z.string().email(), password: z.string().min(1) }).safeParse(request.body);",
378
+ " if (!body.success) return reply.code(400).send({ error: { code: \"VALIDATION_ERROR\", message: \"Invalid login payload\" } });",
379
+ "",
380
+ " const user = users.find((item) => item.email === body.data.email) || users[0];",
381
+ " return { data: { user, token: \"demo-token\", expiresAt: new Date(Date.now() + 3600000).toISOString() } };",
382
+ "});",
383
+ "",
384
+ "const port = Number(process.env.PORT || 4000);",
385
+ "await app.listen({ port, host: \"0.0.0.0\" });",
386
+ ].join("\n"));
387
+ writeTextFile(path.join(targetDir, backendDir, "README.md"), [
388
+ `# ${spec.title} Backend`,
389
+ "",
390
+ "Fastify API generated by Agent Enderun.",
391
+ "",
392
+ "## Commands",
393
+ "",
394
+ "- `npm run dev` strings",
395
+ "- `npm run build` strings",
396
+ "- `npm run test` strings",
397
+ ].join("\n"));
398
+ }
399
+ export function createWebFiles(spec) {
400
+ const pathsMap = getConfiguredPaths();
401
+ const frontendDir = pathsMap.frontend;
402
+ const { "@vitejs/plugin-react": vitePluginReact, vite, react, "react-dom": reactDom, "lucide-react": lucideReact, "@types/react": typesReact, "@types/react-dom": typesReactDom, typescript, "vitest-frontend": vitest } = getDependencyVersions();
403
+ createBaseTypeFiles(path.join(targetDir, frontendDir, "src"));
404
+ writeJsonFile(path.join(targetDir, frontendDir, "package.json"), {
405
+ name: "@agent-enderun/web",
406
+ version: "0.1.0",
407
+ private: true,
408
+ type: "module",
409
+ scripts: {
410
+ dev: "vite --host 0.0.0.0",
411
+ build: "tsc -p tsconfig.json && vite build",
412
+ preview: "vite preview",
413
+ test: "vitest run",
414
+ },
415
+ dependencies: {
416
+ "@vitejs/plugin-react": vitePluginReact,
417
+ vite: vite,
418
+ react: react,
419
+ "react-dom": reactDom,
420
+ "lucide-react": lucideReact,
421
+ },
422
+ devDependencies: {
423
+ "@types/react": typesReact,
424
+ "@types/react-dom": typesReactDom,
425
+ typescript: typescript,
426
+ vitest: vitest,
427
+ },
428
+ });
429
+ writeJsonFile(path.join(targetDir, frontendDir, "tsconfig.json"), {
430
+ extends: "../../tsconfig.json",
431
+ compilerOptions: {
432
+ jsx: "react-jsx",
433
+ module: "NodeNext",
434
+ moduleResolution: "NodeNext",
435
+ target: "ES2022",
436
+ strict: true,
437
+ skipLibCheck: true,
438
+ },
439
+ include: ["src/**/*.ts", "src/**/*.tsx"],
440
+ });
441
+ writeTextFile(path.join(targetDir, frontendDir, "index.html"), [
442
+ "<div id=\"root\"></div>",
443
+ "<script type=\"module\" src=\"/src/main.tsx\"></script>",
444
+ ].join("\n"));
445
+ writeTextFile(path.join(targetDir, frontendDir, "src/main.tsx"), [
446
+ "import React from \"react\";",
447
+ "import { createRoot } from \"react-dom/client\";",
448
+ "import { App } from \"./App.js\";",
449
+ "import \"./styles.css\";",
450
+ "",
451
+ "createRoot(document.getElementById(\"root\") as HTMLElement).render(",
452
+ " <React.StrictMode>",
453
+ " <App />",
454
+ " </React.StrictMode>,",
455
+ ");",
456
+ ].join("\n"));
457
+ writeTextFile(path.join(targetDir, frontendDir, "src/App.tsx"), [
458
+ "import { BarChart3, ShieldCheck, UsersRound } from \"lucide-react\";",
459
+ "",
460
+ "const metrics = [",
461
+ " { label: \"Pipeline\", value: \"$261K\", tone: \"green\" },",
462
+ " { label: \"Active customers\", value: \"18\", tone: \"blue\" },",
463
+ " { label: \"At risk\", value: \"3\", tone: \"red\" },",
464
+ "];",
465
+ "",
466
+ "const customers = [",
467
+ " { name: \"Northwind\", status: \"Active\", owner: \"Sales Manager\", value: \"$125K\" },",
468
+ " { name: \"Acme Corp\", status: \"Lead\", owner: \"Sales Manager\", value: \"$82K\" },",
469
+ " { name: \"Globex\", status: \"At risk\", owner: \"Admin User\", value: \"$54K\" },",
470
+ "];",
471
+ "",
472
+ "export function App() {",
473
+ " return (",
474
+ " <main className=\"shell\">",
475
+ " <aside className=\"sidebar\" aria-label=\"Primary navigation\">",
476
+ " <div className=\"brand\">AE</div>",
477
+ " <nav>",
478
+ " <a className=\"active\" href=\"#dashboard\"><BarChart3 size={18} /> Dashboard</a>",
479
+ " <a href=\"#users\"><UsersRound size={18} /> Users</a>",
480
+ " <a href=\"#roles\"><ShieldCheck size={18} /> Roles</a>",
481
+ " </nav>",
482
+ " </aside>",
483
+ "",
484
+ " <section className=\"workspace\">",
485
+ " <header className=\"topbar\">",
486
+ " <div>",
487
+ ` <p>${spec.domain}</p>`,
488
+ ` <h1>${spec.title}</h1>`,
489
+ " </div>",
490
+ " <button type=\"button\">New customer</button>",
491
+ " </header>",
492
+ "",
493
+ " <section className=\"metrics\" aria-label=\"Report metrics\">",
494
+ " {metrics.map((metric) => (",
495
+ " <article className={`metric ${metric.tone}`} key={metric.label}>",
496
+ " <span>{metric.label}</span>",
497
+ " <strong>{metric.value}</strong>",
498
+ " </article>",
499
+ " ))}",
500
+ " </section>",
501
+ "",
502
+ " <section className=\"panel\">",
503
+ " <div>",
504
+ " <h2>Customers</h2>",
505
+ " <p>Ownership, value and status at a glance.</p>",
506
+ " </div>",
507
+ " <div className=\"table\">",
508
+ " {customers.map((customer) => (",
509
+ " <div className=\"row\" key={customer.name}>",
510
+ " <strong>{customer.name}</strong>",
511
+ " <span>{customer.status}</span>",
512
+ " <span>{customer.owner}</span>",
513
+ " <b>{customer.value}</b>",
514
+ " </div>",
515
+ " ))}",
516
+ " </div>",
517
+ " </section>",
518
+ " </section>",
519
+ " </main>",
520
+ " );",
521
+ "}",
522
+ ].join("\n"));
523
+ writeTextFile(path.join(targetDir, frontendDir, "src/styles.css"), [
524
+ ":root {",
525
+ " color: #172026;",
526
+ " background: #f4f7f6;",
527
+ " font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;",
528
+ "}",
529
+ "",
530
+ "* { box-sizing: border-box; }",
531
+ "body { margin: 0; }",
532
+ "button { font: inherit; }",
533
+ "",
534
+ ".shell {",
535
+ " min-height: 100vh;",
536
+ " display: grid;",
537
+ " grid-template-columns: 240px 1fr;",
538
+ "}",
539
+ "",
540
+ ".sidebar {",
541
+ " background: #102022;",
542
+ " color: #eef6f2;",
543
+ " padding: 24px;",
544
+ "}",
545
+ "",
546
+ ".brand {",
547
+ " width: 40px;",
548
+ " height: 40px;",
549
+ " display: grid;",
550
+ " place-items: center;",
551
+ " background: #d8f36a;",
552
+ " color: #102022;",
553
+ " font-weight: 800;",
554
+ " border-radius: 8px;",
555
+ " margin-bottom: 32px;",
556
+ "}",
557
+ "",
558
+ "nav { display: grid; gap: 8px; }",
559
+ "nav a {",
560
+ " color: inherit;",
561
+ " text-decoration: none;",
562
+ " display: flex;",
563
+ " gap: 10px;",
564
+ " align-items: center;",
565
+ " padding: 10px 12px;",
566
+ " border-radius: 8px;",
567
+ "}",
568
+ "nav a.active, nav a:hover { background: rgba(255,255,255,0.12); }",
569
+ "",
570
+ ".workspace { padding: 32px; }",
571
+ ".topbar {",
572
+ " display: flex;",
573
+ " justify-content: space-between;",
574
+ " align-items: center;",
575
+ " gap: 24px;",
576
+ " margin-bottom: 24px;",
577
+ "}",
578
+ ".topbar p { margin: 0 0 4px; color: #58666a; font-size: 14px; }",
579
+ ".topbar h1 { margin: 0; font-size: 32px; letter-spacing: 0; }",
580
+ ".topbar button {",
581
+ " border: 0;",
582
+ " border-radius: 8px;",
583
+ " background: #176b5d;",
584
+ " color: white;",
585
+ " padding: 10px 14px;",
586
+ "}",
587
+ "",
588
+ ".metrics {",
589
+ " display: grid;",
590
+ " grid-template-columns: repeat(3, minmax(0, 1fr));",
591
+ " gap: 16px;",
592
+ " margin-bottom: 24px;",
593
+ "}",
594
+ ".metric, .panel {",
595
+ " background: white;",
596
+ " border: 1px solid #d9e3e0;",
597
+ " border-radius: 8px;",
598
+ "}",
599
+ ".metric { padding: 18px; }",
600
+ ".metric span { display: block; color: #58666a; margin-bottom: 8px; }",
601
+ ".metric strong { font-size: 28px; }",
602
+ ".metric.green { border-top: 4px solid #49a078; }",
603
+ ".metric.blue { border-top: 4px solid #3f7cac; }",
604
+ ".metric.red { border-top: 4px solid #d95d39; }",
605
+ "",
606
+ ".panel { padding: 20px; }",
607
+ ".panel h2 { margin: 0 0 4px; font-size: 20px; }",
608
+ ".panel p { margin: 0 0 18px; color: #58666a; }",
609
+ ".table { display: grid; gap: 8px; }",
610
+ ".row {",
611
+ " display: grid;",
612
+ " grid-template-columns: 1.4fr 0.8fr 1fr 0.6fr;",
613
+ " gap: 16px;",
614
+ " align-items: center;",
615
+ " padding: 12px;",
616
+ " border-radius: 8px;",
617
+ " background: #f7faf9;",
618
+ "}",
619
+ "",
620
+ "@media (max-width: 760px) {",
621
+ " .shell { grid-template-columns: 1fr; }",
622
+ " .sidebar { position: static; }",
623
+ " .metrics { grid-template-columns: 1fr; }",
624
+ " .topbar { align-items: flex-start; flex-direction: column; }",
625
+ " .row { grid-template-columns: 1fr; }",
626
+ "}",
627
+ ].join("\n"));
628
+ writeTextFile(path.join(targetDir, frontendDir, "README.md"), [
629
+ `# ${spec.title} Web`,
630
+ "",
631
+ "React dashboard generated by Agent Enderun.",
632
+ "",
633
+ "## Commands",
634
+ "",
635
+ "- `npm run dev` strings",
636
+ "- `npm run build` strings",
637
+ "- `npm run test` strings",
638
+ ].join("\n"));
639
+ }
640
+ export function updateProjectDocs(spec) {
641
+ const pathsMap = getConfiguredPaths();
642
+ const docsDir = path.join(targetDir, pathsMap.docs);
643
+ const apiDir = path.join(docsDir, "api");
644
+ ensureDir(apiDir);
645
+ writeTextFile(path.join(docsDir, "project-docs.md"), [
646
+ `# ${spec.title} Requirements`,
647
+ "",
648
+ "## Request",
649
+ "",
650
+ spec.rawDescription,
651
+ "",
652
+ "## Generated Scope",
653
+ "",
654
+ `- Domain: ${spec.domain}`,
655
+ `- Auth: ${spec.modules.auth ? "yes" : "no"}`,
656
+ `- Users: ${spec.modules.users ? "yes" : "no"}`,
657
+ `- Roles: ${spec.modules.roles ? "yes" : "no"}`,
658
+ `- Reports: ${spec.modules.reports ? "yes" : "no"}`,
659
+ "",
660
+ "## Architecture",
661
+ "",
662
+ `- \`${pathsMap.backend}\`: Fastify API`,
663
+ `- \`${pathsMap.frontend}\`: React dashboard`,
664
+ `- \`${pathsMap.backend}/src/types\`: Contract-first backend TypeScript types`,
665
+ ].join("\n"));
666
+ writeTextFile(path.join(apiDir, "README.md"), [
667
+ "# API Registry",
668
+ "",
669
+ "- `POST /api/v1/auth/login`",
670
+ "- `GET /api/v1/dashboard`",
671
+ "- `GET /api/v1/users`",
672
+ "- `GET /api/v1/roles`",
673
+ "- `GET /api/v1/customers`",
674
+ "- `GET /api/v1/reports`",
675
+ ].join("\n"));
676
+ }
677
+ export function updateMemoryForGeneratedApp(spec, traceId) {
678
+ const memoryPath = getMemoryPath();
679
+ if (!fs.existsSync(memoryPath))
680
+ return;
681
+ const pathsMap = getConfiguredPaths();
682
+ const today = new Date().toISOString().split("T")[0];
683
+ const history = [
684
+ `### ${today} — Generated ${spec.title}`,
685
+ "",
686
+ "- **Agent:** @manager",
687
+ `- **Trace ID:** ${traceId}`,
688
+ "- **Action:** Created full-stack starter from natural language request.",
689
+ `- **Files:** ${pathsMap.backend}, ${pathsMap.frontend}, project docs`,
690
+ ].join("\n");
691
+ updateProjectMemoryCommand("HISTORY", history);
692
+ }
693
+ export async function collectCreateAppDescription(args) {
694
+ const initial = args.join(" ").trim();
695
+ if (initial)
696
+ return initial;
697
+ const readline = await import("readline/promises");
698
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
699
+ try {
700
+ const idea = await rl.question("What do you want to build? ");
701
+ const platform = await rl.question("Platform? (full-stack/web/backend) ");
702
+ const auth = await rl.question("Auth and roles? (yes/no) ");
703
+ const reports = await rl.question("Reports/dashboard? (yes/no) ");
704
+ return [idea, platform, auth.includes("y") ? "with auth and roles" : "", reports.includes("y") ? "with reports dashboard" : ""].filter(Boolean).join(" ");
705
+ }
706
+ finally {
707
+ rl.close();
708
+ }
709
+ }
710
+ //# sourceMappingURL=app.js.map