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
@@ -13,7 +13,7 @@ function sessionDir(sessionId) {
13
13
  function roundFile(sessionId, round) {
14
14
  return join(sessionDir(sessionId), `round-${String(round).padStart(3, "0")}.json`);
15
15
  }
16
- function ensureDir(sessionId) {
16
+ function mkdirIfNotExists(sessionId) {
17
17
  const dir = sessionDir(sessionId);
18
18
  if (!existsSync(dir)) {
19
19
  mkdirSync(dir, { recursive: true });
@@ -21,7 +21,7 @@ function ensureDir(sessionId) {
21
21
  }
22
22
  function saveCheckpoint(state) {
23
23
  try {
24
- ensureDir(state.sessionId);
24
+ mkdirIfNotExists(state.sessionId);
25
25
  const path = roundFile(state.sessionId, state.round);
26
26
  const trimmedMessages = trimMessages(state.messages);
27
27
  const data = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agent/checkpoint.ts"],"sourcesContent":["/**\n * TITAN — Execution Checkpointing\n *\n * Persists agent loop state after each round so tasks can be resumed\n * after crashes, restarts, or budget exhaustion. Closes the #1 gap\n * vs LangGraph's durable execution.\n *\n * Storage: ~/.titan/checkpoints/{sessionId}/round-{N}.json\n * Each checkpoint contains: messages, toolsUsed, round, model, phase.\n *\n * Usage:\n * saveCheckpoint(sessionId, round, state); // After each round\n * const cp = loadCheckpoint(sessionId); // Latest checkpoint\n * const cp = loadCheckpoint(sessionId, 3); // Specific round\n * clearCheckpoints(sessionId); // After completion\n */\n\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, rmSync } from 'fs';\nimport { atomicWriteJsonFile } from '../utils/helpers.js';\nimport { join } from 'path';\nimport { TITAN_HOME } from '../utils/constants.js';\nimport logger from '../utils/logger.js';\nimport type { ChatMessage } from '../providers/base.js';\n\nconst COMPONENT = 'Checkpoint';\nconst CHECKPOINTS_DIR = join(TITAN_HOME, 'checkpoints');\n\n// ── Types ───────────────────────────────────────────────────────\n\nexport interface CheckpointState {\n sessionId: string;\n round: number;\n phase: string;\n model: string;\n messages: ChatMessage[];\n toolsUsed: string[];\n orderedToolSequence: string[];\n timestamp: string;\n message: string; // Original user message (first 500 chars)\n channel: string;\n totalPromptTokens: number;\n totalCompletionTokens: number;\n}\n\nexport interface CheckpointMeta {\n sessionId: string;\n rounds: number;\n latestRound: number;\n model: string;\n message: string;\n channel: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// ── Storage ─────────────────────────────────────────────────────\n\nfunction sessionDir(sessionId: string): string {\n // Sanitize sessionId for filesystem safety\n const safe = sessionId.replace(/[^a-zA-Z0-9_:-]/g, '_');\n return join(CHECKPOINTS_DIR, safe);\n}\n\nfunction roundFile(sessionId: string, round: number): string {\n return join(sessionDir(sessionId), `round-${String(round).padStart(3, '0')}.json`);\n}\n\nfunction ensureDir(sessionId: string): void {\n const dir = sessionDir(sessionId);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\n// ── Save ────────────────────────────────────────────────────────\n\nexport function saveCheckpoint(state: CheckpointState): void {\n try {\n ensureDir(state.sessionId);\n const path = roundFile(state.sessionId, state.round);\n\n // Trim messages to avoid huge checkpoints — keep system + last 20 messages\n const trimmedMessages = trimMessages(state.messages);\n\n const data: CheckpointState = {\n ...state,\n messages: trimmedMessages,\n timestamp: new Date().toISOString(),\n };\n\n atomicWriteJsonFile(path, data);\n logger.debug(COMPONENT, `Saved checkpoint: session=${state.sessionId} round=${state.round} messages=${trimmedMessages.length}`);\n } catch (e) {\n logger.warn(COMPONENT, `Failed to save checkpoint: ${(e as Error).message}`);\n }\n}\n\nfunction trimMessages(messages: ChatMessage[]): ChatMessage[] {\n if (messages.length <= 22) return messages;\n\n // Keep system message + first user message + last 20 messages\n const system = messages.find(m => m.role === 'system');\n const firstUser = messages.find(m => m.role === 'user');\n const recent = messages.slice(-20);\n\n const result: ChatMessage[] = [];\n if (system && !recent.includes(system)) result.push(system);\n if (firstUser && !recent.includes(firstUser) && firstUser !== system) result.push(firstUser);\n result.push(...recent);\n\n return result;\n}\n\n// ── Load ────────────────────────────────────────────────────────\n\n/** Load the latest checkpoint for a session, or a specific round */\nexport function loadCheckpoint(sessionId: string, round?: number): CheckpointState | null {\n try {\n const dir = sessionDir(sessionId);\n if (!existsSync(dir)) return null;\n\n if (round !== undefined) {\n const path = roundFile(sessionId, round);\n if (!existsSync(path)) return null;\n return JSON.parse(readFileSync(path, 'utf-8')) as CheckpointState;\n }\n\n // Find latest round\n const files = readdirSync(dir)\n .filter(f => f.startsWith('round-') && f.endsWith('.json'))\n .sort()\n .reverse();\n\n if (files.length === 0) return null;\n return JSON.parse(readFileSync(join(dir, files[0]), 'utf-8')) as CheckpointState;\n } catch (e) {\n logger.warn(COMPONENT, `Failed to load checkpoint: ${(e as Error).message}`);\n return null;\n }\n}\n\n// ── List ────────────────────────────────────────────────────────\n\n/** List all sessions with checkpoints */\nexport function listCheckpoints(): CheckpointMeta[] {\n try {\n if (!existsSync(CHECKPOINTS_DIR)) return [];\n\n const sessions = readdirSync(CHECKPOINTS_DIR).filter(d => {\n const full = join(CHECKPOINTS_DIR, d);\n try { return existsSync(full) && readdirSync(full).some(f => f.endsWith('.json')); }\n catch { return false; }\n });\n\n return sessions.map(sessionId => {\n const dir = join(CHECKPOINTS_DIR, sessionId);\n const files = readdirSync(dir).filter(f => f.startsWith('round-') && f.endsWith('.json')).sort();\n\n if (files.length === 0) return null;\n\n const latest = JSON.parse(readFileSync(join(dir, files[files.length - 1]), 'utf-8')) as CheckpointState;\n const first = JSON.parse(readFileSync(join(dir, files[0]), 'utf-8')) as CheckpointState;\n\n return {\n sessionId: latest.sessionId,\n rounds: files.length,\n latestRound: latest.round,\n model: latest.model,\n message: latest.message,\n channel: latest.channel,\n createdAt: first.timestamp,\n updatedAt: latest.timestamp,\n } as CheckpointMeta;\n }).filter((m): m is CheckpointMeta => m !== null);\n } catch {\n return [];\n }\n}\n\n// ── Clear ───────────────────────────────────────────────────────\n\n/** Clear all checkpoints for a session (call after successful completion) */\nexport function clearCheckpoints(sessionId: string): void {\n try {\n const dir = sessionDir(sessionId);\n if (existsSync(dir)) {\n rmSync(dir, { recursive: true, force: true });\n logger.debug(COMPONENT, `Cleared checkpoints for session ${sessionId}`);\n }\n } catch (e) {\n logger.warn(COMPONENT, `Failed to clear checkpoints: ${(e as Error).message}`);\n }\n}\n\n/** Clear all expired checkpoints (older than maxAge ms, default 24h) */\nexport function clearExpiredCheckpoints(maxAgeMs: number = 24 * 60 * 60 * 1000): number {\n let cleared = 0;\n try {\n if (!existsSync(CHECKPOINTS_DIR)) return 0;\n\n const now = Date.now();\n for (const sessionId of readdirSync(CHECKPOINTS_DIR)) {\n const dir = join(CHECKPOINTS_DIR, sessionId);\n const files = readdirSync(dir).filter(f => f.endsWith('.json')).sort().reverse();\n if (files.length === 0) continue;\n\n try {\n const latest = JSON.parse(readFileSync(join(dir, files[0]), 'utf-8')) as CheckpointState;\n const age = now - new Date(latest.timestamp).getTime();\n if (age > maxAgeMs) {\n rmSync(dir, { recursive: true, force: true });\n cleared++;\n }\n } catch { /* skip corrupted */ }\n }\n\n if (cleared > 0) {\n logger.info(COMPONENT, `Cleared ${cleared} expired checkpoint sessions`);\n }\n } catch { /* non-critical */ }\n return cleared;\n}\n"],"mappings":";AAiBA,SAAS,YAAY,WAA0B,cAAc,aAAa,cAAc;AACxF,SAAS,2BAA2B;AACpC,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAC3B,OAAO,YAAY;AAGnB,MAAM,YAAY;AAClB,MAAM,kBAAkB,KAAK,YAAY,aAAa;AAgCtD,SAAS,WAAW,WAA2B;AAE3C,QAAM,OAAO,UAAU,QAAQ,oBAAoB,GAAG;AACtD,SAAO,KAAK,iBAAiB,IAAI;AACrC;AAEA,SAAS,UAAU,WAAmB,OAAuB;AACzD,SAAO,KAAK,WAAW,SAAS,GAAG,SAAS,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,OAAO;AACrF;AAEA,SAAS,UAAU,WAAyB;AACxC,QAAM,MAAM,WAAW,SAAS;AAChC,MAAI,CAAC,WAAW,GAAG,GAAG;AAClB,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACtC;AACJ;AAIO,SAAS,eAAe,OAA8B;AACzD,MAAI;AACA,cAAU,MAAM,SAAS;AACzB,UAAM,OAAO,UAAU,MAAM,WAAW,MAAM,KAAK;AAGnD,UAAM,kBAAkB,aAAa,MAAM,QAAQ;AAEnD,UAAM,OAAwB;AAAA,MAC1B,GAAG;AAAA,MACH,UAAU;AAAA,MACV,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACtC;AAEA,wBAAoB,MAAM,IAAI;AAC9B,WAAO,MAAM,WAAW,6BAA6B,MAAM,SAAS,UAAU,MAAM,KAAK,aAAa,gBAAgB,MAAM,EAAE;AAAA,EAClI,SAAS,GAAG;AACR,WAAO,KAAK,WAAW,8BAA+B,EAAY,OAAO,EAAE;AAAA,EAC/E;AACJ;AAEA,SAAS,aAAa,UAAwC;AAC1D,MAAI,SAAS,UAAU,GAAI,QAAO;AAGlC,QAAM,SAAS,SAAS,KAAK,OAAK,EAAE,SAAS,QAAQ;AACrD,QAAM,YAAY,SAAS,KAAK,OAAK,EAAE,SAAS,MAAM;AACtD,QAAM,SAAS,SAAS,MAAM,GAAG;AAEjC,QAAM,SAAwB,CAAC;AAC/B,MAAI,UAAU,CAAC,OAAO,SAAS,MAAM,EAAG,QAAO,KAAK,MAAM;AAC1D,MAAI,aAAa,CAAC,OAAO,SAAS,SAAS,KAAK,cAAc,OAAQ,QAAO,KAAK,SAAS;AAC3F,SAAO,KAAK,GAAG,MAAM;AAErB,SAAO;AACX;AAKO,SAAS,eAAe,WAAmB,OAAwC;AACtF,MAAI;AACA,UAAM,MAAM,WAAW,SAAS;AAChC,QAAI,CAAC,WAAW,GAAG,EAAG,QAAO;AAE7B,QAAI,UAAU,QAAW;AACrB,YAAM,OAAO,UAAU,WAAW,KAAK;AACvC,UAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,aAAO,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,IACjD;AAGA,UAAM,QAAQ,YAAY,GAAG,EACxB,OAAO,OAAK,EAAE,WAAW,QAAQ,KAAK,EAAE,SAAS,OAAO,CAAC,EACzD,KAAK,EACL,QAAQ;AAEb,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,WAAO,KAAK,MAAM,aAAa,KAAK,KAAK,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC;AAAA,EAChE,SAAS,GAAG;AACR,WAAO,KAAK,WAAW,8BAA+B,EAAY,OAAO,EAAE;AAC3E,WAAO;AAAA,EACX;AACJ;AAKO,SAAS,kBAAoC;AAChD,MAAI;AACA,QAAI,CAAC,WAAW,eAAe,EAAG,QAAO,CAAC;AAE1C,UAAM,WAAW,YAAY,eAAe,EAAE,OAAO,OAAK;AACtD,YAAM,OAAO,KAAK,iBAAiB,CAAC;AACpC,UAAI;AAAE,eAAO,WAAW,IAAI,KAAK,YAAY,IAAI,EAAE,KAAK,OAAK,EAAE,SAAS,OAAO,CAAC;AAAA,MAAG,QAC7E;AAAE,eAAO;AAAA,MAAO;AAAA,IAC1B,CAAC;AAED,WAAO,SAAS,IAAI,eAAa;AAC7B,YAAM,MAAM,KAAK,iBAAiB,SAAS;AAC3C,YAAM,QAAQ,YAAY,GAAG,EAAE,OAAO,OAAK,EAAE,WAAW,QAAQ,KAAK,EAAE,SAAS,OAAO,CAAC,EAAE,KAAK;AAE/F,UAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,YAAM,SAAS,KAAK,MAAM,aAAa,KAAK,KAAK,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC;AACnF,YAAM,QAAQ,KAAK,MAAM,aAAa,KAAK,KAAK,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC;AAEnE,aAAO;AAAA,QACH,WAAW,OAAO;AAAA,QAClB,QAAQ,MAAM;AAAA,QACd,aAAa,OAAO;AAAA,QACpB,OAAO,OAAO;AAAA,QACd,SAAS,OAAO;AAAA,QAChB,SAAS,OAAO;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,WAAW,OAAO;AAAA,MACtB;AAAA,IACJ,CAAC,EAAE,OAAO,CAAC,MAA2B,MAAM,IAAI;AAAA,EACpD,QAAQ;AACJ,WAAO,CAAC;AAAA,EACZ;AACJ;AAKO,SAAS,iBAAiB,WAAyB;AACtD,MAAI;AACA,UAAM,MAAM,WAAW,SAAS;AAChC,QAAI,WAAW,GAAG,GAAG;AACjB,aAAO,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC5C,aAAO,MAAM,WAAW,mCAAmC,SAAS,EAAE;AAAA,IAC1E;AAAA,EACJ,SAAS,GAAG;AACR,WAAO,KAAK,WAAW,gCAAiC,EAAY,OAAO,EAAE;AAAA,EACjF;AACJ;AAGO,SAAS,wBAAwB,WAAmB,KAAK,KAAK,KAAK,KAAc;AACpF,MAAI,UAAU;AACd,MAAI;AACA,QAAI,CAAC,WAAW,eAAe,EAAG,QAAO;AAEzC,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,aAAa,YAAY,eAAe,GAAG;AAClD,YAAM,MAAM,KAAK,iBAAiB,SAAS;AAC3C,YAAM,QAAQ,YAAY,GAAG,EAAE,OAAO,OAAK,EAAE,SAAS,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ;AAC/E,UAAI,MAAM,WAAW,EAAG;AAExB,UAAI;AACA,cAAM,SAAS,KAAK,MAAM,aAAa,KAAK,KAAK,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC;AACpE,cAAM,MAAM,MAAM,IAAI,KAAK,OAAO,SAAS,EAAE,QAAQ;AACrD,YAAI,MAAM,UAAU;AAChB,iBAAO,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC5C;AAAA,QACJ;AAAA,MACJ,QAAQ;AAAA,MAAuB;AAAA,IACnC;AAEA,QAAI,UAAU,GAAG;AACb,aAAO,KAAK,WAAW,WAAW,OAAO,8BAA8B;AAAA,IAC3E;AAAA,EACJ,QAAQ;AAAA,EAAqB;AAC7B,SAAO;AACX;","names":[]}
1
+ {"version":3,"sources":["../../src/agent/checkpoint.ts"],"sourcesContent":["/**\n * TITAN — Execution Checkpointing\n *\n * Persists agent loop state after each round so tasks can be resumed\n * after crashes, restarts, or budget exhaustion. Closes the #1 gap\n * vs LangGraph's durable execution.\n *\n * Storage: ~/.titan/checkpoints/{sessionId}/round-{N}.json\n * Each checkpoint contains: messages, toolsUsed, round, model, phase.\n *\n * Usage:\n * saveCheckpoint(sessionId, round, state); // After each round\n * const cp = loadCheckpoint(sessionId); // Latest checkpoint\n * const cp = loadCheckpoint(sessionId, 3); // Specific round\n * clearCheckpoints(sessionId); // After completion\n */\n\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, rmSync } from 'fs';\nimport { atomicWriteJsonFile } from '../utils/helpers.js';\nimport { join } from 'path';\nimport { TITAN_HOME } from '../utils/constants.js';\nimport logger from '../utils/logger.js';\nimport type { ChatMessage } from '../providers/base.js';\n\nconst COMPONENT = 'Checkpoint';\nconst CHECKPOINTS_DIR = join(TITAN_HOME, 'checkpoints');\n\n// ── Types ───────────────────────────────────────────────────────\n\nexport interface CheckpointState {\n sessionId: string;\n round: number;\n phase: string;\n model: string;\n messages: ChatMessage[];\n toolsUsed: string[];\n orderedToolSequence: string[];\n timestamp: string;\n message: string; // Original user message (first 500 chars)\n channel: string;\n totalPromptTokens: number;\n totalCompletionTokens: number;\n}\n\nexport interface CheckpointMeta {\n sessionId: string;\n rounds: number;\n latestRound: number;\n model: string;\n message: string;\n channel: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// ── Storage ─────────────────────────────────────────────────────\n\nfunction sessionDir(sessionId: string): string {\n // Sanitize sessionId for filesystem safety\n const safe = sessionId.replace(/[^a-zA-Z0-9_:-]/g, '_');\n return join(CHECKPOINTS_DIR, safe);\n}\n\nfunction roundFile(sessionId: string, round: number): string {\n return join(sessionDir(sessionId), `round-${String(round).padStart(3, '0')}.json`);\n}\n\nfunction mkdirIfNotExists(sessionId: string): void {\n const dir = sessionDir(sessionId);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\n// ── Save ────────────────────────────────────────────────────────\n\nexport function saveCheckpoint(state: CheckpointState): void {\n try {\n mkdirIfNotExists(state.sessionId);\n const path = roundFile(state.sessionId, state.round);\n\n // Trim messages to avoid huge checkpoints — keep system + last 20 messages\n const trimmedMessages = trimMessages(state.messages);\n\n const data: CheckpointState = {\n ...state,\n messages: trimmedMessages,\n timestamp: new Date().toISOString(),\n };\n\n atomicWriteJsonFile(path, data);\n logger.debug(COMPONENT, `Saved checkpoint: session=${state.sessionId} round=${state.round} messages=${trimmedMessages.length}`);\n } catch (e) {\n logger.warn(COMPONENT, `Failed to save checkpoint: ${(e as Error).message}`);\n }\n}\n\nfunction trimMessages(messages: ChatMessage[]): ChatMessage[] {\n if (messages.length <= 22) return messages;\n\n // Keep system message + first user message + last 20 messages\n const system = messages.find(m => m.role === 'system');\n const firstUser = messages.find(m => m.role === 'user');\n const recent = messages.slice(-20);\n\n const result: ChatMessage[] = [];\n if (system && !recent.includes(system)) result.push(system);\n if (firstUser && !recent.includes(firstUser) && firstUser !== system) result.push(firstUser);\n result.push(...recent);\n\n return result;\n}\n\n// ── Load ────────────────────────────────────────────────────────\n\n/** Load the latest checkpoint for a session, or a specific round */\nexport function loadCheckpoint(sessionId: string, round?: number): CheckpointState | null {\n try {\n const dir = sessionDir(sessionId);\n if (!existsSync(dir)) return null;\n\n if (round !== undefined) {\n const path = roundFile(sessionId, round);\n if (!existsSync(path)) return null;\n return JSON.parse(readFileSync(path, 'utf-8')) as CheckpointState;\n }\n\n // Find latest round\n const files = readdirSync(dir)\n .filter(f => f.startsWith('round-') && f.endsWith('.json'))\n .sort()\n .reverse();\n\n if (files.length === 0) return null;\n return JSON.parse(readFileSync(join(dir, files[0]), 'utf-8')) as CheckpointState;\n } catch (e) {\n logger.warn(COMPONENT, `Failed to load checkpoint: ${(e as Error).message}`);\n return null;\n }\n}\n\n// ── List ────────────────────────────────────────────────────────\n\n/** List all sessions with checkpoints */\nexport function listCheckpoints(): CheckpointMeta[] {\n try {\n if (!existsSync(CHECKPOINTS_DIR)) return [];\n\n const sessions = readdirSync(CHECKPOINTS_DIR).filter(d => {\n const full = join(CHECKPOINTS_DIR, d);\n try { return existsSync(full) && readdirSync(full).some(f => f.endsWith('.json')); }\n catch { return false; }\n });\n\n return sessions.map(sessionId => {\n const dir = join(CHECKPOINTS_DIR, sessionId);\n const files = readdirSync(dir).filter(f => f.startsWith('round-') && f.endsWith('.json')).sort();\n\n if (files.length === 0) return null;\n\n const latest = JSON.parse(readFileSync(join(dir, files[files.length - 1]), 'utf-8')) as CheckpointState;\n const first = JSON.parse(readFileSync(join(dir, files[0]), 'utf-8')) as CheckpointState;\n\n return {\n sessionId: latest.sessionId,\n rounds: files.length,\n latestRound: latest.round,\n model: latest.model,\n message: latest.message,\n channel: latest.channel,\n createdAt: first.timestamp,\n updatedAt: latest.timestamp,\n } as CheckpointMeta;\n }).filter((m): m is CheckpointMeta => m !== null);\n } catch {\n return [];\n }\n}\n\n// ── Clear ───────────────────────────────────────────────────────\n\n/** Clear all checkpoints for a session (call after successful completion) */\nexport function clearCheckpoints(sessionId: string): void {\n try {\n const dir = sessionDir(sessionId);\n if (existsSync(dir)) {\n rmSync(dir, { recursive: true, force: true });\n logger.debug(COMPONENT, `Cleared checkpoints for session ${sessionId}`);\n }\n } catch (e) {\n logger.warn(COMPONENT, `Failed to clear checkpoints: ${(e as Error).message}`);\n }\n}\n\n/** Clear all expired checkpoints (older than maxAge ms, default 24h) */\nexport function clearExpiredCheckpoints(maxAgeMs: number = 24 * 60 * 60 * 1000): number {\n let cleared = 0;\n try {\n if (!existsSync(CHECKPOINTS_DIR)) return 0;\n\n const now = Date.now();\n for (const sessionId of readdirSync(CHECKPOINTS_DIR)) {\n const dir = join(CHECKPOINTS_DIR, sessionId);\n const files = readdirSync(dir).filter(f => f.endsWith('.json')).sort().reverse();\n if (files.length === 0) continue;\n\n try {\n const latest = JSON.parse(readFileSync(join(dir, files[0]), 'utf-8')) as CheckpointState;\n const age = now - new Date(latest.timestamp).getTime();\n if (age > maxAgeMs) {\n rmSync(dir, { recursive: true, force: true });\n cleared++;\n }\n } catch { /* skip corrupted */ }\n }\n\n if (cleared > 0) {\n logger.info(COMPONENT, `Cleared ${cleared} expired checkpoint sessions`);\n }\n } catch { /* non-critical */ }\n return cleared;\n}\n"],"mappings":"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","names":[]}
@@ -4,7 +4,7 @@ import { existsSync, readFileSync, writeFileSync, appendFileSync } from "fs";
4
4
  import { spawn } from "child_process";
5
5
  import { join } from "path";
6
6
  import { TITAN_HOME } from "../utils/constants.js";
7
- import { ensureDir } from "../utils/helpers.js";
7
+ import { mkdirIfNotExists } from "../utils/helpers.js";
8
8
  import { titanEvents } from "./daemon.js";
9
9
  import { spawnAgent, stopAgent, listAgents } from "./multiAgent.js";
10
10
  import { listGoals } from "./goals.js";
@@ -53,7 +53,7 @@ function loadState() {
53
53
  }
54
54
  function saveState() {
55
55
  try {
56
- ensureDir(TITAN_HOME);
56
+ mkdirIfNotExists(TITAN_HOME);
57
57
  const state = {
58
58
  checkouts: Array.from(checkouts.values()),
59
59
  budgetPolicies,
@@ -534,7 +534,7 @@ function getDashboard() {
534
534
  function initCommandPost(cfg) {
535
535
  if (initialized) return;
536
536
  config = cfg;
537
- ensureDir(TITAN_HOME);
537
+ mkdirIfNotExists(TITAN_HOME);
538
538
  loadState();
539
539
  syncAgentRegistry();
540
540
  sweepInterval = setInterval(sweepExpiredCheckouts, 6e4);