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,500 @@
1
+ #!/usr/bin/env node
2
+ import { Router } from "express";
3
+ import { join } from "path";
4
+ import fs from "fs";
5
+ import { loadConfig } from "../../config/config.js";
6
+ import {
7
+ queryAuditLog,
8
+ getAuditStats
9
+ } from "../../agent/auditLog.js";
10
+ import {
11
+ getConsentUrl,
12
+ exchangeCode,
13
+ isGoogleConnected,
14
+ getGoogleEmail,
15
+ disconnectGoogle
16
+ } from "../../auth/google.js";
17
+ import { TITAN_VERSION, TITAN_WORKSPACE } from "../../utils/constants.js";
18
+ import logger, { getLogFilePath } from "../../utils/logger.js";
19
+ import { listSessions } from "../../agent/session.js";
20
+ import { getUsageStats } from "../../memory/memory.js";
21
+ import { getAutopilotStatus } from "../../agent/autopilot.js";
22
+ import { listGoals } from "../../agent/goals.js";
23
+ import { getGraphData } from "../../memory/graph.js";
24
+ import { getActiveLlmRequests } from "../server.js";
25
+ const COMPONENT = "AdminRouter";
26
+ function createAdminRouter() {
27
+ const router = Router();
28
+ router.get("/audit", (req, res) => {
29
+ const query = {
30
+ since: req.query.since,
31
+ until: req.query.until,
32
+ action: req.query.action,
33
+ source: req.query.source,
34
+ tool: req.query.tool,
35
+ limit: req.query.limit ? parseInt(req.query.limit, 10) : 100
36
+ };
37
+ res.json({ entries: queryAuditLog(query) });
38
+ });
39
+ router.get("/audit/stats", (req, res) => {
40
+ const hours = req.query.hours ? parseInt(req.query.hours, 10) : 24;
41
+ res.json(getAuditStats(hours));
42
+ });
43
+ router.get("/vulnerabilities", (_req, res) => {
44
+ try {
45
+ const reportPath = join(process.cwd(), "dependency-scan-report.json");
46
+ if (!fs.existsSync(reportPath)) {
47
+ res.json({
48
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
49
+ vulnerabilities: { total: 0, critical: 0, high: 0, moderate: 0, low: 0 },
50
+ outdated: [],
51
+ deprecated: [],
52
+ licenseIssues: [],
53
+ totalDependencies: 0,
54
+ directDependencies: 0,
55
+ errors: ["No scan report found. Run: npm run scan:deps"]
56
+ });
57
+ return;
58
+ }
59
+ const report = JSON.parse(fs.readFileSync(reportPath, "utf-8"));
60
+ res.json(report);
61
+ } catch (err) {
62
+ res.status(500).json({ error: err.message });
63
+ }
64
+ });
65
+ router.post("/vulnerabilities/scan", async (_req, res) => {
66
+ try {
67
+ const scanScript = join(process.cwd(), "scripts", "dependency-scan.cjs");
68
+ if (!fs.existsSync(scanScript)) {
69
+ res.status(404).json({ error: "Scan script not found" });
70
+ return;
71
+ }
72
+ const { exec } = await import("child_process");
73
+ exec(`node ${scanScript}`, (error, stdout, stderr) => {
74
+ if (error) {
75
+ res.status(500).json({ error: error.message, output: stderr });
76
+ return;
77
+ }
78
+ res.json({ success: true, output: stdout });
79
+ });
80
+ } catch (err) {
81
+ res.status(500).json({ error: err.message });
82
+ }
83
+ });
84
+ function getGoogleRedirectUri() {
85
+ const cfg = loadConfig();
86
+ const publicUrl = cfg.gateway.publicUrl;
87
+ const port = cfg.gateway.port || 48420;
88
+ return publicUrl ? `${publicUrl}/api/auth/google/callback` : `http://localhost:${port}/api/auth/google/callback`;
89
+ }
90
+ router.get("/auth/google/status", (_req, res) => {
91
+ res.json({ connected: isGoogleConnected(), email: getGoogleEmail() });
92
+ });
93
+ router.get("/auth/google/start", (req, res) => {
94
+ try {
95
+ const url = getConsentUrl(getGoogleRedirectUri());
96
+ res.redirect(url);
97
+ } catch (err) {
98
+ res.status(400).json({ error: err.message });
99
+ }
100
+ });
101
+ router.get("/auth/google/callback", async (req, res) => {
102
+ const code = req.query.code;
103
+ if (!code) {
104
+ res.status(400).send("Missing authorization code");
105
+ return;
106
+ }
107
+ try {
108
+ await exchangeCode(code, getGoogleRedirectUri());
109
+ res.redirect("/?google_connected=1");
110
+ } catch (err) {
111
+ res.status(500).send(`OAuth failed: ${err.message}`);
112
+ }
113
+ });
114
+ router.post("/auth/google/disconnect", (_req, res) => {
115
+ disconnectGoogle();
116
+ res.json({ ok: true });
117
+ });
118
+ router.get("/soul", (_req, res) => {
119
+ try {
120
+ const cfg = loadConfig();
121
+ const soulPath = join(cfg.agent.workspace || TITAN_WORKSPACE, "SOUL.md");
122
+ if (fs.existsSync(soulPath)) {
123
+ res.json({ content: fs.readFileSync(soulPath, "utf-8") });
124
+ } else {
125
+ res.json({ content: "" });
126
+ }
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.post("/soul", (req, res) => {
133
+ try {
134
+ const cfg = loadConfig();
135
+ const workspace = cfg.agent.workspace || TITAN_WORKSPACE;
136
+ const soulPath = join(workspace, "SOUL.md");
137
+ if (!fs.existsSync(workspace)) fs.mkdirSync(workspace, { recursive: true });
138
+ const { content, aboutMe, personality } = req.body;
139
+ if (content !== void 0) {
140
+ fs.writeFileSync(soulPath, content, "utf-8");
141
+ } else if (aboutMe || personality) {
142
+ const soulContent = [
143
+ "# SOUL.md - Who You Are",
144
+ "",
145
+ "## About Your Human",
146
+ aboutMe || "(Not yet described)",
147
+ "",
148
+ "## Your Personality",
149
+ personality || "(Not yet defined)",
150
+ "",
151
+ "## Core Principles",
152
+ "- Be genuinely helpful, not performatively helpful",
153
+ "- Have opinions and preferences",
154
+ "- Be resourceful before asking",
155
+ "- Earn trust through competence",
156
+ "",
157
+ "## Boundaries",
158
+ "- Private things stay private",
159
+ "- Ask before acting externally",
160
+ "- Never send half-baked replies to messaging surfaces",
161
+ "",
162
+ `_This file evolves as you learn. Update it when you discover new preferences._`
163
+ ].join("\n");
164
+ fs.writeFileSync(soulPath, soulContent, "utf-8");
165
+ } else {
166
+ res.status(400).json({ error: 'Provide either "content" or "aboutMe"/"personality"' });
167
+ return;
168
+ }
169
+ logger.info(COMPONENT, "SOUL.md updated via API");
170
+ res.json({ success: true });
171
+ } catch (e) {
172
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
173
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
174
+ }
175
+ });
176
+ router.get("/activity/recent", (req, res) => {
177
+ try {
178
+ const logPath = getLogFilePath();
179
+ if (!logPath || !fs.existsSync(logPath)) {
180
+ res.json({ events: [] });
181
+ return;
182
+ }
183
+ const limit = req.query.limit ? parseInt(req.query.limit, 10) : 200;
184
+ const filter = req.query.filter || "all";
185
+ const stats = fs.statSync(logPath);
186
+ const readSize = Math.min(stats.size, 2e5);
187
+ const fd = fs.openSync(logPath, "r");
188
+ const buf = Buffer.alloc(readSize);
189
+ fs.readSync(fd, buf, 0, readSize, Math.max(0, stats.size - readSize));
190
+ fs.closeSync(fd);
191
+ const content = buf.toString("utf-8");
192
+ const rawLines = content.split("\n").filter(Boolean);
193
+ const lines = stats.size > readSize ? rawLines.slice(1) : rawLines;
194
+ const classifyEvent = (message, component) => {
195
+ const lc = message.toLowerCase();
196
+ const cc = component.toLowerCase();
197
+ if (cc.includes("toolrunner") || lc.includes("executing tool") || lc.includes("tool:")) return "tool";
198
+ if (cc.includes("agent") || lc.includes("processing message") || lc.includes("response")) return "agent";
199
+ if (cc.includes("autopilot")) return "autopilot";
200
+ if (cc.includes("goal")) return "goal";
201
+ if (cc.includes("websearch") || cc.includes("browse") || lc.includes("search")) return "search";
202
+ if (cc.includes("autonomy") || lc.includes("autonomy")) return "autonomy";
203
+ if (cc.includes("router") || cc.includes("provider")) return "router";
204
+ if (cc.includes("graph") || cc.includes("memory")) return "graph";
205
+ if (lc.includes("error") || lc.includes("fail")) return "error";
206
+ return "system";
207
+ };
208
+ const events = lines.map((line) => {
209
+ const match = line.match(/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s+(DEBUG|INFO|WARN|ERROR)\s+(?:\[([^\]]+)\]\s+)?(.*)$/);
210
+ if (!match) return null;
211
+ const [, timestamp, level, component = "System", message] = match;
212
+ const type = classifyEvent(message, component);
213
+ return { timestamp, level: level.toLowerCase(), component, message, type };
214
+ }).filter((e) => {
215
+ if (!e) return false;
216
+ if (e.level === "debug") return false;
217
+ if (filter === "all") return true;
218
+ if (filter === "errors") return e.level === "error" || e.level === "warn";
219
+ return e.type === filter;
220
+ }).slice(-limit).reverse();
221
+ res.json({ events });
222
+ } catch (e) {
223
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
224
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
225
+ }
226
+ });
227
+ router.get("/activity/summary", (_req, res) => {
228
+ try {
229
+ const cfg = loadConfig();
230
+ const sessions = listSessions();
231
+ const usage = getUsageStats();
232
+ const autopilot = getAutopilotStatus();
233
+ const goals = listGoals();
234
+ const toolCalls = usage.toolCalls ?? usage.totalToolCalls ?? 0;
235
+ let status = "idle";
236
+ if (getActiveLlmRequests() > 0) status = "processing";
237
+ if (autopilot.isRunning) status = "autopilot";
238
+ let lastActivity = null;
239
+ try {
240
+ const logPath = getLogFilePath();
241
+ if (logPath && fs.existsSync(logPath)) {
242
+ const stat = fs.statSync(logPath);
243
+ lastActivity = stat.mtime.toISOString();
244
+ }
245
+ } catch {
246
+ }
247
+ let graphStats = { entities: 0, edges: 0 };
248
+ try {
249
+ const gd = getGraphData();
250
+ graphStats = { entities: gd.nodes.length, edges: gd.edges.length };
251
+ } catch {
252
+ }
253
+ const activeGoals = goals.filter((g) => g.status !== "completed" && g.status !== "failed");
254
+ res.json({
255
+ activeSessions: sessions.length,
256
+ toolCallsLast24h: toolCalls,
257
+ autopilotRunsToday: autopilot.totalRuns ?? 0,
258
+ autopilotEnabled: autopilot.enabled ?? false,
259
+ autopilotNextRun: autopilot.nextRunEstimate ?? null,
260
+ activeGoals: activeGoals.length,
261
+ goals: activeGoals.slice(0, 5).map((g) => ({
262
+ id: g.id,
263
+ title: g.title,
264
+ progress: g.progress ?? (g.subtasks ? Math.round(g.subtasks.filter((s) => s.status === "done").length / Math.max(g.subtasks.length, 1) * 100) : 0)
265
+ })),
266
+ lastActivity,
267
+ currentModel: cfg.agent.model,
268
+ autonomyMode: cfg.autonomy?.mode ?? "supervised",
269
+ status,
270
+ graphStats
271
+ });
272
+ } catch (e) {
273
+ logger.error(COMPONENT, `Endpoint error: ${e.message}`);
274
+ res.status(500).json({ error: "Something went wrong on our end. Please try again in a moment." });
275
+ }
276
+ });
277
+ router.post("/browser/form-fill", async (req, res) => {
278
+ const { url, data, submit, postClicks } = req.body;
279
+ if (!url || typeof url !== "string") {
280
+ return res.status(400).json({ success: false, error: "url is required (string)" });
281
+ }
282
+ if (!data || typeof data !== "object") {
283
+ return res.status(400).json({ success: false, error: "data is required (Record<string, string>)" });
284
+ }
285
+ try {
286
+ const { getPage, releasePage } = await import("../../browsing/browserPool.js");
287
+ const { fillFormSmart } = await import("../../skills/builtin/web_browse_llm.js");
288
+ const page = await getPage();
289
+ const session = { page, lastUsed: Date.now(), elements: /* @__PURE__ */ new Map() };
290
+ try {
291
+ const deferSubmit = Array.isArray(postClicks) && postClicks.length > 0 && submit;
292
+ const result = await fillFormSmart(session, url, data, deferSubmit ? false : submit ?? false);
293
+ const clickResults = [];
294
+ if (Array.isArray(postClicks)) {
295
+ for (const click of postClicks) {
296
+ try {
297
+ if (typeof click === "string") {
298
+ const clicked = await page.evaluate((text) => {
299
+ const els = Array.from(document.querySelectorAll('button, input[type="radio"], label, [role="button"], [role="radio"]'));
300
+ for (const el of els) {
301
+ const elText = el.textContent?.trim() || "";
302
+ if (elText.toLowerCase() === text.toLowerCase() || elText.toLowerCase().includes(text.toLowerCase())) {
303
+ el.click();
304
+ return elText;
305
+ }
306
+ }
307
+ return null;
308
+ }, click);
309
+ if (clicked) {
310
+ clickResults.push(`\u2705 Clicked "${clicked}"`);
311
+ } else {
312
+ try {
313
+ await page.click(click, { timeout: 3e3 });
314
+ clickResults.push(`\u2705 Clicked selector: ${click}`);
315
+ } catch {
316
+ clickResults.push(`\u274C Could not find: "${click}"`);
317
+ }
318
+ }
319
+ await page.waitForTimeout(500);
320
+ }
321
+ } catch (e) {
322
+ clickResults.push(`\u274C Error clicking "${click}": ${e.message?.split("\n")[0]}`);
323
+ }
324
+ }
325
+ }
326
+ if (deferSubmit) {
327
+ try {
328
+ const { solveCaptcha } = await import("../../browsing/captchaSolver.js");
329
+ const solveResult = await solveCaptcha(page);
330
+ if (solveResult.solved) {
331
+ clickResults.push(`\u2705 ${solveResult.type} solved via CapSolver`);
332
+ } else if (solveResult.error) {
333
+ clickResults.push(`\u26A0\uFE0F CAPTCHA: ${solveResult.error}`);
334
+ }
335
+ } catch {
336
+ }
337
+ try {
338
+ const submitClicked = await page.evaluate(() => {
339
+ const btns = Array.from(document.querySelectorAll('button, [type="submit"], [role="button"]'));
340
+ for (const btn of btns) {
341
+ const text = btn.textContent?.trim().toLowerCase() || "";
342
+ if (text.includes("submit") || text.includes("apply")) {
343
+ btn.click();
344
+ return btn.textContent?.trim();
345
+ }
346
+ }
347
+ return null;
348
+ });
349
+ if (submitClicked) {
350
+ clickResults.push(`\u2705 Clicked submit: "${submitClicked}"`);
351
+ await page.waitForTimeout(3e3);
352
+ const finalUrl = page.url();
353
+ const finalTitle = await page.evaluate(() => document.title);
354
+ clickResults.push(`\u{1F4C4} Final page: "${finalTitle}" \u2014 ${finalUrl}`);
355
+ } else {
356
+ clickResults.push(`\u274C Could not find submit button`);
357
+ }
358
+ } catch (e) {
359
+ clickResults.push(`\u274C Submit error: ${e.message?.split("\n")[0]}`);
360
+ }
361
+ }
362
+ const fullResult = clickResults.length > 0 ? result + "\n\nPost-fill clicks:\n" + clickResults.join("\n") : result;
363
+ const lines = fullResult.split("\n");
364
+ const fieldsMatched = lines.filter((l) => l.startsWith("\u2705")).length;
365
+ const fieldsFailed = lines.filter((l) => l.startsWith("\u274C")).map((l) => l.replace(/^❌\s*/, "").split(":")[0]?.trim() || "");
366
+ return res.json({ success: fieldsFailed.length === 0, result: fullResult, fieldsMatched, fieldsFailed });
367
+ } finally {
368
+ await releasePage(page);
369
+ }
370
+ } catch (e) {
371
+ logger.error(COMPONENT, `form-fill error: ${e.message}`);
372
+ return res.status(500).json({ success: false, error: e.message });
373
+ }
374
+ });
375
+ router.post("/browser/solve-captcha", async (req, res) => {
376
+ const { url } = req.body;
377
+ if (!url || typeof url !== "string") {
378
+ return res.status(400).json({ solved: false, error: "url is required (string)" });
379
+ }
380
+ try {
381
+ const { getPage, releasePage } = await import("../../browsing/browserPool.js");
382
+ const { solveCaptcha } = await import("../../browsing/captchaSolver.js");
383
+ const page = await getPage();
384
+ try {
385
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: 3e4 });
386
+ await page.waitForTimeout(3e3);
387
+ const result = await solveCaptcha(page);
388
+ return res.json(result);
389
+ } finally {
390
+ await releasePage(page);
391
+ }
392
+ } catch (e) {
393
+ logger.error(COMPONENT, `solve-captcha error: ${e.message}`);
394
+ return res.status(500).json({ solved: false, error: e.message });
395
+ }
396
+ });
397
+ router.get("/docs", (_req, res) => {
398
+ const spec = {
399
+ openapi: "3.0.0",
400
+ info: {
401
+ title: "TITAN Gateway API",
402
+ version: TITAN_VERSION,
403
+ description: "REST API for the TITAN autonomous AI agent framework."
404
+ },
405
+ paths: {
406
+ "/login": { get: { summary: "Login page", tags: ["Auth"] } },
407
+ "/api/login": { post: { summary: "Authenticate with password", tags: ["Auth"], requestBody: { content: { "application/json": { schema: { type: "object", properties: { password: { type: "string" } } } } } } } },
408
+ "/": { get: { summary: "Dashboard UI", tags: ["System"] } },
409
+ "/api/stats": { get: { summary: "System stats (version, uptime, memory)", tags: ["System"] } },
410
+ "/api/health": { get: { summary: "Provider health check", tags: ["System"] } },
411
+ "/api/update": {
412
+ get: { summary: "Check for updates", tags: ["System"] },
413
+ post: { summary: "Trigger update", tags: ["System"] }
414
+ },
415
+ "/api/costs": { get: { summary: "Cost optimizer status", tags: ["System"] } },
416
+ "/api/sessions": { get: { summary: "List active sessions", tags: ["Sessions"] } },
417
+ "/api/sessions/{id}": { get: { summary: "Get session history by ID", tags: ["Sessions"], parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }] } },
418
+ "/api/sessions/{id}/close": { post: { summary: "Close/drop a session", tags: ["Sessions"], parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }] } },
419
+ "/api/agents": { get: { summary: "List agents and capacity", tags: ["Agents"] } },
420
+ "/api/agents/spawn": { post: { summary: "Spawn new agent", tags: ["Agents"], requestBody: { content: { "application/json": { schema: { type: "object", properties: { name: { type: "string" }, model: { type: "string" } } } } } } } },
421
+ "/api/agents/stop": { post: { summary: "Stop an agent", tags: ["Agents"], requestBody: { content: { "application/json": { schema: { type: "object", properties: { id: { type: "string" } } } } } } } },
422
+ "/api/skills": { get: { summary: "List loaded skills", tags: ["Skills"] } },
423
+ "/api/tools": { get: { summary: "List registered tools", tags: ["Skills"] } },
424
+ "/api/channels": { get: { summary: "List channel statuses", tags: ["Channels"] } },
425
+ "/api/message": { post: { summary: "Send a message", tags: ["Channels"], requestBody: { content: { "application/json": { schema: { type: "object", properties: { content: { type: "string" }, channel: { type: "string" }, userId: { type: "string" } } } } } } } },
426
+ "/api/chat/stream": { post: { summary: "Stream chat via SSE", tags: ["Channels"], requestBody: { content: { "application/json": { schema: { type: "object", properties: { message: { type: "string" }, model: { type: "string" } } } } } } } },
427
+ "/api/config": {
428
+ get: { summary: "Get current config", tags: ["Config"] },
429
+ post: { summary: "Update config", tags: ["Config"] }
430
+ },
431
+ "/api/security": { get: { summary: "Security audit results", tags: ["Config"] } },
432
+ "/api/providers": { get: { summary: "List configured providers", tags: ["Config"] } },
433
+ "/api/models": { get: { summary: "List available models", tags: ["Models"] } },
434
+ "/api/models/discover": { get: { summary: "Discover models from all providers", tags: ["Models"] } },
435
+ "/api/model/switch": { post: { summary: "Switch active model", tags: ["Models"], requestBody: { content: { "application/json": { schema: { type: "object", properties: { model: { type: "string" } } } } } } } },
436
+ "/api/profile": {
437
+ get: { summary: "Get personal profile", tags: ["Memory"] },
438
+ post: { summary: "Update personal profile", tags: ["Memory"] }
439
+ },
440
+ "/api/learning": { get: { summary: "Learning engine stats", tags: ["Memory"] } },
441
+ "/api/graphiti": {
442
+ get: { summary: "Memory graph data", tags: ["Memory"] },
443
+ delete: { summary: "Clear memory graph", tags: ["Memory"] }
444
+ },
445
+ "/api/data": { delete: { summary: "Full data reset (graph+knowledge+memory)", tags: ["Memory"] } },
446
+ "/api/mesh/hello": { get: { summary: "Mesh hello/handshake", tags: ["Mesh"] } },
447
+ "/api/mesh/peers": { get: { summary: "List connected mesh peers", tags: ["Mesh"] } },
448
+ "/api/mesh/models": { get: { summary: "List mesh models", tags: ["Mesh"] } },
449
+ "/api/mesh/pending": { get: { summary: "List peers awaiting approval", tags: ["Mesh"] } },
450
+ "/api/mesh/approve/:nodeId": { post: { summary: "Approve a discovered peer", tags: ["Mesh"] } },
451
+ "/api/mesh/reject/:nodeId": { post: { summary: "Reject a pending peer", tags: ["Mesh"] } },
452
+ "/api/mesh/revoke/:nodeId": { post: { summary: "Disconnect and revoke a peer", tags: ["Mesh"] } },
453
+ "/api/mesh/status": { get: { summary: "Mesh health status and connectivity", tags: ["Mesh"] } },
454
+ "/api/mesh/routes": { get: { summary: "Mesh routing table (multi-hop routes)", tags: ["Mesh"] } },
455
+ "/api/teams": {
456
+ get: { summary: "List all teams", tags: ["Teams"] },
457
+ post: { summary: "Create a new team", tags: ["Teams"] }
458
+ },
459
+ "/api/teams/{teamId}": {
460
+ get: { summary: "Get team details", tags: ["Teams"] },
461
+ patch: { summary: "Update team settings", tags: ["Teams"] },
462
+ delete: { summary: "Delete a team", tags: ["Teams"] }
463
+ },
464
+ "/api/teams/{teamId}/members": {
465
+ get: { summary: "List team members", tags: ["Teams"] },
466
+ post: { summary: "Add a team member", tags: ["Teams"] }
467
+ },
468
+ "/api/teams/{teamId}/members/{userId}": { delete: { summary: "Remove a team member", tags: ["Teams"] } },
469
+ "/api/teams/{teamId}/members/{userId}/role": { patch: { summary: "Update member role", tags: ["Teams"] } },
470
+ "/api/teams/{teamId}/invites": { post: { summary: "Create invite code", tags: ["Teams"] } },
471
+ "/api/teams/join": { post: { summary: "Join team via invite code", tags: ["Teams"] } },
472
+ "/api/teams/{teamId}/permissions/{userId}": { get: { summary: "Get user permissions", tags: ["Teams"] } },
473
+ "/api/teams/{teamId}/roles/{role}/permissions": { put: { summary: "Set role permissions", tags: ["Teams"] } },
474
+ "/api/sessions/search": { get: { summary: "Search conversations", tags: ["Sessions"], parameters: [{ name: "q", in: "query", schema: { type: "string" } }, { name: "limit", in: "query", schema: { type: "integer" } }] } },
475
+ "/api/sessions/{id}/export": { get: { summary: "Export session (JSON or Markdown)", tags: ["Sessions"], parameters: [{ name: "format", in: "query", schema: { type: "string", enum: ["json", "markdown"] } }] } },
476
+ "/api/files/upload": { post: { summary: "Upload file (raw body, X-Filename header)", tags: ["Files"] } },
477
+ "/api/files/uploads": { get: { summary: "List uploaded files", tags: ["Files"], parameters: [{ name: "session", in: "query", schema: { type: "string" } }] } },
478
+ "/api/files/uploads/{name}": { delete: { summary: "Delete uploaded file", tags: ["Files"] } },
479
+ "/api/usage": { get: { summary: "Usage tracking per model (tokens, costs)", tags: ["System"], parameters: [{ name: "hours", in: "query", schema: { type: "integer" } }] } },
480
+ "/api/logs": { get: { summary: "Read log file", tags: ["Logs"], parameters: [{ name: "lines", in: "query", schema: { type: "integer" } }] } },
481
+ "/api/voice/status": { get: { summary: "Voice server status and availability", tags: ["Voice"] } },
482
+ "/api/voice/config": { get: { summary: "Voice configuration", tags: ["Voice"] } },
483
+ "/api/tunnel/status": { get: { summary: "Cloudflare tunnel status", tags: ["Tunnel"] } },
484
+ "/api/autopilot/status": { get: { summary: "Autopilot status", tags: ["Autopilot"] } },
485
+ "/api/autopilot/history": { get: { summary: "Autopilot run history", tags: ["Autopilot"] } },
486
+ "/api/autopilot/run": { post: { summary: "Trigger autopilot run", tags: ["Autopilot"] } },
487
+ "/metrics": { get: { summary: "Prometheus metrics endpoint", tags: ["Telemetry"] } },
488
+ "/api/metrics/summary": { get: { summary: "Metrics summary (JSON)", tags: ["Telemetry"] } },
489
+ "/api/docs": { get: { summary: "OpenAPI spec (JSON)", tags: ["Docs"] } },
490
+ "/docs": { get: { summary: "API documentation page", tags: ["Docs"] } }
491
+ }
492
+ };
493
+ res.json(spec);
494
+ });
495
+ return router;
496
+ }
497
+ export {
498
+ createAdminRouter
499
+ };
500
+ //# sourceMappingURL=adminRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/gateway/routes/adminRouter.ts"],"sourcesContent":["/**\n * Admin Router\n *\n * Extracted from gateway/server.ts.\n * Consolidates audit, vulnerabilities, auth, soul, activity, browser, and docs routes.\n */\n\nimport { Router, type Request, type Response } from 'express';\nimport { join } from 'path';\nimport fs from 'fs';\nimport { loadConfig } from '../../config/config.js';\nimport {\n queryAuditLog,\n getAuditStats,\n} from '../../agent/auditLog.js';\nimport {\n getConsentUrl,\n exchangeCode,\n isGoogleConnected,\n getGoogleEmail,\n disconnectGoogle,\n} from '../../auth/google.js';\nimport { TITAN_VERSION, TITAN_WORKSPACE } from '../../utils/constants.js';\nimport logger, { getLogFilePath } from '../../utils/logger.js';\nimport { listSessions } from '../../agent/session.js';\nimport { getUsageStats } from '../../memory/memory.js';\nimport { getAutopilotStatus } from '../../agent/autopilot.js';\nimport { listGoals } from '../../agent/goals.js';\nimport { getGraphData } from '../../memory/graph.js';\nimport { getActiveLlmRequests } from '../server.js';\n\nconst COMPONENT = 'AdminRouter';\n\nexport function createAdminRouter(): Router {\n const router = Router();\n\n // ── Audit API ────────────────────────────────────────────\n router.get('/audit', (req, res) => {\n const query = {\n since: req.query.since as string | undefined,\n until: req.query.until as string | undefined,\n action: req.query.action as string | undefined,\n source: req.query.source as string | undefined,\n tool: req.query.tool as string | undefined,\n limit: req.query.limit ? parseInt(req.query.limit as string, 10) : 100,\n };\n res.json({ entries: queryAuditLog(query) });\n });\n\n router.get('/audit/stats', (req, res) => {\n const hours = req.query.hours ? parseInt(req.query.hours as string, 10) : 24;\n res.json(getAuditStats(hours));\n });\n\n // ── Vulnerability Scan API ────────────────────────────────\n router.get('/vulnerabilities', (_req, res) => {\n try {\n const reportPath = join(process.cwd(), 'dependency-scan-report.json');\n if (!fs.existsSync(reportPath)) {\n res.json({\n timestamp: new Date().toISOString(),\n vulnerabilities: { total: 0, critical: 0, high: 0, moderate: 0, low: 0 },\n outdated: [],\n deprecated: [],\n licenseIssues: [],\n totalDependencies: 0,\n directDependencies: 0,\n errors: ['No scan report found. Run: npm run scan:deps'],\n });\n return;\n }\n const report = JSON.parse(fs.readFileSync(reportPath, 'utf-8'));\n res.json(report);\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.post('/vulnerabilities/scan', async (_req, res) => {\n try {\n const scanScript = join(process.cwd(), 'scripts', 'dependency-scan.cjs');\n if (!fs.existsSync(scanScript)) {\n res.status(404).json({ error: 'Scan script not found' });\n return;\n }\n\n const { exec } = await import('child_process');\n exec(`node ${scanScript}`, (error, stdout, stderr) => {\n if (error) {\n res.status(500).json({ error: error.message, output: stderr });\n return;\n }\n res.json({ success: true, output: stdout });\n });\n } catch (err) {\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // ── Google OAuth Endpoints ───────────────────────────────\n function getGoogleRedirectUri(): string {\n const cfg = loadConfig();\n const publicUrl = (cfg.gateway as Record<string, unknown>).publicUrl as string | undefined;\n const port = cfg.gateway.port || 48420;\n return publicUrl\n ? `${publicUrl}/api/auth/google/callback`\n : `http://localhost:${port}/api/auth/google/callback`;\n }\n\n router.get('/auth/google/status', (_req, res) => {\n res.json({ connected: isGoogleConnected(), email: getGoogleEmail() });\n });\n\n router.get('/auth/google/start', (req, res) => {\n try {\n const url = getConsentUrl(getGoogleRedirectUri());\n res.redirect(url);\n } catch (err) {\n res.status(400).json({ error: (err as Error).message });\n }\n });\n\n router.get('/auth/google/callback', async (req, res) => {\n const code = req.query.code as string;\n if (!code) { res.status(400).send('Missing authorization code'); return; }\n try {\n await exchangeCode(code, getGoogleRedirectUri());\n res.redirect('/?google_connected=1');\n } catch (err) {\n res.status(500).send(`OAuth failed: ${(err as Error).message}`);\n }\n });\n\n router.post('/auth/google/disconnect', (_req, res) => {\n disconnectGoogle();\n res.json({ ok: true });\n });\n\n // ── SOUL.md Endpoints ───────────────────────────────────\n router.get('/soul', (_req, res) => {\n try {\n const cfg = loadConfig();\n const soulPath = join(cfg.agent.workspace || TITAN_WORKSPACE, 'SOUL.md');\n if (fs.existsSync(soulPath)) {\n res.json({ content: fs.readFileSync(soulPath, 'utf-8') });\n } else {\n res.json({ content: '' });\n }\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`);\n res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.post('/soul', (req, res) => {\n try {\n const cfg = loadConfig();\n const workspace = cfg.agent.workspace || TITAN_WORKSPACE;\n const soulPath = join(workspace, 'SOUL.md');\n\n if (!fs.existsSync(workspace)) fs.mkdirSync(workspace, { recursive: true });\n\n const { content, aboutMe, personality } = req.body as {\n content?: string;\n aboutMe?: string;\n personality?: string;\n };\n\n if (content !== undefined) {\n fs.writeFileSync(soulPath, content, 'utf-8');\n } else if (aboutMe || personality) {\n const soulContent = [\n '# SOUL.md - Who You Are',\n '',\n '## About Your Human',\n aboutMe || '(Not yet described)',\n '',\n '## Your Personality',\n personality || '(Not yet defined)',\n '',\n '## Core Principles',\n '- Be genuinely helpful, not performatively helpful',\n '- Have opinions and preferences',\n '- Be resourceful before asking',\n '- Earn trust through competence',\n '',\n '## Boundaries',\n '- Private things stay private',\n '- Ask before acting externally',\n '- Never send half-baked replies to messaging surfaces',\n '',\n `_This file evolves as you learn. Update it when you discover new preferences._`,\n ].join('\\n');\n fs.writeFileSync(soulPath, soulContent, 'utf-8');\n } else {\n res.status(400).json({ error: 'Provide either \"content\" or \"aboutMe\"/\"personality\"' });\n return;\n }\n\n logger.info(COMPONENT, 'SOUL.md updated via API');\n res.json({ success: true });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`);\n res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n // ── Activity Feed ───────────────────────────────────────\n router.get('/activity/recent', (req, res) => {\n try {\n const logPath = getLogFilePath();\n if (!logPath || !fs.existsSync(logPath)) {\n res.json({ events: [] });\n return;\n }\n const limit = req.query.limit ? parseInt(req.query.limit as string, 10) : 200;\n const filter = (req.query.filter as string) || 'all';\n const stats = fs.statSync(logPath);\n const readSize = Math.min(stats.size, 200000);\n const fd = fs.openSync(logPath, 'r');\n const buf = Buffer.alloc(readSize);\n fs.readSync(fd, buf, 0, readSize, Math.max(0, stats.size - readSize));\n fs.closeSync(fd);\n const content = buf.toString('utf-8');\n const rawLines = content.split('\\n').filter(Boolean);\n const lines = stats.size > readSize ? rawLines.slice(1) : rawLines;\n\n const classifyEvent = (message: string, component: string): string => {\n const lc = message.toLowerCase();\n const cc = component.toLowerCase();\n if (cc.includes('toolrunner') || lc.includes('executing tool') || lc.includes('tool:')) return 'tool';\n if (cc.includes('agent') || lc.includes('processing message') || lc.includes('response')) return 'agent';\n if (cc.includes('autopilot')) return 'autopilot';\n if (cc.includes('goal')) return 'goal';\n if (cc.includes('websearch') || cc.includes('browse') || lc.includes('search')) return 'search';\n if (cc.includes('autonomy') || lc.includes('autonomy')) return 'autonomy';\n if (cc.includes('router') || cc.includes('provider')) return 'router';\n if (cc.includes('graph') || cc.includes('memory')) return 'graph';\n if (lc.includes('error') || lc.includes('fail')) return 'error';\n return 'system';\n };\n\n const events = lines\n .map((line) => {\n const match = line.match(/^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})\\s+(DEBUG|INFO|WARN|ERROR)\\s+(?:\\[([^\\]]+)\\]\\s+)?(.*)$/);\n if (!match) return null;\n const [, timestamp, level, component = 'System', message] = match;\n const type = classifyEvent(message, component);\n return { timestamp, level: level.toLowerCase(), component, message, type };\n })\n .filter((e): e is NonNullable<typeof e> => {\n if (!e) return false;\n if (e.level === 'debug') return false;\n if (filter === 'all') return true;\n if (filter === 'errors') return e.level === 'error' || e.level === 'warn';\n return e.type === filter;\n })\n .slice(-limit)\n .reverse();\n\n res.json({ events });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`);\n res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.get('/activity/summary', (_req, res) => {\n try {\n const cfg = loadConfig();\n const sessions = listSessions();\n const usage = getUsageStats();\n const autopilot = getAutopilotStatus();\n const goals = listGoals();\n\n const toolCalls = (usage as Record<string, unknown>).toolCalls ?? (usage as Record<string, unknown>).totalToolCalls ?? 0;\n\n let status: 'idle' | 'processing' | 'autopilot' = 'idle';\n if (getActiveLlmRequests() > 0) status = 'processing';\n if (autopilot.isRunning) status = 'autopilot';\n\n let lastActivity: string | null = null;\n try {\n const logPath = getLogFilePath();\n if (logPath && fs.existsSync(logPath)) {\n const stat = fs.statSync(logPath);\n lastActivity = stat.mtime.toISOString();\n }\n } catch { /* ignore */ }\n\n let graphStats = { entities: 0, edges: 0 };\n try {\n const gd = getGraphData();\n graphStats = { entities: gd.nodes.length, edges: gd.edges.length };\n } catch { /* graph may not be initialized */ }\n\n const activeGoals = goals.filter((g) => g.status !== 'completed' && g.status !== 'failed');\n\n res.json({\n activeSessions: sessions.length,\n toolCallsLast24h: toolCalls,\n autopilotRunsToday: autopilot.totalRuns ?? 0,\n autopilotEnabled: autopilot.enabled ?? false,\n autopilotNextRun: autopilot.nextRunEstimate ?? null,\n activeGoals: activeGoals.length,\n goals: activeGoals.slice(0, 5).map((g) => ({\n id: g.id,\n title: g.title,\n progress: g.progress ?? (g.subtasks\n ? Math.round((g.subtasks.filter((s) => s.status === 'done').length / Math.max(g.subtasks.length, 1)) * 100)\n : 0),\n })),\n lastActivity,\n currentModel: cfg.agent.model,\n autonomyMode: cfg.autonomy?.mode ?? 'supervised',\n status,\n graphStats,\n });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`);\n res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n // ── Browser automation endpoints ─────────────────────────\n router.post('/browser/form-fill', async (req, res) => {\n const { url, data, submit, postClicks } = req.body;\n if (!url || typeof url !== 'string') {\n return res.status(400).json({ success: false, error: 'url is required (string)' });\n }\n if (!data || typeof data !== 'object') {\n return res.status(400).json({ success: false, error: 'data is required (Record<string, string>)' });\n }\n try {\n const { getPage, releasePage } = await import('../../browsing/browserPool.js');\n const { fillFormSmart } = await import('../../skills/builtin/web_browse_llm.js');\n const page = await getPage();\n const session = { page, lastUsed: Date.now(), elements: new Map<number, string>() };\n try {\n const deferSubmit = Array.isArray(postClicks) && postClicks.length > 0 && submit;\n const result = await fillFormSmart(session as any, url, data as Record<string, string>, deferSubmit ? false : (submit ?? false));\n\n const clickResults: string[] = [];\n if (Array.isArray(postClicks)) {\n for (const click of postClicks) {\n try {\n if (typeof click === 'string') {\n const clicked = await page.evaluate((text: string) => {\n const els = Array.from(document.querySelectorAll('button, input[type=\"radio\"], label, [role=\"button\"], [role=\"radio\"]'));\n for (const el of els) {\n const elText = (el as HTMLElement).textContent?.trim() || '';\n if (elText.toLowerCase() === text.toLowerCase() || elText.toLowerCase().includes(text.toLowerCase())) {\n (el as HTMLElement).click();\n return elText;\n }\n }\n return null;\n }, click);\n if (clicked) {\n clickResults.push(`✅ Clicked \"${clicked}\"`);\n } else {\n try {\n await page.click(click, { timeout: 3000 });\n clickResults.push(`✅ Clicked selector: ${click}`);\n } catch {\n clickResults.push(`❌ Could not find: \"${click}\"`);\n }\n }\n await page.waitForTimeout(500);\n }\n } catch (e) {\n clickResults.push(`❌ Error clicking \"${click}\": ${(e as Error).message?.split('\\n')[0]}`);\n }\n }\n }\n\n if (deferSubmit) {\n try {\n const { solveCaptcha } = await import('../../browsing/captchaSolver.js');\n const solveResult = await solveCaptcha(page as unknown as import('playwright').Page);\n if (solveResult.solved) {\n clickResults.push(`✅ ${solveResult.type} solved via CapSolver`);\n } else if (solveResult.error) {\n clickResults.push(`⚠️ CAPTCHA: ${solveResult.error}`);\n }\n } catch { /* CapSolver not available */ }\n\n try {\n const submitClicked = await page.evaluate(() => {\n const btns = Array.from(document.querySelectorAll('button, [type=\"submit\"], [role=\"button\"]'));\n for (const btn of btns) {\n const text = (btn as HTMLElement).textContent?.trim().toLowerCase() || '';\n if (text.includes('submit') || text.includes('apply')) {\n (btn as HTMLElement).click();\n return (btn as HTMLElement).textContent?.trim();\n }\n }\n return null;\n });\n if (submitClicked) {\n clickResults.push(`✅ Clicked submit: \"${submitClicked}\"`);\n await page.waitForTimeout(3000);\n const finalUrl = page.url();\n const finalTitle = await page.evaluate(() => document.title);\n clickResults.push(`📄 Final page: \"${finalTitle}\" — ${finalUrl}`);\n } else {\n clickResults.push(`❌ Could not find submit button`);\n }\n } catch (e) {\n clickResults.push(`❌ Submit error: ${(e as Error).message?.split('\\n')[0]}`);\n }\n }\n\n const fullResult = clickResults.length > 0\n ? result + '\\n\\nPost-fill clicks:\\n' + clickResults.join('\\n')\n : result;\n const lines = fullResult.split('\\n');\n const fieldsMatched = lines.filter((l: string) => l.startsWith('✅')).length;\n const fieldsFailed = lines.filter((l: string) => l.startsWith('❌'))\n .map((l: string) => l.replace(/^❌\\s*/, '').split(':')[0]?.trim() || '');\n return res.json({ success: fieldsFailed.length === 0, result: fullResult, fieldsMatched, fieldsFailed });\n } finally {\n await releasePage(page);\n }\n } catch (e) {\n logger.error(COMPONENT, `form-fill error: ${(e as Error).message}`);\n return res.status(500).json({ success: false, error: (e as Error).message });\n }\n });\n\n router.post('/browser/solve-captcha', async (req, res) => {\n const { url } = req.body;\n if (!url || typeof url !== 'string') {\n return res.status(400).json({ solved: false, error: 'url is required (string)' });\n }\n try {\n const { getPage, releasePage } = await import('../../browsing/browserPool.js');\n const { solveCaptcha } = await import('../../browsing/captchaSolver.js');\n const page = await getPage();\n try {\n await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30_000 });\n await page.waitForTimeout(3000);\n const result = await solveCaptcha(page);\n return res.json(result);\n } finally {\n await releasePage(page);\n }\n } catch (e) {\n logger.error(COMPONENT, `solve-captcha error: ${(e as Error).message}`);\n return res.status(500).json({ solved: false, error: (e as Error).message });\n }\n });\n\n // ── API Documentation ────────────────────────────────────\n router.get('/docs', (_req, res) => {\n const spec = {\n openapi: '3.0.0',\n info: {\n title: 'TITAN Gateway API',\n version: TITAN_VERSION,\n description: 'REST API for the TITAN autonomous AI agent framework.',\n },\n paths: {\n '/login': { get: { summary: 'Login page', tags: ['Auth'] } },\n '/api/login': { post: { summary: 'Authenticate with password', tags: ['Auth'], requestBody: { content: { 'application/json': { schema: { type: 'object', properties: { password: { type: 'string' } } } } } } } },\n '/': { get: { summary: 'Dashboard UI', tags: ['System'] } },\n '/api/stats': { get: { summary: 'System stats (version, uptime, memory)', tags: ['System'] } },\n '/api/health': { get: { summary: 'Provider health check', tags: ['System'] } },\n '/api/update': { get: { summary: 'Check for updates', tags: ['System'] },\n post: { summary: 'Trigger update', tags: ['System'] } },\n '/api/costs': { get: { summary: 'Cost optimizer status', tags: ['System'] } },\n '/api/sessions': { get: { summary: 'List active sessions', tags: ['Sessions'] } },\n '/api/sessions/{id}': { get: { summary: 'Get session history by ID', tags: ['Sessions'], parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }] } },\n '/api/sessions/{id}/close':{ post: { summary: 'Close/drop a session', tags: ['Sessions'], parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }] } },\n '/api/agents': { get: { summary: 'List agents and capacity', tags: ['Agents'] } },\n '/api/agents/spawn': { post: { summary: 'Spawn new agent', tags: ['Agents'], requestBody: { content: { 'application/json': { schema: { type: 'object', properties: { name: { type: 'string' }, model: { type: 'string' } } } } } } } },\n '/api/agents/stop': { post: { summary: 'Stop an agent', tags: ['Agents'], requestBody: { content: { 'application/json': { schema: { type: 'object', properties: { id: { type: 'string' } } } } } } } },\n '/api/skills': { get: { summary: 'List loaded skills', tags: ['Skills'] } },\n '/api/tools': { get: { summary: 'List registered tools', tags: ['Skills'] } },\n '/api/channels': { get: { summary: 'List channel statuses', tags: ['Channels'] } },\n '/api/message': { post: { summary: 'Send a message', tags: ['Channels'], requestBody: { content: { 'application/json': { schema: { type: 'object', properties: { content: { type: 'string' }, channel: { type: 'string' }, userId: { type: 'string' } } } } } } } },\n '/api/chat/stream': { post: { summary: 'Stream chat via SSE', tags: ['Channels'], requestBody: { content: { 'application/json': { schema: { type: 'object', properties: { message: { type: 'string' }, model: { type: 'string' } } } } } } } },\n '/api/config': { get: { summary: 'Get current config', tags: ['Config'] },\n post: { summary: 'Update config', tags: ['Config'] } },\n '/api/security': { get: { summary: 'Security audit results', tags: ['Config'] } },\n '/api/providers': { get: { summary: 'List configured providers', tags: ['Config'] } },\n '/api/models': { get: { summary: 'List available models', tags: ['Models'] } },\n '/api/models/discover': { get: { summary: 'Discover models from all providers', tags: ['Models'] } },\n '/api/model/switch': { post: { summary: 'Switch active model', tags: ['Models'], requestBody: { content: { 'application/json': { schema: { type: 'object', properties: { model: { type: 'string' } } } } } } } },\n '/api/profile': { get: { summary: 'Get personal profile', tags: ['Memory'] },\n post: { summary: 'Update personal profile', tags: ['Memory'] } },\n '/api/learning': { get: { summary: 'Learning engine stats', tags: ['Memory'] } },\n '/api/graphiti': { get: { summary: 'Memory graph data', tags: ['Memory'] },\n delete: { summary: 'Clear memory graph', tags: ['Memory'] } },\n '/api/data': { delete: { summary: 'Full data reset (graph+knowledge+memory)', tags: ['Memory'] } },\n '/api/mesh/hello': { get: { summary: 'Mesh hello/handshake', tags: ['Mesh'] } },\n '/api/mesh/peers': { get: { summary: 'List connected mesh peers', tags: ['Mesh'] } },\n '/api/mesh/models': { get: { summary: 'List mesh models', tags: ['Mesh'] } },\n '/api/mesh/pending': { get: { summary: 'List peers awaiting approval', tags: ['Mesh'] } },\n '/api/mesh/approve/:nodeId': { post: { summary: 'Approve a discovered peer', tags: ['Mesh'] } },\n '/api/mesh/reject/:nodeId': { post: { summary: 'Reject a pending peer', tags: ['Mesh'] } },\n '/api/mesh/revoke/:nodeId': { post: { summary: 'Disconnect and revoke a peer', tags: ['Mesh'] } },\n '/api/mesh/status': { get: { summary: 'Mesh health status and connectivity', tags: ['Mesh'] } },\n '/api/mesh/routes': { get: { summary: 'Mesh routing table (multi-hop routes)', tags: ['Mesh'] } },\n '/api/teams': { get: { summary: 'List all teams', tags: ['Teams'] },\n post: { summary: 'Create a new team', tags: ['Teams'] } },\n '/api/teams/{teamId}': { get: { summary: 'Get team details', tags: ['Teams'] },\n patch: { summary: 'Update team settings', tags: ['Teams'] },\n delete: { summary: 'Delete a team', tags: ['Teams'] } },\n '/api/teams/{teamId}/members': { get: { summary: 'List team members', tags: ['Teams'] },\n post: { summary: 'Add a team member', tags: ['Teams'] } },\n '/api/teams/{teamId}/members/{userId}': { delete: { summary: 'Remove a team member', tags: ['Teams'] } },\n '/api/teams/{teamId}/members/{userId}/role': { patch: { summary: 'Update member role', tags: ['Teams'] } },\n '/api/teams/{teamId}/invites': { post: { summary: 'Create invite code', tags: ['Teams'] } },\n '/api/teams/join': { post: { summary: 'Join team via invite code', tags: ['Teams'] } },\n '/api/teams/{teamId}/permissions/{userId}': { get: { summary: 'Get user permissions', tags: ['Teams'] } },\n '/api/teams/{teamId}/roles/{role}/permissions': { put: { summary: 'Set role permissions', tags: ['Teams'] } },\n '/api/sessions/search': { get: { summary: 'Search conversations', tags: ['Sessions'], parameters: [{ name: 'q', in: 'query', schema: { type: 'string' } }, { name: 'limit', in: 'query', schema: { type: 'integer' } }] } },\n '/api/sessions/{id}/export': { get: { summary: 'Export session (JSON or Markdown)', tags: ['Sessions'], parameters: [{ name: 'format', in: 'query', schema: { type: 'string', enum: ['json', 'markdown'] } }] } },\n '/api/files/upload': { post: { summary: 'Upload file (raw body, X-Filename header)', tags: ['Files'] } },\n '/api/files/uploads': { get: { summary: 'List uploaded files', tags: ['Files'], parameters: [{ name: 'session', in: 'query', schema: { type: 'string' } }] } },\n '/api/files/uploads/{name}': { delete: { summary: 'Delete uploaded file', tags: ['Files'] } },\n '/api/usage': { get: { summary: 'Usage tracking per model (tokens, costs)', tags: ['System'], parameters: [{ name: 'hours', in: 'query', schema: { type: 'integer' } }] } },\n '/api/logs': { get: { summary: 'Read log file', tags: ['Logs'], parameters: [{ name: 'lines', in: 'query', schema: { type: 'integer' } }] } },\n '/api/voice/status': { get: { summary: 'Voice server status and availability', tags: ['Voice'] } },\n '/api/voice/config': { get: { summary: 'Voice configuration', tags: ['Voice'] } },\n '/api/tunnel/status': { get: { summary: 'Cloudflare tunnel status', tags: ['Tunnel'] } },\n '/api/autopilot/status': { get: { summary: 'Autopilot status', tags: ['Autopilot'] } },\n '/api/autopilot/history': { get: { summary: 'Autopilot run history', tags: ['Autopilot'] } },\n '/api/autopilot/run': { post: { summary: 'Trigger autopilot run', tags: ['Autopilot'] } },\n '/metrics': { get: { summary: 'Prometheus metrics endpoint', tags: ['Telemetry'] } },\n '/api/metrics/summary': { get: { summary: 'Metrics summary (JSON)', tags: ['Telemetry'] } },\n '/api/docs': { get: { summary: 'OpenAPI spec (JSON)', tags: ['Docs'] } },\n '/docs': { get: { summary: 'API documentation page', tags: ['Docs'] } },\n },\n };\n res.json(spec);\n });\n\n return router;\n}\n"],"mappings":"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","names":[]}