titan-agent 5.4.2 → 5.5.6

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 (302) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/agent.js +9 -5
  3. package/dist/agent/agent.js.map +1 -1
  4. package/dist/agent/agentLoop.js +7 -3
  5. package/dist/agent/agentLoop.js.map +1 -1
  6. package/dist/agent/checkpoint.js +2 -2
  7. package/dist/agent/checkpoint.js.map +1 -1
  8. package/dist/agent/commandPost.js +3 -3
  9. package/dist/agent/commandPost.js.map +1 -1
  10. package/dist/agent/goalProposer.js +2 -2
  11. package/dist/agent/goalProposer.js.map +1 -1
  12. package/dist/agent/goals.js +3 -3
  13. package/dist/agent/goals.js.map +1 -1
  14. package/dist/agent/peerAdvise.js +1 -1
  15. package/dist/agent/peerAdvise.js.map +1 -1
  16. package/dist/agent/planner.js +4 -4
  17. package/dist/agent/planner.js.map +1 -1
  18. package/dist/agent/userProfile.js +2 -2
  19. package/dist/agent/userProfile.js.map +1 -1
  20. package/dist/cli/doctor.js +33 -0
  21. package/dist/cli/doctor.js.map +1 -1
  22. package/dist/cli/onboard.js +4 -4
  23. package/dist/cli/onboard.js.map +1 -1
  24. package/dist/config/config.js +3 -3
  25. package/dist/config/config.js.map +1 -1
  26. package/dist/config/schema.js +8 -1
  27. package/dist/config/schema.js.map +1 -1
  28. package/dist/gateway/routes/adminRouter.js +500 -0
  29. package/dist/gateway/routes/adminRouter.js.map +1 -0
  30. package/dist/gateway/routes/agents.js +231 -0
  31. package/dist/gateway/routes/agents.js.map +1 -0
  32. package/dist/gateway/routes/agentsRouter.js +32 -0
  33. package/dist/gateway/routes/agentsRouter.js.map +1 -0
  34. package/dist/gateway/routes/checkpoints.js +41 -0
  35. package/dist/gateway/routes/checkpoints.js.map +1 -0
  36. package/dist/gateway/routes/commandPost.js +755 -0
  37. package/dist/gateway/routes/commandPost.js.map +1 -0
  38. package/dist/gateway/routes/companies.js +166 -0
  39. package/dist/gateway/routes/companies.js.map +1 -0
  40. package/dist/gateway/routes/files.js +295 -0
  41. package/dist/gateway/routes/files.js.map +1 -0
  42. package/dist/gateway/routes/hardwareRouter.js +151 -0
  43. package/dist/gateway/routes/hardwareRouter.js.map +1 -0
  44. package/dist/gateway/routes/mcpRouter.js +88 -0
  45. package/dist/gateway/routes/mcpRouter.js.map +1 -0
  46. package/dist/gateway/routes/mesh.js +464 -0
  47. package/dist/gateway/routes/mesh.js.map +1 -0
  48. package/dist/gateway/routes/metricsRouter.js +131 -0
  49. package/dist/gateway/routes/metricsRouter.js.map +1 -0
  50. package/dist/gateway/routes/organism.js +82 -0
  51. package/dist/gateway/routes/organism.js.map +1 -0
  52. package/dist/gateway/routes/paperclip.js +101 -0
  53. package/dist/gateway/routes/paperclip.js.map +1 -0
  54. package/dist/gateway/routes/sessions.js +227 -0
  55. package/dist/gateway/routes/sessions.js.map +1 -0
  56. package/dist/gateway/routes/skills.js +295 -0
  57. package/dist/gateway/routes/skills.js.map +1 -0
  58. package/dist/gateway/routes/socialRouter.js +145 -0
  59. package/dist/gateway/routes/socialRouter.js.map +1 -0
  60. package/dist/gateway/routes/systemRouter.js +220 -0
  61. package/dist/gateway/routes/systemRouter.js.map +1 -0
  62. package/dist/gateway/routes/teamsRecipes.js +297 -0
  63. package/dist/gateway/routes/teamsRecipes.js.map +1 -0
  64. package/dist/gateway/routes/tests.js +401 -0
  65. package/dist/gateway/routes/tests.js.map +1 -0
  66. package/dist/gateway/routes/traces.js +33 -0
  67. package/dist/gateway/routes/traces.js.map +1 -0
  68. package/dist/gateway/routes/voiceRouter.js +770 -0
  69. package/dist/gateway/routes/voiceRouter.js.map +1 -0
  70. package/dist/gateway/routes/watchRouter.js +131 -0
  71. package/dist/gateway/routes/watchRouter.js.map +1 -0
  72. package/dist/gateway/server.js +1179 -7379
  73. package/dist/gateway/server.js.map +1 -1
  74. package/dist/mcp/registry.js +2 -2
  75. package/dist/mcp/registry.js.map +1 -1
  76. package/dist/memory/episodic.js +2 -2
  77. package/dist/memory/episodic.js.map +1 -1
  78. package/dist/memory/learning.js +3 -3
  79. package/dist/memory/learning.js.map +1 -1
  80. package/dist/memory/memory.js +3 -3
  81. package/dist/memory/memory.js.map +1 -1
  82. package/dist/organism/drives.js +2 -2
  83. package/dist/organism/drives.js.map +1 -1
  84. package/dist/providers/errorTaxonomy.js +13 -0
  85. package/dist/providers/errorTaxonomy.js.map +1 -1
  86. package/dist/providers/ollama.js +3 -1
  87. package/dist/providers/ollama.js.map +1 -1
  88. package/dist/providers/openai_compat.js +4 -3
  89. package/dist/providers/openai_compat.js.map +1 -1
  90. package/dist/providers/router.js +13 -0
  91. package/dist/providers/router.js.map +1 -1
  92. package/dist/safety/fixOscillation.js +15 -0
  93. package/dist/safety/fixOscillation.js.map +1 -1
  94. package/dist/safety/killSwitch.js +2 -2
  95. package/dist/safety/killSwitch.js.map +1 -1
  96. package/dist/safety/selfRepair.js +7 -3
  97. package/dist/safety/selfRepair.js.map +1 -1
  98. package/dist/skills/builtin/agent_debate.js +2 -2
  99. package/dist/skills/builtin/agent_debate.js.map +1 -1
  100. package/dist/skills/builtin/apply_patch.js +3 -3
  101. package/dist/skills/builtin/apply_patch.js.map +1 -1
  102. package/dist/skills/builtin/shell.js +2 -2
  103. package/dist/skills/builtin/shell.js.map +1 -1
  104. package/dist/skills/builtin/voice_control.js +49 -0
  105. package/dist/skills/builtin/voice_control.js.map +1 -0
  106. package/dist/skills/builtin/widget_gallery.js +6 -1
  107. package/dist/skills/builtin/widget_gallery.js.map +1 -1
  108. package/dist/skills/registry.js +15 -4
  109. package/dist/skills/registry.js.map +1 -1
  110. package/dist/storage/JsonStorage.js +4 -4
  111. package/dist/storage/JsonStorage.js.map +1 -1
  112. package/dist/utils/constants.js +1 -1
  113. package/dist/utils/constants.js.map +1 -1
  114. package/dist/utils/helpers.js +3 -1
  115. package/dist/utils/helpers.js.map +1 -1
  116. package/dist/utils/lifecycle.js +86 -0
  117. package/dist/utils/lifecycle.js.map +1 -0
  118. package/dist/voice/bridge.js +136 -0
  119. package/dist/voice/bridge.js.map +1 -0
  120. package/docs/COO-MASTER-PLAN-2026-05-02.md +474 -0
  121. package/docs/HANDOFF/2026-04-29.md +141 -0
  122. package/docs/HANDOFF-2026-04-30.md +144 -0
  123. package/docs/HANDOFF-2026-05-03.md +114 -0
  124. package/docs/adr/2026-04-29-widget-pipeline-traceability.md +49 -0
  125. package/docs/agent-memory/README.md +45 -0
  126. package/docs/agent-memory/commands.md +100 -0
  127. package/docs/agent-memory/context-tree.md +101 -0
  128. package/docs/agent-memory/current-state.md +54 -0
  129. package/docs/agent-memory/decisions.md +78 -0
  130. package/docs/agent-memory/known-issues.md +76 -0
  131. package/docs/agent-memory/reflections.md +52 -0
  132. package/docs/agent-memory/skills-candidates.md +80 -0
  133. package/docs/superpowers/plans/2026-04-29-comprehensive-audit.md +256 -0
  134. package/docs/superpowers/plans/2026-04-29-comprehensive-test-plan.md +396 -0
  135. package/docs/superpowers/plans/2026-04-29-fix-all-prs.md +251 -0
  136. package/docs/superpowers/plans/2026-04-29-gitnexus-gap-remediation.md +969 -0
  137. package/package.json +5 -2
  138. package/ui/dist/assets/{AuditPanel-CM6Wg9hO.js → AuditPanel-VzSndmDN.js} +2 -2
  139. package/ui/dist/assets/{AutonomyPanel-CESx3ANg.js → AutonomyPanel-BiFouzAV.js} +2 -2
  140. package/ui/dist/assets/AutopilotPanel-fjOfM668.js +1 -0
  141. package/ui/dist/assets/{AutoresearchPanel-DR47NqT5.js → AutoresearchPanel-CVCxzAH3.js} +2 -2
  142. package/ui/dist/assets/BackupPanel-CHVTG--q.js +1 -0
  143. package/ui/dist/assets/{BrowserPanel-C15x9bLn.js → BrowserPanel-D5mvMKFU.js} +2 -2
  144. package/ui/dist/assets/CPActivity-B12mt35m.js +1 -0
  145. package/ui/dist/assets/CPAgentDetail-DsdShc-1.js +1 -0
  146. package/ui/dist/assets/CPAgents-j_7C-oQV.js +1 -0
  147. package/ui/dist/assets/CPApprovals-BShKSX9X.js +1 -0
  148. package/ui/dist/assets/CPCosts-CKPlhBDs.js +1 -0
  149. package/ui/dist/assets/CPDashboard-11c0nkxK.js +1 -0
  150. package/ui/dist/assets/CPFiles-BhLEOnXy.js +1 -0
  151. package/ui/dist/assets/CPGoals-Bi3t1b2P.js +1 -0
  152. package/ui/dist/assets/CPInbox-Bbr7khp6.js +11 -0
  153. package/ui/dist/assets/CPIssueDetail-DSdgNK8r.js +1 -0
  154. package/ui/dist/assets/CPIssues-DDEVKhX6.js +1 -0
  155. package/ui/dist/assets/CPLayout-DgPOfyGv.js +17 -0
  156. package/ui/dist/assets/CPOrg-Df73RrRJ.js +8 -0
  157. package/ui/dist/assets/CPRuns-ByioAz8w.js +1 -0
  158. package/ui/dist/assets/{CPSocial-nb-j7sOE.js → CPSocial-Dlnr_w1X.js} +2 -2
  159. package/ui/dist/assets/ChannelsPanel-DQjQCTK5.js +1 -0
  160. package/ui/dist/assets/CheckpointsPanel-C4vKjlAJ.js +1 -0
  161. package/ui/dist/assets/CommandPostHub-C9pp5Giq.js +24 -0
  162. package/ui/dist/assets/CronPanel-C6bzUfrD.js +1 -0
  163. package/ui/dist/assets/DaemonPanel-BA5Tb_UO.js +1 -0
  164. package/ui/dist/assets/{DataTable-B2Ma8hfi.js → DataTable-CH7IYJJh.js} +1 -1
  165. package/ui/dist/assets/{EmptyState-CcKyk5Yn.js → EmptyState-jU6yNDnF.js} +1 -1
  166. package/ui/dist/assets/{EvalHarnessPanel-BqtMc1ZM.js → EvalHarnessPanel-DnYqredY.js} +2 -2
  167. package/ui/dist/assets/EvalPanel-ChO7CD1r.js +1 -0
  168. package/ui/dist/assets/{FilesPanel-3QKvrWPo.js → FilesPanel-CaUkv2is.js} +2 -2
  169. package/ui/dist/assets/FleetPanel-DC_5uj0N.js +1 -0
  170. package/ui/dist/assets/{HomelabPanel-DhrjTX9m.js → HomelabPanel-CE5PGRpL.js} +2 -2
  171. package/ui/dist/assets/InfraView-C-uSlvb9.js +2 -0
  172. package/ui/dist/assets/InlineEditableField-BMQjiE6-.js +1 -0
  173. package/ui/dist/assets/Input-Bu_b3qmY.js +1 -0
  174. package/ui/dist/assets/IntegrationsPanel-DsYpAq43.js +1 -0
  175. package/ui/dist/assets/IntelligenceView-DUdIO1K7.js +2 -0
  176. package/ui/dist/assets/LearningPanel-UpQZC-mA.js +1 -0
  177. package/ui/dist/assets/LogsPanel-ClXJ4fcr.js +1 -0
  178. package/ui/dist/assets/McpPanel-JKgtIERQ.js +1 -0
  179. package/ui/dist/assets/{MemoryGraphPanel-Bzvjmzvk.js → MemoryGraphPanel-Bo2OrvA6.js} +2 -2
  180. package/ui/dist/assets/MemoryWikiPanel-BqJ1AmYm.js +11 -0
  181. package/ui/dist/assets/{MeshPanel-C3LJSlht.js → MeshPanel-BJVGYvwk.js} +2 -2
  182. package/ui/dist/assets/Modal-CAAooiZU.js +1 -0
  183. package/ui/dist/assets/NvidiaPanel-BtCg3G4w.js +1 -0
  184. package/ui/dist/assets/OrganismPanel-DgrTTzcF.js +1 -0
  185. package/ui/dist/assets/OverviewPanel-rVav1Hox.js +1 -0
  186. package/ui/dist/assets/{PageHeader-BimceqQo.js → PageHeader-CnZtP8ek.js} +1 -1
  187. package/ui/dist/assets/PaperclipPanel-C-FKdhiF.js +1 -0
  188. package/ui/dist/assets/{PersonasPanel-L1j78p6H.js → PersonasPanel-BmlxokfB.js} +1 -1
  189. package/ui/dist/assets/RecipesPanel-BNKKChis.js +1 -0
  190. package/ui/dist/assets/SecurityPanel-I7JRHiNy.js +1 -0
  191. package/ui/dist/assets/SelfImprovePanel-u9h0Lt3p.js +1 -0
  192. package/ui/dist/assets/{SelfProposalsPanel-lNmiDThB.js → SelfProposalsPanel-DKl9iBjM.js} +2 -2
  193. package/ui/dist/assets/SessionsPanel-BhRiWI_g.js +1 -0
  194. package/ui/dist/assets/{SessionsTab-JQbltWww.js → SessionsTab-Bk08wyeY.js} +1 -1
  195. package/ui/dist/assets/SettingsPanel-haLfmG2k.js +1 -0
  196. package/ui/dist/assets/SettingsView--gi3fxI8.js +2 -0
  197. package/ui/dist/assets/{SkeletonLoader-atQtpcF5.js → SkeletonLoader-B5v09EF_.js} +1 -1
  198. package/ui/dist/assets/{SkillsPanel-DlFs2ih7.js → SkillsPanel-BlAHFLcQ.js} +1 -1
  199. package/ui/dist/assets/SomaView-CExtS3zw.js +5 -0
  200. package/ui/dist/assets/{StatCard-DciE_Iqc.js → StatCard-BIsyMybM.js} +1 -1
  201. package/ui/dist/assets/{StatusBadge-BtfSPoW2.js → StatusBadge-D5nU7El8.js} +1 -1
  202. package/ui/dist/assets/Tabs-BBYZrBI8.js +1 -0
  203. package/ui/dist/assets/TeamsPanel-LPXJg823.js +1 -0
  204. package/ui/dist/assets/TelemetryPanel-EqpRBmOI.js +1 -0
  205. package/ui/dist/assets/TitanCanvas-BCbWnLMd.js +985 -0
  206. package/ui/dist/assets/ToolsView-CeP0Zz-N.js +2 -0
  207. package/ui/dist/assets/{Tooltip-70UK0E2I.js → Tooltip-BSO2XVpF.js} +1 -1
  208. package/ui/dist/assets/TraceViewer-BKI7o5B0.js +1 -0
  209. package/ui/dist/assets/TrainingPanel-c-RhjdE1.js +1 -0
  210. package/ui/dist/assets/VoiceOverlay-D-gc58b0.js +27 -0
  211. package/ui/dist/assets/VramPanel-C6xc7zgd.js +1 -0
  212. package/ui/dist/assets/{WatchView-C-sGFpVy.js → WatchView-dqBVCVH0.js} +1 -1
  213. package/ui/dist/assets/WorkTab-CBoLNrTM.js +1 -0
  214. package/ui/dist/assets/{WorkflowsPanel-CvgQU1xI.js → WorkflowsPanel-BAnSTOYe.js} +2 -2
  215. package/ui/dist/assets/approvalHeadline-DB9SgR-9.js +1 -0
  216. package/ui/dist/assets/{arrow-left-DwqHtJiU.js → arrow-left-5chqas7J.js} +1 -1
  217. package/ui/dist/assets/briefcase-D4vLzudp.js +6 -0
  218. package/ui/dist/assets/{chart-column-BtNO6sRy.js → chart-column-CdFlBpoP.js} +1 -1
  219. package/ui/dist/assets/check-Bpm1IONe.js +6 -0
  220. package/ui/dist/assets/chevron-down-D7OLjvuD.js +6 -0
  221. package/ui/dist/assets/chevron-right-aQEw2mUW.js +6 -0
  222. package/ui/dist/assets/chevron-up-C5g6pEj8.js +6 -0
  223. package/ui/dist/assets/{circle-check-big-DZRE_MbN.js → circle-check-big-fPhEdP88.js} +1 -1
  224. package/ui/dist/assets/clock-CTsgP_Sn.js +6 -0
  225. package/ui/dist/assets/{dollar-sign-aVG3a5eL.js → dollar-sign-CudFVYFc.js} +1 -1
  226. package/ui/dist/assets/{download-BxiWJU4G.js → download-DZRxDn67.js} +1 -1
  227. package/ui/dist/assets/external-link-BZ0y_Ahx.js +6 -0
  228. package/ui/dist/assets/{eye-off-CkgfFYhm.js → eye-off-BmJF0YYx.js} +1 -1
  229. package/ui/dist/assets/folder-DA43TRCm.js +11 -0
  230. package/ui/dist/assets/{funnel-PkLdxKyC.js → funnel-J3mULzrz.js} +1 -1
  231. package/ui/dist/assets/{git-branch-BM-Gw95X.js → git-branch-oHibJqDq.js} +1 -1
  232. package/ui/dist/assets/{index-D0RJ8701.css → index-BR0vfkIi.css} +1 -1
  233. package/ui/dist/assets/{index-CahJbWSR.js → index-DzwowwSI.js} +20 -20
  234. package/ui/dist/assets/{layers-BuGf4FIJ.js → layers-DsyEyu7z.js} +1 -1
  235. package/ui/dist/assets/{legacy-CR6o4t-y.js → legacy-8ITl64sV.js} +1 -1
  236. package/ui/dist/assets/{lightbulb-n8gc_XAL.js → lightbulb-C54Ske-p.js} +1 -1
  237. package/ui/dist/assets/list-todo-Cnd4rdoK.js +6 -0
  238. package/ui/dist/assets/loader-circle-1YOBsoQp.js +6 -0
  239. package/ui/dist/assets/network-DbGDAdrn.js +6 -0
  240. package/ui/dist/assets/{pause-DCV52koX.js → pause-CYhO_uQo.js} +1 -1
  241. package/ui/dist/assets/{play-CcJ9BnCh.js → play-DVY9c5Ck.js} +1 -1
  242. package/ui/dist/assets/{plug-CfWBXfCl.js → plug-BcXjlPUL.js} +1 -1
  243. package/ui/dist/assets/plus-Csu2v9GN.js +6 -0
  244. package/ui/dist/assets/{proxy-CzZDfLmm.js → proxy-DxS2_9D7.js} +1 -1
  245. package/ui/dist/assets/rotate-ccw-Co-_W04j.js +6 -0
  246. package/ui/dist/assets/save-Btx-kpoW.js +6 -0
  247. package/ui/dist/assets/search-0hXTwEZR.js +6 -0
  248. package/ui/dist/assets/send-TEpapzQR.js +6 -0
  249. package/ui/dist/assets/shield-check-DjBJXZUr.js +6 -0
  250. package/ui/dist/assets/{square-DJpUhlxi.js → square-OweUvjP-.js} +1 -1
  251. package/ui/dist/assets/{target-DWcmM_9m.js → target-BRW80Xer.js} +1 -1
  252. package/ui/dist/assets/terminal-BtiqJ628.js +16 -0
  253. package/ui/dist/assets/{toggle-right-YusFQ69L.js → toggle-right-CKtSrl28.js} +1 -1
  254. package/ui/dist/assets/{trash-2-CK7yQ55V.js → trash-2-DgWrHVax.js} +1 -1
  255. package/ui/dist/assets/{trending-up-DGjFyubC.js → trending-up-MpIrE4j6.js} +1 -1
  256. package/ui/dist/assets/{trophy-uQv_NgDB.js → trophy-CECuZNhX.js} +1 -1
  257. package/ui/dist/assets/users-dZgv4ePG.js +16 -0
  258. package/ui/dist/assets/wrench-CDz3xYve.js +11 -0
  259. package/ui/dist/index.html +2 -2
  260. package/ui/dist/assets/AutopilotPanel-DtEet1hJ.js +0 -1
  261. package/ui/dist/assets/BackupPanel-BGP8p3l3.js +0 -1
  262. package/ui/dist/assets/CPAgents-DYUtPzSq.js +0 -1
  263. package/ui/dist/assets/CPDashboard-Bf0-SyCh.js +0 -6
  264. package/ui/dist/assets/CPFiles-CxgxjQcO.js +0 -1
  265. package/ui/dist/assets/CPGoals-BsmCMTvT.js +0 -1
  266. package/ui/dist/assets/CPInbox-tMSbmQ9H.js +0 -11
  267. package/ui/dist/assets/ChannelsPanel-DP5C2OKd.js +0 -1
  268. package/ui/dist/assets/CheckpointsPanel-DlranVLZ.js +0 -1
  269. package/ui/dist/assets/CommandPostHub-BgxIa4Ev.js +0 -29
  270. package/ui/dist/assets/CronPanel-LoT5yKwJ.js +0 -1
  271. package/ui/dist/assets/DaemonPanel-DBGMqaE_.js +0 -1
  272. package/ui/dist/assets/EvalPanel-Bc33j0pN.js +0 -1
  273. package/ui/dist/assets/FleetPanel-CSsXuQYj.js +0 -1
  274. package/ui/dist/assets/InfraView-CR6HyrL6.js +0 -2
  275. package/ui/dist/assets/InlineEditableField-CnvF-yFR.js +0 -1
  276. package/ui/dist/assets/Input-GTHp2Rkr.js +0 -1
  277. package/ui/dist/assets/IntegrationsPanel-CymCRE3T.js +0 -1
  278. package/ui/dist/assets/IntelligenceView-C1IHxJRC.js +0 -2
  279. package/ui/dist/assets/LearningPanel-DOCES3lH.js +0 -1
  280. package/ui/dist/assets/LogsPanel-BLnAqEaZ.js +0 -1
  281. package/ui/dist/assets/McpPanel-ChUzmr3z.js +0 -1
  282. package/ui/dist/assets/MemoryWikiPanel-Dwk3Aqwd.js +0 -11
  283. package/ui/dist/assets/NvidiaPanel-CeZK_-CV.js +0 -1
  284. package/ui/dist/assets/OrganismPanel-BB6YOiQV.js +0 -1
  285. package/ui/dist/assets/OverviewPanel-BmtBhQnv.js +0 -1
  286. package/ui/dist/assets/PaperclipPanel-C-brgwA3.js +0 -1
  287. package/ui/dist/assets/RecipesPanel-34lCfynJ.js +0 -1
  288. package/ui/dist/assets/SecurityPanel-CBTPWLj6.js +0 -1
  289. package/ui/dist/assets/SelfImprovePanel-BrPbFHhG.js +0 -1
  290. package/ui/dist/assets/SessionsPanel-DAEYIn83.js +0 -1
  291. package/ui/dist/assets/SettingsPanel-CzRROAYQ.js +0 -1
  292. package/ui/dist/assets/SettingsView-CN7ii2uw.js +0 -2
  293. package/ui/dist/assets/SomaView-Ba642Oqb.js +0 -5
  294. package/ui/dist/assets/TeamsPanel-DKQ5z2Qe.js +0 -1
  295. package/ui/dist/assets/TelemetryPanel-B6KAc55Q.js +0 -1
  296. package/ui/dist/assets/TitanCanvas-C-s0A-lv.js +0 -1092
  297. package/ui/dist/assets/ToolsView-Dei0KMP0.js +0 -2
  298. package/ui/dist/assets/TraceViewer-BniolyBx.js +0 -1
  299. package/ui/dist/assets/TrainingPanel-Bz4CTPGW.js +0 -1
  300. package/ui/dist/assets/VoiceOverlay-CmNCrLcd.js +0 -37
  301. package/ui/dist/assets/VramPanel-Xh_OtRDR.js +0 -1
  302. package/ui/dist/assets/WorkTab-BjLNmgIK.js +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/gateway/routes/commandPost.ts"],"sourcesContent":["/**\n * Command Post Router\n *\n * Extracted from gateway/server.ts v5.4.5 → v5.5.0.\n * Consolidates all /api/command-post/* routes for agent governance.\n */\n\nimport { Router, type Request, type Response } from 'express';\nimport logger from '../../utils/logger.js';\n\n// Command Post core\nimport {\n getDashboard as getCPDashboard,\n getRegisteredAgents,\n reportHeartbeat,\n removeAgent,\n checkoutTask,\n checkinTask,\n getActiveCheckouts,\n getBudgetPolicies,\n createBudgetPolicy,\n updateBudgetPolicy,\n deleteBudgetPolicy,\n getActivity,\n getGoalTree,\n getAncestryChain,\n validateGoalAncestry,\n validateGoalParentAssignment,\n sweepExpiredCheckoutsManual,\n getStaleAgents,\n enforceBudgetForAgent,\n getBudgetPolicyForAgent,\n createIssue,\n updateIssue,\n getIssue,\n listIssues,\n searchIssues,\n checkoutIssue,\n deleteIssue,\n addIssueComment,\n getIssueComments,\n createApproval,\n approveApproval,\n rejectApproval,\n listApprovals,\n getApproval,\n replyToApproval,\n snoozeApproval,\n unsnoozeApproval,\n batchApprove,\n batchReject,\n getAgentMessages,\n markAgentMessageRead,\n startRun,\n endRun,\n listRuns,\n getOrgTree,\n updateRegisteredAgent,\n} from '../../agent/commandPost.js';\n\n// Agent wakeup\nimport {\n getAgentInbox,\n queueWakeup,\n getWakeupRequest,\n cancelWakeup,\n drainPendingResults,\n} from '../../agent/agentWakeup.js';\n\n// Daemon events (for SSE)\nimport { titanEvents } from '../../agent/daemon.js';\n\n// Goals\nimport { createGoal } from '../../agent/goals.js';\n\nconst COMPONENT = 'CommandPostRouter';\n\nexport function createCommandPostRouter(): Router {\n const router = Router();\n\n // ── Dashboard ─────────────────────────────────────────────\n router.get('/dashboard', async (_req, res) => {\n const dashboard = getCPDashboard();\n try {\n const { listCompanies, getActiveRunners } = await import('../../agent/company.js');\n const companies = listCompanies();\n const runners = getActiveRunners();\n (dashboard as Record<string, unknown>).companies = companies.map(c => ({\n ...c,\n runnerActive: runners.includes(c.id),\n }));\n } catch { (dashboard as Record<string, unknown>).companies = []; }\n res.json(dashboard);\n });\n\n // ── Agents ──────────────────────────────────────────────────\n router.get('/agents', (_req, res) => {\n res.json(getRegisteredAgents());\n });\n\n router.post('/agents/:id/heartbeat', (req, res) => {\n const ok = reportHeartbeat(req.params.id);\n res.json({ success: ok });\n });\n\n router.post('/agents/:id/fire', async (req, res) => {\n try {\n const { fireHeartbeat } = await import('../../agent/heartbeatScheduler.js');\n await fireHeartbeat(req.params.id);\n res.json({ success: true });\n } catch (err) {\n res.status(500).json({ success: false, error: (err as Error).message });\n }\n });\n\n router.delete('/agents/:id', (req, res) => {\n const ok = removeAgent(req.params.id);\n if (!ok) { res.status(400).json({ error: 'Cannot remove agent (not found or is the primary agent)' }); return; }\n res.json({ success: true });\n });\n\n router.patch('/agents/:id', async (req, res) => {\n const { reportsTo, role, title, name, status, model } = req.body;\n const updated = updateRegisteredAgent(req.params.id, { reportsTo, role, title, name, model });\n if (!updated) { res.status(404).json({ error: 'Agent not found' }); return; }\n if (status && typeof status === 'string') {\n try {\n const { updateAgentStatus } = await import('../../agent/commandPost.js');\n updateAgentStatus(req.params.id, status as 'active' | 'idle' | 'paused' | 'error' | 'stopped');\n } catch { /* ok */ }\n }\n res.json(updated);\n });\n\n router.patch('/agents/:id/identity', async (req, res) => {\n const { voiceId, personaId, systemPromptOverride, memoryNamespace, characterSummary, model } = req.body || {};\n const coerce = (v: unknown): string | null | undefined => {\n if (v === null) return null;\n if (typeof v === 'string') return v;\n if (v === undefined) return undefined;\n res.status(400).json({ error: `Invalid identity field: expected string or null, got ${typeof v}` });\n return undefined;\n };\n if (res.headersSent) return;\n const { updateAgentIdentity } = await import('../../agent/commandPost.js');\n const updated = updateAgentIdentity(req.params.id, {\n voiceId: coerce(voiceId),\n personaId: coerce(personaId),\n systemPromptOverride: coerce(systemPromptOverride),\n memoryNamespace: coerce(memoryNamespace),\n characterSummary: coerce(characterSummary),\n model: coerce(model),\n });\n if (res.headersSent) return;\n if (!updated) { res.status(404).json({ error: 'Agent not found' }); return; }\n res.json(updated);\n });\n\n router.get('/agents/stale', (_req, res) => {\n const stale = getStaleAgents();\n res.json({ stale, total: stale.length });\n });\n\n // ── Tasks (checkout/checkin) ────────────────────────────────\n router.post('/tasks/:goalId/:subtaskId/checkout', (req, res) => {\n const agentId = (req.body as { agentId?: string }).agentId || 'manual';\n const lock = checkoutTask(req.params.goalId, req.params.subtaskId, agentId);\n if (!lock) { res.status(409).json({ error: 'Task already checked out by another agent' }); return; }\n res.json(lock);\n });\n\n router.post('/tasks/:goalId/:subtaskId/checkin', (req, res) => {\n const runId = (req.body as { runId?: string }).runId || '';\n const ok = checkinTask(req.params.subtaskId, runId);\n if (!ok) { res.status(404).json({ error: 'No matching checkout found' }); return; }\n res.json({ success: true });\n });\n\n // ── Checkouts ───────────────────────────────────────────────\n router.get('/checkouts', (_req, res) => {\n res.json(getActiveCheckouts());\n });\n\n router.post('/checkouts/sweep', (_req, res) => {\n const result = sweepExpiredCheckoutsManual();\n res.json(result);\n });\n\n router.get('/checkouts/expired', (_req, res) => {\n const result = sweepExpiredCheckoutsManual();\n res.json({ expired: result.swept, details: result.details });\n });\n\n // ── Budgets ─────────────────────────────────────────────────\n router.get('/budgets', (_req, res) => {\n res.json(getBudgetPolicies());\n });\n\n router.get('/budgets/reservations', (_req, res) => {\n res.json([]);\n });\n\n router.post('/budgets', (req, res) => {\n try {\n const body = req.body as {\n name: string;\n scope: { type: 'agent' | 'goal' | 'global'; targetId?: string };\n period: 'daily' | 'weekly' | 'monthly';\n limitUsd: number;\n warningThresholdPercent?: number;\n action?: 'warn' | 'pause' | 'stop';\n enabled?: boolean;\n };\n const policy = createBudgetPolicy({\n name: body.name,\n scope: body.scope,\n period: body.period,\n limitUsd: body.limitUsd,\n warningThresholdPercent: body.warningThresholdPercent ?? 80,\n action: body.action ?? 'pause',\n enabled: body.enabled ?? true,\n });\n res.status(201).json(policy);\n } catch (err) {\n res.status(400).json({ error: (err as Error).message });\n }\n });\n\n router.put('/budgets/:id', (req, res) => {\n const updated = updateBudgetPolicy(req.params.id, req.body as Record<string, unknown>);\n if (!updated) { res.status(404).json({ error: 'Budget policy not found' }); return; }\n res.json(updated);\n });\n\n router.delete('/budgets/:id', (req, res) => {\n const ok = deleteBudgetPolicy(req.params.id);\n if (!ok) { res.status(404).json({ error: 'Budget policy not found' }); return; }\n res.json({ success: true });\n });\n\n router.post('/budgets/:agentId/enforce', (req, res) => {\n const result = enforceBudgetForAgent(req.params.agentId);\n if (!result.budgetOk) {\n res.status(403).json({ budgetOk: false, policies: result.policies, message: 'Budget exceeded — agent paused' });\n return;\n }\n res.json({ budgetOk: true, policies: result.policies });\n });\n\n router.get('/budgets/agent/:agentId', (req, res) => {\n const budgetInfo = getBudgetPolicyForAgent(req.params.agentId);\n res.json(budgetInfo);\n });\n\n // ── Activity ──────────────────────────────────────────────\n router.get('/activity', (req, res) => {\n const limit = parseInt(req.query.limit as string) || 50;\n const type = req.query.type as string | undefined;\n res.json(getActivity({ limit, type }));\n });\n\n // ── Audit ───────────────────────────────────────────────────\n router.get('/audit', async (req, res) => {\n try {\n const { queryAudit } = await import('../../agent/auditStore.js');\n const query = {\n agentId: req.query.agentId as string | undefined,\n sessionId: req.query.sessionId as string | undefined,\n type: req.query.type as string | undefined,\n toolName: req.query.toolName as string | undefined,\n from: req.query.from as string | undefined,\n to: req.query.to as string | undefined,\n limit: req.query.limit ? parseInt(req.query.limit as string) : 100,\n };\n res.json(queryAudit(query));\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.get('/audit/costs', async (req, res) => {\n try {\n const { getAgentCostSummary, getDailyCostBreakdown } = await import('../../agent/auditStore.js');\n const groupBy = req.query.groupBy as string || 'agent';\n if (groupBy === 'day') {\n const days = req.query.days ? parseInt(req.query.days as string) : 30;\n res.json(getDailyCostBreakdown(days));\n } else {\n const agentId = req.query.agentId as string | undefined;\n res.json(getAgentCostSummary(agentId));\n }\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // ── Goals ───────────────────────────────────────────────────\n router.post('/goals', (req, res) => {\n const { title, description, subtasks, priority, tags, force } = req.body;\n if (!title) { res.status(400).json({ error: 'title is required' }); return; }\n try {\n const goal = createGoal({\n title,\n description: description || '',\n subtasks: subtasks || [],\n priority,\n tags,\n force: !!force,\n });\n res.status(201).json({ goal });\n } catch (err) {\n res.status(429).json({ error: (err as Error).message });\n }\n });\n\n router.get('/goals/tree', (_req, res) => {\n res.json(getGoalTree());\n });\n\n router.get('/goals/:id/ancestry', (req, res) => {\n const chain = getAncestryChain(req.params.id);\n if (chain.length === 0) { res.status(404).json({ error: 'Goal not found' }); return; }\n res.json(chain);\n });\n\n router.post('/goals/:id/validate', (req, res) => {\n const { parentGoalId } = req.body as { parentGoalId?: string | null };\n if (parentGoalId !== undefined) {\n const result = validateGoalParentAssignment(req.params.id, parentGoalId || null);\n if (!result.valid) {\n res.status(422).json({ valid: false, errors: result.errors });\n return;\n }\n res.json({ valid: true });\n } else {\n const result = validateGoalAncestry(req.params.id);\n if (!result.valid) {\n res.status(422).json({ valid: false, errors: result.errors });\n return;\n }\n res.json({ valid: true });\n }\n });\n\n // ── Conflict Resolution ─────────────────────────────────────\n router.post('/conflicts/propose', async (req, res) => {\n try {\n const { conflictResolver } = await import('../../agent/conflictResolver.js');\n const { entities, type, description, metadata } = req.body;\n if (!entities || !Array.isArray(entities) || entities.length === 0) {\n res.status(400).json({ error: 'entities array is required' }); return;\n }\n if (!type || !['file', 'goal', 'resource', 'agent', 'config', 'other'].includes(type)) {\n res.status(400).json({ error: 'valid type is required (file, goal, resource, agent, config, other)' }); return;\n }\n if (!description || typeof description !== 'string') {\n res.status(400).json({ error: 'description string is required' }); return;\n }\n const proposal = await conflictResolver.generateProposal({ entities, type, description, metadata: metadata || {} });\n res.json(proposal);\n } catch (error) {\n logger.error(COMPONENT, 'Conflict proposal generation error:', error);\n res.status(500).json({ error: 'Failed to generate conflict resolution proposal' });\n }\n });\n\n router.post('/conflicts/propose/formatted', async (req, res) => {\n try {\n const { conflictResolver } = await import('../../agent/conflictResolver.js');\n const { entities, type, description, metadata } = req.body;\n if (!entities || !Array.isArray(entities) || entities.length === 0) {\n res.status(400).json({ error: 'entities array is required' }); return;\n }\n if (!type || !['file', 'goal', 'resource', 'agent', 'config', 'other'].includes(type)) {\n res.status(400).json({ error: 'valid type is required (file, goal, resource, agent, config, other)' }); return;\n }\n if (!description || typeof description !== 'string') {\n res.status(400).json({ error: 'description string is required' }); return;\n }\n const proposal = await conflictResolver.generateProposal({ entities, type, description, metadata: metadata || {} });\n const formatted = conflictResolver.formatProposal(proposal);\n res.type('text/plain').send(formatted);\n } catch (error) {\n logger.error(COMPONENT, 'Conflict proposal formatting error:', error);\n res.status(500).json({ error: 'Failed to format conflict resolution proposal' });\n }\n });\n\n router.get('/conflicts/types', (_req, res) => {\n res.json({\n types: [\n { id: 'file', name: 'File Conflict', description: 'Merge conflicts, version conflicts' },\n { id: 'goal', name: 'Goal Conflict', description: 'Competing or conflicting goals' },\n { id: 'resource', name: 'Resource Conflict', description: 'Resource contention (GPU, memory, etc.)' },\n { id: 'agent', name: 'Agent Conflict', description: 'Agent coordination conflicts' },\n { id: 'config', name: 'Configuration Conflict', description: 'Conflicting configuration values' },\n { id: 'other', name: 'Other', description: 'Unclassified conflict type' }\n ]\n });\n });\n\n // ── SSE Stream ────────────────────────────────────────────\n const CP_SSE_EVENTS = [\n 'commandpost:activity', 'commandpost:task:checkout', 'commandpost:task:checkin',\n 'commandpost:task:expired', 'commandpost:budget:warning', 'commandpost:budget:exceeded',\n 'commandpost:agent:heartbeat', 'commandpost:agent:status',\n ];\n\n router.get('/stream', (req, res) => {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n 'X-Accel-Buffering': 'no',\n });\n\n const onEvent = (event: string, data: unknown) => {\n try { res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`); } catch { /* client gone */ }\n };\n\n const listeners = new Map<string, (data: unknown) => void>();\n for (const evt of CP_SSE_EVENTS) {\n const handler = (data: unknown) => onEvent(evt, data);\n listeners.set(evt, handler);\n titanEvents.on(evt, handler);\n }\n\n const keepalive = setInterval(() => {\n try { res.write(': keepalive\\n\\n'); } catch { /* client gone */ }\n }, 15_000);\n\n req.on('close', () => {\n clearInterval(keepalive);\n for (const [evt, handler] of listeners) {\n titanEvents.removeListener(evt, handler);\n }\n });\n });\n\n // ── Org Chart ───────────────────────────────────────────────\n router.get('/org', async (_req, res) => {\n const org = getOrgTree();\n try {\n const { listCompanies } = await import('../../agent/company.js');\n const companies = listCompanies();\n const companyNodes = companies.map(c => ({\n id: c.id,\n name: c.name,\n role: 'Company',\n title: c.description,\n status: c.status,\n model: '',\n reports: c.agents.map(a => ({\n id: a.id,\n name: a.name,\n role: a.role,\n title: a.template,\n status: a.status,\n model: '',\n reports: [],\n })),\n }));\n if (Array.isArray(org)) {\n org.push(...companyNodes);\n } else if (org && typeof org === 'object') {\n (org as Record<string, unknown>).companies = companyNodes;\n }\n } catch { /* non-critical */ }\n res.json(org);\n });\n\n // ── Issues ──────────────────────────────────────────────────\n router.get('/issues', (req, res) => {\n const filters = {\n status: req.query.status as string | undefined,\n assigneeAgentId: req.query.assignee as string | undefined,\n goalId: req.query.goalId as string | undefined,\n };\n res.json(listIssues(filters));\n });\n\n router.get('/issues/search', (req, res) => {\n const q = req.query.q as string | undefined;\n if (!q || q.trim().length < 2) {\n res.status(400).json({ error: 'Query must be at least 2 characters' }); return;\n }\n res.json(searchIssues(q));\n });\n\n router.post('/issues', (req, res) => {\n const { title, description, priority, assigneeAgentId, goalId, parentId } = req.body;\n if (!title) { res.status(400).json({ error: 'title is required' }); return; }\n const issue = createIssue({ title, description, priority, assigneeAgentId, goalId, parentId, createdByUser: 'board' });\n res.status(201).json(issue);\n });\n\n router.get('/issues/:id/context', (req, res) => {\n const issue = getIssue(req.params.id);\n if (!issue) { res.status(404).json({ error: 'Issue not found' }); return; }\n res.json({ ancestry: issue.goalId || '', issue });\n });\n\n router.get('/issues/:id', (req, res) => {\n const issue = getIssue(req.params.id);\n if (!issue) { res.status(404).json({ error: 'Issue not found' }); return; }\n const issueComments = getIssueComments(req.params.id);\n res.json({ ...issue, comments: issueComments });\n });\n\n router.get('/issues/:id/comments', (req, res) => {\n const issue = getIssue(req.params.id);\n if (!issue) { res.status(404).json({ error: 'Issue not found' }); return; }\n res.json(getIssueComments(req.params.id));\n });\n\n router.patch('/issues/:id', (req, res) => {\n const { title, description, status, priority, assigneeAgentId, goalId } = req.body;\n const updated = updateIssue(req.params.id, { title, description, status, priority, assigneeAgentId, goalId });\n if (!updated) { res.status(404).json({ error: 'Issue not found' }); return; }\n res.json(updated);\n });\n\n router.delete('/issues/:id', (req, res) => {\n const ok = deleteIssue(req.params.id);\n if (!ok) { res.status(404).json({ error: 'Issue not found' }); return; }\n res.json({ success: true });\n });\n\n router.post('/issues/:id/checkout', (req, res) => {\n const { agentId } = req.body;\n if (!agentId) { res.status(400).json({ error: 'agentId is required' }); return; }\n const result = checkoutIssue(req.params.id, agentId);\n if (!result) { res.status(409).json({ error: 'Issue already checked out by another agent' }); return; }\n res.json(result);\n });\n\n router.post('/issues/:id/comments', (req, res) => {\n const { body: commentBody, agentId } = req.body;\n if (!commentBody) { res.status(400).json({ error: 'body is required' }); return; }\n const comment = addIssueComment(req.params.id, commentBody, { agentId, user: agentId ? undefined : 'board' });\n if (!comment) { res.status(404).json({ error: 'Issue not found' }); return; }\n res.status(201).json(comment);\n });\n\n // ── Approvals ─────────────────────────────────────────────\n router.get('/approvals', (req, res) => {\n const status = req.query.status as string | undefined;\n res.json(listApprovals(status));\n });\n\n router.post('/approvals', (req, res) => {\n const { type, requestedBy, payload, linkedIssueIds } = req.body;\n if (!type) { res.status(400).json({ error: 'type is required' }); return; }\n const approval = createApproval({ type, requestedBy: requestedBy || 'board', payload: payload || {}, linkedIssueIds });\n res.status(201).json(approval);\n });\n\n router.post('/approvals/:id/approve', async (req, res) => {\n const { decidedBy, note } = req.body;\n const result = await approveApproval(req.params.id, decidedBy || 'board', note);\n if (!result) { res.status(404).json({ error: 'Approval not found or already decided' }); return; }\n res.json(result);\n });\n\n router.post('/approvals/:id/reject', (req, res) => {\n const { decidedBy, note } = req.body;\n const result = rejectApproval(req.params.id, decidedBy || 'board', note);\n if (!result) { res.status(404).json({ error: 'Approval not found or already decided' }); return; }\n res.json(result);\n });\n\n router.post('/approvals/:id/reply', (req, res) => {\n const { author, body } = req.body;\n if (!body || typeof body !== 'string') { res.status(400).json({ error: 'body is required' }); return; }\n const result = replyToApproval(req.params.id, author || 'user', body);\n if (!result) { res.status(404).json({ error: 'Approval not found' }); return; }\n res.json(result);\n });\n\n router.post('/approvals/:id/snooze', (req, res) => {\n const { until } = req.body;\n if (!until) { res.status(400).json({ error: 'until timestamp is required' }); return; }\n const result = snoozeApproval(req.params.id, until);\n if (!result) { res.status(404).json({ error: 'Approval not found or not pending' }); return; }\n res.json(result);\n });\n\n router.post('/approvals/:id/unsnooze', (req, res) => {\n const result = unsnoozeApproval(req.params.id);\n if (!result) { res.status(404).json({ error: 'Approval not found' }); return; }\n res.json(result);\n });\n\n router.get('/approvals/:id/thread', (req, res) => {\n const approval = listApprovals().find(a => a.id === req.params.id);\n if (!approval) { res.status(404).json({ error: 'Approval not found' }); return; }\n res.json({ approvalId: approval.id, thread: approval.thread || [] });\n });\n\n router.post('/approvals/batch', async (req, res) => {\n const { ids, action, decidedBy, note } = req.body;\n if (!Array.isArray(ids) || ids.length === 0) { res.status(400).json({ error: 'ids array required' }); return; }\n if (action === 'approve') {\n const result = await batchApprove(ids, decidedBy || 'board', note);\n res.json(result);\n } else if (action === 'reject') {\n const result = batchReject(ids, decidedBy || 'board', note);\n res.json(result);\n } else {\n res.status(400).json({ error: 'action must be approve or reject' });\n }\n });\n\n router.post('/approvals/sweep', async (_req, res) => {\n const { sweepStaleApprovalsManual } = await import('../../agent/commandPost.js');\n const result = sweepStaleApprovalsManual();\n res.json(result);\n });\n\n // ── Agent Messages ──────────────────────────────────────────\n router.get('/agent-messages', (req, res) => {\n const agentId = req.query.agentId as string | undefined;\n const userId = req.query.userId as string | undefined;\n const unreadOnly = req.query.unread === 'true';\n res.json(getAgentMessages(agentId, userId, unreadOnly));\n });\n\n router.post('/agent-messages/:id/read', (req, res) => {\n const ok = markAgentMessageRead(req.params.id);\n if (!ok) { res.status(404).json({ error: 'Message not found' }); return; }\n res.json({ read: true });\n });\n\n // ── Debates ─────────────────────────────────────────────────\n router.post('/debates', async (req, res) => {\n try {\n const { question, participants, rounds, resolution, judgeModel } = req.body || {};\n if (!question || !Array.isArray(participants) || participants.length < 2) {\n res.status(400).json({ error: 'question + 2-5 participants required' }); return;\n }\n const { runDebate } = await import('../../skills/builtin/agent_debate.js');\n const result = await runDebate({\n question: String(question),\n participants,\n rounds: Math.max(1, Math.min(4, Number(rounds) || 2)),\n resolution: (resolution === 'vote' || resolution === 'synthesize' || resolution === 'judge') ? resolution : 'judge',\n judgeModel: judgeModel ? String(judgeModel) : undefined,\n });\n res.json({ ok: true, id: result.id, winner: result.winner });\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.get('/debates', async (req, res) => {\n const limit = parseInt(req.query.limit as string) || 50;\n const { listDebates } = await import('../../skills/builtin/agent_debate.js');\n res.json({ items: listDebates(limit) });\n });\n\n router.get('/debates/:id', async (req, res) => {\n const { getDebate } = await import('../../skills/builtin/agent_debate.js');\n const debate = getDebate(req.params.id);\n if (!debate) { res.status(404).json({ error: 'Debate not found' }); return; }\n res.json(debate);\n });\n\n // ── Runs ────────────────────────────────────────────────────\n router.get('/runs', (req, res) => {\n const agentId = req.query.agentId as string | undefined;\n const limit = parseInt(req.query.limit as string) || 50;\n res.json(listRuns(agentId, limit));\n });\n\n router.post('/runs/:id/retry', async (req, res) => {\n const allRuns = listRuns(undefined, 500);\n const run = allRuns.find(r => r.id === req.params.id);\n if (!run) { res.status(404).json({ error: 'Run not found' }); return; }\n const agent = getRegisteredAgents().find(a => a.id === run.agentId);\n if (!agent) { res.status(404).json({ error: 'Agent not found' }); return; }\n\n let task = `Retry failed run (${run.id})`;\n if (run.error) task += `: ${run.error}`;\n let issueDesc = task;\n if (run.issueId) {\n const originalIssue = getIssue(run.issueId);\n if (originalIssue) {\n task = `Retry: ${originalIssue.title}`;\n issueDesc = `${originalIssue.description || ''}\\n\\nRetrying after failure: ${run.error || 'unknown error'}`;\n }\n }\n\n const issue = createIssue({ title: task, description: issueDesc, priority: 'high', assigneeAgentId: agent.id, createdByUser: 'board' });\n const newRun = startRun(agent.id, 'manual', issue.id);\n queueWakeup({ issueId: issue.id, issueIdentifier: issue.identifier, agentId: agent.id, agentName: agent.name, parentSessionId: null, task, templateName: agent.role || 'default' });\n res.json({ retried: true, runId: newRun.id, issueId: issue.id });\n });\n\n // ── Wakeup System ───────────────────────────────────────────\n router.get('/agents/:agentId/inbox', (req, res) => {\n const items = getAgentInbox(req.params.agentId);\n res.json({ items, total: items.length });\n });\n\n router.post('/wakeup', (req, res) => {\n const { issueId, agentId, agentName, task, templateName } = req.body;\n if (!issueId || !agentId || !task) {\n res.status(400).json({ error: 'issueId, agentId, and task are required' }); return;\n }\n const wakeup = queueWakeup({ issueId, issueIdentifier: issueId, agentId, agentName: agentName || 'Agent', parentSessionId: null, task, templateName: templateName || '' });\n res.json({ wakeupRequestId: wakeup.id, status: wakeup.status });\n });\n\n router.get('/wakeup/:requestId', (req, res) => {\n const request = getWakeupRequest(req.params.requestId);\n if (!request) { res.status(404).json({ error: 'Wakeup request not found' }); return; }\n res.json(request);\n });\n\n router.delete('/wakeup/:requestId', (req, res) => {\n const cancelled = cancelWakeup(req.params.requestId);\n if (!cancelled) { res.status(409).json({ error: 'Request already running or completed' }); return; }\n res.json({ cancelled: true });\n });\n\n router.get('/sessions/:sessionId/pending-results', (req, res) => {\n const results = drainPendingResults(req.params.sessionId);\n res.json({ results, count: results.length });\n });\n\n return router;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env node
