titan-agent 6.5.2 → 7.0.0

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 (311) hide show
  1. package/README.md +180 -53
  2. package/assets/agent-skills/NOTICE-ECC.md +39 -0
  3. package/assets/agent-skills/agent-introspection-debugging/SKILL.md +153 -0
  4. package/assets/agent-skills/continuous-agent-loop/SKILL.md +45 -0
  5. package/assets/agent-skills/continuous-learning/SKILL.md +131 -0
  6. package/assets/agent-skills/continuous-learning/config.json +18 -0
  7. package/assets/agent-skills/continuous-learning/evaluate-session.sh +69 -0
  8. package/assets/agent-skills/production-audit/SKILL.md +206 -0
  9. package/assets/agent-skills/recursive-decision-ledger/SKILL.md +79 -0
  10. package/assets/agent-skills/scientific-thinking-literature-review/SKILL.md +192 -0
  11. package/assets/agent-skills/scientific-thinking-scholar-evaluation/SKILL.md +160 -0
  12. package/assets/agent-skills/verification-loop/SKILL.md +126 -0
  13. package/dist/agent/agent.js +67 -26
  14. package/dist/agent/agent.js.map +1 -1
  15. package/dist/agent/agentLoop.js +6 -2
  16. package/dist/agent/agentLoop.js.map +1 -1
  17. package/dist/agent/autoModeClassifier.js +26 -2
  18. package/dist/agent/autoModeClassifier.js.map +1 -1
  19. package/dist/agent/goalDriver.js +2 -0
  20. package/dist/agent/goalDriver.js.map +1 -1
  21. package/dist/agent/goalSpec.js +229 -0
  22. package/dist/agent/goalSpec.js.map +1 -0
  23. package/dist/agent/heartbeat.js +130 -0
  24. package/dist/agent/heartbeat.js.map +1 -0
  25. package/dist/agent/missionDecompose.js +38 -0
  26. package/dist/agent/missionDecompose.js.map +1 -0
  27. package/dist/agent/muscleMemory.js +291 -0
  28. package/dist/agent/muscleMemory.js.map +1 -0
  29. package/dist/agent/observationWriter.js +56 -0
  30. package/dist/agent/observationWriter.js.map +1 -0
  31. package/dist/agent/promptSectionCaps.js +6 -0
  32. package/dist/agent/promptSectionCaps.js.map +1 -1
  33. package/dist/agent/reminders.js +101 -0
  34. package/dist/agent/reminders.js.map +1 -0
  35. package/dist/agent/systemWidgets.js +41 -0
  36. package/dist/agent/systemWidgets.js.map +1 -0
  37. package/dist/agent/toolRunner.js +24 -0
  38. package/dist/agent/toolRunner.js.map +1 -1
  39. package/dist/agent/toolSearch.js +3 -0
  40. package/dist/agent/toolSearch.js.map +1 -1
  41. package/dist/channels/messenger.js +39 -0
  42. package/dist/channels/messenger.js.map +1 -1
  43. package/dist/config/config.js +7 -0
  44. package/dist/config/config.js.map +1 -1
  45. package/dist/config/schema.js +18 -1
  46. package/dist/config/schema.js.map +1 -1
  47. package/dist/eval/harness.js +13 -3
  48. package/dist/eval/harness.js.map +1 -1
  49. package/dist/gateway/onboarding.js +91 -0
  50. package/dist/gateway/onboarding.js.map +1 -0
  51. package/dist/gateway/routes/skills.js +2 -1
  52. package/dist/gateway/routes/skills.js.map +1 -1
  53. package/dist/gateway/routes/studioRouter.js +88 -0
  54. package/dist/gateway/routes/studioRouter.js.map +1 -0
  55. package/dist/gateway/routes/watchRouter.js +4 -4
  56. package/dist/gateway/routes/watchRouter.js.map +1 -1
  57. package/dist/gateway/server.js +251 -43
  58. package/dist/gateway/server.js.map +1 -1
  59. package/dist/memory/taxonomy.js +117 -0
  60. package/dist/memory/taxonomy.js.map +1 -0
  61. package/dist/providers/modelCapabilities.js +13 -0
  62. package/dist/providers/modelCapabilities.js.map +1 -1
  63. package/dist/providers/ollama.js +8 -2
  64. package/dist/providers/ollama.js.map +1 -1
  65. package/dist/providers/openai.js +1 -1
  66. package/dist/providers/openai.js.map +1 -1
  67. package/dist/providers/openai_compat.js +38 -2
  68. package/dist/providers/openai_compat.js.map +1 -1
  69. package/dist/providers/router.js +14 -0
  70. package/dist/providers/router.js.map +1 -1
  71. package/dist/recipes/runner.js +8 -1
  72. package/dist/recipes/runner.js.map +1 -1
  73. package/dist/recipes/store.js +2 -1
  74. package/dist/recipes/store.js.map +1 -1
  75. package/dist/skills/builtin/codebase_explore.js +214 -0
  76. package/dist/skills/builtin/codebase_explore.js.map +1 -0
  77. package/dist/skills/builtin/config_audit.js +160 -0
  78. package/dist/skills/builtin/config_audit.js.map +1 -0
  79. package/dist/skills/builtin/delegate_agent.js +107 -0
  80. package/dist/skills/builtin/delegate_agent.js.map +1 -0
  81. package/dist/skills/builtin/memory_map.js +38 -0
  82. package/dist/skills/builtin/memory_map.js.map +1 -0
  83. package/dist/skills/builtin/reminders.js +67 -0
  84. package/dist/skills/builtin/reminders.js.map +1 -0
  85. package/dist/skills/builtin/spec.js +139 -0
  86. package/dist/skills/builtin/spec.js.map +1 -0
  87. package/dist/skills/builtin/widget_gallery.js +12 -5
  88. package/dist/skills/builtin/widget_gallery.js.map +1 -1
  89. package/dist/skills/frontmatterLoader.js +7 -1
  90. package/dist/skills/frontmatterLoader.js.map +1 -1
  91. package/dist/skills/registry.js +12 -0
  92. package/dist/skills/registry.js.map +1 -1
  93. package/dist/substrate/traceBus.js.map +1 -1
  94. package/dist/telemetry/traceStore.js +127 -0
  95. package/dist/telemetry/traceStore.js.map +1 -0
  96. package/dist/utils/constants.js +1 -1
  97. package/dist/utils/constants.js.map +1 -1
  98. package/dist/utils/contrast.js +69 -0
  99. package/dist/utils/contrast.js.map +1 -0
  100. package/dist/watch/sessionContext.js +14 -0
  101. package/dist/watch/sessionContext.js.map +1 -0
  102. package/dist/watch/sessionTrace.js +51 -0
  103. package/dist/watch/sessionTrace.js.map +1 -0
  104. package/dist/watch/studioBuffer.js +53 -0
  105. package/dist/watch/studioBuffer.js.map +1 -0
  106. package/package.json +4 -3
  107. package/ui/dist/assets/AboutYouMemory-CZKEOd_O.js +11 -0
  108. package/ui/dist/assets/AuditPanel-Bu71N5Er.js +1 -0
  109. package/ui/dist/assets/{AutonomyPanel-CmaXJV8d.js → AutonomyPanel-DB-39dX4.js} +2 -2
  110. package/ui/dist/assets/{AutopilotPanel-CbohPtXW.js → AutopilotPanel-Cj8oKxWv.js} +1 -1
  111. package/ui/dist/assets/{AutoresearchPanel-DCwiQ2v2.js → AutoresearchPanel-3s8pjm6Z.js} +2 -2
  112. package/ui/dist/assets/BackupPanel-EUQJMJE7.js +1 -0
  113. package/ui/dist/assets/{BrowserPanel-D6UaSxap.js → BrowserPanel-Beo4F5Ar.js} +2 -2
  114. package/ui/dist/assets/Button-MdXmb4_n.js +1 -0
  115. package/ui/dist/assets/CPActivity-B1Se9VVc.js +1 -0
  116. package/ui/dist/assets/CPAgentDetail-BYji6tT8.js +1 -0
  117. package/ui/dist/assets/CPAgents-BSUKucTe.js +1 -0
  118. package/ui/dist/assets/CPApprovals-B4v0em6e.js +1 -0
  119. package/ui/dist/assets/CPCosts-9ikh61Kv.js +1 -0
  120. package/ui/dist/assets/CPDashboard-sOok2T5v.js +1 -0
  121. package/ui/dist/assets/{CPFiles-BO73EZwJ.js → CPFiles-DB2nY5JE.js} +1 -1
  122. package/ui/dist/assets/CPGoals-8Z1yOY8e.js +1 -0
  123. package/ui/dist/assets/CPInbox-Cq6-UY8F.js +11 -0
  124. package/ui/dist/assets/CPIssueDetail-NAGfmJg8.js +1 -0
  125. package/ui/dist/assets/CPIssues-BzX6Rckx.js +1 -0
  126. package/ui/dist/assets/CPLayout-BcRM6QSg.js +2 -0
  127. package/ui/dist/assets/CPOrg-B7DQ4UQP.js +1 -0
  128. package/ui/dist/assets/CPRuns-D-cpPw_M.js +1 -0
  129. package/ui/dist/assets/{CPSocial-Qw5rKy_4.js → CPSocial-DshtmcK0.js} +3 -3
  130. package/ui/dist/assets/CPVoice-DfXRnQVU.js +1 -0
  131. package/ui/dist/assets/{ChannelsPanel-DS21E-Iz.js → ChannelsPanel-BnaTOeyf.js} +1 -1
  132. package/ui/dist/assets/CheckpointsPanel-C62naE4U.js +1 -0
  133. package/ui/dist/assets/CommandPostHub-B_L1CAss.js +24 -0
  134. package/ui/dist/assets/ConfirmDialog-VErHWAbo.js +1 -0
  135. package/ui/dist/assets/CronPanel-BwMrrZ5d.js +1 -0
  136. package/ui/dist/assets/{DataTable-PnhPeDBG.js → DataTable-BCqSUuN7.js} +1 -1
  137. package/ui/dist/assets/{DreamPanel-DIrtlk2K.js → DreamPanel-BNAcCLBB.js} +2 -2
  138. package/ui/dist/assets/EmptyState-D9kQf1PX.js +1 -0
  139. package/ui/dist/assets/{EvalHarnessPanel-uYb_ZEQG.js → EvalHarnessPanel-BaMLdBNm.js} +2 -2
  140. package/ui/dist/assets/EvalPanel-CW-SSjtg.js +1 -0
  141. package/ui/dist/assets/{FileViewer-CVO3TRs3.js → FileViewer-BL00nsd7.js} +1 -1
  142. package/ui/dist/assets/FilesPanel-CeC6YUSd.js +16 -0
  143. package/ui/dist/assets/FleetPanel-EyWF7l3W.js +1 -0
  144. package/ui/dist/assets/{HomelabPanel-BZvN4LPM.js → HomelabPanel-BRfKRYe7.js} +2 -2
  145. package/ui/dist/assets/InfraView-Jmqhg_Yc.js +2 -0
  146. package/ui/dist/assets/{InlineEditableField-mBzpbcLB.js → InlineEditableField-DgMrLDj1.js} +1 -1
  147. package/ui/dist/assets/Input-CBTwa_Iw.js +1 -0
  148. package/ui/dist/assets/IntegrationsPanel-DQL-7Ec6.js +1 -0
  149. package/ui/dist/assets/IntelligenceView-DxD78qfP.js +2 -0
  150. package/ui/dist/assets/LearningPanel-C_JzSbJU.js +1 -0
  151. package/ui/dist/assets/LiveStudio-Db5yeaWo.js +7 -0
  152. package/ui/dist/assets/{LogsPanel-DbP3Mwnr.js → LogsPanel-CpinKwaZ.js} +1 -1
  153. package/ui/dist/assets/McpPanel-D-MqN_f-.js +1 -0
  154. package/ui/dist/assets/MemoryGraphPanel-BnD5jRqf.js +1 -0
  155. package/ui/dist/assets/MemoryTaxonomyPanel-BBI202dd.js +6 -0
  156. package/ui/dist/assets/MemoryWikiPanel-Dn3XZHL0.js +6 -0
  157. package/ui/dist/assets/{MeshPanel-Bf-4brXL.js → MeshPanel-C-mRJpr0.js} +1 -1
  158. package/ui/dist/assets/{MissionCanvas-CJyhnauG.js → MissionCanvas-CbZW83Ch.js} +1 -1
  159. package/ui/dist/assets/{MissionChat-C2Nto3zM.js → MissionChat-Bs75jPAD.js} +1 -1
  160. package/ui/dist/assets/{MissionLibrary-RXyBHsLL.js → MissionLibrary-BxQ6SxPe.js} +1 -1
  161. package/ui/dist/assets/MissionStart-CBuBPasl.js +1 -0
  162. package/ui/dist/assets/Modal-ybPGvlQs.js +9 -0
  163. package/ui/dist/assets/{NvidiaPanel-4DlcQlyl.js → NvidiaPanel-DdG13OX4.js} +1 -1
  164. package/ui/dist/assets/OrganismPanel-xZWUJKyr.js +1 -0
  165. package/ui/dist/assets/OverviewPanel-B45ZYhJV.js +1 -0
  166. package/ui/dist/assets/{PageHeader-bnc85wQN.js → PageHeader-DdrbS1aq.js} +1 -1
  167. package/ui/dist/assets/PersonaProfilesPanel-CKER-EU5.js +8 -0
  168. package/ui/dist/assets/{PersonasPanel-dR8VppcD.js → PersonasPanel-CMMQ3nh3.js} +1 -1
  169. package/ui/dist/assets/{PhoneDeskPanel-CdVOY7H9.js → PhoneDeskPanel-Bw_Y-cVE.js} +2 -2
  170. package/ui/dist/assets/RecipesPanel-DzMcxpJJ.js +1 -0
  171. package/ui/dist/assets/SecurityPanel-BCq3Fzbr.js +1 -0
  172. package/ui/dist/assets/SelfImprovePanel-YE3hT8jK.js +1 -0
  173. package/ui/dist/assets/SelfProposalsPanel-DXuqBM6p.js +1 -0
  174. package/ui/dist/assets/SessionsPanel-DORz5goR.js +1 -0
  175. package/ui/dist/assets/SessionsTab-qYHDOuC8.js +1 -0
  176. package/ui/dist/assets/SettingsPanel-BbwPu1i7.js +1 -0
  177. package/ui/dist/assets/SettingsView-zgqkDDBJ.js +2 -0
  178. package/ui/dist/assets/{SkeletonLoader-Cax7YTqW.js → SkeletonLoader-r6OGXaU9.js} +1 -1
  179. package/ui/dist/assets/SkillsPanel-BjEOBMRo.js +11 -0
  180. package/ui/dist/assets/{SomaView-eG3wI4S1.js → SomaView-DLzApZVW.js} +2 -2
  181. package/ui/dist/assets/{StatCard-Djr487DV.js → StatCard-DLq8aBps.js} +1 -1
  182. package/ui/dist/assets/{StatusBadge-JpCoA33_.js → StatusBadge-BqlvIbdj.js} +1 -1
  183. package/ui/dist/assets/{Tabs-DJHu-roP.js → Tabs-DdUThlp1.js} +1 -1
  184. package/ui/dist/assets/TeamsPanel-uIIKoU7I.js +1 -0
  185. package/ui/dist/assets/{TelemetryPanel-D4PXsd-X.js → TelemetryPanel-dVr3yQQr.js} +1 -1
  186. package/ui/dist/assets/TitanCanvas-xHAJqwG2.js +945 -0
  187. package/ui/dist/assets/ToolsView-CG1mZdiy.js +2 -0
  188. package/ui/dist/assets/{Tooltip-B1LhTXJ8.js → Tooltip-C2tXJcrN.js} +1 -1
  189. package/ui/dist/assets/TraceViewer-BIMD_Osr.js +1 -0
  190. package/ui/dist/assets/TracesPanel-nMUiyMj5.js +1 -0
  191. package/ui/dist/assets/TrainingPanel-CT5R4HWm.js +1 -0
  192. package/ui/dist/assets/{VoiceOverlay-B_ss7Zg_.js → VoiceOverlay-Br4QnCtw.js} +3 -3
  193. package/ui/dist/assets/VramPanel-CdnJYytg.js +1 -0
  194. package/ui/dist/assets/WatchView-TNU6Ns1Q.js +13 -0
  195. package/ui/dist/assets/WorkTab-wTlX_UKP.js +1 -0
  196. package/ui/dist/assets/WorkflowBuilderPanel-CDpVt5ux.js +6 -0
  197. package/ui/dist/assets/WorkflowsPanel-zsFqsLdn.js +11 -0
  198. package/ui/dist/assets/{archive-gZFnGd5A.js → archive-Bh689DNg.js} +1 -1
  199. package/ui/dist/assets/{arrow-left-qA0Qer2h.js → arrow-left-WkVYLm80.js} +1 -1
  200. package/ui/dist/assets/{book-open-DIxdPqmD.js → book-open-ohEXgUsS.js} +1 -1
  201. package/ui/dist/assets/{bot-CvIF1uHi.js → bot-DvEcyQcD.js} +1 -1
  202. package/ui/dist/assets/{chart-column-BQiM-Td4.js → chart-column-w3goFd5f.js} +1 -1
  203. package/ui/dist/assets/{check-DgyDEFtq.js → check-CuRYh4Zh.js} +1 -1
  204. package/ui/dist/assets/{chevron-right-CQ1NTOtd.js → chevron-right-DbLSHmff.js} +1 -1
  205. package/ui/dist/assets/{circle-check-big-CAFcaPPH.js → circle-check-big-Bkba568b.js} +1 -1
  206. package/ui/dist/assets/{circle-stop-C-8xGv0n.js → circle-stop-Bx2ohEg8.js} +1 -1
  207. package/ui/dist/assets/{clipboard-list-9DdqBj1F.js → clipboard-list-Dj9tORnu.js} +1 -1
  208. package/ui/dist/assets/{clock-CF9BCIpL.js → clock-JyQAYy6X.js} +1 -1
  209. package/ui/dist/assets/{dollar-sign-LDRZBae6.js → dollar-sign-XxwPAA2a.js} +1 -1
  210. package/ui/dist/assets/{download-BBNXvBO0.js → download-D1izVEOL.js} +1 -1
  211. package/ui/dist/assets/{external-link-D_ji4Bec.js → external-link-DZ_rZsIt.js} +1 -1
  212. package/ui/dist/assets/{file-text-DrdTDEYp.js → file-text-Cfawu8Bs.js} +1 -1
  213. package/ui/dist/assets/{flask-conical-BGn5PgFX.js → flask-conical-Ql8QxhgY.js} +1 -1
  214. package/ui/dist/assets/{folder-BeZZUGnK.js → folder-DAdIw-Pb.js} +1 -1
  215. package/ui/dist/assets/{funnel-CAJgGO5M.js → funnel-FycfZcXo.js} +1 -1
  216. package/ui/dist/assets/{git-branch-BcXabeOs.js → git-branch-C2qrhGGu.js} +1 -1
  217. package/ui/dist/assets/index-Cml2x9pA.js +507 -0
  218. package/ui/dist/assets/index-yWybhcfI.css +1 -0
  219. package/ui/dist/assets/{layers-DxYDmPA_.js → layers-yzjtGlHB.js} +1 -1
  220. package/ui/dist/assets/{legacy-dHWI7k8P.js → legacy-D21WSMF1.js} +1 -1
  221. package/ui/dist/assets/{lightbulb-B0Du4SM4.js → lightbulb-BZJNK69S.js} +1 -1
  222. package/ui/dist/assets/{link-CUpaumqr.js → link-CnFkBkaY.js} +1 -1
  223. package/ui/dist/assets/{list-todo-CDDhmPQB.js → list-todo-BlgfQHup.js} +1 -1
  224. package/ui/dist/assets/{message-square-D5VWlv-Q.js → message-square-CRsG9u6_.js} +1 -1
  225. package/ui/dist/assets/{mic-Ddcc6Ann.js → mic-B32RHc7Y.js} +1 -1
  226. package/ui/dist/assets/{missions-2zox16Tc.js → missions-1iw8Z2_0.js} +1 -1
  227. package/ui/dist/assets/{network-DaJ7ugwX.js → network-C9RXQGrV.js} +1 -1
  228. package/ui/dist/assets/{pause-BukaK6rs.js → pause-BT1Bc2q3.js} +1 -1
  229. package/ui/dist/assets/{pencil-D_YwQBeg.js → pencil-BK5IU6o0.js} +1 -1
  230. package/ui/dist/assets/{play-BjdwtYMk.js → play-Cl1nC_gc.js} +1 -1
  231. package/ui/dist/assets/{plug-yISDdeW2.js → plug-DvcpOalj.js} +1 -1
  232. package/ui/dist/assets/{plus-BSjTdepW.js → plus-Dpo1qfrl.js} +1 -1
  233. package/ui/dist/assets/{radio-B7kX_yWE.js → radio-C5c9IyqX.js} +1 -1
  234. package/ui/dist/assets/{refresh-cw-CwDpzXUn.js → refresh-cw-C-iZkzuS.js} +1 -1
  235. package/ui/dist/assets/{rotate-ccw-7SQDTI0_.js → rotate-ccw-qzrB3SNw.js} +1 -1
  236. package/ui/dist/assets/{save-CjTPAQM0.js → save-DwR9wQVu.js} +1 -1
  237. package/ui/dist/assets/{search-BP7VlNxX.js → search-D10l0m3-.js} +1 -1
  238. package/ui/dist/assets/{send-C2XDuRPf.js → send-DtXGsaFW.js} +1 -1
  239. package/ui/dist/assets/{server-BE8W-AT4.js → server-BzisF3LL.js} +1 -1
  240. package/ui/dist/assets/settings-Dbwd1_-c.js +6 -0
  241. package/ui/dist/assets/{shield-check-s7la2J2K.js → shield-check-CXlDJyAW.js} +1 -1
  242. package/ui/dist/assets/square-BBC-JKzY.js +11 -0
  243. package/ui/dist/assets/{terminal-B8IK4WsO.js → terminal-DaBIlWEM.js} +1 -1
  244. package/ui/dist/assets/{test-tube-Xfn9DJeg.js → test-tube-CDATRD5t.js} +1 -1
  245. package/ui/dist/assets/{toggle-right-CHpzOIlj.js → toggle-right-DTmrC5RD.js} +1 -1
  246. package/ui/dist/assets/{trash-2-B1C85ePK.js → trash-2-CTeyjxD_.js} +1 -1
  247. package/ui/dist/assets/{trending-up-DDGHQZY1.js → trending-up-CXPRjRV4.js} +1 -1
  248. package/ui/dist/assets/{trophy-D0LhJSPA.js → trophy-DbVdXRtU.js} +1 -1
  249. package/ui/dist/assets/{volume-2-DMaE91b5.js → volume-2-DYDBmm3M.js} +1 -1
  250. package/ui/dist/assets/{wifi-off-DR9h8HGA.js → wifi-off-BBuIGbiP.js} +1 -1
  251. package/ui/dist/assets/zoom-out-D47_pRAO.js +16 -0
  252. package/ui/dist/index.html +2 -2
  253. package/ui/dist/sw.js +1 -1
  254. package/ui/dist/assets/AuditPanel-BaftX5MP.js +0 -1
  255. package/ui/dist/assets/BackupPanel-DAy9G7Wt.js +0 -1
  256. package/ui/dist/assets/CPActivity-BYDsUoMn.js +0 -1
  257. package/ui/dist/assets/CPAgentDetail-Bb9-GAJY.js +0 -1
  258. package/ui/dist/assets/CPAgents-BTZuGnki.js +0 -1
  259. package/ui/dist/assets/CPApprovals-BME2ARkO.js +0 -1
  260. package/ui/dist/assets/CPCosts-mOXwWq0i.js +0 -1
  261. package/ui/dist/assets/CPDashboard-CTlKGXXQ.js +0 -1
  262. package/ui/dist/assets/CPGoals-BNWhNP14.js +0 -1
  263. package/ui/dist/assets/CPInbox-ybe4r8LW.js +0 -16
  264. package/ui/dist/assets/CPIssueDetail-DaMMGbjw.js +0 -1
  265. package/ui/dist/assets/CPIssues-BgpQOISw.js +0 -1
  266. package/ui/dist/assets/CPLayout-bgErauTx.js +0 -2
  267. package/ui/dist/assets/CPOrg-C8l5SIWJ.js +0 -8
  268. package/ui/dist/assets/CPRuns-DB8S7loF.js +0 -1
  269. package/ui/dist/assets/CPVoice-DfwHPewA.js +0 -1
  270. package/ui/dist/assets/CheckpointsPanel-9-l_8GdG.js +0 -1
  271. package/ui/dist/assets/CommandPostHub-z55Yrhj1.js +0 -24
  272. package/ui/dist/assets/CronPanel-kEZK3gpx.js +0 -1
  273. package/ui/dist/assets/EmptyState-CfvU7SdB.js +0 -1
  274. package/ui/dist/assets/EvalPanel-CDG-njyj.js +0 -1
  275. package/ui/dist/assets/FilesPanel-CaLPog2e.js +0 -16
  276. package/ui/dist/assets/FleetPanel-BtlaV6pH.js +0 -1
  277. package/ui/dist/assets/InfraView-C0zEuFrR.js +0 -2
  278. package/ui/dist/assets/Input-CbrMbLgn.js +0 -1
  279. package/ui/dist/assets/IntegrationsPanel-B4TyR6jC.js +0 -1
  280. package/ui/dist/assets/IntelligenceView-DZ4HxYZ3.js +0 -2
  281. package/ui/dist/assets/LearningPanel-B4RIm_iQ.js +0 -1
  282. package/ui/dist/assets/McpPanel-BmNUFozc.js +0 -1
  283. package/ui/dist/assets/MemoryGraphPanel-JPurHV0L.js +0 -16
  284. package/ui/dist/assets/MemoryWikiPanel-DdvCAZHa.js +0 -6
  285. package/ui/dist/assets/MissionStart-wUkcEP0T.js +0 -1
  286. package/ui/dist/assets/Modal-BmS7C6FN.js +0 -1
  287. package/ui/dist/assets/OrganismPanel-C2LYDPrn.js +0 -1
  288. package/ui/dist/assets/OverviewPanel-DK8uuq4D.js +0 -1
  289. package/ui/dist/assets/PersonaProfilesPanel-DGtokXUu.js +0 -8
  290. package/ui/dist/assets/RecipesPanel-D3Zs2wxr.js +0 -1
  291. package/ui/dist/assets/SecurityPanel-BMERf796.js +0 -1
  292. package/ui/dist/assets/SelfImprovePanel-BxqWHXCU.js +0 -1
  293. package/ui/dist/assets/SelfProposalsPanel-CuC94vdx.js +0 -2
  294. package/ui/dist/assets/SessionsPanel-CQ8qvzp7.js +0 -1
  295. package/ui/dist/assets/SessionsTab-B3eHV3jf.js +0 -1
  296. package/ui/dist/assets/SettingsPanel-Cumls7N2.js +0 -1
  297. package/ui/dist/assets/SettingsView-BtA67pol.js +0 -2
  298. package/ui/dist/assets/SkillsPanel-CA415CT8.js +0 -11
  299. package/ui/dist/assets/TeamsPanel-C_Vu6vnY.js +0 -1
  300. package/ui/dist/assets/TitanCanvas-TuYZSZO7.js +0 -1117
  301. package/ui/dist/assets/ToolsView-BvTN6vFn.js +0 -2
  302. package/ui/dist/assets/TraceViewer-Bh8Jo3Dr.js +0 -1
  303. package/ui/dist/assets/TrainingPanel-Dmbd1rJ-.js +0 -1
  304. package/ui/dist/assets/VramPanel-CPICbZ2s.js +0 -1
  305. package/ui/dist/assets/WatchView-BCgLVfiV.js +0 -13
  306. package/ui/dist/assets/WorkTab-iptofXO9.js +0 -1
  307. package/ui/dist/assets/WorkflowsPanel-3RYkFHyf.js +0 -11
  308. package/ui/dist/assets/chevron-up-UyfdjRp6.js +0 -6
  309. package/ui/dist/assets/index-CUgepw5Q.js +0 -337
  310. package/ui/dist/assets/index-Dm6zcSTS.css +0 -1
  311. package/ui/dist/assets/proxy-CWET5FFX.js +0 -9
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/skills/builtin/widget_gallery.ts"],"sourcesContent":["/**\n * TITAN — Widget Gallery Skill\n *\n * Loads the bundled widget template library at startup and exposes:\n * - gallery_search(query): fuzzy match against triggers, tags, name, description\n * - gallery_get(id): fetch a single template by id (with source code + placeholders)\n * - gallery_list(category?): list templates (optionally filtered)\n * - gallery_categories(): list of all category names with counts\n *\n * The canvas chat agent should ALWAYS call gallery_search FIRST when the user\n * asks for a widget. Only generate from scratch when nothing matches well.\n *\n * Templates live in assets/widget-templates/<category>/<id>.json with schema:\n * {\n * id, name, category, tags[], description, triggers[],\n * defaultSize: { w, h },\n * source: \"function MyWidget() {...} render(<MyWidget/>);\",\n * placeholders: [{ name, description, default }]\n * }\n *\n * `source` is the React component body for <WidgetSandbox> srcdoc — it's\n * wrapped in the iframe's React 18 UMD + Babel standalone runtime by the\n * canvas, so just author it as a self-contained component ending in\n * `render(<X/>);`. Inline tokens like REPLACE_WITH_SYMBOL are swapped at\n * runtime via gallery_get's `fill` argument.\n */\n\nimport { readdirSync, readFileSync, existsSync, statSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { registerSkill } from '../registry.js';\nimport logger from '../../utils/logger.js';\n\nconst COMPONENT = 'WidgetGallery';\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// dist/skills/builtin → ../../../assets = project root / assets\n// Fallback to CWD/assets/widget-templates when bundled or invoked from a\n// non-standard layout (kimi review: defensive for single-file bundles).\nconst PRIMARY_TEMPLATES_DIR = join(__dirname, '../../../assets/widget-templates');\nconst TEMPLATES_DIR = existsSync(PRIMARY_TEMPLATES_DIR)\n ? PRIMARY_TEMPLATES_DIR\n : join(process.cwd(), 'assets/widget-templates');\n\nexport interface WidgetPlaceholder {\n name: string;\n description: string;\n default?: string;\n}\n\nexport interface WidgetTemplate {\n id: string;\n name: string;\n category: string;\n tags: string[];\n description: string;\n triggers: string[];\n defaultSize?: { w: number; h: number };\n source: string;\n placeholders?: WidgetPlaceholder[];\n}\n\n// System widgets are hardcoded React components in the UI.\n// They are included in the gallery so the agent can discover and emit them.\nconst SYSTEM_WIDGET_TEMPLATES: WidgetTemplate[] = [\n { id: 'system-backup', name: 'Backup Manager', category: 'system', tags: ['backup', 'storage', 'archive'], description: 'Create, list, and verify TITAN data backups', triggers: ['backup', 'snapshot', 'archive'], defaultSize: { w: 6, h: 6 }, source: 'system:backup' },\n { id: 'system-training', name: 'Training Dashboard', category: 'system', tags: ['training', 'model', 'specialist'], description: 'View training stats, progress, and export data', triggers: ['training', 'train', 'specialist', 'model'], defaultSize: { w: 6, h: 6 }, source: 'system:training' },\n { id: 'system-recipes', name: 'Recipe Kitchen', category: 'system', tags: ['recipe', 'playbook', 'workflow'], description: 'Run and manage AI playbook recipes', triggers: ['recipe', 'playbook', 'workflow', 'jarvis'], defaultSize: { w: 6, h: 6 }, source: 'system:recipes' },\n { id: 'system-vram', name: 'VRAM Monitor', category: 'system', tags: ['vram', 'gpu', 'memory', 'nvidia'], description: 'Monitor GPU memory usage and manage leases', triggers: ['vram', 'gpu', 'memory', 'nvidia'], defaultSize: { w: 6, h: 6 }, source: 'system:vram' },\n { id: 'system-teams', name: 'Team Hub', category: 'system', tags: ['team', 'member', 'role', 'rbac'], description: 'Manage teams, members, and role permissions', triggers: ['team', 'member', 'role', 'permission', 'rbac'], defaultSize: { w: 6, h: 6 }, source: 'system:teams' },\n { id: 'system-cron', name: 'Cron Scheduler', category: 'system', tags: ['cron', 'schedule', 'job', 'timer'], description: 'View and manage scheduled cron jobs', triggers: ['cron', 'schedule', 'job', 'timer'], defaultSize: { w: 6, h: 6 }, source: 'system:cron' },\n { id: 'system-checkpoints', name: 'Checkpoints', category: 'system', tags: ['checkpoint', 'restore', 'save'], description: 'Browse and restore session checkpoints', triggers: ['checkpoint', 'restore', 'save state'], defaultSize: { w: 6, h: 5 }, source: 'system:checkpoints' },\n { id: 'system-organism', name: 'Organism Monitor', category: 'system', tags: ['organism', 'drive', 'safety', 'alert'], description: 'View organism drives, safety alerts, and metrics', triggers: ['organism', 'drive', 'safety', 'alert', 'guardrail'], defaultSize: { w: 6, h: 6 }, source: 'system:organism' },\n { id: 'system-fleet', name: 'Fleet Router', category: 'system', tags: ['fleet', 'node', 'route', 'mesh'], description: 'View mesh fleet nodes and route requests', triggers: ['fleet', 'node', 'route', 'mesh'], defaultSize: { w: 6, h: 5 }, source: 'system:fleet' },\n { id: 'system-browser', name: 'Browser Tools', category: 'system', tags: ['browser', 'captcha', 'automation'], description: 'Solve captchas and automate browser tasks', triggers: ['captcha', 'browser', 'form fill', 'web automation'], defaultSize: { w: 6, h: 5 }, source: 'system:browser' },\n // v6.0 step 1 — system-paperclip removed (pre-v5 branding, Bucket C / killed).\n { id: 'system-eval', name: 'Test Lab', category: 'system', tags: ['test', 'eval', 'flaky', 'coverage'], description: 'View test health, failing tests, and run evaluations', triggers: ['test', 'flaky', 'failing', 'coverage', 'eval'], defaultSize: { w: 6, h: 6 }, source: 'system:eval' },\n // v6.0 step 1 — system-daemon removed (overlapped with system-organism, Bucket C / killed).\n { id: 'system-memory-wiki', name: 'Memory Wiki', category: 'system', tags: ['wiki', 'memory', 'knowledge', 'entity'], description: 'Browse the memory wiki and knowledge graph entities', triggers: ['wiki', 'memory', 'knowledge', 'entity'], defaultSize: { w: 6, h: 6 }, source: 'system:memory-wiki' },\n { id: 'system-autoresearch', name: 'Autoresearch', category: 'system', tags: ['research', 'benchmark', 'deploy'], description: 'Run autoresearch benchmarks and deploy pipelines', triggers: ['research', 'benchmark', 'deploy'], defaultSize: { w: 6, h: 6 }, source: 'system:autoresearch' },\n { id: 'system-self-proposals', name: 'Self-Proposals', category: 'system', tags: ['proposal', 'self-improve', 'pr'], description: 'Review and manage self-improvement proposals', triggers: ['proposal', 'self-improve', 'pr'], defaultSize: { w: 6, h: 6 }, source: 'system:self-proposals' },\n { id: 'system-overview', name: 'Overview', category: 'system', tags: ['overview', 'stats', 'dashboard'], description: 'System overview and activity dashboard', triggers: ['overview', 'stats', 'dashboard'], defaultSize: { w: 6, h: 5 }, source: 'system:overview' },\n { id: 'system-sessions', name: 'Sessions', category: 'system', tags: ['session', 'chat', 'history'], description: 'Browse and manage chat sessions', triggers: ['session', 'chat', 'history'], defaultSize: { w: 6, h: 5 }, source: 'system:sessions' },\n { id: 'system-watch', name: 'Watch', category: 'system', tags: ['watch', 'monitor', 'live'], description: 'Live organism and drive activity monitor', triggers: ['watch', 'monitor', 'live', 'activity'], defaultSize: { w: 8, h: 7 }, source: 'system:watch' },\n];\n\nlet templateCache: Map<string, WidgetTemplate> | null = null;\n\nfunction loadTemplates(): Map<string, WidgetTemplate> {\n if (templateCache) return templateCache;\n const map = new Map<string, WidgetTemplate>();\n if (!existsSync(TEMPLATES_DIR)) {\n logger.warn(COMPONENT, `Templates dir missing: ${TEMPLATES_DIR}`);\n templateCache = map;\n return map;\n }\n const walk = (dir: string): void => {\n let entries: string[] = [];\n try { entries = readdirSync(dir); } catch { return; }\n for (const name of entries) {\n const full = join(dir, name);\n let stat;\n try { stat = statSync(full); } catch { continue; }\n if (stat.isDirectory()) { walk(full); continue; }\n if (!name.endsWith('.json')) continue;\n try {\n const raw = readFileSync(full, 'utf-8');\n const t = JSON.parse(raw) as WidgetTemplate;\n if (!t.id || !t.source) {\n logger.warn(COMPONENT, `Skipped malformed template: ${full}`);\n continue;\n }\n if (map.has(t.id)) {\n logger.warn(COMPONENT, `Duplicate template id \"${t.id}\" — keeping first.`);\n continue;\n }\n // Fill defaults so search/list don't have to null-check\n t.tags = Array.isArray(t.tags) ? t.tags : [];\n t.triggers = Array.isArray(t.triggers) ? t.triggers : [];\n t.description = t.description || '';\n t.category = t.category || 'misc';\n map.set(t.id, t);\n } catch (e) {\n logger.warn(COMPONENT, `Failed to parse ${full}: ${(e as Error).message}`);\n }\n }\n };\n walk(TEMPLATES_DIR);\n // Merge system widgets into the gallery\n for (const sw of SYSTEM_WIDGET_TEMPLATES) {\n if (!map.has(sw.id)) {\n map.set(sw.id, sw);\n }\n }\n templateCache = map;\n logger.info(COMPONENT, `Loaded ${map.size} widget templates (${map.size - SYSTEM_WIDGET_TEMPLATES.length} JSON + ${SYSTEM_WIDGET_TEMPLATES.length} system) from ${TEMPLATES_DIR}`);\n return map;\n}\n\n/** Drop the cache so the next call reloads from disk (useful for dev). */\nexport function reloadTemplates(): number {\n templateCache = null;\n return loadTemplates().size;\n}\n\nfunction tokenize(s: string): string[] {\n return s.toLowerCase().replace(/[^a-z0-9\\s]+/g, ' ').split(/\\s+/).filter(Boolean);\n}\n\ninterface ScoredTemplate {\n template: WidgetTemplate;\n score: number;\n matched: string[];\n}\n\nfunction scoreTemplate(t: WidgetTemplate, queryTokens: Set<string>): ScoredTemplate {\n let score = 0;\n const matched = new Set<string>();\n\n // Trigger phrases get the heaviest weight (they're hand-curated intents)\n for (const trigger of t.triggers) {\n const triggerLower = trigger.toLowerCase();\n // Whole-phrase match in original query\n const queryString = Array.from(queryTokens).join(' ');\n if (queryString.includes(triggerLower)) {\n score += 10;\n matched.add(trigger);\n } else {\n const triggerTokens = tokenize(trigger);\n for (const tk of triggerTokens) {\n if (queryTokens.has(tk)) { score += 3; matched.add(trigger); }\n }\n }\n }\n\n // Tags: medium weight\n for (const tag of t.tags) {\n if (queryTokens.has(tag.toLowerCase())) { score += 2; matched.add(tag); }\n }\n\n // Name tokens: weight 4 each (a name match is strong signal)\n for (const tk of tokenize(t.name)) {\n if (queryTokens.has(tk)) { score += 4; matched.add(t.name); }\n }\n\n // Description: weight 1 (last-resort match)\n for (const tk of tokenize(t.description)) {\n if (queryTokens.has(tk)) { score += 1; }\n }\n\n // Category: weight 1\n if (queryTokens.has(t.category.toLowerCase())) { score += 1; matched.add(`category:${t.category}`); }\n\n return { template: t, score, matched: Array.from(matched) };\n}\n\nexport function searchGallery(query: string, limit = 5): ScoredTemplate[] {\n const map = loadTemplates();\n const queryTokens = new Set(tokenize(query));\n if (queryTokens.size === 0) return [];\n const scored: ScoredTemplate[] = [];\n for (const t of map.values()) {\n const s = scoreTemplate(t, queryTokens);\n if (s.score > 0) scored.push(s);\n }\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, limit);\n}\n\nexport function getTemplate(id: string, fill?: Record<string, string>): WidgetTemplate | null {\n const t = loadTemplates().get(id);\n if (!t) return null;\n if (!fill || Object.keys(fill).length === 0) return t;\n let source = t.source;\n for (const [key, value] of Object.entries(fill)) {\n // Replace both REPLACE_WITH_X and {{X}} forms; agent may use either.\n // Escape backslash, single-quote, AND backtick (kimi review: backticks\n // could break out of template literals if a value contained one).\n const safe = String(value)\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/'/g, \"\\\\'\")\n .replace(/`/g, '\\\\`');\n source = source.split(`REPLACE_WITH_${key}`).join(safe);\n source = source.split(`{{${key}}}`).join(safe);\n }\n return { ...t, source };\n}\n\nexport function listTemplates(category?: string): Array<Omit<WidgetTemplate, 'source'>> {\n const map = loadTemplates();\n const out: Array<Omit<WidgetTemplate, 'source'>> = [];\n for (const t of map.values()) {\n if (category && t.category !== category) continue;\n // Strip `source` so list calls stay token-light. Agent calls gallery_get to fetch source.\n const { source: _omit, ...rest } = t;\n out.push(rest);\n }\n out.sort((a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name));\n return out;\n}\n\nexport function listCategories(): Array<{ category: string; count: number }> {\n const map = loadTemplates();\n const counts = new Map<string, number>();\n for (const t of map.values()) {\n counts.set(t.category, (counts.get(t.category) ?? 0) + 1);\n }\n return Array.from(counts.entries())\n .map(([category, count]) => ({ category, count }))\n .sort((a, b) => a.category.localeCompare(b.category));\n}\n\nexport function registerWidgetGallerySkill(): void {\n // Eager-load so the count appears in startup logs.\n loadTemplates();\n\n registerSkill(\n {\n name: 'widget_gallery',\n description: 'Curated library of pre-built canvas widget templates (timers, trackers, dashboards, automations, smart-home controls, agent-employee panels, software-builder skeletons). The canvas chat agent should ALWAYS call gallery_search FIRST when the user asks for a widget. Only generate from scratch when no template matches.',\n version: '1.0.0',\n source: 'bundled',\n enabled: true,\n },\n {\n name: 'gallery_search',\n description: `Search the 109-template widget gallery for the closest matches to the user's intent. Returns ranked results with id + score; pass the top id to gallery_get to retrieve the source. THIS IS THE FIRST THING YOU CALL when the user wants any widget — only fall back to generating from scratch (_____react) when no result scores well.\n\nUSE WHEN: \"build me a X widget\" / \"I want a Y panel\" / \"make me a Z dashboard\" / \"add a calculator\" / \"spawn an SDR agent\" — any request for a UI element on the canvas. Also when the user says \"do you have a template for X?\"\n\nDO NOT USE FOR:\n- Listing every template → use gallery_list.\n- Searching the marketplace (third-party skills) → use a different tool (this gallery is bundled-only).\n- Searching skills (tools the agent can call) → use tool_search.\n\nParameters:\n- query (string, required) — the user's intent. Best results from phrases (\"stock tracker for AAPL\"), worst from single words (\"widget\"). Include the SUBJECT (AAPL, the user's symbol/topic) if known — that biases scoring.\n- limit (number, optional) — default 5; max 20.\n\nReturns: { results: Array<{ id, name, category, description, score, matched: string[] }> }. score >= 10 means a strong trigger-phrase match — use that template confidently. Score < 3 → no good match, generate from scratch.\n\nErrors: this tool can't really error. Empty results means generate from scratch.\n\nALWAYS show the top match's name + category to the user before calling gallery_get, so they can correct you if you picked the wrong one (\"I'm using the 'Stock Tracker' template — want a different one?\").`,\n parameters: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'User intent — phrase, keyword, or full request. Example: \"stock tracker for AAPL\", \"pomodoro\", \"control my smart lights\".' },\n limit: { type: 'number', description: 'Max results (default 5).' },\n },\n required: ['query'],\n },\n execute: async (args: Record<string, unknown>) => {\n const query = String(args.query ?? '');\n const limit = typeof args.limit === 'number' ? args.limit : undefined;\n const results = searchGallery(query, limit ?? 5);\n if (results.length === 0) {\n return JSON.stringify({\n query,\n results: [],\n hint: 'No matches. Generate a custom widget from scratch.',\n });\n }\n return JSON.stringify({\n query,\n results: results.map(r => ({\n id: r.template.id,\n name: r.template.name,\n category: r.template.category,\n description: r.template.description,\n defaultSize: r.template.defaultSize,\n placeholders: r.template.placeholders ?? [],\n score: r.score,\n matched: r.matched,\n })),\n hint: 'Pick the best match, call gallery_get with its id and a `fill` map of placeholder values from the user request.',\n });\n },\n },\n );\n\n registerSkill(\n {\n name: 'widget_gallery_get',\n description: 'Fetch the full source of a gallery template, with placeholders replaced.',\n version: '1.0.0',\n source: 'bundled',\n enabled: true,\n },\n {\n name: 'gallery_get',\n description: `Fetch a single widget template from the gallery by id, with REPLACE_WITH_X placeholders substituted. Returns the canvas-ready React source you can paste into a _____react block.\n\nUSE WHEN: you just got a template id from gallery_search and now need its source. ALWAYS call gallery_search first to get the id — never guess a template name.\n\nDO NOT USE FOR:\n- Browsing what's available → use gallery_search (returns ranked matches with descriptions).\n- Listing every template → use gallery_list (full catalogue).\n- Generating a brand-new widget that's not in the catalogue → emit a fresh _____react block directly; do not gallery_get for templates that don't exist.\n\nParameters:\n- id (string, required) — exact template id from gallery_search results.\n- fill (object, optional) — placeholder substitutions. Keys are the placeholder name WITHOUT the REPLACE_WITH_ prefix (so { \"SYMBOL\": \"AAPL\" } substitutes REPLACE_WITH_SYMBOL). Values are escaped automatically for backslash, single quote, and backtick.\n\nReturns: { source: string, size: { width, height }, category, displayName }. source is the full React component with placeholders filled. Drop it inside a _____react block on the next assistant turn.\n\nErrors:\n- \"Template not found: <id>\" — the id is wrong (typo or stale). Re-run gallery_search to get a fresh id.\n- Placeholders left unfilled — they appear as literal REPLACE_WITH_X strings in source. Catch this before emitting; either provide fill values or substitute them yourself.`,\n parameters: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Template id from gallery_search results.' },\n fill: {\n type: 'object',\n description: 'Placeholder values (key = placeholder name without REPLACE_WITH_ prefix, value = string to insert). Example: {\"SYMBOL\": \"AAPL\"} → REPLACE_WITH_SYMBOL becomes \"AAPL\".',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['id'],\n },\n execute: async (args: Record<string, unknown>) => {\n const id = String(args.id ?? '');\n const fill = (args.fill && typeof args.fill === 'object') ? args.fill as Record<string, string> : undefined;\n const t = getTemplate(id, fill);\n if (!t) return JSON.stringify({ error: `Template not found: ${id}` });\n // v5.4.2: Prepend size metadata as a leading comment so the canvas\n // frontend can extract defaultSize from the source (Bug #3 fix).\n // The frontend parses `// __WIDGET_META__ w=6 h=6` on _____react gate.\n const w = t.defaultSize?.w ?? 4;\n const h = t.defaultSize?.h ?? 4;\n const metaComment = `// __WIDGET_META__ w=${w} h=${h}\\n`;\n const sourceWithMeta = metaComment + (t.source || '');\n return JSON.stringify({\n id: t.id,\n name: t.name,\n category: t.category,\n defaultSize: t.defaultSize,\n source: sourceWithMeta,\n placeholders: t.placeholders ?? [],\n });\n },\n },\n );\n\n registerSkill(\n {\n name: 'widget_gallery_list',\n description: 'List all gallery templates (optionally filtered by category).',\n version: '1.0.0',\n source: 'bundled',\n enabled: true,\n },\n {\n name: 'gallery_list',\n description: 'List all widget gallery templates. Filter by category. Returns metadata (id, name, category, description, tags, triggers) without source — call gallery_get to fetch source.',\n parameters: {\n type: 'object',\n properties: {\n category: { type: 'string', description: 'Optional category filter (e.g. \"finance\", \"productivity\", \"automation\", \"smart-home\", \"agents\").' },\n },\n },\n execute: async (args: Record<string, unknown>) => {\n const category = typeof args.category === 'string' ? args.category : undefined;\n const items = listTemplates(category);\n return JSON.stringify({\n count: items.length,\n categories: listCategories(),\n templates: items,\n });\n },\n },\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/skills/builtin/widget_gallery.ts"],"sourcesContent":["/**\n * TITAN — Widget Gallery Skill\n *\n * Loads the bundled widget template library at startup and exposes:\n * - gallery_search(query): fuzzy match against triggers, tags, name, description\n * - gallery_get(id): fetch a single template by id (with source code + placeholders)\n * - gallery_list(category?): list templates (optionally filtered)\n * - gallery_categories(): list of all category names with counts\n *\n * The canvas chat agent should ALWAYS call gallery_search FIRST when the user\n * asks for a widget. Only generate from scratch when nothing matches well.\n *\n * Templates live in assets/widget-templates/<category>/<id>.json with schema:\n * {\n * id, name, category, tags[], description, triggers[],\n * defaultSize: { w, h },\n * source: \"function MyWidget() {...} render(<MyWidget/>);\",\n * placeholders: [{ name, description, default }]\n * }\n *\n * `source` is the React component body for <WidgetSandbox> srcdoc — it's\n * wrapped in the iframe's React 18 UMD + Babel standalone runtime by the\n * canvas, so just author it as a self-contained component ending in\n * `render(<X/>);`. Inline tokens like REPLACE_WITH_SYMBOL are swapped at\n * runtime via gallery_get's `fill` argument.\n */\n\nimport { readdirSync, readFileSync, existsSync, statSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { registerSkill } from '../registry.js';\nimport logger from '../../utils/logger.js';\n\nconst COMPONENT = 'WidgetGallery';\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// dist/skills/builtin → ../../../assets = project root / assets\n// Fallback to CWD/assets/widget-templates when bundled or invoked from a\n// non-standard layout (kimi review: defensive for single-file bundles).\nconst PRIMARY_TEMPLATES_DIR = join(__dirname, '../../../assets/widget-templates');\nconst TEMPLATES_DIR = existsSync(PRIMARY_TEMPLATES_DIR)\n ? PRIMARY_TEMPLATES_DIR\n : join(process.cwd(), 'assets/widget-templates');\n\nexport interface WidgetPlaceholder {\n name: string;\n description: string;\n default?: string;\n}\n\nexport interface WidgetTemplate {\n id: string;\n name: string;\n category: string;\n tags: string[];\n description: string;\n triggers: string[];\n defaultSize?: { w: number; h: number };\n source: string;\n placeholders?: WidgetPlaceholder[];\n}\n\n// System widgets are hardcoded React components in the UI.\n// They are included in the gallery so the agent can discover and emit them.\nconst SYSTEM_WIDGET_TEMPLATES: WidgetTemplate[] = [\n { id: 'system-backup', name: 'Backup Manager', category: 'system', tags: ['backup', 'storage', 'archive'], description: 'Create, list, and verify TITAN data backups', triggers: ['backup', 'snapshot', 'archive'], defaultSize: { w: 6, h: 6 }, source: 'system:backup' },\n { id: 'system-training', name: 'Training Dashboard', category: 'system', tags: ['training', 'model', 'specialist'], description: 'View training stats, progress, and export data', triggers: ['training', 'train', 'specialist', 'model'], defaultSize: { w: 6, h: 6 }, source: 'system:training' },\n { id: 'system-recipes', name: 'Recipe Kitchen', category: 'system', tags: ['recipe', 'playbook', 'workflow'], description: 'Run and manage AI playbook recipes', triggers: ['recipe', 'playbook', 'workflow', 'jarvis'], defaultSize: { w: 6, h: 6 }, source: 'system:recipes' },\n { id: 'system-vram', name: 'VRAM Monitor', category: 'system', tags: ['vram', 'gpu', 'memory', 'nvidia'], description: 'Monitor GPU memory usage and manage leases', triggers: ['vram', 'gpu', 'memory', 'nvidia'], defaultSize: { w: 6, h: 6 }, source: 'system:vram' },\n { id: 'system-teams', name: 'Team Hub', category: 'system', tags: ['team', 'member', 'role', 'rbac'], description: 'Manage teams, members, and role permissions', triggers: ['team', 'member', 'role', 'permission', 'rbac'], defaultSize: { w: 6, h: 6 }, source: 'system:teams' },\n { id: 'system-cron', name: 'Cron Scheduler', category: 'system', tags: ['cron', 'schedule', 'job', 'timer'], description: 'View and manage scheduled cron jobs', triggers: ['cron', 'schedule', 'job', 'timer'], defaultSize: { w: 6, h: 6 }, source: 'system:cron' },\n { id: 'system-checkpoints', name: 'Checkpoints', category: 'system', tags: ['checkpoint', 'restore', 'save'], description: 'Browse and restore session checkpoints', triggers: ['checkpoint', 'restore', 'save state'], defaultSize: { w: 6, h: 5 }, source: 'system:checkpoints' },\n { id: 'system-organism', name: 'Organism Monitor', category: 'system', tags: ['organism', 'drive', 'safety', 'alert'], description: 'View organism drives, safety alerts, and metrics', triggers: ['organism', 'drive', 'safety', 'alert', 'guardrail'], defaultSize: { w: 6, h: 6 }, source: 'system:organism' },\n { id: 'system-fleet', name: 'Fleet Router', category: 'system', tags: ['fleet', 'node', 'route', 'mesh'], description: 'View mesh fleet nodes and route requests', triggers: ['fleet', 'node', 'route', 'mesh'], defaultSize: { w: 6, h: 5 }, source: 'system:fleet' },\n { id: 'system-browser', name: 'Browser Tools', category: 'system', tags: ['browser', 'captcha', 'automation'], description: 'Solve captchas and automate browser tasks', triggers: ['captcha', 'browser', 'form fill', 'web automation'], defaultSize: { w: 6, h: 5 }, source: 'system:browser' },\n // v6.0 step 1 — system-paperclip removed (pre-v5 branding, Bucket C / killed).\n { id: 'system-eval', name: 'Test Lab', category: 'system', tags: ['test', 'eval', 'flaky', 'coverage'], description: 'View test health, failing tests, and run evaluations', triggers: ['test', 'flaky', 'failing', 'coverage', 'eval'], defaultSize: { w: 6, h: 6 }, source: 'system:eval' },\n // v6.0 step 1 — system-daemon removed (overlapped with system-organism, Bucket C / killed).\n { id: 'system-memory-wiki', name: 'Memory Wiki', category: 'system', tags: ['wiki', 'memory', 'knowledge', 'entity'], description: 'Browse the memory wiki and knowledge graph entities', triggers: ['wiki', 'memory', 'knowledge', 'entity'], defaultSize: { w: 6, h: 6 }, source: 'system:memory-wiki' },\n { id: 'system-autoresearch', name: 'Autoresearch', category: 'system', tags: ['research', 'benchmark', 'deploy'], description: 'Run autoresearch benchmarks and deploy pipelines', triggers: ['research', 'benchmark', 'deploy'], defaultSize: { w: 6, h: 6 }, source: 'system:autoresearch' },\n { id: 'system-self-proposals', name: 'Self-Proposals', category: 'system', tags: ['proposal', 'self-improve', 'pr'], description: 'Review and manage self-improvement proposals', triggers: ['proposal', 'self-improve', 'pr'], defaultSize: { w: 6, h: 6 }, source: 'system:self-proposals' },\n { id: 'system-overview', name: 'Overview', category: 'system', tags: ['overview', 'stats', 'dashboard'], description: 'System overview and activity dashboard', triggers: ['overview', 'stats', 'dashboard'], defaultSize: { w: 6, h: 5 }, source: 'system:overview' },\n { id: 'system-sessions', name: 'Sessions', category: 'system', tags: ['session', 'chat', 'history'], description: 'Browse and manage chat sessions', triggers: ['session', 'chat', 'history'], defaultSize: { w: 6, h: 5 }, source: 'system:sessions' },\n { id: 'system-watch', name: 'Watch', category: 'system', tags: ['watch', 'monitor', 'live'], description: 'Live organism and drive activity monitor', triggers: ['watch', 'monitor', 'live', 'activity'], defaultSize: { w: 8, h: 7 }, source: 'system:watch' },\n];\n\nlet templateCache: Map<string, WidgetTemplate> | null = null;\n\nfunction loadTemplates(): Map<string, WidgetTemplate> {\n if (templateCache) return templateCache;\n const map = new Map<string, WidgetTemplate>();\n if (!existsSync(TEMPLATES_DIR)) {\n logger.warn(COMPONENT, `Templates dir missing: ${TEMPLATES_DIR}`);\n templateCache = map;\n return map;\n }\n const walk = (dir: string): void => {\n let entries: string[] = [];\n try { entries = readdirSync(dir); } catch { return; }\n for (const name of entries) {\n const full = join(dir, name);\n let stat;\n try { stat = statSync(full); } catch { continue; }\n if (stat.isDirectory()) { walk(full); continue; }\n if (!name.endsWith('.json')) continue;\n try {\n const raw = readFileSync(full, 'utf-8');\n const t = JSON.parse(raw) as WidgetTemplate;\n if (!t.id || !t.source) {\n logger.warn(COMPONENT, `Skipped malformed template: ${full}`);\n continue;\n }\n if (map.has(t.id)) {\n logger.warn(COMPONENT, `Duplicate template id \"${t.id}\" — keeping first.`);\n continue;\n }\n // Fill defaults so search/list don't have to null-check\n t.tags = Array.isArray(t.tags) ? t.tags : [];\n t.triggers = Array.isArray(t.triggers) ? t.triggers : [];\n t.description = t.description || '';\n t.category = t.category || 'misc';\n map.set(t.id, t);\n } catch (e) {\n logger.warn(COMPONENT, `Failed to parse ${full}: ${(e as Error).message}`);\n }\n }\n };\n walk(TEMPLATES_DIR);\n // Merge system widgets into the gallery\n for (const sw of SYSTEM_WIDGET_TEMPLATES) {\n if (!map.has(sw.id)) {\n map.set(sw.id, sw);\n }\n }\n templateCache = map;\n logger.info(COMPONENT, `Loaded ${map.size} widget templates (${map.size - SYSTEM_WIDGET_TEMPLATES.length} JSON + ${SYSTEM_WIDGET_TEMPLATES.length} system) from ${TEMPLATES_DIR}`);\n return map;\n}\n\n/** Drop the cache so the next call reloads from disk (useful for dev). */\nexport function reloadTemplates(): number {\n templateCache = null;\n return loadTemplates().size;\n}\n\nfunction tokenize(s: string): string[] {\n return s.toLowerCase().replace(/[^a-z0-9\\s]+/g, ' ').split(/\\s+/).filter(Boolean);\n}\n\ninterface ScoredTemplate {\n template: WidgetTemplate;\n score: number;\n matched: string[];\n}\n\nfunction scoreTemplate(t: WidgetTemplate, queryTokens: Set<string>): ScoredTemplate {\n let score = 0;\n const matched = new Set<string>();\n\n // Trigger phrases get the heaviest weight (they're hand-curated intents)\n for (const trigger of t.triggers) {\n const triggerLower = trigger.toLowerCase();\n // Whole-phrase match in original query\n const queryString = Array.from(queryTokens).join(' ');\n if (queryString.includes(triggerLower)) {\n score += 10;\n matched.add(trigger);\n } else {\n const triggerTokens = tokenize(trigger);\n for (const tk of triggerTokens) {\n if (queryTokens.has(tk)) { score += 3; matched.add(trigger); }\n }\n }\n }\n\n // Tags: medium weight\n for (const tag of t.tags) {\n if (queryTokens.has(tag.toLowerCase())) { score += 2; matched.add(tag); }\n }\n\n // Name tokens: weight 4 each (a name match is strong signal)\n for (const tk of tokenize(t.name)) {\n if (queryTokens.has(tk)) { score += 4; matched.add(t.name); }\n }\n\n // Description: weight 1 (last-resort match)\n for (const tk of tokenize(t.description)) {\n if (queryTokens.has(tk)) { score += 1; }\n }\n\n // Category: weight 1\n if (queryTokens.has(t.category.toLowerCase())) { score += 1; matched.add(`category:${t.category}`); }\n\n return { template: t, score, matched: Array.from(matched) };\n}\n\nexport function searchGallery(query: string, limit = 5): ScoredTemplate[] {\n const map = loadTemplates();\n const queryTokens = new Set(tokenize(query));\n if (queryTokens.size === 0) return [];\n const scored: ScoredTemplate[] = [];\n for (const t of map.values()) {\n const s = scoreTemplate(t, queryTokens);\n if (s.score > 0) scored.push(s);\n }\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, limit);\n}\n\nexport function getTemplate(id: string, fill?: Record<string, string>): WidgetTemplate | null {\n const t = loadTemplates().get(id);\n if (!t) return null;\n if (!fill || Object.keys(fill).length === 0) return t;\n let source = t.source;\n for (const [key, value] of Object.entries(fill)) {\n // Replace both REPLACE_WITH_X and {{X}} forms; agent may use either.\n // Escape backslash, single-quote, AND backtick (kimi review: backticks\n // could break out of template literals if a value contained one).\n const safe = String(value)\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/'/g, \"\\\\'\")\n .replace(/`/g, '\\\\`');\n source = source.split(`REPLACE_WITH_${key}`).join(safe);\n source = source.split(`{{${key}}}`).join(safe);\n }\n return { ...t, source };\n}\n\nexport function listTemplates(category?: string): Array<Omit<WidgetTemplate, 'source'>> {\n const map = loadTemplates();\n const out: Array<Omit<WidgetTemplate, 'source'>> = [];\n for (const t of map.values()) {\n if (category && t.category !== category) continue;\n // Strip `source` so list calls stay token-light. Agent calls gallery_get to fetch source.\n const { source: _omit, ...rest } = t;\n out.push(rest);\n }\n out.sort((a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name));\n return out;\n}\n\nexport function listCategories(): Array<{ category: string; count: number }> {\n const map = loadTemplates();\n const counts = new Map<string, number>();\n for (const t of map.values()) {\n counts.set(t.category, (counts.get(t.category) ?? 0) + 1);\n }\n return Array.from(counts.entries())\n .map(([category, count]) => ({ category, count }))\n .sort((a, b) => a.category.localeCompare(b.category));\n}\n\nexport function registerWidgetGallerySkill(): void {\n // Eager-load so the count appears in startup logs.\n loadTemplates();\n\n registerSkill(\n {\n name: 'widget_gallery',\n description: 'Curated library of pre-built canvas widget templates (timers, trackers, dashboards, automations, smart-home controls, agent-employee panels, software-builder skeletons). The canvas chat agent should ALWAYS call gallery_search FIRST when the user asks for a widget. Only generate from scratch when no template matches.',\n version: '1.0.0',\n source: 'bundled',\n enabled: true,\n },\n {\n name: 'gallery_search',\n description: `Search the 109-template widget gallery for the closest matches to the user's intent. Returns ranked results with id + score; pass the top id to gallery_get to retrieve the source. THIS IS THE FIRST THING YOU CALL when the user wants any widget — only fall back to generating from scratch (_____react) when no result scores well.\n\nUSE WHEN: \"build me a X widget\" / \"I want a Y panel\" / \"make me a Z dashboard\" / \"add a calculator\" / \"spawn an SDR agent\" — any request for a UI element on the canvas. Also when the user says \"do you have a template for X?\"\n\nDO NOT USE FOR:\n- Listing every template → use gallery_list.\n- Searching the marketplace (third-party skills) → use a different tool (this gallery is bundled-only).\n- Searching skills (tools the agent can call) → use tool_search.\n\nParameters:\n- query (string, required) — the user's intent. Best results from phrases (\"stock tracker for AAPL\"), worst from single words (\"widget\"). Include the SUBJECT (AAPL, the user's symbol/topic) if known — that biases scoring.\n- limit (number, optional) — default 5; max 20.\n\nReturns: { results: Array<{ id, name, category, description, score, matched: string[] }> }. score >= 10 means a strong trigger-phrase match — use that template confidently. Score < 3 → no good match, generate from scratch.\n\nErrors: this tool can't really error. Empty results means generate from scratch.\n\nALWAYS show the top match's name + category to the user before calling gallery_get, so they can correct you if you picked the wrong one (\"I'm using the 'Stock Tracker' template — want a different one?\").`,\n parameters: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'User intent — phrase, keyword, or full request. Example: \"stock tracker for AAPL\", \"pomodoro\", \"control my smart lights\".' },\n limit: { type: 'number', description: 'Max results (default 5).' },\n },\n required: ['query'],\n },\n execute: async (args: Record<string, unknown>) => {\n const query = String(args.query ?? '');\n const limit = typeof args.limit === 'number' ? args.limit : undefined;\n const results = searchGallery(query, limit ?? 5);\n if (results.length === 0) {\n return JSON.stringify({\n query,\n results: [],\n hint: 'No matches. Generate a custom widget from scratch.',\n });\n }\n return JSON.stringify({\n query,\n results: results.map(r => ({\n id: r.template.id,\n name: r.template.name,\n category: r.template.category,\n description: r.template.description,\n defaultSize: r.template.defaultSize,\n placeholders: r.template.placeholders ?? [],\n score: r.score,\n matched: r.matched,\n })),\n hint: 'Pick the best match, call gallery_get with its id and a `fill` map of placeholder values from the user request.',\n });\n },\n },\n );\n\n registerSkill(\n {\n name: 'widget_gallery_get',\n description: 'Fetch the full source of a gallery template, with placeholders replaced.',\n version: '1.0.0',\n source: 'bundled',\n enabled: true,\n },\n {\n name: 'gallery_get',\n description: `Fetch a single widget template from the gallery by id, with REPLACE_WITH_X placeholders substituted. Use it to INSPECT a template; to actually place the widget, call create_widget — NOT a _____react fence.\n\nUSE WHEN: you just got a template id from gallery_search and need to inspect/verify its source. ALWAYS call gallery_search first to get the id — never guess a template name.\n\nAFTER THIS: call create_widget({ template: \"<id>\", fill: {...} }) to place it on the user's canvas. create_widget reports whether the canvas actually received it — a pasted _____react fence cannot confirm delivery and creates duplicates. Never claim a widget is \"on the canvas\" unless create_widget confirmed delivery.\n\nDO NOT USE FOR:\n- Browsing what's available → use gallery_search (returns ranked matches with descriptions).\n- Listing every template → use gallery_list (full catalogue).\n- Generating a brand-new widget that's not in the catalogue → call create_widget with raw source.\n\nParameters:\n- id (string, required) — exact template id from gallery_search results.\n- fill (object, optional) — placeholder substitutions. Keys are the placeholder name WITHOUT the REPLACE_WITH_ prefix (so { \"SYMBOL\": \"AAPL\" } substitutes REPLACE_WITH_SYMBOL). Values are escaped automatically for backslash, single quote, and backtick.\n\nReturns: { source: string, size: { width, height }, category, displayName, next }. Follow the \\`next\\` instruction.\n\nErrors:\n- \"Template not found: <id>\" — the id is wrong (typo or stale). Re-run gallery_search to get a fresh id.\n- Placeholders left unfilled — they appear as literal REPLACE_WITH_X strings in source. Catch this before emitting; either provide fill values or substitute them yourself.`,\n parameters: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Template id from gallery_search results.' },\n fill: {\n type: 'object',\n description: 'Placeholder values (key = placeholder name without REPLACE_WITH_ prefix, value = string to insert). Example: {\"SYMBOL\": \"AAPL\"} → REPLACE_WITH_SYMBOL becomes \"AAPL\".',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['id'],\n },\n execute: async (args: Record<string, unknown>) => {\n const id = String(args.id ?? '');\n const fill = (args.fill && typeof args.fill === 'object') ? args.fill as Record<string, string> : undefined;\n const t = getTemplate(id, fill);\n if (!t) return JSON.stringify({ error: `Template not found: ${id}` });\n // v5.4.2: Prepend size metadata as a leading comment so the canvas\n // frontend can extract defaultSize from the source (Bug #3 fix).\n // The frontend parses `// __WIDGET_META__ w=6 h=6` on _____react gate.\n const w = t.defaultSize?.w ?? 4;\n const h = t.defaultSize?.h ?? 4;\n const metaComment = `// __WIDGET_META__ w=${w} h=${h}\\n`;\n const sourceWithMeta = metaComment + (t.source || '');\n return JSON.stringify({\n id: t.id,\n name: t.name,\n category: t.category,\n defaultSize: t.defaultSize,\n source: sourceWithMeta,\n placeholders: t.placeholders ?? [],\n // v7.0 honesty fix: models were pasting the source into a\n // _____react fence and claiming \"it's on your canvas\" with\n // no delivery confirmation. The result itself now routes\n // them to the verifiable path.\n next: `Call create_widget({ template: \"${t.id}\"${fill ? `, fill: ${JSON.stringify(fill)}` : ''} }) NOW to place it — do NOT paste a _____react fence (it cannot confirm delivery and duplicates). Only claim the widget is on the canvas if create_widget confirms delivery.`,\n });\n },\n },\n );\n\n registerSkill(\n {\n name: 'widget_gallery_list',\n description: 'List all gallery templates (optionally filtered by category).',\n version: '1.0.0',\n source: 'bundled',\n enabled: true,\n },\n {\n name: 'gallery_list',\n description: 'List all widget gallery templates. Filter by category. Returns metadata (id, name, category, description, tags, triggers) without source — call gallery_get to fetch source.',\n parameters: {\n type: 'object',\n properties: {\n category: { type: 'string', description: 'Optional category filter (e.g. \"finance\", \"productivity\", \"automation\", \"smart-home\", \"agents\").' },\n },\n },\n execute: async (args: Record<string, unknown>) => {\n const category = typeof args.category === 'string' ? args.category : undefined;\n const items = listTemplates(category);\n return JSON.stringify({\n count: items.length,\n categories: listCategories(),\n templates: items,\n });\n },\n },\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { existsSync, readdirSync, readFileSync } from "fs";
3
- import { join } from "path";
3
+ import { join, dirname } from "path";
4
+ import { fileURLToPath } from "url";
4
5
  import { TITAN_HOME } from "../utils/constants.js";
5
6
  import logger from "../utils/logger.js";
6
7
  const COMPONENT = "FrontmatterSkills";
8
+ const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
7
9
  const SKILL_DIRS = [
8
10
  join(process.cwd(), "src", "skills", "frontmatter"),
11
+ // Bundled skill library shipped in the npm package (includes the
12
+ // ECC-attributed software-craft skills) — package-relative so it resolves
13
+ // for installed users, not just an in-repo run.
14
+ join(PKG_ROOT, "assets", "agent-skills"),
9
15
  join(TITAN_HOME, "skills")
10
16
  ];
11
17
  function parseFrontmatter(raw) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/skills/frontmatterLoader.ts"],"sourcesContent":["/**\n * TITAN — Skill Frontmatter Loader\n *\n * Discovers SKILL.md files with YAML frontmatter + markdown body\n * and registers them as dynamic context-injection skills.\n *\n * Inspired by space-agent's skill system and Hermes Agent's skill library.\n */\n\nimport { existsSync, readdirSync, readFileSync, type Dirent } from 'fs';\nimport { join } from 'path';\nimport { TITAN_HOME } from '../utils/constants.js';\nimport logger from '../utils/logger.js';\n\nconst COMPONENT = 'FrontmatterSkills';\n\nexport interface FrontmatterSkill {\n name: string;\n version: string;\n description: string;\n author?: string;\n tags: string[];\n content: string;\n sourcePath: string;\n /**\n * v6.0.5 — Space Agent parity. When `auto: true` is set in the\n * frontmatter (or `placement: system`), the skill's body is injected\n * directly into the agent's system prompt every turn instead of\n * waiting to be invoked as a tool. Use for behavior overlays + standing\n * preferences. Inspired by Space Agent's auto-loaded memory skill.\n */\n auto: boolean;\n}\n\nconst SKILL_DIRS = [\n join(process.cwd(), 'src', 'skills', 'frontmatter'),\n join(TITAN_HOME, 'skills'),\n];\n\nfunction parseFrontmatter(raw: string): { frontmatter: Record<string, unknown>; body: string } {\n const match = raw.match(/^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/);\n if (!match) {\n return { frontmatter: {}, body: raw.trim() };\n }\n\n const yamlBlock = match[1];\n const body = match[2].trim();\n\n // Simple YAML parser — only handles key: value and key: [a, b, c]\n const frontmatter: Record<string, unknown> = {};\n for (const line of yamlBlock.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.slice(0, colonIdx).trim();\n let value: unknown = trimmed.slice(colonIdx + 1).trim();\n\n // Array: [a, b, c]\n if (typeof value === 'string' && value.startsWith('[') && value.endsWith(']')) {\n value = value\n .slice(1, -1)\n .split(',')\n .map(s => s.trim().replace(/^[\"']|[\"']$/g, ''))\n .filter(Boolean);\n } else if (typeof value === 'string') {\n value = value.replace(/^[\"']|[\"']$/g, '');\n }\n\n frontmatter[key] = value;\n }\n\n return { frontmatter, body };\n}\n\nfunction scanSkillFiles(dir: string): string[] {\n if (!existsSync(dir)) return [];\n\n const results: string[] = [];\n const walk = (d: string): void => {\n let entries: Dirent[] = [];\n try { entries = readdirSync(d, { withFileTypes: true }) as Dirent[]; } catch { return; }\n for (const entry of entries) {\n const full = join(d, entry.name);\n if (entry.isDirectory()) {\n walk(full);\n } else if (entry.name.toLowerCase().endsWith('.skill.md')) {\n results.push(full);\n }\n }\n };\n\n walk(dir);\n return results;\n}\n\nexport function loadFrontmatterSkills(): FrontmatterSkill[] {\n const skills: FrontmatterSkill[] = [];\n\n for (const dir of SKILL_DIRS) {\n const files = scanSkillFiles(dir);\n for (const path of files) {\n try {\n const raw = readFileSync(path, 'utf-8');\n const { frontmatter, body } = parseFrontmatter(raw);\n\n const name = String(frontmatter.name || '');\n if (!name) {\n logger.warn(COMPONENT, `Skipped ${path}: missing 'name' in frontmatter`);\n continue;\n }\n\n const tags = Array.isArray(frontmatter.tags)\n ? frontmatter.tags.map(String)\n : String(frontmatter.tags || '').split(',').map(s => s.trim()).filter(Boolean);\n\n const auto =\n frontmatter.auto === true ||\n String(frontmatter.auto).toLowerCase() === 'true' ||\n String(frontmatter.placement || '').toLowerCase() === 'system';\n\n skills.push({\n name,\n version: String(frontmatter.version || '1.0.0'),\n description: String(frontmatter.description || ''),\n author: String(frontmatter.author || ''),\n tags,\n content: body,\n sourcePath: path,\n auto,\n });\n } catch (e) {\n logger.warn(COMPONENT, `Failed to parse ${path}: ${(e as Error).message}`);\n }\n }\n }\n\n if (skills.length > 0) {\n logger.info(COMPONENT, `Loaded ${skills.length} frontmatter skill(s)`);\n }\n\n return skills;\n}\n\n/** Convert frontmatter skills into TITAN tool handlers ready for registration */\nexport function getFrontmatterToolHandlers(): Array<{ name: string; description: string; handler: { name: string; description: string; parameters: { type: 'object'; properties: Record<string, unknown>; required: string[] }; execute: (args: Record<string, unknown>) => Promise<string> } }> {\n const skills = loadFrontmatterSkills();\n return skills.map(skill => ({\n name: skill.name,\n description: skill.description || `Frontmatter skill: ${skill.name}`,\n handler: {\n name: skill.name,\n description: `${skill.description}\\n\\nTags: ${skill.tags.join(', ') || 'none'}${skill.author ? ` | Author: ${skill.author}` : ''}\\n\\n${skill.content.slice(0, 400)}...`,\n parameters: {\n type: 'object' as const,\n properties: {},\n required: [],\n },\n execute: async (_args: Record<string, unknown>) => {\n return `## ${skill.name} (v${skill.version})\\n\\n${skill.content}`;\n },\n },\n }));\n}\n\n/**\n * v6.0.5 — Render the auto-injected skills + a one-line catalog of the\n * lazy-loaded ones for the agent's system prompt.\n *\n * Auto skills get their FULL body injected. Lazy skills get one-line\n * name + description so the agent knows what's available without bloating\n * the prompt — it can call them as tools if it needs the body.\n *\n * Empty string when no SKILL.md files exist. Capped at ~6KB total so a\n * runaway skills directory can't blow the prompt budget.\n */\nconst SKILL_PROMPT_CAP = 6000;\n\nexport function renderSkillsForPrompt(): string {\n const skills = loadFrontmatterSkills();\n if (skills.length === 0) return '';\n\n const auto = skills.filter(s => s.auto);\n const lazy = skills.filter(s => !s.auto);\n const parts: string[] = [];\n\n if (auto.length > 0) {\n parts.push('## Skills you\\'ve authored (auto-injected)');\n let used = 0;\n for (const s of auto) {\n const section = `### ${s.name}\\n${s.content.trim()}\\n`;\n if (used + section.length > SKILL_PROMPT_CAP) {\n parts.push(`(${auto.length - parts.length + 1} more auto skills truncated to fit prompt budget)`);\n break;\n }\n parts.push(section);\n used += section.length;\n }\n }\n\n if (lazy.length > 0) {\n parts.push('## Skills available on demand');\n parts.push('Call them like any other tool. Each runs its body as a markdown reference (helpers + examples).');\n for (const s of lazy.slice(0, 30)) {\n const desc = s.description ? `: ${s.description.slice(0, 120)}` : '';\n parts.push(`- \\`${s.name}\\`${desc}`);\n }\n }\n\n parts.push('');\n parts.push('You can author a new skill at any time by writing `~/.titan/skills/<name>.skill.md` with `--- name: <id>\\\\ndescription: <text>\\\\nauto: true|false\\\\n--- <body>`. Auto skills inject every turn; lazy skills are tool-callable.');\n\n return '\\n' + parts.join('\\n') + '\\n';\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/skills/frontmatterLoader.ts"],"sourcesContent":["/**\n * TITAN — Skill Frontmatter Loader\n *\n * Discovers SKILL.md files with YAML frontmatter + markdown body\n * and registers them as dynamic context-injection skills.\n *\n * Inspired by space-agent's skill system and Hermes Agent's skill library.\n */\n\nimport { existsSync, readdirSync, readFileSync, type Dirent } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { TITAN_HOME } from '../utils/constants.js';\nimport logger from '../utils/logger.js';\n\nconst COMPONENT = 'FrontmatterSkills';\n\n// Package root, resolved relative to THIS module (works for both `tsx src/` in\n// dev and a global npm install) — not process.cwd(), which is the user's shell\n// dir. dist/skills/ and src/skills/ are both two levels under the package root.\nconst PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..');\n\nexport interface FrontmatterSkill {\n name: string;\n version: string;\n description: string;\n author?: string;\n tags: string[];\n content: string;\n sourcePath: string;\n /**\n * v6.0.5 — Space Agent parity. When `auto: true` is set in the\n * frontmatter (or `placement: system`), the skill's body is injected\n * directly into the agent's system prompt every turn instead of\n * waiting to be invoked as a tool. Use for behavior overlays + standing\n * preferences. Inspired by Space Agent's auto-loaded memory skill.\n */\n auto: boolean;\n}\n\nconst SKILL_DIRS = [\n join(process.cwd(), 'src', 'skills', 'frontmatter'),\n // Bundled skill library shipped in the npm package (includes the\n // ECC-attributed software-craft skills) — package-relative so it resolves\n // for installed users, not just an in-repo run.\n join(PKG_ROOT, 'assets', 'agent-skills'),\n join(TITAN_HOME, 'skills'),\n];\n\nfunction parseFrontmatter(raw: string): { frontmatter: Record<string, unknown>; body: string } {\n const match = raw.match(/^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/);\n if (!match) {\n return { frontmatter: {}, body: raw.trim() };\n }\n\n const yamlBlock = match[1];\n const body = match[2].trim();\n\n // Simple YAML parser — only handles key: value and key: [a, b, c]\n const frontmatter: Record<string, unknown> = {};\n for (const line of yamlBlock.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.slice(0, colonIdx).trim();\n let value: unknown = trimmed.slice(colonIdx + 1).trim();\n\n // Array: [a, b, c]\n if (typeof value === 'string' && value.startsWith('[') && value.endsWith(']')) {\n value = value\n .slice(1, -1)\n .split(',')\n .map(s => s.trim().replace(/^[\"']|[\"']$/g, ''))\n .filter(Boolean);\n } else if (typeof value === 'string') {\n value = value.replace(/^[\"']|[\"']$/g, '');\n }\n\n frontmatter[key] = value;\n }\n\n return { frontmatter, body };\n}\n\nfunction scanSkillFiles(dir: string): string[] {\n if (!existsSync(dir)) return [];\n\n const results: string[] = [];\n const walk = (d: string): void => {\n let entries: Dirent[] = [];\n try { entries = readdirSync(d, { withFileTypes: true }) as Dirent[]; } catch { return; }\n for (const entry of entries) {\n const full = join(d, entry.name);\n if (entry.isDirectory()) {\n walk(full);\n } else if (entry.name.toLowerCase().endsWith('.skill.md')) {\n results.push(full);\n }\n }\n };\n\n walk(dir);\n return results;\n}\n\nexport function loadFrontmatterSkills(): FrontmatterSkill[] {\n const skills: FrontmatterSkill[] = [];\n\n for (const dir of SKILL_DIRS) {\n const files = scanSkillFiles(dir);\n for (const path of files) {\n try {\n const raw = readFileSync(path, 'utf-8');\n const { frontmatter, body } = parseFrontmatter(raw);\n\n const name = String(frontmatter.name || '');\n if (!name) {\n logger.warn(COMPONENT, `Skipped ${path}: missing 'name' in frontmatter`);\n continue;\n }\n\n const tags = Array.isArray(frontmatter.tags)\n ? frontmatter.tags.map(String)\n : String(frontmatter.tags || '').split(',').map(s => s.trim()).filter(Boolean);\n\n const auto =\n frontmatter.auto === true ||\n String(frontmatter.auto).toLowerCase() === 'true' ||\n String(frontmatter.placement || '').toLowerCase() === 'system';\n\n skills.push({\n name,\n version: String(frontmatter.version || '1.0.0'),\n description: String(frontmatter.description || ''),\n author: String(frontmatter.author || ''),\n tags,\n content: body,\n sourcePath: path,\n auto,\n });\n } catch (e) {\n logger.warn(COMPONENT, `Failed to parse ${path}: ${(e as Error).message}`);\n }\n }\n }\n\n if (skills.length > 0) {\n logger.info(COMPONENT, `Loaded ${skills.length} frontmatter skill(s)`);\n }\n\n return skills;\n}\n\n/** Convert frontmatter skills into TITAN tool handlers ready for registration */\nexport function getFrontmatterToolHandlers(): Array<{ name: string; description: string; handler: { name: string; description: string; parameters: { type: 'object'; properties: Record<string, unknown>; required: string[] }; execute: (args: Record<string, unknown>) => Promise<string> } }> {\n const skills = loadFrontmatterSkills();\n return skills.map(skill => ({\n name: skill.name,\n description: skill.description || `Frontmatter skill: ${skill.name}`,\n handler: {\n name: skill.name,\n description: `${skill.description}\\n\\nTags: ${skill.tags.join(', ') || 'none'}${skill.author ? ` | Author: ${skill.author}` : ''}\\n\\n${skill.content.slice(0, 400)}...`,\n parameters: {\n type: 'object' as const,\n properties: {},\n required: [],\n },\n execute: async (_args: Record<string, unknown>) => {\n return `## ${skill.name} (v${skill.version})\\n\\n${skill.content}`;\n },\n },\n }));\n}\n\n/**\n * v6.0.5 — Render the auto-injected skills + a one-line catalog of the\n * lazy-loaded ones for the agent's system prompt.\n *\n * Auto skills get their FULL body injected. Lazy skills get one-line\n * name + description so the agent knows what's available without bloating\n * the prompt — it can call them as tools if it needs the body.\n *\n * Empty string when no SKILL.md files exist. Capped at ~6KB total so a\n * runaway skills directory can't blow the prompt budget.\n */\nconst SKILL_PROMPT_CAP = 6000;\n\nexport function renderSkillsForPrompt(): string {\n const skills = loadFrontmatterSkills();\n if (skills.length === 0) return '';\n\n const auto = skills.filter(s => s.auto);\n const lazy = skills.filter(s => !s.auto);\n const parts: string[] = [];\n\n if (auto.length > 0) {\n parts.push('## Skills you\\'ve authored (auto-injected)');\n let used = 0;\n for (const s of auto) {\n const section = `### ${s.name}\\n${s.content.trim()}\\n`;\n if (used + section.length > SKILL_PROMPT_CAP) {\n parts.push(`(${auto.length - parts.length + 1} more auto skills truncated to fit prompt budget)`);\n break;\n }\n parts.push(section);\n used += section.length;\n }\n }\n\n if (lazy.length > 0) {\n parts.push('## Skills available on demand');\n parts.push('Call them like any other tool. Each runs its body as a markdown reference (helpers + examples).');\n for (const s of lazy.slice(0, 30)) {\n const desc = s.description ? `: ${s.description.slice(0, 120)}` : '';\n parts.push(`- \\`${s.name}\\`${desc}`);\n }\n }\n\n parts.push('');\n parts.push('You can author a new skill at any time by writing `~/.titan/skills/<name>.skill.md` with `--- name: <id>\\\\ndescription: <text>\\\\nauto: true|false\\\\n--- <body>`. Auto skills inject every turn; lazy skills are tool-callable.');\n\n return '\\n' + parts.join('\\n') + '\\n';\n}\n"],"mappings":"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","names":[]}
@@ -224,6 +224,12 @@ async function initBuiltinSkills() {
224
224
  const { registerPhoneCallSkill } = await import("./builtin/phone_call.js");
225
225
  const { registerVRAMSkills } = await import("./builtin/vram.js");
226
226
  const { registerSecurityScanSkill } = await import("./builtin/security_scan.js");
227
+ const { registerConfigAuditSkill } = await import("./builtin/config_audit.js");
228
+ const { registerSpecSkill } = await import("./builtin/spec.js");
229
+ const { registerMemoryMapSkill } = await import("./builtin/memory_map.js");
230
+ const { registerCodebaseExploreSkill } = await import("./builtin/codebase_explore.js");
231
+ const { registerReminderSkill } = await import("./builtin/reminders.js");
232
+ const { registerDelegateAgentSkill } = await import("./builtin/delegate_agent.js");
227
233
  const { registerChangelogGenSkill } = await import("./builtin/changelog_gen.js");
228
234
  const { registerJiraLinearSkill } = await import("./builtin/jira_linear.js");
229
235
  const { registerAuditTrailSkill } = await import("./builtin/audit_trail.js");
@@ -322,6 +328,12 @@ async function initBuiltinSkills() {
322
328
  ["phone_call", registerPhoneCallSkill],
323
329
  ["vram", registerVRAMSkills],
324
330
  ["security_scan", registerSecurityScanSkill],
331
+ ["config_audit", registerConfigAuditSkill],
332
+ ["spec", registerSpecSkill],
333
+ ["memory_map", registerMemoryMapSkill],
334
+ ["codebase_explore", registerCodebaseExploreSkill],
335
+ ["reminder", registerReminderSkill],
336
+ ["delegate_agent", registerDelegateAgentSkill],
325
337
  ["changelog_gen", registerChangelogGenSkill],
326
338
  ["jira_linear", registerJiraLinearSkill],
327
339
  ["audit_trail", registerAuditTrailSkill],
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/skills/registry.ts"],"sourcesContent":["/**\n * TITAN — Skills Registry\n * Discovers, loads, and manages skills from bundled, workspace, and marketplace sources.\n */\nimport { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport vm from 'vm';\nimport { TITAN_HOME, TITAN_SKILLS_DIR } from '../utils/constants.js';\nimport { registerTool, type ToolHandler } from '../agent/toolRunner.js';\nimport { mkdirIfNotExists } from '../utils/helpers.js';\nimport logger from '../utils/logger.js';\nimport { loadConfig } from '../config/config.js';\n\nconst COMPONENT = 'Skills';\nconst DISABLED_SKILLS_PATH = join(TITAN_HOME, 'disabled-skills.json');\n\nexport interface SkillMeta {\n name: string;\n description: string;\n version: string;\n author?: string;\n source: 'bundled' | 'workspace' | 'marketplace' | 'frontmatter';\n enabled: boolean;\n}\n\nconst registeredSkills: Map<string, SkillMeta> = new Map();\n\n/** Maps skill name → tool names belonging to that skill */\nconst skillToolMap: Map<string, Set<string>> = new Map();\n\n/** Register a built-in skill (tool handler + metadata) */\nexport function registerSkill(meta: SkillMeta, handler: ToolHandler): void {\n registeredSkills.set(meta.name, meta);\n // Track which tools belong to this skill\n if (!skillToolMap.has(meta.name)) {\n skillToolMap.set(meta.name, new Set());\n }\n skillToolMap.get(meta.name)!.add(handler.name);\n registerTool(handler);\n logger.debug(COMPONENT, `Registered skill: ${meta.name} (${meta.source})`);\n}\n\n/** Get all registered skills (with persisted enabled/disabled state applied) */\nexport function getSkills(): SkillMeta[] {\n const disabled = loadDisabledSkills();\n return Array.from(registeredSkills.values()).map(s => ({\n ...s,\n enabled: !disabled.includes(s.name),\n }));\n}\n\n/** Get a skill by name */\nexport function getSkill(name: string): SkillMeta | undefined {\n return registeredSkills.get(name);\n}\n\n/** Get tool names belonging to a skill */\nexport function getSkillTools(skillName: string): string[] {\n return Array.from(skillToolMap.get(skillName) || []);\n}\n\n/** Check if a skill is enabled */\nexport function isSkillEnabled(skillName: string): boolean {\n return !loadDisabledSkills().includes(skillName);\n}\n\n/** Check if a specific tool's parent skill is enabled */\nexport function isToolSkillEnabled(toolName: string): boolean {\n for (const [skillName, tools] of skillToolMap.entries()) {\n if (tools.has(toolName)) {\n return isSkillEnabled(skillName);\n }\n }\n return true; // Tools not belonging to any skill are always enabled\n}\n\n/** Toggle a skill on/off. Returns the new enabled state. */\nexport function toggleSkill(skillName: string): boolean {\n const skill = registeredSkills.get(skillName);\n if (!skill) {\n throw new Error(`Skill \"${skillName}\" not found`);\n }\n\n const disabled = loadDisabledSkills();\n const idx = disabled.indexOf(skillName);\n let nowEnabled: boolean;\n\n if (idx >= 0) {\n disabled.splice(idx, 1);\n nowEnabled = true;\n } else {\n disabled.push(skillName);\n nowEnabled = false;\n }\n\n saveDisabledSkills(disabled);\n logger.info(COMPONENT, `Skill \"${skillName}\" ${nowEnabled ? 'enabled' : 'disabled'}`);\n return nowEnabled;\n}\n\n/** Set a skill's enabled state explicitly */\nexport function setSkillEnabled(skillName: string, enabled: boolean): void {\n const skill = registeredSkills.get(skillName);\n if (!skill) {\n throw new Error(`Skill \"${skillName}\" not found`);\n }\n\n const disabled = loadDisabledSkills();\n const idx = disabled.indexOf(skillName);\n\n if (enabled && idx >= 0) {\n disabled.splice(idx, 1);\n } else if (!enabled && idx < 0) {\n disabled.push(skillName);\n }\n\n saveDisabledSkills(disabled);\n}\n\n// ── Disabled-skills disk cache (30s TTL) ─────────────────────────\nlet _disabledSkillsCache: string[] | null = null;\nlet _disabledSkillsCacheAt = 0;\nconst DISABLED_SKILLS_CACHE_TTL_MS = 30_000;\n\n/** Load disabled skills list from disk (cached for 30 s to avoid ~7 k reads/req) */\nfunction loadDisabledSkills(): string[] {\n const now = Date.now();\n if (_disabledSkillsCache !== null && now - _disabledSkillsCacheAt < DISABLED_SKILLS_CACHE_TTL_MS) {\n return _disabledSkillsCache;\n }\n let result: string[] = [];\n try {\n if (existsSync(DISABLED_SKILLS_PATH)) {\n result = JSON.parse(readFileSync(DISABLED_SKILLS_PATH, 'utf-8')) as string[];\n }\n } catch {\n // Corrupt file — treat as empty\n }\n _disabledSkillsCache = result;\n _disabledSkillsCacheAt = now;\n return result;\n}\n\n/** Save disabled skills list to disk and invalidate the in-memory cache */\nfunction saveDisabledSkills(disabled: string[]): void {\n _disabledSkillsCache = null; // Invalidate cache on write\n try {\n const dir = dirname(DISABLED_SKILLS_PATH);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(DISABLED_SKILLS_PATH, JSON.stringify(disabled, null, 2), 'utf-8');\n } catch (e) {\n logger.warn(COMPONENT, `Failed to save disabled skills: ${(e as Error).message}`);\n }\n}\n\n/** Discover workspace skills from ~/.titan/workspace/skills/ */\nexport function discoverWorkspaceSkills(): SkillMeta[] {\n mkdirIfNotExists(TITAN_SKILLS_DIR);\n const discovered: SkillMeta[] = [];\n\n if (!existsSync(TITAN_SKILLS_DIR)) return discovered;\n\n const entries = readdirSync(TITAN_SKILLS_DIR, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillDir = join(TITAN_SKILLS_DIR, entry.name);\n const skillMdPath = join(skillDir, 'SKILL.md');\n\n if (!existsSync(skillMdPath)) continue;\n\n try {\n const content = readFileSync(skillMdPath, 'utf-8');\n const meta = parseSkillMd(content, entry.name);\n if (meta) {\n discovered.push({ ...meta, source: 'workspace', enabled: true });\n }\n } catch (error) {\n logger.warn(COMPONENT, `Failed to load skill ${entry.name}: ${(error as Error).message}`);\n }\n }\n\n logger.info(COMPONENT, `Discovered ${discovered.length} workspace skills`);\n return discovered;\n}\n\n/** Parse SKILL.md frontmatter to extract metadata */\nfunction parseSkillMd(content: string, fallbackName: string): Omit<SkillMeta, 'source' | 'enabled'> | null {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!frontmatterMatch) {\n return {\n name: fallbackName,\n description: content.split('\\n')[0] || 'No description',\n version: '1.0.0',\n };\n }\n\n const frontmatter = frontmatterMatch[1];\n const name = frontmatter.match(/name:\\s*(.+)/)?.[1]?.trim() || fallbackName;\n const description = frontmatter.match(/description:\\s*(.+)/)?.[1]?.trim() || 'No description';\n const version = frontmatter.match(/version:\\s*(.+)/)?.[1]?.trim() || '1.0.0';\n const author = frontmatter.match(/author:\\s*(.+)/)?.[1]?.trim();\n\n return { name, description, version, author };\n}\n\n/** Initialize all built-in skills */\nexport async function initBuiltinSkills(): Promise<void> {\n logger.info(COMPONENT, 'Loading built-in skills...');\n\n // beta.15 (Phase D.3) — register the canonical tool contracts so\n // the tool runner can validate args BEFORE skills' execute()\n // runs. Done FIRST so contracts are available the moment a skill\n // is registered (in case any skill registration triggers a tool\n // call as a side-effect, which shouldn't happen but defends\n // against future bootstrap shuffles).\n try {\n const { registerCanonicalContracts } = await import('./builtin/contracts.js');\n registerCanonicalContracts();\n logger.debug(COMPONENT, 'Registered canonical tool contracts');\n } catch (err) {\n logger.warn(COMPONENT, `Failed to register canonical contracts: ${(err as Error).message}`);\n }\n\n // Import and register built-in skills\n const { registerShellSkill } = await import('./builtin/shell.js');\n const { registerFilesystemSkill } = await import('./builtin/filesystem.js');\n const { registerWebSearchSkill } = await import('./builtin/web_search.js');\n const { registerCronSkill } = await import('./builtin/cron.js');\n const { registerWebhookSkill } = await import('./builtin/webhook.js');\n const { registerMemorySkill } = await import('./builtin/memory_skill.js');\n const { registerBrowserSkill } = await import('./builtin/browser.js');\n const { registerSessionsSkill } = await import('./builtin/sessions.js');\n const { registerProcessSkill } = await import('./builtin/process.js');\n const { registerWebFetchSkill } = await import('./builtin/web_fetch.js');\n const { registerDownloadImageSkill } = await import('./builtin/download_image.js');\n const { registerApplyPatchSkill } = await import('./builtin/apply_patch.js');\n const { registerAutoGenerateSkill } = await import('./builtin/auto_generate.js');\n const { registerVisionSkill } = await import('./builtin/vision.js');\n const { registerVoiceSkills } = await import('./builtin/voice.js');\n const { registerMemoryGraphSkill } = await import('./builtin/memory_graph.js');\n const { initWebBrowserTool } = await import('./builtin/web_browser.js');\n const { registerGitHubSkill } = await import('./builtin/github.js');\n const { registerEmailSkill } = await import('./builtin/email.js');\n const { registerComputerUseSkill } = await import('./builtin/computer_use.js');\n const { registerImageGenSkill } = await import('./builtin/image_gen.js');\n const { registerPdfSkill } = await import('./builtin/pdf.js');\n const { registerCalendarSkill } = await import('./builtin/calendar.js');\n const { registerSmartHomeSkill } = await import('./builtin/smart_home.js');\n const { registerDataAnalysisSkill } = await import('./builtin/data_analysis.js');\n const { registerSkyvernSkill } = await import('./builtin/skyvern.js');\n const { registerWebBrowseLlmSkill } = await import('./builtin/web_browse_llm.js');\n const { registerIncomeTrackerSkill } = await import('./builtin/income_tracker.js');\n const { registerFreelanceMonitorSkill } = await import('./builtin/freelance_monitor.js');\n const { registerContentPublisherSkill } = await import('./builtin/content_publisher.js');\n const { registerLeadScorerSkill } = await import('./builtin/lead_scorer.js');\n const { registerHunterSkill } = await import('./builtin/hunter.js');\n const { registerCodeExecSkill } = await import('./builtin/code_exec.js');\n const { registerExecuteCodeSkill } = await import('./builtin/executeCode.js');\n const { registerWeatherSkill } = await import('./builtin/weather.js');\n const { registerGoalsSkill } = await import('./builtin/goals.js');\n const { registerXPosterSkill } = await import('./builtin/x_poster.js');\n const { initModelSwitchTool } = await import('./builtin/model_switch.js');\n const { registerRagSkill } = await import('./builtin/rag.js');\n const { registerDeepResearchSkill } = await import('./builtin/deep_research.js');\n const { registerSystemInfoSkill } = await import('./builtin/system_info.js');\n const { registerCurrentModelSkill } = await import('./builtin/current_model.js');\n const { registerPersonaManagerSkill } = await import('./builtin/persona_manager.js');\n const { registerResearchPipelineSkill } = await import('./builtin/research_pipeline.js');\n const { registerAutoresearchSkill } = await import('./builtin/autoresearch.js');\n const { registerSelfDoctorSkill } = await import('./builtin/self_doctor.js');\n const { registerInteractionTrackerSkill } = await import('./builtin/interaction_tracker.js');\n const { registerFeedbackTrackerSkill } = await import('./builtin/feedback_tracker.js');\n const { registerGrowthExperimentsSkill } = await import('./builtin/growth_experiments.js');\n const { registerContentCalendarSkill } = await import('./builtin/content_calendar.js');\n const { registerSlackSkill } = await import('./builtin/slack.js');\n const { registerRevenueCatKBSkill } = await import('./builtin/revenuecat_kb.js');\n const { registerWeeklyReportSkill } = await import('./builtin/weekly_report.js');\n const { registerSelfImproveSkill } = await import('./builtin/self_improve.js');\n const { registerGepaSkill } = await import('./builtin/gepa.js');\n const { registerModelTrainerSkill } = await import('./builtin/model_trainer.js');\n const { registerSocialSchedulerSkill } = await import('./builtin/social_scheduler.js');\n const { registerStructuredOutputSkill } = await import('./builtin/structured_output.js');\n const { registerWorkflowsSkill } = await import('./builtin/workflows.js');\n const { registerAgentHandoffSkill } = await import('./builtin/agent_handoff.js');\n const { registerKnowledgeBaseSkill } = await import('./builtin/knowledge_base.js');\n const { registerEventTriggersSkill } = await import('./builtin/event_triggers.js');\n const { registerA2AProtocolSkill } = await import('./builtin/a2a_protocol.js');\n const { registerEvalsSkill } = await import('./builtin/evals.js');\n const { registerApprovalGatesSkill } = await import('./builtin/approval_gates.js');\n const { registerPhoneCallSkill } = await import('./builtin/phone_call.js');\n const { registerVRAMSkills } = await import('./builtin/vram.js');\n const { registerSecurityScanSkill } = await import('./builtin/security_scan.js');\n const { registerChangelogGenSkill } = await import('./builtin/changelog_gen.js');\n const { registerJiraLinearSkill } = await import('./builtin/jira_linear.js');\n const { registerAuditTrailSkill } = await import('./builtin/audit_trail.js');\n const { registerVisualPlanSkill } = await import('./builtin/visual_plan.js');\n const { registerScreenRecordSkill } = await import('./builtin/screen_record.js');\n const { registerSessionTeleportSkill } = await import('./builtin/session_teleport.js');\n const { registerCrossProviderSkill } = await import('./builtin/cross_provider.js');\n const { registerSentrySkill } = await import('./builtin/sentry.js');\n const { registerVideoSkill } = await import('./builtin/video.js');\n const { registerMixtureOfAgentsSkill } = await import('./builtin/mixture_of_agents.js');\n const { registerAgentDebateSkill } = await import('./builtin/agent_debate.js');\n const { registerFileCheckpointsSkill } = await import('./builtin/file_checkpoints.js');\n const { registerVerifyPageSkill } = await import('./builtin/verify_page.js');\n const { registerAgentMessagingSkill } = await import('./builtin/agent_messaging.js');\n const { registerFacebookSkill } = await import('./builtin/facebook.js');\n const { registerFBAutopilotSkill } = await import('./builtin/fb_autopilot.js');\n const { registerWidgetGallerySkill } = await import('./builtin/widget_gallery.js');\n const { registerCanvasWidgetsSkill } = await import('./builtin/canvas_widgets.js');\n const { registerCanvasSpacesSkill } = await import('./builtin/canvas_spaces.js');\n const { registerPersonalGallerySkill } = await import('./builtin/personal_gallery.js');\n const { registerBackupSkill } = await import('./builtin/backup.js');\n\n const config = loadConfig();\n const primitiveMode = config.skills.primitiveMode;\n\n if (primitiveMode) {\n logger.info(COMPONENT, 'PRIMITIVE MODE ENABLED — loading only shell, filesystem, web_search');\n }\n\n const registrations: [string, () => void][] = [\n ['shell', registerShellSkill],\n ['filesystem', registerFilesystemSkill],\n ['web_search', registerWebSearchSkill],\n ];\n\n if (!primitiveMode) {\n registrations.push(\n ['cron', registerCronSkill],\n ['webhook', registerWebhookSkill],\n ['memory', registerMemorySkill],\n ['browser', registerBrowserSkill],\n ['sessions', registerSessionsSkill],\n ['process', registerProcessSkill],\n ['web_fetch', registerWebFetchSkill],\n ['download_image', registerDownloadImageSkill],\n ['apply_patch', registerApplyPatchSkill],\n ['auto_generate', registerAutoGenerateSkill],\n ['vision', registerVisionSkill],\n ['voice', registerVoiceSkills],\n ['memory_graph', registerMemoryGraphSkill],\n ['web_browser', initWebBrowserTool],\n ['github', registerGitHubSkill],\n ['email', registerEmailSkill],\n ['computer_use', registerComputerUseSkill],\n ['image_gen', registerImageGenSkill],\n ['pdf', registerPdfSkill],\n ['calendar', registerCalendarSkill],\n ['smart_home', registerSmartHomeSkill],\n ['data_analysis', registerDataAnalysisSkill],\n ['skyvern', registerSkyvernSkill],\n ['web_browse_llm', registerWebBrowseLlmSkill],\n ['income_tracker', registerIncomeTrackerSkill],\n ['freelance_monitor', registerFreelanceMonitorSkill],\n ['content_publisher', registerContentPublisherSkill],\n ['lead_scorer', registerLeadScorerSkill],\n ['hunter', registerHunterSkill],\n ['code_exec', registerCodeExecSkill],\n ['execute_code', registerExecuteCodeSkill],\n ['weather', registerWeatherSkill],\n ['goals', registerGoalsSkill],\n ['x_poster', registerXPosterSkill],\n ['model_switch', initModelSwitchTool],\n ['rag', registerRagSkill],\n ['deep_research', registerDeepResearchSkill],\n ['system_info', registerSystemInfoSkill],\n ['current_model', registerCurrentModelSkill],\n ['persona_manager', registerPersonaManagerSkill],\n ['research_pipeline', registerResearchPipelineSkill],\n ['autoresearch', registerAutoresearchSkill],\n ['self_doctor', registerSelfDoctorSkill],\n ['interaction_tracker', registerInteractionTrackerSkill],\n ['feedback_tracker', registerFeedbackTrackerSkill],\n ['growth_experiments', registerGrowthExperimentsSkill],\n ['content_calendar', registerContentCalendarSkill],\n ['slack', registerSlackSkill],\n ['revenuecat_kb', registerRevenueCatKBSkill],\n ['weekly_report', registerWeeklyReportSkill],\n ['self_improve', registerSelfImproveSkill],\n ['gepa', registerGepaSkill],\n ['model_trainer', registerModelTrainerSkill],\n ['social_scheduler', registerSocialSchedulerSkill],\n ['structured_output', registerStructuredOutputSkill],\n ['workflows', registerWorkflowsSkill],\n ['agent_handoff', registerAgentHandoffSkill],\n ['knowledge_base', registerKnowledgeBaseSkill],\n ['event_triggers', registerEventTriggersSkill],\n ['evals', registerEvalsSkill],\n ['a2a_protocol', registerA2AProtocolSkill],\n ['approval_gates', registerApprovalGatesSkill],\n ['phone_call', registerPhoneCallSkill],\n ['vram', registerVRAMSkills],\n ['security_scan', registerSecurityScanSkill],\n ['changelog_gen', registerChangelogGenSkill],\n ['jira_linear', registerJiraLinearSkill],\n ['audit_trail', registerAuditTrailSkill],\n ['visual_plan', registerVisualPlanSkill],\n ['screen_record', registerScreenRecordSkill],\n ['session_teleport', registerSessionTeleportSkill],\n ['cross_provider', registerCrossProviderSkill],\n ['sentry', registerSentrySkill],\n ['video', registerVideoSkill],\n ['mixture_of_agents', registerMixtureOfAgentsSkill],\n ['agent_debate', registerAgentDebateSkill],\n ['file_checkpoints', registerFileCheckpointsSkill],\n ['verify_page', registerVerifyPageSkill],\n ['agent_messaging', registerAgentMessagingSkill],\n ['facebook', registerFacebookSkill],\n ['fb_autopilot', registerFBAutopilotSkill],\n ['widget_gallery', registerWidgetGallerySkill],\n ['widget_gallery', registerWidgetGallerySkill],\n ['canvas_widgets', registerCanvasWidgetsSkill],\n ['canvas_spaces', registerCanvasSpacesSkill],\n ['personal_gallery', registerPersonalGallerySkill],\n ['backup', registerBackupSkill],\n );\n }\n for (const [name, fn] of registrations) {\n try { fn(); } catch (e) { logger.warn(COMPONENT, `Failed to register skill \"${name}\": ${(e as Error).message}`); }\n }\n\n if (!primitiveMode) {\n // Register planner as an LLM-invocable tool\n const { registerPlannerTool } = await import('../agent/planner.js');\n try { registerPlannerTool(); } catch (e) { logger.warn(COMPONENT, `Failed to register planner: ${(e as Error).message}`); }\n\n // Register TopFacts context engine plugin (DeerFlow-inspired persistent memory)\n try {\n const { createTopFactsPlugin } = await import('../plugins/topFacts.js');\n const { createMemoryRetrievalPlugin } = await import('../plugins/memoryRetrieval.js');\n const { registerPlugin } = await import('../plugins/registry.js');\n const topFacts = createTopFactsPlugin();\n registerPlugin(topFacts);\n if (topFacts.bootstrap) await topFacts.bootstrap({});\n const memoryRetrieval = createMemoryRetrievalPlugin();\n registerPlugin(memoryRetrieval);\n if (memoryRetrieval.bootstrap) await memoryRetrieval.bootstrap({});\n } catch (e) { logger.warn(COMPONENT, `Failed to register TopFacts plugin: ${(e as Error).message}`); }\n\n // Register SmartCompress context engine plugin (task-type-aware compression)\n try {\n const { createSmartCompressPlugin } = await import('../plugins/smartCompress.js');\n const { registerPlugin: regPlugin } = await import('../plugins/registry.js');\n const smartCompress = createSmartCompressPlugin();\n regPlugin(smartCompress);\n if (smartCompress.bootstrap) await smartCompress.bootstrap({});\n } catch (e) { logger.warn(COMPONENT, `Failed to register SmartCompress plugin: ${(e as Error).message}`); }\n\n // Register tool_search + tool_expand — meta-tools for discovering tools on demand\n // tool_expand is the progressive disclosure extension (Hermes competitive gap fix)\n const { getToolSearchHandler, getToolExpandHandler } = await import('../agent/toolSearch.js');\n try { registerTool(getToolSearchHandler()); } catch (e) { logger.warn(COMPONENT, `Failed to register tool_search: ${(e as Error).message}`); }\n try { registerTool(getToolExpandHandler()); } catch (e) { logger.warn(COMPONENT, `Failed to register tool_expand: ${(e as Error).message}`); }\n\n // F3: Register procedural memory tools (Hermes-inspired skill learning)\n try {\n const { saveSkill, searchSkills } = await import('./proceduralMemory.js');\n registerTool({\n name: 'save_skill',\n description: 'Save a reusable approach/technique as a procedural skill for future tasks. Use this when you discover an effective approach that could help in similar future situations.',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Short descriptive name for the skill (e.g., \"Deploy Node.js app to Docker\")' },\n tags: { type: 'array', items: { type: 'string' }, description: 'Tags for searchability (e.g., [\"docker\", \"deployment\", \"nodejs\"])' },\n content: { type: 'string', description: 'The reusable approach/technique in markdown format. Include key steps, commands, and gotchas.' },\n },\n required: ['name', 'tags', 'content'],\n },\n execute: async (args: Record<string, unknown>) => {\n const name = args.name as string;\n const tags = (args.tags as string[]) || [];\n const content = args.content as string;\n if (!name || !content) return 'Error: name and content are required';\n const skill = saveSkill(name, tags, content);\n return `Skill saved: \"${skill.name}\" (tags: ${skill.tags.join(', ')}). It will be auto-recalled in future tasks matching these tags.`;\n },\n });\n registerTool({\n name: 'recall_skill',\n description: 'Search for previously saved procedural skills by keyword or tag. Returns reusable approaches from past tasks.',\n parameters: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query — keywords or tags to find relevant skills' },\n },\n required: ['query'],\n },\n execute: async (args: Record<string, unknown>) => {\n const query = args.query as string;\n if (!query) return 'Error: query is required';\n const results = searchSkills(query, 5);\n if (results.length === 0) return 'No matching skills found. Consider saving useful approaches with save_skill.';\n return results.map(s =>\n `### ${s.name}\\nTags: ${s.tags.join(', ')} | Used ${s.useCount}x\\n${s.content.slice(0, 800)}`\n ).join('\\n\\n---\\n\\n');\n },\n });\n logger.info(COMPONENT, 'Registered procedural memory tools (save_skill, recall_skill)');\n } catch (e) { logger.warn(COMPONENT, `Failed to register procedural memory tools: ${(e as Error).message}`); }\n }\n\n logger.info(COMPONENT, `Loaded ${registeredSkills.size} built-in skills`);\n\n // Load dev skills (only in dev mode — skip import entirely in production)\n if (process.env.NODE_ENV !== 'production' || process.env.TITAN_DEV) {\n const { initDevSkills } = await import('./dev/loader.js');\n await initDevSkills();\n }\n\n // Load NVIDIA skills (optional — only when TITAN_NVIDIA=1 or nvidia.enabled in config)\n try {\n let nvidiaEnabled = process.env.TITAN_NVIDIA === '1';\n if (!nvidiaEnabled) {\n try {\n const { loadConfig: _loadConfig } = await import('../config/config.js');\n const cfg = _loadConfig() as Record<string, unknown>;\n const nvCfg = cfg.nvidia as Record<string, unknown> | undefined;\n nvidiaEnabled = nvCfg?.enabled === true;\n } catch { /* config not available in test env */ }\n }\n if (nvidiaEnabled) {\n const { initNvidiaSkills } = await import('./nvidia/loader.js');\n await initNvidiaSkills();\n }\n } catch (err) {\n logger.warn(COMPONENT, `NVIDIA skills failed to load: ${(err as Error).message}`);\n }\n\n // Load personal skills (private, gitignored — only when TITAN_PERSONAL=1)\n // Primary location: dist/skills/personal/loader.js (co-located with dist/skills/registry.js\n // so `../registry` resolves to the SAME module instance — tools register into the correct registry)\n // Fallback: ~/.titan/personal/loader.js (legacy / TITAN_PERSONAL_DIR override)\n if (process.env.TITAN_PERSONAL === '1') {\n try {\n const { pathToFileURL, fileURLToPath } = await import('node:url');\n const { join: _join, dirname: _dirname } = await import('node:path');\n // Compute dist/skills/ dir from this file's location (works on any machine)\n const thisDir = _dirname(fileURLToPath(import.meta.url));\n const distPersonalDir = _join(thisDir, 'personal');\n // TITAN_PERSONAL_DIR env var overrides; otherwise try dist-local first, then ~/.titan/personal/\n const personalDir = process.env.TITAN_PERSONAL_DIR\n || (existsSync(_join(distPersonalDir, 'loader.js')) ? distPersonalDir : _join(TITAN_HOME, 'personal'));\n const loaderPath = _join(personalDir, 'loader.js');\n if (existsSync(loaderPath)) {\n // Inject the main app's registerSkill into a global so the personal bundle\n // (which has its own bundled copy) uses the correct shared toolRegistry instance.\n (globalThis as Record<string, unknown>).__titanRegisterSkill = registerSkill;\n const { initPersonalSkills } = await import(pathToFileURL(loaderPath).href) as { initPersonalSkills: () => Promise<void> };\n await initPersonalSkills();\n } else {\n logger.warn(COMPONENT, `TITAN_PERSONAL=1 but ${loaderPath} not found — run: npm run build:personal`);\n }\n } catch (err) {\n logger.warn(COMPONENT, `Personal skills failed to load: ${(err as Error).message}`);\n }\n }\n}\n\n/**\n * Discover and load user skills from ~/.titan/skills/ (all subdirs).\n * Supports:\n * 1. JavaScript files (.js) that export default { name, description, parameters, execute }\n * 2. YAML skill definitions (.yaml/.yml) with inline scripts\n * 3. Auto-generated skills from ~/.titan/skills/auto/\n */\nexport async function loadAutoSkills(): Promise<void> {\n const skillsRoot = join(TITAN_HOME, 'skills');\n if (!existsSync(skillsRoot)) return;\n\n logger.info(COMPONENT, 'Scanning for user skills...');\n let loadedCount = 0;\n\n // Scan both root and all subdirectories\n const dirsToScan = [skillsRoot];\n const entries = readdirSync(skillsRoot, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) dirsToScan.push(join(skillsRoot, entry.name));\n }\n\n for (const dir of dirsToScan) {\n const files = readdirSync(dir).filter(f =>\n f.endsWith('.js') || f.endsWith('.yaml') || f.endsWith('.yml')\n );\n\n for (const file of files) {\n const filePath = join(dir, file);\n try {\n if (file.endsWith('.js')) {\n // JavaScript skill — export default { name, description, parameters, execute }\n const modulePath = `file://${filePath}?t=${Date.now()}`;\n const mod = await import(modulePath);\n if (mod.default && mod.default.name && mod.default.execute) {\n const handler = mod.default as ToolHandler;\n if (registeredSkills.has(handler.name)) continue; // Skip duplicates\n registerSkill({\n name: handler.name,\n description: handler.description || 'User skill',\n version: '1.0.0',\n source: 'workspace',\n enabled: true,\n }, handler);\n loadedCount++;\n }\n } else {\n // YAML skill definition\n const loaded = loadYamlSkill(filePath);\n if (loaded && !registeredSkills.has(loaded.name)) {\n registerSkill({\n name: loaded.name,\n description: loaded.description,\n version: '1.0.0',\n source: 'workspace',\n enabled: true,\n }, loaded);\n loadedCount++;\n }\n }\n } catch (e: unknown) {\n logger.warn(COMPONENT, `Failed to load skill ${file}: ${(e as Error).message}`);\n }\n }\n }\n\n if (loadedCount > 0) {\n logger.info(COMPONENT, `Loaded ${loadedCount} user skill(s) from ~/.titan/skills/`);\n }\n\n // Load frontmatter skills (*.skill.md) — Space Agent / Hermes parity\n try {\n const { getFrontmatterToolHandlers } = await import('./frontmatterLoader.js');\n const fmHandlers = getFrontmatterToolHandlers();\n for (const { name, handler } of fmHandlers) {\n if (registeredSkills.has(name)) continue;\n registerSkill({\n name: handler.name,\n description: handler.description,\n version: '1.0.0',\n source: 'frontmatter',\n enabled: true,\n }, handler);\n loadedCount++;\n }\n if (fmHandlers.length > 0) {\n logger.info(COMPONENT, `Loaded ${fmHandlers.length} frontmatter skill(s)`);\n }\n } catch (e) {\n logger.warn(COMPONENT, `Frontmatter skills failed to load: ${(e as Error).message}`);\n }\n}\n\n/**\n * Load a YAML skill definition.\n * Format:\n * name: my_tool\n * description: What it does\n * parameters:\n * myParam:\n * type: string\n * description: A parameter\n * required: true\n * script: |\n * // JavaScript code. Use `args.myParam` for inputs.\n * // Return a string result.\n * return \"Hello \" + args.myParam;\n */\nfunction loadYamlSkill(filePath: string): ToolHandler | null {\n const content = readFileSync(filePath, 'utf-8');\n\n // Simple YAML parser (no dependency needed for this basic format)\n const name = content.match(/^name:\\s*(.+)$/m)?.[1]?.trim();\n const description = content.match(/^description:\\s*(.+)$/m)?.[1]?.trim();\n const scriptMatch = content.match(/^script:\\s*\\|\\n([\\s\\S]+?)(?=\\n\\w|\\n$|$)/m);\n const script = scriptMatch?.[1]?.replace(/^ {2}/gm, ''); // Remove YAML indent\n\n if (!name || !description || !script) {\n logger.debug(COMPONENT, `Skipping ${filePath}: missing name, description, or script`);\n return null;\n }\n\n // Parse parameters section\n const paramsSection = content.match(/^parameters:\\n((?:\\s{2}\\w[\\s\\S]*?)(?=\\nscript:|\\n\\w|\\n$))/m);\n const properties: Record<string, Record<string, unknown>> = {};\n const required: string[] = [];\n\n if (paramsSection) {\n const paramLines = paramsSection[1].split('\\n');\n let currentParam = '';\n for (const line of paramLines) {\n const paramMatch = line.match(/^\\s{2}(\\w+):\\s*$/);\n if (paramMatch) {\n currentParam = paramMatch[1];\n properties[currentParam] = {};\n continue;\n }\n if (currentParam) {\n const typeMatch = line.match(/^\\s{4}type:\\s*(.+)$/);\n const descMatch = line.match(/^\\s{4}description:\\s*(.+)$/);\n const reqMatch = line.match(/^\\s{4}required:\\s*true$/);\n const defMatch = line.match(/^\\s{4}default:\\s*(.+)$/);\n if (typeMatch) properties[currentParam].type = typeMatch[1].trim();\n if (descMatch) properties[currentParam].description = descMatch[1].trim();\n if (reqMatch) required.push(currentParam);\n if (defMatch) properties[currentParam].default = defMatch[1].trim();\n }\n }\n }\n\n // Create the execute function from the script\n const handler: ToolHandler = {\n name,\n description,\n parameters: {\n type: 'object',\n properties,\n required: required.length > 0 ? required : undefined,\n },\n execute: async (args: Record<string, unknown>) => {\n try {\n // Run in a restricted VM context — no access to globalThis, process, eval, or Function\n const safeRequire = (mod: string) => {\n // SECURITY: child_process, http, https removed — YAML skills must use builtin tools for shell/network\n const allowed = ['fs', 'path', 'os', 'crypto', 'url', 'util'];\n if (!allowed.includes(mod)) throw new Error(`Module \"${mod}\" not allowed in YAML skills`);\n return require(mod); // eslint-disable-line @typescript-eslint/no-require-imports\n };\n const sandbox: Record<string, unknown> = {\n args,\n require: safeRequire,\n console: { log: console.log },\n JSON,\n Math,\n Date,\n String,\n Number,\n Array,\n Object,\n RegExp,\n Map,\n Set,\n Promise,\n setTimeout,\n Buffer,\n };\n // Wrap the user script in an async IIFE so `return` works and we can await it\n const wrapped = `(async function() { ${script} })()`;\n const result = await vm.runInNewContext(wrapped, sandbox, { timeout: 10000 });\n return typeof result === 'string' ? result : JSON.stringify(result, null, 2);\n } catch (err) {\n return `Error: ${(err as Error).message}`;\n }\n },\n };\n\n logger.debug(COMPONENT, `Loaded YAML skill: ${name} from ${filePath}`);\n return handler;\n}\n"],"mappings":";AAIA,SAAS,YAAY,aAAa,cAAc,eAAe,iBAAiB;AAChF,SAAS,MAAM,eAAe;AAC9B,OAAO,QAAQ;AACf,SAAS,YAAY,wBAAwB;AAC7C,SAAS,oBAAsC;AAC/C,SAAS,wBAAwB;AACjC,OAAO,YAAY;AACnB,SAAS,kBAAkB;AAE3B,MAAM,YAAY;AAClB,MAAM,uBAAuB,KAAK,YAAY,sBAAsB;AAWpE,MAAM,mBAA2C,oBAAI,IAAI;AAGzD,MAAM,eAAyC,oBAAI,IAAI;AAGhD,SAAS,cAAc,MAAiB,SAA4B;AACvE,mBAAiB,IAAI,KAAK,MAAM,IAAI;AAEpC,MAAI,CAAC,aAAa,IAAI,KAAK,IAAI,GAAG;AAC9B,iBAAa,IAAI,KAAK,MAAM,oBAAI,IAAI,CAAC;AAAA,EACzC;AACA,eAAa,IAAI,KAAK,IAAI,EAAG,IAAI,QAAQ,IAAI;AAC7C,eAAa,OAAO;AACpB,SAAO,MAAM,WAAW,qBAAqB,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG;AAC7E;AAGO,SAAS,YAAyB;AACrC,QAAM,WAAW,mBAAmB;AACpC,SAAO,MAAM,KAAK,iBAAiB,OAAO,CAAC,EAAE,IAAI,QAAM;AAAA,IACnD,GAAG;AAAA,IACH,SAAS,CAAC,SAAS,SAAS,EAAE,IAAI;AAAA,EACtC,EAAE;AACN;AAGO,SAAS,SAAS,MAAqC;AAC1D,SAAO,iBAAiB,IAAI,IAAI;AACpC;AAGO,SAAS,cAAc,WAA6B;AACvD,SAAO,MAAM,KAAK,aAAa,IAAI,SAAS,KAAK,CAAC,CAAC;AACvD;AAGO,SAAS,eAAe,WAA4B;AACvD,SAAO,CAAC,mBAAmB,EAAE,SAAS,SAAS;AACnD;AAGO,SAAS,mBAAmB,UAA2B;AAC1D,aAAW,CAAC,WAAW,KAAK,KAAK,aAAa,QAAQ,GAAG;AACrD,QAAI,MAAM,IAAI,QAAQ,GAAG;AACrB,aAAO,eAAe,SAAS;AAAA,IACnC;AAAA,EACJ;AACA,SAAO;AACX;AAGO,SAAS,YAAY,WAA4B;AACpD,QAAM,QAAQ,iBAAiB,IAAI,SAAS;AAC5C,MAAI,CAAC,OAAO;AACR,UAAM,IAAI,MAAM,UAAU,SAAS,aAAa;AAAA,EACpD;AAEA,QAAM,WAAW,mBAAmB;AACpC,QAAM,MAAM,SAAS,QAAQ,SAAS;AACtC,MAAI;AAEJ,MAAI,OAAO,GAAG;AACV,aAAS,OAAO,KAAK,CAAC;AACtB,iBAAa;AAAA,EACjB,OAAO;AACH,aAAS,KAAK,SAAS;AACvB,iBAAa;AAAA,EACjB;AAEA,qBAAmB,QAAQ;AAC3B,SAAO,KAAK,WAAW,UAAU,SAAS,KAAK,aAAa,YAAY,UAAU,EAAE;AACpF,SAAO;AACX;AAGO,SAAS,gBAAgB,WAAmB,SAAwB;AACvE,QAAM,QAAQ,iBAAiB,IAAI,SAAS;AAC5C,MAAI,CAAC,OAAO;AACR,UAAM,IAAI,MAAM,UAAU,SAAS,aAAa;AAAA,EACpD;AAEA,QAAM,WAAW,mBAAmB;AACpC,QAAM,MAAM,SAAS,QAAQ,SAAS;AAEtC,MAAI,WAAW,OAAO,GAAG;AACrB,aAAS,OAAO,KAAK,CAAC;AAAA,EAC1B,WAAW,CAAC,WAAW,MAAM,GAAG;AAC5B,aAAS,KAAK,SAAS;AAAA,EAC3B;AAEA,qBAAmB,QAAQ;AAC/B;AAGA,IAAI,uBAAwC;AAC5C,IAAI,yBAAyB;AAC7B,MAAM,+BAA+B;AAGrC,SAAS,qBAA+B;AACpC,QAAM,MAAM,KAAK,IAAI;AACrB,MAAI,yBAAyB,QAAQ,MAAM,yBAAyB,8BAA8B;AAC9F,WAAO;AAAA,EACX;AACA,MAAI,SAAmB,CAAC;AACxB,MAAI;AACA,QAAI,WAAW,oBAAoB,GAAG;AAClC,eAAS,KAAK,MAAM,aAAa,sBAAsB,OAAO,CAAC;AAAA,IACnE;AAAA,EACJ,QAAQ;AAAA,EAER;AACA,yBAAuB;AACvB,2BAAyB;AACzB,SAAO;AACX;AAGA,SAAS,mBAAmB,UAA0B;AAClD,yBAAuB;AACvB,MAAI;AACA,UAAM,MAAM,QAAQ,oBAAoB;AACxC,QAAI,CAAC,WAAW,GAAG,GAAG;AAClB,gBAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACtC;AACA,kBAAc,sBAAsB,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,OAAO;AAAA,EAClF,SAAS,GAAG;AACR,WAAO,KAAK,WAAW,mCAAoC,EAAY,OAAO,EAAE;AAAA,EACpF;AACJ;AAGO,SAAS,0BAAuC;AACnD,mBAAiB,gBAAgB;AACjC,QAAM,aAA0B,CAAC;AAEjC,MAAI,CAAC,WAAW,gBAAgB,EAAG,QAAO;AAE1C,QAAM,UAAU,YAAY,kBAAkB,EAAE,eAAe,KAAK,CAAC;AACrE,aAAW,SAAS,SAAS;AACzB,QAAI,CAAC,MAAM,YAAY,EAAG;AAE1B,UAAM,WAAW,KAAK,kBAAkB,MAAM,IAAI;AAClD,UAAM,cAAc,KAAK,UAAU,UAAU;AAE7C,QAAI,CAAC,WAAW,WAAW,EAAG;AAE9B,QAAI;AACA,YAAM,UAAU,aAAa,aAAa,OAAO;AACjD,YAAM,OAAO,aAAa,SAAS,MAAM,IAAI;AAC7C,UAAI,MAAM;AACN,mBAAW,KAAK,EAAE,GAAG,MAAM,QAAQ,aAAa,SAAS,KAAK,CAAC;AAAA,MACnE;AAAA,IACJ,SAAS,OAAO;AACZ,aAAO,KAAK,WAAW,wBAAwB,MAAM,IAAI,KAAM,MAAgB,OAAO,EAAE;AAAA,IAC5F;AAAA,EACJ;AAEA,SAAO,KAAK,WAAW,cAAc,WAAW,MAAM,mBAAmB;AACzE,SAAO;AACX;AAGA,SAAS,aAAa,SAAiB,cAAoE;AACvG,QAAM,mBAAmB,QAAQ,MAAM,uBAAuB;AAC9D,MAAI,CAAC,kBAAkB;AACnB,WAAO;AAAA,MACH,MAAM;AAAA,MACN,aAAa,QAAQ,MAAM,IAAI,EAAE,CAAC,KAAK;AAAA,MACvC,SAAS;AAAA,IACb;AAAA,EACJ;AAEA,QAAM,cAAc,iBAAiB,CAAC;AACtC,QAAM,OAAO,YAAY,MAAM,cAAc,IAAI,CAAC,GAAG,KAAK,KAAK;AAC/D,QAAM,cAAc,YAAY,MAAM,qBAAqB,IAAI,CAAC,GAAG,KAAK,KAAK;AAC7E,QAAM,UAAU,YAAY,MAAM,iBAAiB,IAAI,CAAC,GAAG,KAAK,KAAK;AACrE,QAAM,SAAS,YAAY,MAAM,gBAAgB,IAAI,CAAC,GAAG,KAAK;AAE9D,SAAO,EAAE,MAAM,aAAa,SAAS,OAAO;AAChD;AAGA,eAAsB,oBAAmC;AACrD,SAAO,KAAK,WAAW,4BAA4B;AAQnD,MAAI;AACA,UAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,wBAAwB;AAC5E,+BAA2B;AAC3B,WAAO,MAAM,WAAW,qCAAqC;AAAA,EACjE,SAAS,KAAK;AACV,WAAO,KAAK,WAAW,2CAA4C,IAAc,OAAO,EAAE;AAAA,EAC9F;AAGA,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,oBAAoB;AAChE,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,yBAAyB;AAC1E,QAAM,EAAE,uBAAuB,IAAI,MAAM,OAAO,yBAAyB;AACzE,QAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,mBAAmB;AAC9D,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,sBAAsB;AACpE,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,2BAA2B;AACxE,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,sBAAsB;AACpE,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,uBAAuB;AACtE,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,sBAAsB;AACpE,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,wBAAwB;AACvE,QAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,0BAA0B;AAC3E,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,qBAAqB;AAClE,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,oBAAoB;AACjE,QAAM,EAAE,yBAAyB,IAAI,MAAM,OAAO,2BAA2B;AAC7E,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,0BAA0B;AACtE,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,qBAAqB;AAClE,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,oBAAoB;AAChE,QAAM,EAAE,yBAAyB,IAAI,MAAM,OAAO,2BAA2B;AAC7E,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,wBAAwB;AACvE,QAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,kBAAkB;AAC5D,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,uBAAuB;AACtE,QAAM,EAAE,uBAAuB,IAAI,MAAM,OAAO,yBAAyB;AACzE,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,sBAAsB;AACpE,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,6BAA6B;AAChF,QAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,QAAM,EAAE,8BAA8B,IAAI,MAAM,OAAO,gCAAgC;AACvF,QAAM,EAAE,8BAA8B,IAAI,MAAM,OAAO,gCAAgC;AACvF,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,0BAA0B;AAC3E,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,qBAAqB;AAClE,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,wBAAwB;AACvE,QAAM,EAAE,yBAAyB,IAAI,MAAM,OAAO,0BAA0B;AAC5E,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,sBAAsB;AACpE,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,oBAAoB;AAChE,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,uBAAuB;AACrE,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,2BAA2B;AACxE,QAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,kBAAkB;AAC5D,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,0BAA0B;AAC3E,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,4BAA4B,IAAI,MAAM,OAAO,8BAA8B;AACnF,QAAM,EAAE,8BAA8B,IAAI,MAAM,OAAO,gCAAgC;AACvF,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,2BAA2B;AAC9E,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,0BAA0B;AAC3E,QAAM,EAAE,gCAAgC,IAAI,MAAM,OAAO,kCAAkC;AAC3F,QAAM,EAAE,6BAA6B,IAAI,MAAM,OAAO,+BAA+B;AACrF,QAAM,EAAE,+BAA+B,IAAI,MAAM,OAAO,iCAAiC;AACzF,QAAM,EAAE,6BAA6B,IAAI,MAAM,OAAO,+BAA+B;AACrF,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,oBAAoB;AAChE,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,yBAAyB,IAAI,MAAM,OAAO,2BAA2B;AAC7E,QAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,mBAAmB;AAC9D,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,6BAA6B,IAAI,MAAM,OAAO,+BAA+B;AACrF,QAAM,EAAE,8BAA8B,IAAI,MAAM,OAAO,gCAAgC;AACvF,QAAM,EAAE,uBAAuB,IAAI,MAAM,OAAO,wBAAwB;AACxE,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,QAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,QAAM,EAAE,yBAAyB,IAAI,MAAM,OAAO,2BAA2B;AAC7E,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,oBAAoB;AAChE,QAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,QAAM,EAAE,uBAAuB,IAAI,MAAM,OAAO,yBAAyB;AACzE,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,mBAAmB;AAC/D,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,0BAA0B;AAC3E,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,0BAA0B;AAC3E,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,0BAA0B;AAC3E,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,6BAA6B,IAAI,MAAM,OAAO,+BAA+B;AACrF,QAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,qBAAqB;AAClE,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,oBAAoB;AAChE,QAAM,EAAE,6BAA6B,IAAI,MAAM,OAAO,gCAAgC;AACtF,QAAM,EAAE,yBAAyB,IAAI,MAAM,OAAO,2BAA2B;AAC7E,QAAM,EAAE,6BAA6B,IAAI,MAAM,OAAO,+BAA+B;AACrF,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,0BAA0B;AAC3E,QAAM,EAAE,4BAA4B,IAAI,MAAM,OAAO,8BAA8B;AACnF,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,uBAAuB;AACtE,QAAM,EAAE,yBAAyB,IAAI,MAAM,OAAO,2BAA2B;AAC7E,QAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,QAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,QAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,4BAA4B;AAC/E,QAAM,EAAE,6BAA6B,IAAI,MAAM,OAAO,+BAA+B;AACrF,QAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,qBAAqB;AAElE,QAAM,SAAS,WAAW;AAC1B,QAAM,gBAAgB,OAAO,OAAO;AAEpC,MAAI,eAAe;AACf,WAAO,KAAK,WAAW,0EAAqE;AAAA,EAChG;AAEA,QAAM,gBAAwC;AAAA,IAC1C,CAAC,SAAS,kBAAkB;AAAA,IAC5B,CAAC,cAAc,uBAAuB;AAAA,IACtC,CAAC,cAAc,sBAAsB;AAAA,EACzC;AAEA,MAAI,CAAC,eAAe;AAChB,kBAAc;AAAA,MACV,CAAC,QAAQ,iBAAiB;AAAA,MAC9B,CAAC,WAAW,oBAAoB;AAAA,MAChC,CAAC,UAAU,mBAAmB;AAAA,MAC9B,CAAC,WAAW,oBAAoB;AAAA,MAChC,CAAC,YAAY,qBAAqB;AAAA,MAClC,CAAC,WAAW,oBAAoB;AAAA,MAChC,CAAC,aAAa,qBAAqB;AAAA,MACnC,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,eAAe,uBAAuB;AAAA,MACvC,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,UAAU,mBAAmB;AAAA,MAC9B,CAAC,SAAS,mBAAmB;AAAA,MAC7B,CAAC,gBAAgB,wBAAwB;AAAA,MACzC,CAAC,eAAe,kBAAkB;AAAA,MAClC,CAAC,UAAU,mBAAmB;AAAA,MAC9B,CAAC,SAAS,kBAAkB;AAAA,MAC5B,CAAC,gBAAgB,wBAAwB;AAAA,MACzC,CAAC,aAAa,qBAAqB;AAAA,MACnC,CAAC,OAAO,gBAAgB;AAAA,MACxB,CAAC,YAAY,qBAAqB;AAAA,MAClC,CAAC,cAAc,sBAAsB;AAAA,MACrC,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,WAAW,oBAAoB;AAAA,MAChC,CAAC,kBAAkB,yBAAyB;AAAA,MAC5C,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,qBAAqB,6BAA6B;AAAA,MACnD,CAAC,qBAAqB,6BAA6B;AAAA,MACnD,CAAC,eAAe,uBAAuB;AAAA,MACvC,CAAC,UAAU,mBAAmB;AAAA,MAC9B,CAAC,aAAa,qBAAqB;AAAA,MACnC,CAAC,gBAAgB,wBAAwB;AAAA,MACzC,CAAC,WAAW,oBAAoB;AAAA,MAChC,CAAC,SAAS,kBAAkB;AAAA,MAC5B,CAAC,YAAY,oBAAoB;AAAA,MACjC,CAAC,gBAAgB,mBAAmB;AAAA,MACpC,CAAC,OAAO,gBAAgB;AAAA,MACxB,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,eAAe,uBAAuB;AAAA,MACvC,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,mBAAmB,2BAA2B;AAAA,MAC/C,CAAC,qBAAqB,6BAA6B;AAAA,MACnD,CAAC,gBAAgB,yBAAyB;AAAA,MAC1C,CAAC,eAAe,uBAAuB;AAAA,MACvC,CAAC,uBAAuB,+BAA+B;AAAA,MACvD,CAAC,oBAAoB,4BAA4B;AAAA,MACjD,CAAC,sBAAsB,8BAA8B;AAAA,MACrD,CAAC,oBAAoB,4BAA4B;AAAA,MACjD,CAAC,SAAS,kBAAkB;AAAA,MAC5B,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,gBAAgB,wBAAwB;AAAA,MACzC,CAAC,QAAQ,iBAAiB;AAAA,MAC1B,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,oBAAoB,4BAA4B;AAAA,MACjD,CAAC,qBAAqB,6BAA6B;AAAA,MACnD,CAAC,aAAa,sBAAsB;AAAA,MACpC,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,SAAS,kBAAkB;AAAA,MAC5B,CAAC,gBAAgB,wBAAwB;AAAA,MACzC,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,cAAc,sBAAsB;AAAA,MACrC,CAAC,QAAQ,kBAAkB;AAAA,MAC3B,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,eAAe,uBAAuB;AAAA,MACvC,CAAC,eAAe,uBAAuB;AAAA,MACvC,CAAC,eAAe,uBAAuB;AAAA,MACvC,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,oBAAoB,4BAA4B;AAAA,MACjD,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,UAAU,mBAAmB;AAAA,MAC9B,CAAC,SAAS,kBAAkB;AAAA,MAC5B,CAAC,qBAAqB,4BAA4B;AAAA,MAClD,CAAC,gBAAgB,wBAAwB;AAAA,MACzC,CAAC,oBAAoB,4BAA4B;AAAA,MACjD,CAAC,eAAe,uBAAuB;AAAA,MACvC,CAAC,mBAAmB,2BAA2B;AAAA,MAC/C,CAAC,YAAY,qBAAqB;AAAA,MAClC,CAAC,gBAAgB,wBAAwB;AAAA,MACzC,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,kBAAkB,0BAA0B;AAAA,MAC7C,CAAC,iBAAiB,yBAAyB;AAAA,MAC3C,CAAC,oBAAoB,4BAA4B;AAAA,MACjD,CAAC,UAAU,mBAAmB;AAAA,IAC9B;AAAA,EACJ;AACA,aAAW,CAAC,MAAM,EAAE,KAAK,eAAe;AACpC,QAAI;AAAE,SAAG;AAAA,IAAG,SAAS,GAAG;AAAE,aAAO,KAAK,WAAW,6BAA6B,IAAI,MAAO,EAAY,OAAO,EAAE;AAAA,IAAG;AAAA,EACrH;AAEA,MAAI,CAAC,eAAe;AAEhB,UAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,qBAAqB;AAClE,QAAI;AAAE,0BAAoB;AAAA,IAAG,SAAS,GAAG;AAAE,aAAO,KAAK,WAAW,+BAAgC,EAAY,OAAO,EAAE;AAAA,IAAG;AAG1H,QAAI;AACA,YAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,wBAAwB;AACtE,YAAM,EAAE,4BAA4B,IAAI,MAAM,OAAO,+BAA+B;AACpF,YAAM,EAAE,eAAe,IAAI,MAAM,OAAO,wBAAwB;AAChE,YAAM,WAAW,qBAAqB;AACtC,qBAAe,QAAQ;AACvB,UAAI,SAAS,UAAW,OAAM,SAAS,UAAU,CAAC,CAAC;AACnD,YAAM,kBAAkB,4BAA4B;AACpD,qBAAe,eAAe;AAC9B,UAAI,gBAAgB,UAAW,OAAM,gBAAgB,UAAU,CAAC,CAAC;AAAA,IACrE,SAAS,GAAG;AAAE,aAAO,KAAK,WAAW,uCAAwC,EAAY,OAAO,EAAE;AAAA,IAAG;AAGrG,QAAI;AACA,YAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,6BAA6B;AAChF,YAAM,EAAE,gBAAgB,UAAU,IAAI,MAAM,OAAO,wBAAwB;AAC3E,YAAM,gBAAgB,0BAA0B;AAChD,gBAAU,aAAa;AACvB,UAAI,cAAc,UAAW,OAAM,cAAc,UAAU,CAAC,CAAC;AAAA,IACjE,SAAS,GAAG;AAAE,aAAO,KAAK,WAAW,4CAA6C,EAAY,OAAO,EAAE;AAAA,IAAG;AAI1G,UAAM,EAAE,sBAAsB,qBAAqB,IAAI,MAAM,OAAO,wBAAwB;AAC5F,QAAI;AAAE,mBAAa,qBAAqB,CAAC;AAAA,IAAG,SAAS,GAAG;AAAE,aAAO,KAAK,WAAW,mCAAoC,EAAY,OAAO,EAAE;AAAA,IAAG;AAC7I,QAAI;AAAE,mBAAa,qBAAqB,CAAC;AAAA,IAAG,SAAS,GAAG;AAAE,aAAO,KAAK,WAAW,mCAAoC,EAAY,OAAO,EAAE;AAAA,IAAG;AAG7I,QAAI;AACA,YAAM,EAAE,WAAW,aAAa,IAAI,MAAM,OAAO,uBAAuB;AACxE,mBAAa;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,QACb,YAAY;AAAA,UACR,MAAM;AAAA,UACN,YAAY;AAAA,YACR,MAAM,EAAE,MAAM,UAAU,aAAa,8EAA8E;AAAA,YACnH,MAAM,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,aAAa,oEAAoE;AAAA,YACnI,SAAS,EAAE,MAAM,UAAU,aAAa,gGAAgG;AAAA,UAC5I;AAAA,UACA,UAAU,CAAC,QAAQ,QAAQ,SAAS;AAAA,QACxC;AAAA,QACA,SAAS,OAAO,SAAkC;AAC9C,gBAAM,OAAO,KAAK;AAClB,gBAAM,OAAQ,KAAK,QAAqB,CAAC;AACzC,gBAAM,UAAU,KAAK;AACrB,cAAI,CAAC,QAAQ,CAAC,QAAS,QAAO;AAC9B,gBAAM,QAAQ,UAAU,MAAM,MAAM,OAAO;AAC3C,iBAAO,iBAAiB,MAAM,IAAI,YAAY,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,QACvE;AAAA,MACJ,CAAC;AACD,mBAAa;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,QACb,YAAY;AAAA,UACR,MAAM;AAAA,UACN,YAAY;AAAA,YACR,OAAO,EAAE,MAAM,UAAU,aAAa,+DAA0D;AAAA,UACpG;AAAA,UACA,UAAU,CAAC,OAAO;AAAA,QACtB;AAAA,QACA,SAAS,OAAO,SAAkC;AAC9C,gBAAM,QAAQ,KAAK;AACnB,cAAI,CAAC,MAAO,QAAO;AACnB,gBAAM,UAAU,aAAa,OAAO,CAAC;AACrC,cAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,iBAAO,QAAQ;AAAA,YAAI,OACf,OAAO,EAAE,IAAI;AAAA,QAAW,EAAE,KAAK,KAAK,IAAI,CAAC,WAAW,EAAE,QAAQ;AAAA,EAAM,EAAE,QAAQ,MAAM,GAAG,GAAG,CAAC;AAAA,UAC/F,EAAE,KAAK,aAAa;AAAA,QACxB;AAAA,MACJ,CAAC;AACD,aAAO,KAAK,WAAW,+DAA+D;AAAA,IAC1F,SAAS,GAAG;AAAE,aAAO,KAAK,WAAW,+CAAgD,EAAY,OAAO,EAAE;AAAA,IAAG;AAAA,EACjH;AAEA,SAAO,KAAK,WAAW,UAAU,iBAAiB,IAAI,kBAAkB;AAGxE,MAAI,QAAQ,IAAI,aAAa,gBAAgB,QAAQ,IAAI,WAAW;AAChE,UAAM,EAAE,cAAc,IAAI,MAAM,OAAO,iBAAiB;AACxD,UAAM,cAAc;AAAA,EACxB;AAGA,MAAI;AACA,QAAI,gBAAgB,QAAQ,IAAI,iBAAiB;AACjD,QAAI,CAAC,eAAe;AAChB,UAAI;AACA,cAAM,EAAE,YAAY,YAAY,IAAI,MAAM,OAAO,qBAAqB;AACtE,cAAM,MAAM,YAAY;AACxB,cAAM,QAAQ,IAAI;AAClB,wBAAgB,OAAO,YAAY;AAAA,MACvC,QAAQ;AAAA,MAAyC;AAAA,IACrD;AACA,QAAI,eAAe;AACf,YAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,oBAAoB;AAC9D,YAAM,iBAAiB;AAAA,IAC3B;AAAA,EACJ,SAAS,KAAK;AACV,WAAO,KAAK,WAAW,iCAAkC,IAAc,OAAO,EAAE;AAAA,EACpF;AAMA,MAAI,QAAQ,IAAI,mBAAmB,KAAK;AACpC,QAAI;AACA,YAAM,EAAE,eAAe,cAAc,IAAI,MAAM,OAAO,UAAU;AAChE,YAAM,EAAE,MAAM,OAAO,SAAS,SAAS,IAAI,MAAM,OAAO,WAAW;AAEnE,YAAM,UAAU,SAAS,cAAc,YAAY,GAAG,CAAC;AACvD,YAAM,kBAAkB,MAAM,SAAS,UAAU;AAEjD,YAAM,cAAc,QAAQ,IAAI,uBACxB,WAAW,MAAM,iBAAiB,WAAW,CAAC,IAAI,kBAAkB,MAAM,YAAY,UAAU;AACxG,YAAM,aAAa,MAAM,aAAa,WAAW;AACjD,UAAI,WAAW,UAAU,GAAG;AAGxB,QAAC,WAAuC,uBAAuB;AAC/D,cAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,cAAc,UAAU,EAAE;AACtE,cAAM,mBAAmB;AAAA,MAC7B,OAAO;AACH,eAAO,KAAK,WAAW,wBAAwB,UAAU,+CAA0C;AAAA,MACvG;AAAA,IACJ,SAAS,KAAK;AACV,aAAO,KAAK,WAAW,mCAAoC,IAAc,OAAO,EAAE;AAAA,IACtF;AAAA,EACJ;AACJ;AASA,eAAsB,iBAAgC;AAClD,QAAM,aAAa,KAAK,YAAY,QAAQ;AAC5C,MAAI,CAAC,WAAW,UAAU,EAAG;AAE7B,SAAO,KAAK,WAAW,6BAA6B;AACpD,MAAI,cAAc;AAGlB,QAAM,aAAa,CAAC,UAAU;AAC9B,QAAM,UAAU,YAAY,YAAY,EAAE,eAAe,KAAK,CAAC;AAC/D,aAAW,SAAS,SAAS;AACzB,QAAI,MAAM,YAAY,EAAG,YAAW,KAAK,KAAK,YAAY,MAAM,IAAI,CAAC;AAAA,EACzE;AAEA,aAAW,OAAO,YAAY;AAC1B,UAAM,QAAQ,YAAY,GAAG,EAAE;AAAA,MAAO,OAClC,EAAE,SAAS,KAAK,KAAK,EAAE,SAAS,OAAO,KAAK,EAAE,SAAS,MAAM;AAAA,IACjE;AAEA,eAAW,QAAQ,OAAO;AACtB,YAAM,WAAW,KAAK,KAAK,IAAI;AAC/B,UAAI;AACA,YAAI,KAAK,SAAS,KAAK,GAAG;AAEtB,gBAAM,aAAa,UAAU,QAAQ,MAAM,KAAK,IAAI,CAAC;AACrD,gBAAM,MAAM,MAAM,OAAO;AACzB,cAAI,IAAI,WAAW,IAAI,QAAQ,QAAQ,IAAI,QAAQ,SAAS;AACxD,kBAAM,UAAU,IAAI;AACpB,gBAAI,iBAAiB,IAAI,QAAQ,IAAI,EAAG;AACxC,0BAAc;AAAA,cACV,MAAM,QAAQ;AAAA,cACd,aAAa,QAAQ,eAAe;AAAA,cACpC,SAAS;AAAA,cACT,QAAQ;AAAA,cACR,SAAS;AAAA,YACb,GAAG,OAAO;AACV;AAAA,UACJ;AAAA,QACJ,OAAO;AAEH,gBAAM,SAAS,cAAc,QAAQ;AACrC,cAAI,UAAU,CAAC,iBAAiB,IAAI,OAAO,IAAI,GAAG;AAC9C,0BAAc;AAAA,cACV,MAAM,OAAO;AAAA,cACb,aAAa,OAAO;AAAA,cACpB,SAAS;AAAA,cACT,QAAQ;AAAA,cACR,SAAS;AAAA,YACb,GAAG,MAAM;AACT;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ,SAAS,GAAY;AACjB,eAAO,KAAK,WAAW,wBAAwB,IAAI,KAAM,EAAY,OAAO,EAAE;AAAA,MAClF;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,cAAc,GAAG;AACjB,WAAO,KAAK,WAAW,UAAU,WAAW,sCAAsC;AAAA,EACtF;AAGA,MAAI;AACA,UAAM,EAAE,2BAA2B,IAAI,MAAM,OAAO,wBAAwB;AAC5E,UAAM,aAAa,2BAA2B;AAC9C,eAAW,EAAE,MAAM,QAAQ,KAAK,YAAY;AACxC,UAAI,iBAAiB,IAAI,IAAI,EAAG;AAChC,oBAAc;AAAA,QACV,MAAM,QAAQ;AAAA,QACd,aAAa,QAAQ;AAAA,QACrB,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,MACb,GAAG,OAAO;AACV;AAAA,IACJ;AACA,QAAI,WAAW,SAAS,GAAG;AACvB,aAAO,KAAK,WAAW,UAAU,WAAW,MAAM,uBAAuB;AAAA,IAC7E;AAAA,EACJ,SAAS,GAAG;AACR,WAAO,KAAK,WAAW,sCAAuC,EAAY,OAAO,EAAE;AAAA,EACvF;AACJ;AAiBA,SAAS,cAAc,UAAsC;AACzD,QAAM,UAAU,aAAa,UAAU,OAAO;AAG9C,QAAM,OAAO,QAAQ,MAAM,iBAAiB,IAAI,CAAC,GAAG,KAAK;AACzD,QAAM,cAAc,QAAQ,MAAM,wBAAwB,IAAI,CAAC,GAAG,KAAK;AACvE,QAAM,cAAc,QAAQ,MAAM,0CAA0C;AAC5E,QAAM,SAAS,cAAc,CAAC,GAAG,QAAQ,WAAW,EAAE;AAEtD,MAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ;AAClC,WAAO,MAAM,WAAW,YAAY,QAAQ,wCAAwC;AACpF,WAAO;AAAA,EACX;AAGA,QAAM,gBAAgB,QAAQ,MAAM,4DAA4D;AAChG,QAAM,aAAsD,CAAC;AAC7D,QAAM,WAAqB,CAAC;AAE5B,MAAI,eAAe;AACf,UAAM,aAAa,cAAc,CAAC,EAAE,MAAM,IAAI;AAC9C,QAAI,eAAe;AACnB,eAAW,QAAQ,YAAY;AAC3B,YAAM,aAAa,KAAK,MAAM,kBAAkB;AAChD,UAAI,YAAY;AACZ,uBAAe,WAAW,CAAC;AAC3B,mBAAW,YAAY,IAAI,CAAC;AAC5B;AAAA,MACJ;AACA,UAAI,cAAc;AACd,cAAM,YAAY,KAAK,MAAM,qBAAqB;AAClD,cAAM,YAAY,KAAK,MAAM,4BAA4B;AACzD,cAAM,WAAW,KAAK,MAAM,yBAAyB;AACrD,cAAM,WAAW,KAAK,MAAM,wBAAwB;AACpD,YAAI,UAAW,YAAW,YAAY,EAAE,OAAO,UAAU,CAAC,EAAE,KAAK;AACjE,YAAI,UAAW,YAAW,YAAY,EAAE,cAAc,UAAU,CAAC,EAAE,KAAK;AACxE,YAAI,SAAU,UAAS,KAAK,YAAY;AACxC,YAAI,SAAU,YAAW,YAAY,EAAE,UAAU,SAAS,CAAC,EAAE,KAAK;AAAA,MACtE;AAAA,IACJ;AAAA,EACJ;AAGA,QAAM,UAAuB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,YAAY;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,IAC/C;AAAA,IACA,SAAS,OAAO,SAAkC;AAC9C,UAAI;AAEA,cAAM,cAAc,CAAC,QAAgB;AAEjC,gBAAM,UAAU,CAAC,MAAM,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC5D,cAAI,CAAC,QAAQ,SAAS,GAAG,EAAG,OAAM,IAAI,MAAM,WAAW,GAAG,8BAA8B;AACxF,iBAAO,QAAQ,GAAG;AAAA,QACtB;AACA,cAAM,UAAmC;AAAA,UACrC;AAAA,UACA,SAAS;AAAA,UACT,SAAS,EAAE,KAAK,QAAQ,IAAI;AAAA,UAC5B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACJ;AAEA,cAAM,UAAU,uBAAuB,MAAM;AAC7C,cAAM,SAAS,MAAM,GAAG,gBAAgB,SAAS,SAAS,EAAE,SAAS,IAAM,CAAC;AAC5E,eAAO,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,MAC/E,SAAS,KAAK;AACV,eAAO,UAAW,IAAc,OAAO;AAAA,MAC3C;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,MAAM,WAAW,sBAAsB,IAAI,SAAS,QAAQ,EAAE;AACrE,SAAO;AACX;","names":[]}
1
+ {"version":3,"sources":["../../src/skills/registry.ts"],"sourcesContent":["/**\n * TITAN — Skills Registry\n * Discovers, loads, and manages skills from bundled, workspace, and marketplace sources.\n */\nimport { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport vm from 'vm';\nimport { TITAN_HOME, TITAN_SKILLS_DIR } from '../utils/constants.js';\nimport { registerTool, type ToolHandler } from '../agent/toolRunner.js';\nimport { mkdirIfNotExists } from '../utils/helpers.js';\nimport logger from '../utils/logger.js';\nimport { loadConfig } from '../config/config.js';\n\nconst COMPONENT = 'Skills';\nconst DISABLED_SKILLS_PATH = join(TITAN_HOME, 'disabled-skills.json');\n\nexport interface SkillMeta {\n name: string;\n description: string;\n version: string;\n author?: string;\n source: 'bundled' | 'workspace' | 'marketplace' | 'frontmatter';\n enabled: boolean;\n}\n\nconst registeredSkills: Map<string, SkillMeta> = new Map();\n\n/** Maps skill name → tool names belonging to that skill */\nconst skillToolMap: Map<string, Set<string>> = new Map();\n\n/** Register a built-in skill (tool handler + metadata) */\nexport function registerSkill(meta: SkillMeta, handler: ToolHandler): void {\n registeredSkills.set(meta.name, meta);\n // Track which tools belong to this skill\n if (!skillToolMap.has(meta.name)) {\n skillToolMap.set(meta.name, new Set());\n }\n skillToolMap.get(meta.name)!.add(handler.name);\n registerTool(handler);\n logger.debug(COMPONENT, `Registered skill: ${meta.name} (${meta.source})`);\n}\n\n/** Get all registered skills (with persisted enabled/disabled state applied) */\nexport function getSkills(): SkillMeta[] {\n const disabled = loadDisabledSkills();\n return Array.from(registeredSkills.values()).map(s => ({\n ...s,\n enabled: !disabled.includes(s.name),\n }));\n}\n\n/** Get a skill by name */\nexport function getSkill(name: string): SkillMeta | undefined {\n return registeredSkills.get(name);\n}\n\n/** Get tool names belonging to a skill */\nexport function getSkillTools(skillName: string): string[] {\n return Array.from(skillToolMap.get(skillName) || []);\n}\n\n/** Check if a skill is enabled */\nexport function isSkillEnabled(skillName: string): boolean {\n return !loadDisabledSkills().includes(skillName);\n}\n\n/** Check if a specific tool's parent skill is enabled */\nexport function isToolSkillEnabled(toolName: string): boolean {\n for (const [skillName, tools] of skillToolMap.entries()) {\n if (tools.has(toolName)) {\n return isSkillEnabled(skillName);\n }\n }\n return true; // Tools not belonging to any skill are always enabled\n}\n\n/** Toggle a skill on/off. Returns the new enabled state. */\nexport function toggleSkill(skillName: string): boolean {\n const skill = registeredSkills.get(skillName);\n if (!skill) {\n throw new Error(`Skill \"${skillName}\" not found`);\n }\n\n const disabled = loadDisabledSkills();\n const idx = disabled.indexOf(skillName);\n let nowEnabled: boolean;\n\n if (idx >= 0) {\n disabled.splice(idx, 1);\n nowEnabled = true;\n } else {\n disabled.push(skillName);\n nowEnabled = false;\n }\n\n saveDisabledSkills(disabled);\n logger.info(COMPONENT, `Skill \"${skillName}\" ${nowEnabled ? 'enabled' : 'disabled'}`);\n return nowEnabled;\n}\n\n/** Set a skill's enabled state explicitly */\nexport function setSkillEnabled(skillName: string, enabled: boolean): void {\n const skill = registeredSkills.get(skillName);\n if (!skill) {\n throw new Error(`Skill \"${skillName}\" not found`);\n }\n\n const disabled = loadDisabledSkills();\n const idx = disabled.indexOf(skillName);\n\n if (enabled && idx >= 0) {\n disabled.splice(idx, 1);\n } else if (!enabled && idx < 0) {\n disabled.push(skillName);\n }\n\n saveDisabledSkills(disabled);\n}\n\n// ── Disabled-skills disk cache (30s TTL) ─────────────────────────\nlet _disabledSkillsCache: string[] | null = null;\nlet _disabledSkillsCacheAt = 0;\nconst DISABLED_SKILLS_CACHE_TTL_MS = 30_000;\n\n/** Load disabled skills list from disk (cached for 30 s to avoid ~7 k reads/req) */\nfunction loadDisabledSkills(): string[] {\n const now = Date.now();\n if (_disabledSkillsCache !== null && now - _disabledSkillsCacheAt < DISABLED_SKILLS_CACHE_TTL_MS) {\n return _disabledSkillsCache;\n }\n let result: string[] = [];\n try {\n if (existsSync(DISABLED_SKILLS_PATH)) {\n result = JSON.parse(readFileSync(DISABLED_SKILLS_PATH, 'utf-8')) as string[];\n }\n } catch {\n // Corrupt file — treat as empty\n }\n _disabledSkillsCache = result;\n _disabledSkillsCacheAt = now;\n return result;\n}\n\n/** Save disabled skills list to disk and invalidate the in-memory cache */\nfunction saveDisabledSkills(disabled: string[]): void {\n _disabledSkillsCache = null; // Invalidate cache on write\n try {\n const dir = dirname(DISABLED_SKILLS_PATH);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(DISABLED_SKILLS_PATH, JSON.stringify(disabled, null, 2), 'utf-8');\n } catch (e) {\n logger.warn(COMPONENT, `Failed to save disabled skills: ${(e as Error).message}`);\n }\n}\n\n/** Discover workspace skills from ~/.titan/workspace/skills/ */\nexport function discoverWorkspaceSkills(): SkillMeta[] {\n mkdirIfNotExists(TITAN_SKILLS_DIR);\n const discovered: SkillMeta[] = [];\n\n if (!existsSync(TITAN_SKILLS_DIR)) return discovered;\n\n const entries = readdirSync(TITAN_SKILLS_DIR, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillDir = join(TITAN_SKILLS_DIR, entry.name);\n const skillMdPath = join(skillDir, 'SKILL.md');\n\n if (!existsSync(skillMdPath)) continue;\n\n try {\n const content = readFileSync(skillMdPath, 'utf-8');\n const meta = parseSkillMd(content, entry.name);\n if (meta) {\n discovered.push({ ...meta, source: 'workspace', enabled: true });\n }\n } catch (error) {\n logger.warn(COMPONENT, `Failed to load skill ${entry.name}: ${(error as Error).message}`);\n }\n }\n\n logger.info(COMPONENT, `Discovered ${discovered.length} workspace skills`);\n return discovered;\n}\n\n/** Parse SKILL.md frontmatter to extract metadata */\nfunction parseSkillMd(content: string, fallbackName: string): Omit<SkillMeta, 'source' | 'enabled'> | null {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!frontmatterMatch) {\n return {\n name: fallbackName,\n description: content.split('\\n')[0] || 'No description',\n version: '1.0.0',\n };\n }\n\n const frontmatter = frontmatterMatch[1];\n const name = frontmatter.match(/name:\\s*(.+)/)?.[1]?.trim() || fallbackName;\n const description = frontmatter.match(/description:\\s*(.+)/)?.[1]?.trim() || 'No description';\n const version = frontmatter.match(/version:\\s*(.+)/)?.[1]?.trim() || '1.0.0';\n const author = frontmatter.match(/author:\\s*(.+)/)?.[1]?.trim();\n\n return { name, description, version, author };\n}\n\n/** Initialize all built-in skills */\nexport async function initBuiltinSkills(): Promise<void> {\n logger.info(COMPONENT, 'Loading built-in skills...');\n\n // beta.15 (Phase D.3) — register the canonical tool contracts so\n // the tool runner can validate args BEFORE skills' execute()\n // runs. Done FIRST so contracts are available the moment a skill\n // is registered (in case any skill registration triggers a tool\n // call as a side-effect, which shouldn't happen but defends\n // against future bootstrap shuffles).\n try {\n const { registerCanonicalContracts } = await import('./builtin/contracts.js');\n registerCanonicalContracts();\n logger.debug(COMPONENT, 'Registered canonical tool contracts');\n } catch (err) {\n logger.warn(COMPONENT, `Failed to register canonical contracts: ${(err as Error).message}`);\n }\n\n // Import and register built-in skills\n const { registerShellSkill } = await import('./builtin/shell.js');\n const { registerFilesystemSkill } = await import('./builtin/filesystem.js');\n const { registerWebSearchSkill } = await import('./builtin/web_search.js');\n const { registerCronSkill } = await import('./builtin/cron.js');\n const { registerWebhookSkill } = await import('./builtin/webhook.js');\n const { registerMemorySkill } = await import('./builtin/memory_skill.js');\n const { registerBrowserSkill } = await import('./builtin/browser.js');\n const { registerSessionsSkill } = await import('./builtin/sessions.js');\n const { registerProcessSkill } = await import('./builtin/process.js');\n const { registerWebFetchSkill } = await import('./builtin/web_fetch.js');\n const { registerDownloadImageSkill } = await import('./builtin/download_image.js');\n const { registerApplyPatchSkill } = await import('./builtin/apply_patch.js');\n const { registerAutoGenerateSkill } = await import('./builtin/auto_generate.js');\n const { registerVisionSkill } = await import('./builtin/vision.js');\n const { registerVoiceSkills } = await import('./builtin/voice.js');\n const { registerMemoryGraphSkill } = await import('./builtin/memory_graph.js');\n const { initWebBrowserTool } = await import('./builtin/web_browser.js');\n const { registerGitHubSkill } = await import('./builtin/github.js');\n const { registerEmailSkill } = await import('./builtin/email.js');\n const { registerComputerUseSkill } = await import('./builtin/computer_use.js');\n const { registerImageGenSkill } = await import('./builtin/image_gen.js');\n const { registerPdfSkill } = await import('./builtin/pdf.js');\n const { registerCalendarSkill } = await import('./builtin/calendar.js');\n const { registerSmartHomeSkill } = await import('./builtin/smart_home.js');\n const { registerDataAnalysisSkill } = await import('./builtin/data_analysis.js');\n const { registerSkyvernSkill } = await import('./builtin/skyvern.js');\n const { registerWebBrowseLlmSkill } = await import('./builtin/web_browse_llm.js');\n const { registerIncomeTrackerSkill } = await import('./builtin/income_tracker.js');\n const { registerFreelanceMonitorSkill } = await import('./builtin/freelance_monitor.js');\n const { registerContentPublisherSkill } = await import('./builtin/content_publisher.js');\n const { registerLeadScorerSkill } = await import('./builtin/lead_scorer.js');\n const { registerHunterSkill } = await import('./builtin/hunter.js');\n const { registerCodeExecSkill } = await import('./builtin/code_exec.js');\n const { registerExecuteCodeSkill } = await import('./builtin/executeCode.js');\n const { registerWeatherSkill } = await import('./builtin/weather.js');\n const { registerGoalsSkill } = await import('./builtin/goals.js');\n const { registerXPosterSkill } = await import('./builtin/x_poster.js');\n const { initModelSwitchTool } = await import('./builtin/model_switch.js');\n const { registerRagSkill } = await import('./builtin/rag.js');\n const { registerDeepResearchSkill } = await import('./builtin/deep_research.js');\n const { registerSystemInfoSkill } = await import('./builtin/system_info.js');\n const { registerCurrentModelSkill } = await import('./builtin/current_model.js');\n const { registerPersonaManagerSkill } = await import('./builtin/persona_manager.js');\n const { registerResearchPipelineSkill } = await import('./builtin/research_pipeline.js');\n const { registerAutoresearchSkill } = await import('./builtin/autoresearch.js');\n const { registerSelfDoctorSkill } = await import('./builtin/self_doctor.js');\n const { registerInteractionTrackerSkill } = await import('./builtin/interaction_tracker.js');\n const { registerFeedbackTrackerSkill } = await import('./builtin/feedback_tracker.js');\n const { registerGrowthExperimentsSkill } = await import('./builtin/growth_experiments.js');\n const { registerContentCalendarSkill } = await import('./builtin/content_calendar.js');\n const { registerSlackSkill } = await import('./builtin/slack.js');\n const { registerRevenueCatKBSkill } = await import('./builtin/revenuecat_kb.js');\n const { registerWeeklyReportSkill } = await import('./builtin/weekly_report.js');\n const { registerSelfImproveSkill } = await import('./builtin/self_improve.js');\n const { registerGepaSkill } = await import('./builtin/gepa.js');\n const { registerModelTrainerSkill } = await import('./builtin/model_trainer.js');\n const { registerSocialSchedulerSkill } = await import('./builtin/social_scheduler.js');\n const { registerStructuredOutputSkill } = await import('./builtin/structured_output.js');\n const { registerWorkflowsSkill } = await import('./builtin/workflows.js');\n const { registerAgentHandoffSkill } = await import('./builtin/agent_handoff.js');\n const { registerKnowledgeBaseSkill } = await import('./builtin/knowledge_base.js');\n const { registerEventTriggersSkill } = await import('./builtin/event_triggers.js');\n const { registerA2AProtocolSkill } = await import('./builtin/a2a_protocol.js');\n const { registerEvalsSkill } = await import('./builtin/evals.js');\n const { registerApprovalGatesSkill } = await import('./builtin/approval_gates.js');\n const { registerPhoneCallSkill } = await import('./builtin/phone_call.js');\n const { registerVRAMSkills } = await import('./builtin/vram.js');\n const { registerSecurityScanSkill } = await import('./builtin/security_scan.js');\n const { registerConfigAuditSkill } = await import('./builtin/config_audit.js');\n const { registerSpecSkill } = await import('./builtin/spec.js');\n const { registerMemoryMapSkill } = await import('./builtin/memory_map.js');\n const { registerCodebaseExploreSkill } = await import('./builtin/codebase_explore.js');\n const { registerReminderSkill } = await import('./builtin/reminders.js');\n const { registerDelegateAgentSkill } = await import('./builtin/delegate_agent.js');\n const { registerChangelogGenSkill } = await import('./builtin/changelog_gen.js');\n const { registerJiraLinearSkill } = await import('./builtin/jira_linear.js');\n const { registerAuditTrailSkill } = await import('./builtin/audit_trail.js');\n const { registerVisualPlanSkill } = await import('./builtin/visual_plan.js');\n const { registerScreenRecordSkill } = await import('./builtin/screen_record.js');\n const { registerSessionTeleportSkill } = await import('./builtin/session_teleport.js');\n const { registerCrossProviderSkill } = await import('./builtin/cross_provider.js');\n const { registerSentrySkill } = await import('./builtin/sentry.js');\n const { registerVideoSkill } = await import('./builtin/video.js');\n const { registerMixtureOfAgentsSkill } = await import('./builtin/mixture_of_agents.js');\n const { registerAgentDebateSkill } = await import('./builtin/agent_debate.js');\n const { registerFileCheckpointsSkill } = await import('./builtin/file_checkpoints.js');\n const { registerVerifyPageSkill } = await import('./builtin/verify_page.js');\n const { registerAgentMessagingSkill } = await import('./builtin/agent_messaging.js');\n const { registerFacebookSkill } = await import('./builtin/facebook.js');\n const { registerFBAutopilotSkill } = await import('./builtin/fb_autopilot.js');\n const { registerWidgetGallerySkill } = await import('./builtin/widget_gallery.js');\n const { registerCanvasWidgetsSkill } = await import('./builtin/canvas_widgets.js');\n const { registerCanvasSpacesSkill } = await import('./builtin/canvas_spaces.js');\n const { registerPersonalGallerySkill } = await import('./builtin/personal_gallery.js');\n const { registerBackupSkill } = await import('./builtin/backup.js');\n\n const config = loadConfig();\n const primitiveMode = config.skills.primitiveMode;\n\n if (primitiveMode) {\n logger.info(COMPONENT, 'PRIMITIVE MODE ENABLED — loading only shell, filesystem, web_search');\n }\n\n const registrations: [string, () => void][] = [\n ['shell', registerShellSkill],\n ['filesystem', registerFilesystemSkill],\n ['web_search', registerWebSearchSkill],\n ];\n\n if (!primitiveMode) {\n registrations.push(\n ['cron', registerCronSkill],\n ['webhook', registerWebhookSkill],\n ['memory', registerMemorySkill],\n ['browser', registerBrowserSkill],\n ['sessions', registerSessionsSkill],\n ['process', registerProcessSkill],\n ['web_fetch', registerWebFetchSkill],\n ['download_image', registerDownloadImageSkill],\n ['apply_patch', registerApplyPatchSkill],\n ['auto_generate', registerAutoGenerateSkill],\n ['vision', registerVisionSkill],\n ['voice', registerVoiceSkills],\n ['memory_graph', registerMemoryGraphSkill],\n ['web_browser', initWebBrowserTool],\n ['github', registerGitHubSkill],\n ['email', registerEmailSkill],\n ['computer_use', registerComputerUseSkill],\n ['image_gen', registerImageGenSkill],\n ['pdf', registerPdfSkill],\n ['calendar', registerCalendarSkill],\n ['smart_home', registerSmartHomeSkill],\n ['data_analysis', registerDataAnalysisSkill],\n ['skyvern', registerSkyvernSkill],\n ['web_browse_llm', registerWebBrowseLlmSkill],\n ['income_tracker', registerIncomeTrackerSkill],\n ['freelance_monitor', registerFreelanceMonitorSkill],\n ['content_publisher', registerContentPublisherSkill],\n ['lead_scorer', registerLeadScorerSkill],\n ['hunter', registerHunterSkill],\n ['code_exec', registerCodeExecSkill],\n ['execute_code', registerExecuteCodeSkill],\n ['weather', registerWeatherSkill],\n ['goals', registerGoalsSkill],\n ['x_poster', registerXPosterSkill],\n ['model_switch', initModelSwitchTool],\n ['rag', registerRagSkill],\n ['deep_research', registerDeepResearchSkill],\n ['system_info', registerSystemInfoSkill],\n ['current_model', registerCurrentModelSkill],\n ['persona_manager', registerPersonaManagerSkill],\n ['research_pipeline', registerResearchPipelineSkill],\n ['autoresearch', registerAutoresearchSkill],\n ['self_doctor', registerSelfDoctorSkill],\n ['interaction_tracker', registerInteractionTrackerSkill],\n ['feedback_tracker', registerFeedbackTrackerSkill],\n ['growth_experiments', registerGrowthExperimentsSkill],\n ['content_calendar', registerContentCalendarSkill],\n ['slack', registerSlackSkill],\n ['revenuecat_kb', registerRevenueCatKBSkill],\n ['weekly_report', registerWeeklyReportSkill],\n ['self_improve', registerSelfImproveSkill],\n ['gepa', registerGepaSkill],\n ['model_trainer', registerModelTrainerSkill],\n ['social_scheduler', registerSocialSchedulerSkill],\n ['structured_output', registerStructuredOutputSkill],\n ['workflows', registerWorkflowsSkill],\n ['agent_handoff', registerAgentHandoffSkill],\n ['knowledge_base', registerKnowledgeBaseSkill],\n ['event_triggers', registerEventTriggersSkill],\n ['evals', registerEvalsSkill],\n ['a2a_protocol', registerA2AProtocolSkill],\n ['approval_gates', registerApprovalGatesSkill],\n ['phone_call', registerPhoneCallSkill],\n ['vram', registerVRAMSkills],\n ['security_scan', registerSecurityScanSkill],\n ['config_audit', registerConfigAuditSkill],\n ['spec', registerSpecSkill],\n ['memory_map', registerMemoryMapSkill],\n ['codebase_explore', registerCodebaseExploreSkill],\n ['reminder', registerReminderSkill],\n ['delegate_agent', registerDelegateAgentSkill],\n ['changelog_gen', registerChangelogGenSkill],\n ['jira_linear', registerJiraLinearSkill],\n ['audit_trail', registerAuditTrailSkill],\n ['visual_plan', registerVisualPlanSkill],\n ['screen_record', registerScreenRecordSkill],\n ['session_teleport', registerSessionTeleportSkill],\n ['cross_provider', registerCrossProviderSkill],\n ['sentry', registerSentrySkill],\n ['video', registerVideoSkill],\n ['mixture_of_agents', registerMixtureOfAgentsSkill],\n ['agent_debate', registerAgentDebateSkill],\n ['file_checkpoints', registerFileCheckpointsSkill],\n ['verify_page', registerVerifyPageSkill],\n ['agent_messaging', registerAgentMessagingSkill],\n ['facebook', registerFacebookSkill],\n ['fb_autopilot', registerFBAutopilotSkill],\n ['widget_gallery', registerWidgetGallerySkill],\n ['widget_gallery', registerWidgetGallerySkill],\n ['canvas_widgets', registerCanvasWidgetsSkill],\n ['canvas_spaces', registerCanvasSpacesSkill],\n ['personal_gallery', registerPersonalGallerySkill],\n ['backup', registerBackupSkill],\n );\n }\n for (const [name, fn] of registrations) {\n try { fn(); } catch (e) { logger.warn(COMPONENT, `Failed to register skill \"${name}\": ${(e as Error).message}`); }\n }\n\n if (!primitiveMode) {\n // Register planner as an LLM-invocable tool\n const { registerPlannerTool } = await import('../agent/planner.js');\n try { registerPlannerTool(); } catch (e) { logger.warn(COMPONENT, `Failed to register planner: ${(e as Error).message}`); }\n\n // Register TopFacts context engine plugin (DeerFlow-inspired persistent memory)\n try {\n const { createTopFactsPlugin } = await import('../plugins/topFacts.js');\n const { createMemoryRetrievalPlugin } = await import('../plugins/memoryRetrieval.js');\n const { registerPlugin } = await import('../plugins/registry.js');\n const topFacts = createTopFactsPlugin();\n registerPlugin(topFacts);\n if (topFacts.bootstrap) await topFacts.bootstrap({});\n const memoryRetrieval = createMemoryRetrievalPlugin();\n registerPlugin(memoryRetrieval);\n if (memoryRetrieval.bootstrap) await memoryRetrieval.bootstrap({});\n } catch (e) { logger.warn(COMPONENT, `Failed to register TopFacts plugin: ${(e as Error).message}`); }\n\n // Register SmartCompress context engine plugin (task-type-aware compression)\n try {\n const { createSmartCompressPlugin } = await import('../plugins/smartCompress.js');\n const { registerPlugin: regPlugin } = await import('../plugins/registry.js');\n const smartCompress = createSmartCompressPlugin();\n regPlugin(smartCompress);\n if (smartCompress.bootstrap) await smartCompress.bootstrap({});\n } catch (e) { logger.warn(COMPONENT, `Failed to register SmartCompress plugin: ${(e as Error).message}`); }\n\n // Register tool_search + tool_expand — meta-tools for discovering tools on demand\n // tool_expand is the progressive disclosure extension (Hermes competitive gap fix)\n const { getToolSearchHandler, getToolExpandHandler } = await import('../agent/toolSearch.js');\n try { registerTool(getToolSearchHandler()); } catch (e) { logger.warn(COMPONENT, `Failed to register tool_search: ${(e as Error).message}`); }\n try { registerTool(getToolExpandHandler()); } catch (e) { logger.warn(COMPONENT, `Failed to register tool_expand: ${(e as Error).message}`); }\n\n // F3: Register procedural memory tools (Hermes-inspired skill learning)\n try {\n const { saveSkill, searchSkills } = await import('./proceduralMemory.js');\n registerTool({\n name: 'save_skill',\n description: 'Save a reusable approach/technique as a procedural skill for future tasks. Use this when you discover an effective approach that could help in similar future situations.',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Short descriptive name for the skill (e.g., \"Deploy Node.js app to Docker\")' },\n tags: { type: 'array', items: { type: 'string' }, description: 'Tags for searchability (e.g., [\"docker\", \"deployment\", \"nodejs\"])' },\n content: { type: 'string', description: 'The reusable approach/technique in markdown format. Include key steps, commands, and gotchas.' },\n },\n required: ['name', 'tags', 'content'],\n },\n execute: async (args: Record<string, unknown>) => {\n const name = args.name as string;\n const tags = (args.tags as string[]) || [];\n const content = args.content as string;\n if (!name || !content) return 'Error: name and content are required';\n const skill = saveSkill(name, tags, content);\n return `Skill saved: \"${skill.name}\" (tags: ${skill.tags.join(', ')}). It will be auto-recalled in future tasks matching these tags.`;\n },\n });\n registerTool({\n name: 'recall_skill',\n description: 'Search for previously saved procedural skills by keyword or tag. Returns reusable approaches from past tasks.',\n parameters: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query — keywords or tags to find relevant skills' },\n },\n required: ['query'],\n },\n execute: async (args: Record<string, unknown>) => {\n const query = args.query as string;\n if (!query) return 'Error: query is required';\n const results = searchSkills(query, 5);\n if (results.length === 0) return 'No matching skills found. Consider saving useful approaches with save_skill.';\n return results.map(s =>\n `### ${s.name}\\nTags: ${s.tags.join(', ')} | Used ${s.useCount}x\\n${s.content.slice(0, 800)}`\n ).join('\\n\\n---\\n\\n');\n },\n });\n logger.info(COMPONENT, 'Registered procedural memory tools (save_skill, recall_skill)');\n } catch (e) { logger.warn(COMPONENT, `Failed to register procedural memory tools: ${(e as Error).message}`); }\n }\n\n logger.info(COMPONENT, `Loaded ${registeredSkills.size} built-in skills`);\n\n // Load dev skills (only in dev mode — skip import entirely in production)\n if (process.env.NODE_ENV !== 'production' || process.env.TITAN_DEV) {\n const { initDevSkills } = await import('./dev/loader.js');\n await initDevSkills();\n }\n\n // Load NVIDIA skills (optional — only when TITAN_NVIDIA=1 or nvidia.enabled in config)\n try {\n let nvidiaEnabled = process.env.TITAN_NVIDIA === '1';\n if (!nvidiaEnabled) {\n try {\n const { loadConfig: _loadConfig } = await import('../config/config.js');\n const cfg = _loadConfig() as Record<string, unknown>;\n const nvCfg = cfg.nvidia as Record<string, unknown> | undefined;\n nvidiaEnabled = nvCfg?.enabled === true;\n } catch { /* config not available in test env */ }\n }\n if (nvidiaEnabled) {\n const { initNvidiaSkills } = await import('./nvidia/loader.js');\n await initNvidiaSkills();\n }\n } catch (err) {\n logger.warn(COMPONENT, `NVIDIA skills failed to load: ${(err as Error).message}`);\n }\n\n // Load personal skills (private, gitignored — only when TITAN_PERSONAL=1)\n // Primary location: dist/skills/personal/loader.js (co-located with dist/skills/registry.js\n // so `../registry` resolves to the SAME module instance — tools register into the correct registry)\n // Fallback: ~/.titan/personal/loader.js (legacy / TITAN_PERSONAL_DIR override)\n if (process.env.TITAN_PERSONAL === '1') {\n try {\n const { pathToFileURL, fileURLToPath } = await import('node:url');\n const { join: _join, dirname: _dirname } = await import('node:path');\n // Compute dist/skills/ dir from this file's location (works on any machine)\n const thisDir = _dirname(fileURLToPath(import.meta.url));\n const distPersonalDir = _join(thisDir, 'personal');\n // TITAN_PERSONAL_DIR env var overrides; otherwise try dist-local first, then ~/.titan/personal/\n const personalDir = process.env.TITAN_PERSONAL_DIR\n || (existsSync(_join(distPersonalDir, 'loader.js')) ? distPersonalDir : _join(TITAN_HOME, 'personal'));\n const loaderPath = _join(personalDir, 'loader.js');\n if (existsSync(loaderPath)) {\n // Inject the main app's registerSkill into a global so the personal bundle\n // (which has its own bundled copy) uses the correct shared toolRegistry instance.\n (globalThis as Record<string, unknown>).__titanRegisterSkill = registerSkill;\n const { initPersonalSkills } = await import(pathToFileURL(loaderPath).href) as { initPersonalSkills: () => Promise<void> };\n await initPersonalSkills();\n } else {\n logger.warn(COMPONENT, `TITAN_PERSONAL=1 but ${loaderPath} not found — run: npm run build:personal`);\n }\n } catch (err) {\n logger.warn(COMPONENT, `Personal skills failed to load: ${(err as Error).message}`);\n }\n }\n}\n\n/**\n * Discover and load user skills from ~/.titan/skills/ (all subdirs).\n * Supports:\n * 1. JavaScript files (.js) that export default { name, description, parameters, execute }\n * 2. YAML skill definitions (.yaml/.yml) with inline scripts\n * 3. Auto-generated skills from ~/.titan/skills/auto/\n */\nexport async function loadAutoSkills(): Promise<void> {\n const skillsRoot = join(TITAN_HOME, 'skills');\n if (!existsSync(skillsRoot)) return;\n\n logger.info(COMPONENT, 'Scanning for user skills...');\n let loadedCount = 0;\n\n // Scan both root and all subdirectories\n const dirsToScan = [skillsRoot];\n const entries = readdirSync(skillsRoot, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) dirsToScan.push(join(skillsRoot, entry.name));\n }\n\n for (const dir of dirsToScan) {\n const files = readdirSync(dir).filter(f =>\n f.endsWith('.js') || f.endsWith('.yaml') || f.endsWith('.yml')\n );\n\n for (const file of files) {\n const filePath = join(dir, file);\n try {\n if (file.endsWith('.js')) {\n // JavaScript skill — export default { name, description, parameters, execute }\n const modulePath = `file://${filePath}?t=${Date.now()}`;\n const mod = await import(modulePath);\n if (mod.default && mod.default.name && mod.default.execute) {\n const handler = mod.default as ToolHandler;\n if (registeredSkills.has(handler.name)) continue; // Skip duplicates\n registerSkill({\n name: handler.name,\n description: handler.description || 'User skill',\n version: '1.0.0',\n source: 'workspace',\n enabled: true,\n }, handler);\n loadedCount++;\n }\n } else {\n // YAML skill definition\n const loaded = loadYamlSkill(filePath);\n if (loaded && !registeredSkills.has(loaded.name)) {\n registerSkill({\n name: loaded.name,\n description: loaded.description,\n version: '1.0.0',\n source: 'workspace',\n enabled: true,\n }, loaded);\n loadedCount++;\n }\n }\n } catch (e: unknown) {\n logger.warn(COMPONENT, `Failed to load skill ${file}: ${(e as Error).message}`);\n }\n }\n }\n\n if (loadedCount > 0) {\n logger.info(COMPONENT, `Loaded ${loadedCount} user skill(s) from ~/.titan/skills/`);\n }\n\n // Load frontmatter skills (*.skill.md) — Space Agent / Hermes parity\n try {\n const { getFrontmatterToolHandlers } = await import('./frontmatterLoader.js');\n const fmHandlers = getFrontmatterToolHandlers();\n for (const { name, handler } of fmHandlers) {\n if (registeredSkills.has(name)) continue;\n registerSkill({\n name: handler.name,\n description: handler.description,\n version: '1.0.0',\n source: 'frontmatter',\n enabled: true,\n }, handler);\n loadedCount++;\n }\n if (fmHandlers.length > 0) {\n logger.info(COMPONENT, `Loaded ${fmHandlers.length} frontmatter skill(s)`);\n }\n } catch (e) {\n logger.warn(COMPONENT, `Frontmatter skills failed to load: ${(e as Error).message}`);\n }\n}\n\n/**\n * Load a YAML skill definition.\n * Format:\n * name: my_tool\n * description: What it does\n * parameters:\n * myParam:\n * type: string\n * description: A parameter\n * required: true\n * script: |\n * // JavaScript code. Use `args.myParam` for inputs.\n * // Return a string result.\n * return \"Hello \" + args.myParam;\n */\nfunction loadYamlSkill(filePath: string): ToolHandler | null {\n const content = readFileSync(filePath, 'utf-8');\n\n // Simple YAML parser (no dependency needed for this basic format)\n const name = content.match(/^name:\\s*(.+)$/m)?.[1]?.trim();\n const description = content.match(/^description:\\s*(.+)$/m)?.[1]?.trim();\n const scriptMatch = content.match(/^script:\\s*\\|\\n([\\s\\S]+?)(?=\\n\\w|\\n$|$)/m);\n const script = scriptMatch?.[1]?.replace(/^ {2}/gm, ''); // Remove YAML indent\n\n if (!name || !description || !script) {\n logger.debug(COMPONENT, `Skipping ${filePath}: missing name, description, or script`);\n return null;\n }\n\n // Parse parameters section\n const paramsSection = content.match(/^parameters:\\n((?:\\s{2}\\w[\\s\\S]*?)(?=\\nscript:|\\n\\w|\\n$))/m);\n const properties: Record<string, Record<string, unknown>> = {};\n const required: string[] = [];\n\n if (paramsSection) {\n const paramLines = paramsSection[1].split('\\n');\n let currentParam = '';\n for (const line of paramLines) {\n const paramMatch = line.match(/^\\s{2}(\\w+):\\s*$/);\n if (paramMatch) {\n currentParam = paramMatch[1];\n properties[currentParam] = {};\n continue;\n }\n if (currentParam) {\n const typeMatch = line.match(/^\\s{4}type:\\s*(.+)$/);\n const descMatch = line.match(/^\\s{4}description:\\s*(.+)$/);\n const reqMatch = line.match(/^\\s{4}required:\\s*true$/);\n const defMatch = line.match(/^\\s{4}default:\\s*(.+)$/);\n if (typeMatch) properties[currentParam].type = typeMatch[1].trim();\n if (descMatch) properties[currentParam].description = descMatch[1].trim();\n if (reqMatch) required.push(currentParam);\n if (defMatch) properties[currentParam].default = defMatch[1].trim();\n }\n }\n }\n\n // Create the execute function from the script\n const handler: ToolHandler = {\n name,\n description,\n parameters: {\n type: 'object',\n properties,\n required: required.length > 0 ? required : undefined,\n },\n execute: async (args: Record<string, unknown>) => {\n try {\n // Run in a restricted VM context — no access to globalThis, process, eval, or Function\n const safeRequire = (mod: string) => {\n // SECURITY: child_process, http, https removed — YAML skills must use builtin tools for shell/network\n const allowed = ['fs', 'path', 'os', 'crypto', 'url', 'util'];\n if (!allowed.includes(mod)) throw new Error(`Module \"${mod}\" not allowed in YAML skills`);\n return require(mod); // eslint-disable-line @typescript-eslint/no-require-imports\n };\n const sandbox: Record<string, unknown> = {\n args,\n require: safeRequire,\n console: { log: console.log },\n JSON,\n Math,\n Date,\n String,\n Number,\n Array,\n Object,\n RegExp,\n Map,\n Set,\n Promise,\n setTimeout,\n Buffer,\n };\n // Wrap the user script in an async IIFE so `return` works and we can await it\n const wrapped = `(async function() { ${script} })()`;\n const result = await vm.runInNewContext(wrapped, sandbox, { timeout: 10000 });\n return typeof result === 'string' ? result : JSON.stringify(result, null, 2);\n } catch (err) {\n return `Error: ${(err as Error).message}`;\n }\n },\n };\n\n logger.debug(COMPONENT, `Loaded YAML skill: ${name} from ${filePath}`);\n return handler;\n}\n"],"mappings":"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","names":[]}