2
+ import { Router } from "express";
3
+ import { logger } from "../../utils/logger.js";
4
+ const COMPONENT = "companies-router";
5
+ function createCompaniesRouter() {
6
+ const router = Router();
7
+ router.get("/", async (_req, res) => {
8
+ try {
9
+ const { listCompanies, getActiveRunners } = await import("../../agent/company.js");
10
+ const includeArchived = _req.query.archived === "true";
11
+ const companies = listCompanies(includeArchived);
12
+ const runners = getActiveRunners();
13
+ res.json({ companies: companies.map((c) => ({ ...c, runnerActive: runners.includes(c.id) })) });
14
+ } catch (e) {
15
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
16
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
17
+ }
18
+ });
19
+ router.post("/", async (req, res) => {
20
+ try {
21
+ const { createCompany } = await import("../../agent/company.js");
22
+ const company = createCompany(req.body);
23
+ res.json(company);
24
+ } catch (e) {
25
+ res.status(400).json({ error: e.message });
26
+ }
27
+ });
28
+ router.get("/:id", async (req, res) => {
29
+ try {
30
+ const { getCompany, isRunnerActive } = await import("../../agent/company.js");
31
+ const company = getCompany(req.params.id);
32
+ if (!company) {
33
+ res.status(404).json({ error: "Company not found" });
34
+ return;
35
+ }
36
+ res.json({ ...company, runnerActive: isRunnerActive(company.id) });
37
+ } catch (e) {
38
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
39
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
40
+ }
41
+ });
42
+ router.patch("/:id", async (req, res) => {
43
+ try {
44
+ const { updateCompany } = await import("../../agent/company.js");
45
+ const company = updateCompany(req.params.id, req.body);
46
+ if (!company) {
47
+ res.status(404).json({ error: "Company not found" });
48
+ return;
49
+ }
50
+ res.json(company);
51
+ } catch (e) {
52
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
53
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
54
+ }
55
+ });
56
+ router.delete("/:id", async (req, res) => {
57
+ try {
58
+ const { deleteCompany, stopCompanyRunner } = await import("../../agent/company.js");
59
+ stopCompanyRunner(req.params.id);
60
+ const ok = deleteCompany(req.params.id);
61
+ res.json({ success: ok });
62
+ } catch (e) {
63
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
64
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
65
+ }
66
+ });
67
+ router.post("/:id/start", async (req, res) => {
68
+ try {
69
+ const { startCompanyRunner } = await import("../../agent/company.js");
70
+ const interval = parseInt(req.body?.intervalMs || "60000", 10);
71
+ const ok = startCompanyRunner(req.params.id, interval);
72
+ res.json({ success: ok, message: ok ? "Runner started" : "Already running or company not active" });
73
+ } catch (e) {
74
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
75
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
76
+ }
77
+ });
78
+ router.post("/:id/stop", async (req, res) => {
79
+ try {
80
+ const { stopCompanyRunner } = await import("../../agent/company.js");
81
+ const ok = stopCompanyRunner(req.params.id);
82
+ res.json({ success: ok });
83
+ } catch (e) {
84
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
85
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
86
+ }
87
+ });
88
+ router.post("/:id/agents", async (req, res) => {
89
+ try {
90
+ const { addAgentToCompany } = await import("../../agent/company.js");
91
+ const agent = addAgentToCompany(req.params.id, req.body);
92
+ if (!agent) {
93
+ res.status(404).json({ error: "Company not found" });
94
+ return;
95
+ }
96
+ res.json(agent);
97
+ } catch (e) {
98
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
99
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
100
+ }
101
+ });
102
+ router.post("/:id/goals", async (req, res) => {
103
+ try {
104
+ const { addGoalToCompany } = await import("../../agent/company.js");
105
+ const goal = addGoalToCompany(req.params.id, req.body);
106
+ if (!goal) {
107
+ res.status(404).json({ error: "Company not found" });
108
+ return;
109
+ }
110
+ res.json(goal);
111
+ } catch (e) {
112
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
113
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
114
+ }
115
+ });
116
+ router.post("/:id/export", async (req, res) => {
117
+ try {
118
+ const { getCompany } = await import("../../agent/company.js");
119
+ const { writeCompanyPackage } = await import("../../agent/companyPortability.js");
120
+ const company = getCompany(req.params.id);
121
+ if (!company) {
122
+ res.status(404).json({ error: "Company not found" });
123
+ return;
124
+ }
125
+ const outPath = writeCompanyPackage(company, req.body?.outDir);
126
+ res.json({ success: true, path: outPath, name: company.name });
127
+ } catch (e) {
128
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
129
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
130
+ }
131
+ });
132
+ router.get("/exports", async (_req, res) => {
133
+ try {
134
+ const { listExportedPackages } = await import("../../agent/companyPortability.js");
135
+ res.json(listExportedPackages());
136
+ } catch (e) {
137
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
138
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
139
+ }
140
+ });
141
+ router.post("/import", async (req, res) => {
142
+ try {
143
+ const { importCompanyFromDirectory, importCompanyFromMarkdown } = await import("../../agent/companyPortability.js");
144
+ const { createCompany } = await import("../../agent/company.js");
145
+ let imported = null;
146
+ if (req.body?.packagePath) {
147
+ imported = importCompanyFromDirectory(req.body.packagePath);
148
+ } else if (req.body?.markdown) {
149
+ imported = importCompanyFromMarkdown(req.body.markdown);
150
+ }
151
+ if (!imported) {
152
+ res.status(400).json({ error: "Invalid import. Provide packagePath or markdown." });
153
+ return;
154
+ }
155
+ const company = createCompany(imported);
156
+ res.json({ success: true, company });
157
+ } catch (e) {
158
+ res.status(400).json({ error: e.message });
159
+ }
160
+ });
161
+ return router;
162
+ }
163
+ export {
164
+ createCompaniesRouter
165
+ };
166
+ //# sourceMappingURL=companies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/gateway/routes/companies.ts"],"sourcesContent":["import { Router } from 'express';\nimport { logger } from '../../utils/logger.js';\n\nconst COMPONENT = 'companies-router';\n\nexport function createCompaniesRouter() {\n const router = Router();\n\n router.get('/', async (_req, res) => {\n try {\n const { listCompanies, getActiveRunners } = await import('../../agent/company.js');\n const includeArchived = _req.query.archived === 'true';\n const companies = listCompanies(includeArchived);\n const runners = getActiveRunners();\n res.json({ companies: companies.map(c => ({ ...c, runnerActive: runners.includes(c.id) })) });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/', async (req, res) => {\n try {\n const { createCompany } = await import('../../agent/company.js');\n const company = createCompany(req.body);\n res.json(company);\n } catch (e) { res.status(400).json({ error: (e as Error).message }); }\n });\n\n router.get('/:id', async (req, res) => {\n try {\n const { getCompany, isRunnerActive } = await import('../../agent/company.js');\n const company = getCompany(req.params.id);\n if (!company) { res.status(404).json({ error: 'Company not found' }); return; }\n res.json({ ...company, runnerActive: isRunnerActive(company.id) });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.patch('/:id', async (req, res) => {\n try {\n const { updateCompany } = await import('../../agent/company.js');\n const company = updateCompany(req.params.id, req.body);\n if (!company) { res.status(404).json({ error: 'Company not found' }); return; }\n res.json(company);\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.delete('/:id', async (req, res) => {\n try {\n const { deleteCompany, stopCompanyRunner } = await import('../../agent/company.js');\n stopCompanyRunner(req.params.id);\n const ok = deleteCompany(req.params.id);\n res.json({ success: ok });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // Start/stop company heartbeat runner\n router.post('/:id/start', async (req, res) => {\n try {\n const { startCompanyRunner } = await import('../../agent/company.js');\n const interval = parseInt(req.body?.intervalMs || '60000', 10);\n const ok = startCompanyRunner(req.params.id, interval);\n res.json({ success: ok, message: ok ? 'Runner started' : 'Already running or company not active' });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/:id/stop', async (req, res) => {\n try {\n const { stopCompanyRunner } = await import('../../agent/company.js');\n const ok = stopCompanyRunner(req.params.id);\n res.json({ success: ok });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // Add agent/goal to company\n router.post('/:id/agents', async (req, res) => {\n try {\n const { addAgentToCompany } = await import('../../agent/company.js');\n const agent = addAgentToCompany(req.params.id, req.body);\n if (!agent) { res.status(404).json({ error: 'Company not found' }); return; }\n res.json(agent);\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/:id/goals', async (req, res) => {\n try {\n const { addGoalToCompany } = await import('../../agent/company.js');\n const goal = addGoalToCompany(req.params.id, req.body);\n if (!goal) { res.status(404).json({ error: 'Company not found' }); return; }\n res.json(goal);\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // Company Portability (Export/Import)\n router.post('/:id/export', async (req, res) => {\n try {\n const { getCompany } = await import('../../agent/company.js');\n const { writeCompanyPackage } = await import('../../agent/companyPortability.js');\n const company = getCompany(req.params.id);\n if (!company) { res.status(404).json({ error: 'Company not found' }); return; }\n const outPath = writeCompanyPackage(company, req.body?.outDir);\n res.json({ success: true, path: outPath, name: company.name });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.get('/exports', async (_req, res) => {\n try {\n const { listExportedPackages } = await import('../../agent/companyPortability.js');\n res.json(listExportedPackages());\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/import', async (req, res) => {\n try {\n const { importCompanyFromDirectory, importCompanyFromMarkdown } = await import('../../agent/companyPortability.js');\n const { createCompany } = await import('../../agent/company.js');\n let imported = null;\n if (req.body?.packagePath) {\n imported = importCompanyFromDirectory(req.body.packagePath);\n } else if (req.body?.markdown) {\n imported = importCompanyFromMarkdown(req.body.markdown);\n }\n if (!imported) { res.status(400).json({ error: 'Invalid import. Provide packagePath or markdown.' }); return; }\n const company = createCompany(imported);\n res.json({ success: true, company });\n } catch (e) { res.status(400).json({ error: (e as Error).message }); }\n });\n\n return router;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env node
2
+ import { Router } from "express";
3
+ import { homedir } from "os";
4
+ import { join, dirname, resolve } from "path";
5
+ import fs from "fs";
6
+ import logger from "../../utils/logger.js";
7
+ import { loadConfig } from "../../config/config.js";
8
+ const COMPONENT = "FilesRouter";
9
+ function getFileRoots() {
10
+ const cfg = loadConfig();
11
+ const fmCfg = cfg.fileManager;
12
+ const roots = fmCfg?.roots || ["~/.titan"];
13
+ return roots.map((r) => {
14
+ const expanded = r.replace(/^~/, homedir());
15
+ const abs = resolve(expanded);
16
+ const label = abs.split("/").filter(Boolean).pop() || abs;
17
+ return { label, path: abs };
18
+ });
19
+ }
20
+ function validateFilePath(reqPath, rootParam) {
21
+ const roots = getFileRoots();
22
+ if (roots.length === 0) return { valid: false, fullPath: "", basePath: "", error: "No file roots configured" };
23
+ let selectedRoot = roots[0];
24
+ if (rootParam) {
25
+ const byIndex = roots[parseInt(rootParam, 10)];
26
+ const byLabel = roots.find((r) => r.label === rootParam || r.path === rootParam);
27
+ selectedRoot = byIndex || byLabel || roots[0];
28
+ }
29
+ const basePath = selectedRoot.path;
30
+ const fullPath = resolve(basePath, reqPath.replace(/^\//, ""));
31
+ const basePathWithSep = basePath.endsWith("/") ? basePath : basePath + "/";
32
+ if (fullPath !== basePath && !fullPath.startsWith(basePathWithSep)) {
33
+ return { valid: false, fullPath, basePath, error: "Access denied: path outside allowed root" };
34
+ }
35
+ const cfg = loadConfig();
36
+ const fmCfg = cfg.fileManager;
37
+ const blocked = fmCfg?.blockedPatterns || [".ssh", ".env", ".aws", ".gnupg", "node_modules", ".git/objects"];
38
+ for (const pattern of blocked) {
39
+ if (fullPath.includes(`/${pattern}`) || fullPath.endsWith(`/${pattern}`)) {
40
+ return { valid: false, fullPath, basePath, error: `Access denied: blocked pattern "${pattern}"` };
41
+ }
42
+ }
43
+ return { valid: true, fullPath, basePath };
44
+ }
45
+ function createFilesRouter() {
46
+ const router = Router();
47
+ const UPLOADS_DIR = join(homedir(), ".titan", "uploads");
48
+ router.get("/roots", (_req, res) => {
49
+ res.json({ roots: getFileRoots() });
50
+ });
51
+ router.get("/", (req, res) => {
52
+ const reqPath = req.query.path || "";
53
+ const rootParam = req.query.root;
54
+ const { valid, fullPath, basePath, error } = validateFilePath(reqPath, rootParam);
55
+ if (!valid) {
56
+ res.status(403).json({ error });
57
+ return;
58
+ }
59
+ try {
60
+ if (!fs.existsSync(fullPath)) {
61
+ res.status(404).json({ error: "Path not found" });
62
+ return;
63
+ }
64
+ const stat = fs.statSync(fullPath);
65
+ if (!stat.isDirectory()) {
66
+ res.status(400).json({ error: "Not a directory. Use /api/files/read for files." });
67
+ return;
68
+ }
69
+ const entries = fs.readdirSync(fullPath).map((name) => {
70
+ try {
71
+ const entryPath = join(fullPath, name);
72
+ const entryStat = fs.statSync(entryPath);
73
+ return {
74
+ name,
75
+ path: reqPath ? `${reqPath}/${name}` : name,
76
+ type: entryStat.isDirectory() ? "directory" : "file",
77
+ size: entryStat.size,
78
+ modified: entryStat.mtime.toISOString()
79
+ };
80
+ } catch {
81
+ return { name, path: reqPath ? `${reqPath}/${name}` : name, type: "file", size: 0, modified: "" };
82
+ }
83
+ });
84
+ entries.sort((a, b) => {
85
+ if (a.type !== b.type) return a.type === "directory" ? -1 : 1;
86
+ return a.name.localeCompare(b.name);
87
+ });
88
+ res.json({ path: reqPath || "/", entries, basePath });
89
+ } catch (err) {
90
+ res.status(500).json({ error: err.message });
91
+ }
92
+ });
93
+ router.get("/read", (req, res) => {
94
+ const reqPath = req.query.path;
95
+ if (!reqPath) {
96
+ res.status(400).json({ error: "path parameter required" });
97
+ return;
98
+ }
99
+ const rootParam = req.query.root;
100
+ const { valid, fullPath, error } = validateFilePath(reqPath, rootParam);
101
+ if (!valid) {
102
+ res.status(403).json({ error });
103
+ return;
104
+ }
105
+ try {
106
+ if (!fs.existsSync(fullPath)) {
107
+ res.status(404).json({ error: "File not found" });
108
+ return;
109
+ }
110
+ const stat = fs.statSync(fullPath);
111
+ if (stat.isDirectory()) {
112
+ res.status(400).json({ error: "Path is a directory" });
113
+ return;
114
+ }
115
+ const MAX_SIZE = 1024 * 1024;
116
+ if (stat.size > MAX_SIZE) {
117
+ const content2 = fs.readFileSync(fullPath, "utf-8").slice(0, MAX_SIZE);
118
+ res.json({ path: reqPath, content: content2, truncated: true, size: stat.size, modified: stat.mtime.toISOString() });
119
+ return;
120
+ }
121
+ const content = fs.readFileSync(fullPath, "utf-8");
122
+ res.json({ path: reqPath, content, truncated: false, size: stat.size, modified: stat.mtime.toISOString() });
123
+ } catch (err) {
124
+ res.status(500).json({ error: err.message });
125
+ }
126
+ });
127
+ router.post("/write", (req, res) => {
128
+ const { path: reqPath, content, root: rootParam } = req.body;
129
+ if (!reqPath) {
130
+ res.status(400).json({ error: "path required" });
131
+ return;
132
+ }
133
+ if (content === void 0) {
134
+ res.status(400).json({ error: "content required" });
135
+ return;
136
+ }
137
+ const { valid, fullPath, error } = validateFilePath(reqPath, rootParam);
138
+ if (!valid) {
139
+ res.status(403).json({ error });
140
+ return;
141
+ }
142
+ try {
143
+ const dir = dirname(fullPath);
144
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
145
+ fs.writeFileSync(fullPath, content, "utf-8");
146
+ const stat = fs.statSync(fullPath);
147
+ res.json({ success: true, path: reqPath, size: stat.size, modified: stat.mtime.toISOString() });
148
+ } catch (err) {
149
+ res.status(500).json({ error: err.message });
150
+ }
151
+ });
152
+ router.post("/mkdir", (req, res) => {
153
+ const { path: reqPath, root: rootParam } = req.body;
154
+ if (!reqPath) {
155
+ res.status(400).json({ error: "path required" });
156
+ return;
157
+ }
158
+ const { valid, fullPath, error } = validateFilePath(reqPath, rootParam);
159
+ if (!valid) {
160
+ res.status(403).json({ error });
161
+ return;
162
+ }
163
+ try {
164
+ if (fs.existsSync(fullPath)) {
165
+ res.status(409).json({ error: "Path already exists" });
166
+ return;
167
+ }
168
+ fs.mkdirSync(fullPath, { recursive: true });
169
+ res.json({ success: true, path: reqPath });
170
+ } catch (err) {
171
+ res.status(500).json({ error: err.message });
172
+ }
173
+ });
174
+ router.post("/rename", (req, res) => {
175
+ const { oldPath, newPath, root: rootParam } = req.body;
176
+ if (!oldPath || !newPath) {
177
+ res.status(400).json({ error: "oldPath and newPath required" });
178
+ return;
179
+ }
180
+ const oldValidation = validateFilePath(oldPath, rootParam);
181
+ const newValidation = validateFilePath(newPath, rootParam);
182
+ if (!oldValidation.valid) {
183
+ res.status(403).json({ error: oldValidation.error });
184
+ return;
185
+ }
186
+ if (!newValidation.valid) {
187
+ res.status(403).json({ error: newValidation.error });
188
+ return;
189
+ }
190
+ try {
191
+ if (!fs.existsSync(oldValidation.fullPath)) {
192
+ res.status(404).json({ error: "Source not found" });
193
+ return;
194
+ }
195
+ if (fs.existsSync(newValidation.fullPath)) {
196
+ res.status(409).json({ error: "Destination already exists" });
197
+ return;
198
+ }
199
+ fs.renameSync(oldValidation.fullPath, newValidation.fullPath);
200
+ res.json({ success: true, oldPath, newPath });
201
+ } catch (err) {
202
+ res.status(500).json({ error: err.message });
203
+ }
204
+ });
205
+ router.delete("/delete", (req, res) => {
206
+ const reqPath = req.query.path;
207
+ const rootParam = req.query.root;
208
+ if (!reqPath) {
209
+ res.status(400).json({ error: "path required" });
210
+ return;
211
+ }
212
+ const { valid, fullPath, error } = validateFilePath(reqPath, rootParam);
213
+ if (!valid) {
214
+ res.status(403).json({ error });
215
+ return;
216
+ }
217
+ try {
218
+ if (!fs.existsSync(fullPath)) {
219
+ res.status(404).json({ error: "Not found" });
220
+ return;
221
+ }
222
+ const stat = fs.statSync(fullPath);
223
+ if (stat.isDirectory()) {
224
+ const contents = fs.readdirSync(fullPath);
225
+ if (contents.length > 0) {
226
+ res.status(400).json({ error: "Directory not empty. Delete contents first." });
227
+ return;
228
+ }
229
+ fs.rmdirSync(fullPath);
230
+ } else {
231
+ fs.unlinkSync(fullPath);
232
+ }
233
+ res.json({ success: true, path: reqPath });
234
+ } catch (err) {
235
+ res.status(500).json({ error: err.message });
236
+ }
237
+ });
238
+ router.post("/upload", (req, res) => {
239
+ try {
240
+ const fileName = req.headers["x-filename"] || `upload-${Date.now()}`;
241
+ const safeName = fileName.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 100);
242
+ const sessionId = req.headers["x-session-id"] || "default";
243
+ const body = Buffer.isBuffer(req.body) ? req.body : Buffer.from(JSON.stringify(req.body));
244
+ if (!body || body.length === 0) {
245
+ res.status(400).json({ error: "Empty upload body" });
246
+ return;
247
+ }
248
+ const sessionDir = join(UPLOADS_DIR, sessionId);
249
+ if (!fs.existsSync(sessionDir)) fs.mkdirSync(sessionDir, { recursive: true });
250
+ const filePath = join(sessionDir, safeName);
251
+ fs.writeFileSync(filePath, body);
252
+ const stat = fs.statSync(filePath);
253
+ logger.info(COMPONENT, `File uploaded: ${safeName} (${(stat.size / 1024).toFixed(0)}KB) \u2192 session ${sessionId}`);
254
+ res.json({ ok: true, file: { name: safeName, path: filePath, size: stat.size, session: sessionId, uploadedAt: (/* @__PURE__ */ new Date()).toISOString() } });
255
+ } catch (err) {
256
+ res.status(500).json({ error: err.message });
257
+ }
258
+ });
259
+ router.get("/uploads", (req, res) => {
260
+ try {
261
+ const sessionId = req.query.session || "default";
262
+ const sessionDir = join(UPLOADS_DIR, sessionId);
263
+ if (!fs.existsSync(sessionDir)) {
264
+ res.json({ files: [] });
265
+ return;
266
+ }
267
+ const files = fs.readdirSync(sessionDir).map((name) => {
268
+ const stat = fs.statSync(join(sessionDir, name));
269
+ return { name, size: stat.size, modified: stat.mtime.toISOString() };
270
+ });
271
+ res.json({ files, session: sessionId });
272
+ } catch (err) {
273
+ res.status(500).json({ error: err.message });
274
+ }
275
+ });
276
+ router.delete("/uploads/:name", (req, res) => {
277
+ try {
278
+ const sessionId = req.query.session || "default";
279
+ const filePath = join(UPLOADS_DIR, sessionId, req.params.name.replace(/[^a-zA-Z0-9._-]/g, "_"));
280
+ if (!filePath.startsWith(UPLOADS_DIR)) {
281
+ res.status(403).json({ error: "Access denied" });
282
+ return;
283
+ }
284
+ if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
285
+ res.json({ ok: true });
286
+ } catch (err) {
287
+ res.status(500).json({ error: err.message });
288
+ }
289
+ });
290
+ return router;
291
+ }
292
+ export {
293
+ createFilesRouter
294
+ };
295
+ //# sourceMappingURL=files.js.map