waterplane 0.1.24 → 0.1.26

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 (429) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/SECURITY.md +25 -5
  3. package/node_modules/@waterplane/shared/dist/agentseries/compare.d.ts +8 -0
  4. package/node_modules/@waterplane/shared/dist/agentseries/compare.js +103 -0
  5. package/node_modules/@waterplane/shared/dist/agentseries/compare.js.map +1 -0
  6. package/node_modules/@waterplane/shared/dist/agentseries/markers.d.ts +17 -0
  7. package/node_modules/@waterplane/shared/dist/agentseries/markers.js +125 -0
  8. package/node_modules/@waterplane/shared/dist/agentseries/markers.js.map +1 -0
  9. package/node_modules/@waterplane/shared/dist/agentseries/series.d.ts +16 -0
  10. package/node_modules/@waterplane/shared/dist/agentseries/series.js +93 -0
  11. package/node_modules/@waterplane/shared/dist/agentseries/series.js.map +1 -0
  12. package/node_modules/@waterplane/shared/dist/agentseries/stats.d.ts +8 -0
  13. package/node_modules/@waterplane/shared/dist/agentseries/stats.js +33 -0
  14. package/node_modules/@waterplane/shared/dist/agentseries/stats.js.map +1 -0
  15. package/node_modules/@waterplane/shared/dist/agentseries/types.d.ts +103 -0
  16. package/node_modules/@waterplane/shared/dist/agentseries/types.js +11 -0
  17. package/node_modules/@waterplane/shared/dist/agentseries/types.js.map +1 -0
  18. package/node_modules/@waterplane/shared/dist/agentseries.d.ts +10 -0
  19. package/node_modules/@waterplane/shared/dist/agentseries.js +11 -0
  20. package/node_modules/@waterplane/shared/dist/agentseries.js.map +1 -0
  21. package/node_modules/@waterplane/shared/dist/calday.d.ts +5 -0
  22. package/node_modules/@waterplane/shared/dist/calday.js +10 -0
  23. package/node_modules/@waterplane/shared/dist/calday.js.map +1 -1
  24. package/node_modules/@waterplane/shared/dist/clihealth/healthfixture.d.ts +13 -1
  25. package/node_modules/@waterplane/shared/dist/clihealth/healthfixture.js +22 -4
  26. package/node_modules/@waterplane/shared/dist/clihealth/healthfixture.js.map +1 -1
  27. package/node_modules/@waterplane/shared/dist/clihealth.d.ts +1 -1
  28. package/node_modules/@waterplane/shared/dist/clihealth.js +1 -1
  29. package/node_modules/@waterplane/shared/dist/clihealth.js.map +1 -1
  30. package/node_modules/@waterplane/shared/dist/dictate.d.ts +6 -0
  31. package/node_modules/@waterplane/shared/dist/dictate.js.map +1 -1
  32. package/node_modules/@waterplane/shared/dist/dictatemodels.d.ts +23 -0
  33. package/node_modules/@waterplane/shared/dist/dictatemodels.js +31 -0
  34. package/node_modules/@waterplane/shared/dist/dictatemodels.js.map +1 -0
  35. package/node_modules/@waterplane/shared/dist/healthindex/commits.d.ts +1 -1
  36. package/node_modules/@waterplane/shared/dist/healthindex/commits.js +2 -2
  37. package/node_modules/@waterplane/shared/dist/healthindex/commits.js.map +1 -1
  38. package/node_modules/@waterplane/shared/dist/healthindex/coverage.d.ts +128 -0
  39. package/node_modules/@waterplane/shared/dist/healthindex/coverage.js +343 -0
  40. package/node_modules/@waterplane/shared/dist/healthindex/coverage.js.map +1 -0
  41. package/node_modules/@waterplane/shared/dist/healthindex/readings.d.ts +9 -1
  42. package/node_modules/@waterplane/shared/dist/healthindex/readings.js +122 -4
  43. package/node_modules/@waterplane/shared/dist/healthindex/readings.js.map +1 -1
  44. package/node_modules/@waterplane/shared/dist/healthindex/repoindex.d.ts +5 -0
  45. package/node_modules/@waterplane/shared/dist/healthindex/repoindex.js +2 -0
  46. package/node_modules/@waterplane/shared/dist/healthindex/repoindex.js.map +1 -1
  47. package/node_modules/@waterplane/shared/dist/healthindex/score.d.ts +3 -0
  48. package/node_modules/@waterplane/shared/dist/healthindex/score.js +52 -16
  49. package/node_modules/@waterplane/shared/dist/healthindex/score.js.map +1 -1
  50. package/node_modules/@waterplane/shared/dist/healthindex/types.d.ts +82 -6
  51. package/node_modules/@waterplane/shared/dist/healthindex/types.js +35 -2
  52. package/node_modules/@waterplane/shared/dist/healthindex/types.js.map +1 -1
  53. package/node_modules/@waterplane/shared/dist/healthindex/words.js +65 -6
  54. package/node_modules/@waterplane/shared/dist/healthindex/words.js.map +1 -1
  55. package/node_modules/@waterplane/shared/dist/healthindex.d.ts +21 -7
  56. package/node_modules/@waterplane/shared/dist/healthindex.js +20 -7
  57. package/node_modules/@waterplane/shared/dist/healthindex.js.map +1 -1
  58. package/node_modules/@waterplane/shared/dist/healthindexresponse.js +3 -2
  59. package/node_modules/@waterplane/shared/dist/healthindexresponse.js.map +1 -1
  60. package/node_modules/@waterplane/shared/dist/healthspend.d.ts +23 -0
  61. package/node_modules/@waterplane/shared/dist/healthspend.js +32 -1
  62. package/node_modules/@waterplane/shared/dist/healthspend.js.map +1 -1
  63. package/node_modules/@waterplane/shared/dist/hints.js +9 -0
  64. package/node_modules/@waterplane/shared/dist/hints.js.map +1 -1
  65. package/node_modules/@waterplane/shared/dist/index.d.ts +9 -0
  66. package/node_modules/@waterplane/shared/dist/index.js +9 -0
  67. package/node_modules/@waterplane/shared/dist/index.js.map +1 -1
  68. package/node_modules/@waterplane/shared/dist/installrow.js +10 -0
  69. package/node_modules/@waterplane/shared/dist/installrow.js.map +1 -1
  70. package/node_modules/@waterplane/shared/dist/intent/kind.d.ts +45 -1
  71. package/node_modules/@waterplane/shared/dist/intent/kind.js +60 -2
  72. package/node_modules/@waterplane/shared/dist/intent/kind.js.map +1 -1
  73. package/node_modules/@waterplane/shared/dist/intent.d.ts +1 -1
  74. package/node_modules/@waterplane/shared/dist/intent.js +1 -1
  75. package/node_modules/@waterplane/shared/dist/intent.js.map +1 -1
  76. package/node_modules/@waterplane/shared/dist/itempaths.d.ts +23 -0
  77. package/node_modules/@waterplane/shared/dist/itempaths.js +38 -0
  78. package/node_modules/@waterplane/shared/dist/itempaths.js.map +1 -1
  79. package/node_modules/@waterplane/shared/dist/pluginlaunch.d.ts +3 -2
  80. package/node_modules/@waterplane/shared/dist/pluginlaunch.js +1 -1
  81. package/node_modules/@waterplane/shared/dist/pluginlaunch.js.map +1 -1
  82. package/node_modules/@waterplane/shared/dist/pricelist.d.ts +57 -0
  83. package/node_modules/@waterplane/shared/dist/pricelist.js +128 -0
  84. package/node_modules/@waterplane/shared/dist/pricelist.js.map +1 -0
  85. package/node_modules/@waterplane/shared/dist/pricing.d.ts +86 -9
  86. package/node_modules/@waterplane/shared/dist/pricing.js +140 -20
  87. package/node_modules/@waterplane/shared/dist/pricing.js.map +1 -1
  88. package/node_modules/@waterplane/shared/dist/queue/queuelanestate.d.ts +14 -0
  89. package/node_modules/@waterplane/shared/dist/queue/queuelanestate.js +25 -0
  90. package/node_modules/@waterplane/shared/dist/queue/queuelanestate.js.map +1 -0
  91. package/node_modules/@waterplane/shared/dist/queue/queueplan.d.ts +4 -0
  92. package/node_modules/@waterplane/shared/dist/queue/queueplan.js +21 -0
  93. package/node_modules/@waterplane/shared/dist/queue/queueplan.js.map +1 -1
  94. package/node_modules/@waterplane/shared/dist/queue/queuewords.js +2 -1
  95. package/node_modules/@waterplane/shared/dist/queue/queuewords.js.map +1 -1
  96. package/node_modules/@waterplane/shared/dist/queue.d.ts +2 -0
  97. package/node_modules/@waterplane/shared/dist/queue.js +1 -0
  98. package/node_modules/@waterplane/shared/dist/queue.js.map +1 -1
  99. package/node_modules/@waterplane/shared/dist/repohealth.d.ts +178 -0
  100. package/node_modules/@waterplane/shared/dist/repohealth.js.map +1 -1
  101. package/node_modules/@waterplane/shared/dist/repohealthhabits.d.ts +15 -0
  102. package/node_modules/@waterplane/shared/dist/repohealthhabits.js +117 -0
  103. package/node_modules/@waterplane/shared/dist/repohealthhabits.js.map +1 -0
  104. package/node_modules/@waterplane/shared/dist/repohealthnative.d.ts +10 -0
  105. package/node_modules/@waterplane/shared/dist/repohealthnative.js +94 -0
  106. package/node_modules/@waterplane/shared/dist/repohealthnative.js.map +1 -0
  107. package/node_modules/@waterplane/shared/dist/repohealthread.js +23 -1
  108. package/node_modules/@waterplane/shared/dist/repohealthread.js.map +1 -1
  109. package/node_modules/@waterplane/shared/dist/skillstate.d.ts +51 -0
  110. package/node_modules/@waterplane/shared/dist/skillstate.js +176 -0
  111. package/node_modules/@waterplane/shared/dist/skillstate.js.map +1 -0
  112. package/node_modules/@waterplane/shared/dist/skillwords.d.ts +10 -0
  113. package/node_modules/@waterplane/shared/dist/skillwords.js +18 -0
  114. package/node_modules/@waterplane/shared/dist/skillwords.js.map +1 -0
  115. package/node_modules/@waterplane/shared/dist/wire/agentreadings.d.ts +248 -0
  116. package/node_modules/@waterplane/shared/dist/wire/agentreadings.js +36 -0
  117. package/node_modules/@waterplane/shared/dist/wire/agentreadings.js.map +1 -0
  118. package/node_modules/@waterplane/shared/dist/wire/backend.d.ts +2 -0
  119. package/node_modules/@waterplane/shared/dist/wire/costwindow.d.ts +4 -0
  120. package/node_modules/@waterplane/shared/dist/wire/dictatesetup.d.ts +42 -0
  121. package/node_modules/@waterplane/shared/dist/wire/dictatesetup.js +9 -0
  122. package/node_modules/@waterplane/shared/dist/wire/dictatesetup.js.map +1 -0
  123. package/node_modules/@waterplane/shared/dist/wire/messages/hostcore.d.ts +22 -1
  124. package/node_modules/@waterplane/shared/dist/wire/notify.d.ts +6 -1
  125. package/node_modules/@waterplane/shared/dist/wire/notify.js +6 -1
  126. package/node_modules/@waterplane/shared/dist/wire/notify.js.map +1 -1
  127. package/node_modules/@waterplane/shared/dist/wire/repo.d.ts +1 -1
  128. package/node_modules/@waterplane/shared/dist/wire/skills.d.ts +142 -0
  129. package/node_modules/@waterplane/shared/dist/wire/skills.js +6 -0
  130. package/node_modules/@waterplane/shared/dist/wire/skills.js.map +1 -0
  131. package/node_modules/@waterplane/shared/dist/wire/sysstat.d.ts +17 -0
  132. package/node_modules/@waterplane/shared/dist/wire/telemetry.d.ts +4 -0
  133. package/npm-shrinkwrap.json +2 -2
  134. package/package.json +1 -1
  135. package/packages/extensions/diskspace/waterplane-plugin.json +16 -0
  136. package/packages/extensions/links/waterplane-plugin.json +18 -0
  137. package/packages/host/dist/agentclass.d.ts +116 -0
  138. package/packages/host/dist/agentclass.js +339 -0
  139. package/packages/host/dist/agentclass.js.map +1 -0
  140. package/packages/host/dist/agentintents.d.ts +18 -0
  141. package/packages/host/dist/agentintents.js +40 -7
  142. package/packages/host/dist/agentintents.js.map +1 -1
  143. package/packages/host/dist/agentmarkers.d.ts +49 -0
  144. package/packages/host/dist/agentmarkers.js +255 -0
  145. package/packages/host/dist/agentmarkers.js.map +1 -0
  146. package/packages/host/dist/agentreadings.d.ts +68 -0
  147. package/packages/host/dist/agentreadings.js +336 -0
  148. package/packages/host/dist/agentreadings.js.map +1 -0
  149. package/packages/host/dist/agentscan.d.ts +8 -0
  150. package/packages/host/dist/agentscan.js +427 -0
  151. package/packages/host/dist/agentscan.js.map +1 -0
  152. package/packages/host/dist/archive.js +9 -3
  153. package/packages/host/dist/archive.js.map +1 -1
  154. package/packages/host/dist/artifacts.js +4 -7
  155. package/packages/host/dist/artifacts.js.map +1 -1
  156. package/packages/host/dist/askrules.js +12 -4
  157. package/packages/host/dist/askrules.js.map +1 -1
  158. package/packages/host/dist/auth.d.ts +1 -0
  159. package/packages/host/dist/auth.js +5 -3
  160. package/packages/host/dist/auth.js.map +1 -1
  161. package/packages/host/dist/autopull.js +4 -8
  162. package/packages/host/dist/autopull.js.map +1 -1
  163. package/packages/host/dist/backends/claude.js +1 -0
  164. package/packages/host/dist/backends/claude.js.map +1 -1
  165. package/packages/host/dist/backends/derive.js +3 -1
  166. package/packages/host/dist/backends/derive.js.map +1 -1
  167. package/packages/host/dist/binguard.js +19 -2
  168. package/packages/host/dist/binguard.js.map +1 -1
  169. package/packages/host/dist/capture.js +7 -10
  170. package/packages/host/dist/capture.js.map +1 -1
  171. package/packages/host/dist/clifixtures.d.ts +24 -4
  172. package/packages/host/dist/clifixtures.js +50 -10
  173. package/packages/host/dist/clifixtures.js.map +1 -1
  174. package/packages/host/dist/clihealth.d.ts +8 -2
  175. package/packages/host/dist/clihealth.js +11 -3
  176. package/packages/host/dist/clihealth.js.map +1 -1
  177. package/packages/host/dist/costwindow.js +4 -2
  178. package/packages/host/dist/costwindow.js.map +1 -1
  179. package/packages/host/dist/ctxlog/ctxagents.d.ts +2 -0
  180. package/packages/host/dist/ctxlog/ctxagents.js +5 -5
  181. package/packages/host/dist/ctxlog/ctxagents.js.map +1 -1
  182. package/packages/host/dist/ctxlog/ctxcursor.d.ts +2 -0
  183. package/packages/host/dist/ctxlog/ctxcursor.js +2 -2
  184. package/packages/host/dist/ctxlog/ctxcursor.js.map +1 -1
  185. package/packages/host/dist/ctxlog/ctxupdate.js +11 -6
  186. package/packages/host/dist/ctxlog/ctxupdate.js.map +1 -1
  187. package/packages/host/dist/deliver/deliverknobs.d.ts +0 -2
  188. package/packages/host/dist/deliver/deliverknobs.js +0 -2
  189. package/packages/host/dist/deliver/deliverknobs.js.map +1 -1
  190. package/packages/host/dist/deliver/deliverproof.d.ts +3 -2
  191. package/packages/host/dist/deliver/deliverproof.js +9 -8
  192. package/packages/host/dist/deliver/deliverproof.js.map +1 -1
  193. package/packages/host/dist/deliver/deliverreturn.d.ts +3 -2
  194. package/packages/host/dist/deliver/deliverreturn.js +13 -12
  195. package/packages/host/dist/deliver/deliverreturn.js.map +1 -1
  196. package/packages/host/dist/deliver/deliverrun.js +20 -18
  197. package/packages/host/dist/deliver/deliverrun.js.map +1 -1
  198. package/packages/host/dist/deliver/deliverscreen.d.ts +2 -1
  199. package/packages/host/dist/deliver/deliverscreen.js +9 -8
  200. package/packages/host/dist/deliver/deliverscreen.js.map +1 -1
  201. package/packages/host/dist/deliver/delivertypes.d.ts +4 -0
  202. package/packages/host/dist/deliver.js +2 -1
  203. package/packages/host/dist/deliver.js.map +1 -1
  204. package/packages/host/dist/dictate.d.ts +11 -0
  205. package/packages/host/dist/dictate.js +20 -10
  206. package/packages/host/dist/dictate.js.map +1 -1
  207. package/packages/host/dist/dictatesetup.d.ts +54 -0
  208. package/packages/host/dist/dictatesetup.js +261 -0
  209. package/packages/host/dist/dictatesetup.js.map +1 -0
  210. package/packages/host/dist/doctor.js +1 -1
  211. package/packages/host/dist/doctor.js.map +1 -1
  212. package/packages/host/dist/exposure.d.ts +10 -0
  213. package/packages/host/dist/exposure.js +25 -0
  214. package/packages/host/dist/exposure.js.map +1 -1
  215. package/packages/host/dist/exposurepush.js +2 -2
  216. package/packages/host/dist/exposurepush.js.map +1 -1
  217. package/packages/host/dist/extensions/diskspace/host/candidates.d.mts +180 -0
  218. package/packages/host/dist/extensions/diskspace/host/candidates.mjs +716 -0
  219. package/packages/host/dist/extensions/diskspace/host/candidates.mjs.map +1 -0
  220. package/packages/host/dist/extensions/diskspace/host/engine.d.mts +21 -0
  221. package/packages/host/dist/extensions/diskspace/host/engine.mjs +498 -0
  222. package/packages/host/dist/extensions/diskspace/host/engine.mjs.map +1 -0
  223. package/packages/host/dist/extensions/diskspace/host/index.d.mts +25 -0
  224. package/packages/host/dist/extensions/diskspace/host/index.mjs +135 -0
  225. package/packages/host/dist/extensions/diskspace/host/index.mjs.map +1 -0
  226. package/packages/host/dist/extensions/diskspace/host/large.d.mts +11 -0
  227. package/packages/host/dist/extensions/diskspace/host/large.mjs +56 -0
  228. package/packages/host/dist/extensions/diskspace/host/large.mjs.map +1 -0
  229. package/packages/host/dist/extensions/diskspace/host/run.d.mts +94 -0
  230. package/packages/host/dist/extensions/diskspace/host/run.mjs +200 -0
  231. package/packages/host/dist/extensions/diskspace/host/run.mjs.map +1 -0
  232. package/packages/host/dist/extensions/diskspace/shared/wire.d.mts +197 -0
  233. package/packages/host/dist/extensions/diskspace/shared/wire.mjs +23 -0
  234. package/packages/host/dist/extensions/diskspace/shared/wire.mjs.map +1 -0
  235. package/packages/host/dist/extensions/links/host/engine.d.mts +39 -0
  236. package/packages/host/dist/extensions/links/host/engine.mjs +285 -0
  237. package/packages/host/dist/extensions/links/host/engine.mjs.map +1 -0
  238. package/packages/host/dist/extensions/links/host/index.d.mts +10 -0
  239. package/packages/host/dist/extensions/links/host/index.mjs +72 -0
  240. package/packages/host/dist/extensions/links/host/index.mjs.map +1 -0
  241. package/packages/host/dist/extensions/links/host/parse.d.mts +61 -0
  242. package/packages/host/dist/extensions/links/host/parse.mjs +225 -0
  243. package/packages/host/dist/extensions/links/host/parse.mjs.map +1 -0
  244. package/packages/host/dist/extensions/links/host/run.d.mts +15 -0
  245. package/packages/host/dist/extensions/links/host/run.mjs +32 -0
  246. package/packages/host/dist/extensions/links/host/run.mjs.map +1 -0
  247. package/packages/host/dist/extensions/links/host/store.d.mts +11 -0
  248. package/packages/host/dist/extensions/links/host/store.mjs +76 -0
  249. package/packages/host/dist/extensions/links/host/store.mjs.map +1 -0
  250. package/packages/host/dist/extensions/links/shared/wire.d.mts +141 -0
  251. package/packages/host/dist/extensions/links/shared/wire.mjs +20 -0
  252. package/packages/host/dist/extensions/links/shared/wire.mjs.map +1 -0
  253. package/packages/host/dist/git.d.ts +5 -3
  254. package/packages/host/dist/git.js +16 -28
  255. package/packages/host/dist/git.js.map +1 -1
  256. package/packages/host/dist/halt.js +16 -3
  257. package/packages/host/dist/halt.js.map +1 -1
  258. package/packages/host/dist/jsonstore.d.ts +16 -4
  259. package/packages/host/dist/jsonstore.js +32 -8
  260. package/packages/host/dist/jsonstore.js.map +1 -1
  261. package/packages/host/dist/landedbase.d.ts +41 -0
  262. package/packages/host/dist/landedbase.js +59 -0
  263. package/packages/host/dist/landedbase.js.map +1 -0
  264. package/packages/host/dist/lantls.js +2 -2
  265. package/packages/host/dist/lantls.js.map +1 -1
  266. package/packages/host/dist/limitretry.js +2 -3
  267. package/packages/host/dist/limitretry.js.map +1 -1
  268. package/packages/host/dist/localledger.js +9 -12
  269. package/packages/host/dist/localledger.js.map +1 -1
  270. package/packages/host/dist/main.js +2 -0
  271. package/packages/host/dist/main.js.map +1 -1
  272. package/packages/host/dist/opendeliveries.d.ts +4 -0
  273. package/packages/host/dist/opendeliveries.js +27 -1
  274. package/packages/host/dist/opendeliveries.js.map +1 -1
  275. package/packages/host/dist/plugins/setupcontrib.js +3 -2
  276. package/packages/host/dist/plugins/setupcontrib.js.map +1 -1
  277. package/packages/host/dist/pricefetch.d.ts +80 -0
  278. package/packages/host/dist/pricefetch.js +289 -0
  279. package/packages/host/dist/pricefetch.js.map +1 -0
  280. package/packages/host/dist/pricegap.d.ts +11 -0
  281. package/packages/host/dist/pricegap.js +30 -0
  282. package/packages/host/dist/pricegap.js.map +1 -0
  283. package/packages/host/dist/repohealthscopes.js +16 -24
  284. package/packages/host/dist/repohealthscopes.js.map +1 -1
  285. package/packages/host/dist/repos.d.ts +4 -0
  286. package/packages/host/dist/repos.js +1 -1
  287. package/packages/host/dist/repos.js.map +1 -1
  288. package/packages/host/dist/reposkilltext.d.ts +2 -0
  289. package/packages/host/dist/reposkilltext.js +8 -2
  290. package/packages/host/dist/reposkilltext.js.map +1 -1
  291. package/packages/host/dist/routes/apiagentpoints.d.ts +5 -0
  292. package/packages/host/dist/routes/apiagentpoints.js +48 -0
  293. package/packages/host/dist/routes/apiagentpoints.js.map +1 -0
  294. package/packages/host/dist/routes/apidictate.d.ts +2 -0
  295. package/packages/host/dist/routes/apidictate.js +27 -0
  296. package/packages/host/dist/routes/apidictate.js.map +1 -0
  297. package/packages/host/dist/routes/apihost.js +3 -2
  298. package/packages/host/dist/routes/apihost.js.map +1 -1
  299. package/packages/host/dist/routes/apirepofiles.js +3 -1
  300. package/packages/host/dist/routes/apirepofiles.js.map +1 -1
  301. package/packages/host/dist/routes/apirepowork.js +14 -0
  302. package/packages/host/dist/routes/apirepowork.js.map +1 -1
  303. package/packages/host/dist/routes/apiroutes.js +4 -1
  304. package/packages/host/dist/routes/apiroutes.js.map +1 -1
  305. package/packages/host/dist/routes/apiskills.d.ts +3 -0
  306. package/packages/host/dist/routes/apiskills.js +81 -0
  307. package/packages/host/dist/routes/apiskills.js.map +1 -0
  308. package/packages/host/dist/routes/apistats.js +2 -2
  309. package/packages/host/dist/routes/apistats.js.map +1 -1
  310. package/packages/host/dist/routes/apisystem.js +3 -1
  311. package/packages/host/dist/routes/apisystem.js.map +1 -1
  312. package/packages/host/dist/routes/apitable.d.ts +2 -0
  313. package/packages/host/dist/routes/apitable.js.map +1 -1
  314. package/packages/host/dist/server/billingwire.js +5 -0
  315. package/packages/host/dist/server/billingwire.js.map +1 -1
  316. package/packages/host/dist/server/deliveries.d.ts +4 -1
  317. package/packages/host/dist/server/deliveries.js +38 -6
  318. package/packages/host/dist/server/deliveries.js.map +1 -1
  319. package/packages/host/dist/server/http.js +1 -1
  320. package/packages/host/dist/server/http.js.map +1 -1
  321. package/packages/host/dist/server/intentDeps.js +20 -6
  322. package/packages/host/dist/server/intentDeps.js.map +1 -1
  323. package/packages/host/dist/server/wsops.js +2 -1
  324. package/packages/host/dist/server/wsops.js.map +1 -1
  325. package/packages/host/dist/sessions/core.d.ts +1 -0
  326. package/packages/host/dist/sessions/ctxseries.js +7 -5
  327. package/packages/host/dist/sessions/ctxseries.js.map +1 -1
  328. package/packages/host/dist/sessions/drive.d.ts +6 -1
  329. package/packages/host/dist/sessions/drive.js +13 -10
  330. package/packages/host/dist/sessions/drive.js.map +1 -1
  331. package/packages/host/dist/sessions/record.js +16 -17
  332. package/packages/host/dist/sessions/record.js.map +1 -1
  333. package/packages/host/dist/sessions/sidechannel.js +1 -1
  334. package/packages/host/dist/sessions/sidechannel.js.map +1 -1
  335. package/packages/host/dist/sessions/tmux.js +6 -1
  336. package/packages/host/dist/sessions/tmux.js.map +1 -1
  337. package/packages/host/dist/sessions/turn.js +5 -0
  338. package/packages/host/dist/sessions/turn.js.map +1 -1
  339. package/packages/host/dist/sessions.d.ts +2 -1
  340. package/packages/host/dist/sessions.js +1 -1
  341. package/packages/host/dist/sessions.js.map +1 -1
  342. package/packages/host/dist/settle.d.ts +3 -2
  343. package/packages/host/dist/settle.js +13 -13
  344. package/packages/host/dist/settle.js.map +1 -1
  345. package/packages/host/dist/sidecar/sidecarname.d.ts +2 -0
  346. package/packages/host/dist/sidecar/sidecarname.js +5 -1
  347. package/packages/host/dist/sidecar/sidecarname.js.map +1 -1
  348. package/packages/host/dist/sidecar/sidecarroute.d.ts +1 -1
  349. package/packages/host/dist/sidecar/sidecarroute.js +5 -0
  350. package/packages/host/dist/sidecar/sidecarroute.js.map +1 -1
  351. package/packages/host/dist/sidecar.d.ts +1 -1
  352. package/packages/host/dist/sidecar.js +1 -1
  353. package/packages/host/dist/sidecar.js.map +1 -1
  354. package/packages/host/dist/skills/skillinventory.d.ts +23 -0
  355. package/packages/host/dist/skills/skillinventory.js +275 -0
  356. package/packages/host/dist/skills/skillinventory.js.map +1 -0
  357. package/packages/host/dist/skills/skilllayers.d.ts +28 -0
  358. package/packages/host/dist/skills/skilllayers.js +73 -0
  359. package/packages/host/dist/skills/skilllayers.js.map +1 -0
  360. package/packages/host/dist/skills/skillrecommend.d.ts +42 -0
  361. package/packages/host/dist/skills/skillrecommend.js +171 -0
  362. package/packages/host/dist/skills/skillrecommend.js.map +1 -0
  363. package/packages/host/dist/skills/skillrefs.d.ts +2 -0
  364. package/packages/host/dist/skills/skillrefs.js +50 -0
  365. package/packages/host/dist/skills/skillrefs.js.map +1 -0
  366. package/packages/host/dist/skills/skilluse.d.ts +57 -0
  367. package/packages/host/dist/skills/skilluse.js +242 -0
  368. package/packages/host/dist/skills/skilluse.js.map +1 -0
  369. package/packages/host/dist/skills/skillweight.d.ts +18 -0
  370. package/packages/host/dist/skills/skillweight.js +69 -0
  371. package/packages/host/dist/skills/skillweight.js.map +1 -0
  372. package/packages/host/dist/skills/skillwrite.d.ts +56 -0
  373. package/packages/host/dist/skills/skillwrite.js +183 -0
  374. package/packages/host/dist/skills/skillwrite.js.map +1 -0
  375. package/packages/host/dist/sysstat.d.ts +34 -1
  376. package/packages/host/dist/sysstat.js +82 -14
  377. package/packages/host/dist/sysstat.js.map +1 -1
  378. package/packages/host/dist/tokenscan.js +5 -2
  379. package/packages/host/dist/tokenscan.js.map +1 -1
  380. package/packages/host/dist/tokenstats.js +7 -4
  381. package/packages/host/dist/tokenstats.js.map +1 -1
  382. package/packages/host/dist/transcript/transcriptparse.js +2 -2
  383. package/packages/host/dist/transcript/transcriptparse.js.map +1 -1
  384. package/packages/host/dist/waitclock.d.ts +12 -0
  385. package/packages/host/dist/waitclock.js +23 -0
  386. package/packages/host/dist/waitclock.js.map +1 -0
  387. package/packages/host/dist/weekburn.js +7 -5
  388. package/packages/host/dist/weekburn.js.map +1 -1
  389. package/packages/host/dist/worktreeleftover.js +13 -15
  390. package/packages/host/dist/worktreeleftover.js.map +1 -1
  391. package/packages/web/dist/assets/demo-DHkwSmU5.js +26 -0
  392. package/packages/web/dist/assets/{icons-D8RlmSLR.js → icons-5lVTFNUU.js} +1 -1
  393. package/packages/web/dist/assets/index-Bh4cH6X8.js +170 -0
  394. package/packages/web/dist/assets/index-F7VHtsLI.css +1 -0
  395. package/packages/web/dist/assets/shared-BvQMg9ra.js +51 -0
  396. package/packages/web/dist/assets/sheets-Cwi72V02.js +257 -0
  397. package/packages/web/dist/assets/sheets-DjU2XiUd.css +1 -0
  398. package/packages/web/dist/build-id.txt +1 -1
  399. package/packages/web/dist/buildstamp.json +1 -1
  400. package/packages/web/dist/index.html +7 -7
  401. package/packages/web/dist/sw.js +2 -2
  402. package/release.json +11 -3
  403. package/tools/repohealth/constants.mjs +34 -1
  404. package/tools/repohealth/fixture.json +5374 -38
  405. package/tools/repohealth/git.mjs +77 -0
  406. package/tools/repohealth/lang/dart-analyze.mjs +181 -0
  407. package/tools/repohealth/lang/dart-lex.mjs +494 -0
  408. package/tools/repohealth/lang/dart-resolve.mjs +95 -0
  409. package/tools/repohealth/lang/python-ast.mjs +602 -0
  410. package/tools/repohealth/lang/python-resolve.mjs +228 -0
  411. package/tools/repohealth/metrics/habits.mjs +286 -0
  412. package/tools/repohealth/metrics/native.mjs +542 -0
  413. package/tools/repohealth/metrics/untested.mjs +20 -8
  414. package/tools/repohealth/metrics/workspace.mjs +256 -0
  415. package/tools/repohealth/own.mjs +67 -5
  416. package/tools/repohealth/packs/dart.mjs +153 -85
  417. package/tools/repohealth/packs/python.mjs +51 -14
  418. package/tools/repohealth/plot.mjs +143 -1
  419. package/tools/repohealth/reach.mjs +98 -0
  420. package/tools/repohealth/scope.mjs +14 -1
  421. package/tools/repohealth/series.mjs +5 -0
  422. package/tools/repohealth/types.mjs +4 -0
  423. package/tools/repohealth.mjs +39 -5
  424. package/packages/web/dist/assets/demo-ad3g3HDa.js +0 -26
  425. package/packages/web/dist/assets/index-Csb7jynu.js +0 -170
  426. package/packages/web/dist/assets/index-Cz9Haocy.css +0 -1
  427. package/packages/web/dist/assets/shared-DBaaGttP.js +0 -51
  428. package/packages/web/dist/assets/sheets-CqsP9w1V.js +0 -256
  429. package/packages/web/dist/assets/sheets-DoUhPGK0.css +0 -1
@@ -0,0 +1,275 @@
1
+ /**
2
+ * The skills and plugins this desktop's claude would list, with the state at each settings level and
3
+ * what each costs (docs/analysis/skills-switch/PLAN.md, P2). Read-only. Counts are P4's (`usage` here
4
+ * is absent until then); bundled skills are not enumerated (no file names them).
5
+ *
6
+ * A plugin skill is `switchable:false`: the CLI ignores `skillOverrides` for it (fact 3), only the
7
+ * plugin's own switch works. Plugin ids and installs come from `claude plugin list --json` (cached
8
+ * 60 s); a failure falls back to `installed_plugins.json` + the synced dir and SAYS so in `hostNote`.
9
+ */
10
+ import { execFile } from "node:child_process";
11
+ import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { addLocalDays, lineCost, resolvePluginEnabled, resolveSkillState, } from "@waterplane/shared";
14
+ import { claudeBin } from "../backends/claude.js";
15
+ import { claudeConfigDir } from "../claudeconfig.js";
16
+ import { disablesModelInvocation, weightOf } from "./skillweight.js";
17
+ import { readSkillLayers } from "./skilllayers.js";
18
+ export const PLUGIN_SKILLS_SWITCHABLE = false;
19
+ const PLUGIN_SKILL_WHY = "The CLI ignores per-skill switches for plugin skills; switch the whole plugin.";
20
+ const LIST_TTL_MS = 60_000;
21
+ const cache = new Map();
22
+ function runPluginList(cwd, timeoutMs = 10_000) {
23
+ return new Promise((resolve, reject) => {
24
+ execFile(claudeBin(), ["plugin", "list", "--json"], { timeout: timeoutMs, maxBuffer: 4 * 1024 * 1024, env: process.env, ...(cwd ? { cwd } : {}) }, (err, stdout) => {
25
+ if (err)
26
+ return reject(err);
27
+ try {
28
+ const j = JSON.parse(stdout);
29
+ if (!Array.isArray(j))
30
+ throw new Error("not a list");
31
+ resolve(j.filter((p) => p && typeof p.id === "string" && typeof p.installPath === "string").map((p) => ({
32
+ id: p.id, version: typeof p.version === "string" ? p.version : undefined, scope: String(p.scope ?? ""),
33
+ enabled: p.enabled !== false, installPath: p.installPath,
34
+ })));
35
+ }
36
+ catch (e) {
37
+ reject(e);
38
+ }
39
+ });
40
+ });
41
+ }
42
+ /** installed_plugins.json (v2: plugins[id] = [{scope, installPath, version}]) + the synced dir. */
43
+ export function fallbackPlugins() {
44
+ const out = [];
45
+ const root = join(claudeConfigDir(), "plugins");
46
+ try {
47
+ const j = JSON.parse(readFileSync(join(root, "installed_plugins.json"), "utf8"));
48
+ for (const [id, arr] of Object.entries(j?.plugins ?? {})) {
49
+ const e = Array.isArray(arr) ? arr[0] : null;
50
+ if (e && typeof e.installPath === "string")
51
+ out.push({ id, version: e.version, scope: String(e.scope ?? ""), enabled: true, installPath: e.installPath });
52
+ }
53
+ }
54
+ catch { /* none */ }
55
+ try {
56
+ for (const acct of readdirSync(join(root, "synced"))) {
57
+ const dir = join(root, "synced", acct);
58
+ if (!statSync(dir).isDirectory())
59
+ continue;
60
+ for (const d of readdirSync(dir)) {
61
+ if (d.endsWith(".json") || !statSync(join(dir, d)).isDirectory())
62
+ continue;
63
+ const name = d.replace(/~g\d+$/, "");
64
+ const id = `${name}@synced`;
65
+ if (!out.some((p) => p.id === id))
66
+ out.push({ id, scope: "synced", enabled: true, installPath: join(dir, d) });
67
+ }
68
+ }
69
+ }
70
+ catch { /* none */ }
71
+ return out;
72
+ }
73
+ /** Asked from the repo's own folder, so its on/off default folds in THAT repo's settings and no other's. */
74
+ async function pluginList(worktree) {
75
+ const key = worktree ?? "";
76
+ const hit = cache.get(key);
77
+ if (hit && Date.now() - hit.at < LIST_TTL_MS)
78
+ return hit.list;
79
+ let list;
80
+ try {
81
+ list = { plugins: await runPluginList(worktree) };
82
+ }
83
+ catch {
84
+ list = { plugins: fallbackPlugins(), note: "claude plugin list could not be run, so plugins are read from the files on disk and a plugin's on/off default is assumed on." };
85
+ }
86
+ cache.set(key, { at: Date.now(), list });
87
+ return list;
88
+ }
89
+ /** Dropped after a write (a settings file just changed) and by tests. */
90
+ export function resetPluginListCache() { cache.clear(); }
91
+ const isDir = (p) => { try {
92
+ return statSync(p).isDirectory();
93
+ }
94
+ catch {
95
+ return false;
96
+ } };
97
+ /** `<dir>/*\/SKILL.md`, symlinks followed. */
98
+ function skillFiles(dir) {
99
+ const out = [];
100
+ let names = [];
101
+ try {
102
+ names = readdirSync(dir).sort();
103
+ }
104
+ catch {
105
+ return out;
106
+ }
107
+ for (const n of names) {
108
+ const file = join(dir, n, "SKILL.md");
109
+ if (existsSync(file))
110
+ out.push({ dir: n, file });
111
+ }
112
+ return out;
113
+ }
114
+ function mcpCount(installPath) {
115
+ try {
116
+ const j = JSON.parse(readFileSync(join(installPath, ".mcp.json"), "utf8"));
117
+ const m = j && typeof j === "object" ? (j.mcpServers ?? j) : null;
118
+ return m && typeof m === "object" && !Array.isArray(m) ? Object.keys(m).length : undefined;
119
+ }
120
+ catch {
121
+ return undefined;
122
+ }
123
+ }
124
+ export async function buildInventory(opts = {}) {
125
+ const L = readSkillLayers(opts.worktree);
126
+ const byLevel = (lvl) => L.reads.find((r) => r.layer.level === lvl);
127
+ const user = byLevel("global"), shared = byLevel("repo-shared"), local = byLevel("repo-local");
128
+ const layers = { user: user?.skillOverrides, project: shared?.skillOverrides, local: local?.skillOverrides };
129
+ const pLayers = { user: user?.enabledPlugins, project: shared?.enabledPlugins, local: local?.enabledPlugins };
130
+ const files = {};
131
+ const rows = [];
132
+ let unmeasured = 0;
133
+ const seen = new Set();
134
+ // The CLI reserves a bare name for the personal / project skill that holds it: a synced skill's bare key is then ignored.
135
+ const heldNames = new Set();
136
+ for (const s of skillFiles(join(claudeConfigDir(), "skills")))
137
+ if (s.dir !== "synced")
138
+ heldNames.add(s.dir);
139
+ if (opts.worktree)
140
+ for (const s of skillFiles(join(opts.worktree, ".claude", "skills")))
141
+ heldNames.add(s.dir);
142
+ const setOf = (id, bare) => {
143
+ const set = {};
144
+ for (const r of L.reads) {
145
+ const v = r.skillOverrides[id] ?? (bare ? r.skillOverrides[bare] : undefined);
146
+ if (typeof v === "string" && ["on", "name-only", "user-invocable-only", "off"].includes(v))
147
+ set[r.layer.level] = v;
148
+ }
149
+ return set;
150
+ };
151
+ const addSkill = (id, source, file, plugin, bareName) => {
152
+ if (seen.has(id))
153
+ return;
154
+ const bare = bareName !== undefined && !heldNames.has(bareName) ? bareName : undefined;
155
+ seen.add(id);
156
+ let text = null;
157
+ try {
158
+ text = readFileSync(file, "utf8");
159
+ }
160
+ catch { /* unreadable */ }
161
+ const switchable = source === "plugin" ? PLUGIN_SKILLS_SWITCHABLE : true;
162
+ const locks = { policy: L.policy.skillOverrides };
163
+ // The CLI reads the prefixed key at every level first, then the bare name of a synced skill.
164
+ let res = resolveSkillState(id, layers, locks);
165
+ if (bare && res.from === "default")
166
+ res = resolveSkillState(bare, layers, locks);
167
+ const authorLocked = text !== null && disablesModelInvocation(text);
168
+ const row = {
169
+ kind: "skill", id, source, set: setOf(id, bare), effective: res.state, from: res.from, switchable,
170
+ };
171
+ if (plugin)
172
+ row.plugin = plugin;
173
+ // The CLI fixes a skill with `disable-model-invocation: true` at user-invocable-only (never in the
174
+ // model's listing) before it looks at any skillOverrides; only a managed "off" is stronger.
175
+ // Any non-plugin "off" beats it (read from the CLI 2.1.322 resolver: overrides across all sources
176
+ // return off first); a plugin skill ignores skillOverrides, so only a managed value counts there.
177
+ if (authorLocked && !(res.state === "off" && (source !== "plugin" || res.from === "locked"))) {
178
+ row.effective = "user-invocable-only";
179
+ row.from = "locked";
180
+ row.lockedBy = "author";
181
+ row.locked = "The skill's own file says only you may run it (disable-model-invocation), so the model never lists it and no setting changes that.";
182
+ }
183
+ else if (res.from === "locked")
184
+ row.locked = "A managed setting fixes this value; it cannot be changed here.";
185
+ if (text !== null) {
186
+ const w = weightOf(id, text, L.maxDesc);
187
+ row.listingChars = w.listingChars;
188
+ row.bodyChars = w.bodyChars;
189
+ if (w.capped)
190
+ row.capped = true;
191
+ }
192
+ else {
193
+ unmeasured++;
194
+ row.why = "Its SKILL.md could not be read, so its weight is not measured.";
195
+ }
196
+ if (!switchable)
197
+ row.why = row.why ? `${row.why} ${PLUGIN_SKILL_WHY}` : PLUGIN_SKILL_WHY;
198
+ files[id] = file;
199
+ rows.push(row);
200
+ };
201
+ // Personal (and the claude.ai standalone skills under skills/synced/<account>/).
202
+ const personal = join(claudeConfigDir(), "skills");
203
+ for (const s of skillFiles(personal))
204
+ if (s.dir !== "synced")
205
+ addSkill(s.dir, "personal", s.file);
206
+ try {
207
+ for (const acct of readdirSync(join(personal, "synced"))) {
208
+ for (const s of skillFiles(join(personal, "synced", acct)))
209
+ addSkill(`anthropic-skills:${s.dir}`, "synced-skill", s.file, undefined, s.dir);
210
+ }
211
+ }
212
+ catch { /* none */ }
213
+ // Project.
214
+ if (opts.worktree)
215
+ for (const s of skillFiles(join(opts.worktree, ".claude", "skills")))
216
+ addSkill(s.dir, "project", s.file);
217
+ // Plugins.
218
+ const pl = await pluginList(opts.worktree);
219
+ for (const p of pl.plugins) {
220
+ const name = p.id.split("@")[0] || p.id;
221
+ let installPath = p.installPath;
222
+ try {
223
+ installPath = realpathSync(installPath);
224
+ }
225
+ catch { /* keep as given */ }
226
+ const skillIds = [];
227
+ if (isDir(installPath)) {
228
+ for (const s of skillFiles(join(installPath, "skills"))) {
229
+ // The CLI names a skills/<dir>/SKILL.md `<plugin>:<dir>` (odd characters become "-"); the frontmatter name is ignored.
230
+ const id = `${name}:${s.dir.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
231
+ addSkill(id, "plugin", s.file, p.id);
232
+ skillIds.push(id);
233
+ }
234
+ }
235
+ const res = resolvePluginEnabled(p.id, pLayers, { policy: L.policy.enabledPlugins }, p.enabled);
236
+ const set = {};
237
+ for (const r of L.reads)
238
+ if (typeof r.enabledPlugins[p.id] === "boolean")
239
+ set[r.layer.level] = r.enabledPlugins[p.id];
240
+ const mine = rows.filter((r) => r.kind === "skill" && skillIds.includes(r.id));
241
+ const measured = mine.length > 0 && mine.every((r) => r.listingChars !== undefined);
242
+ const prow = { kind: "plugin", id: p.id, name, scope: p.scope, set, enabled: res.enabled, from: res.from, skills: skillIds };
243
+ if (p.version)
244
+ prow.version = p.version;
245
+ if (measured)
246
+ prow.listingChars = mine.reduce((n, r) => n + (r.lockedBy === "author" ? 0 : r.listingChars ?? 0), 0); // an author-locked skill is never listed
247
+ else
248
+ prow.why = mine.length === 0 ? "No skills found in this plugin's folder, so its weight is not measured." : "Some of its skills could not be read, so its weight is not measured.";
249
+ const mcp = isDir(installPath) ? mcpCount(installPath) : undefined;
250
+ if (mcp !== undefined)
251
+ prow.mcpServers = mcp;
252
+ rows.push(prow);
253
+ }
254
+ // What the listing carries NOW: a skill counts at its effective state (name-only is its name line,
255
+ // off is nothing) and a plugin's skills only while the plugin is on, so a save lowers the total.
256
+ const pluginOn = new Map(rows.filter((r) => r.kind === "plugin").map((p) => [p.id, p.enabled]));
257
+ const carried = (r) => (r.plugin && pluginOn.get(r.plugin) === false ? 0 : lineCost(r, r.effective) ?? 0);
258
+ const sum = (pred) => {
259
+ const m = rows.filter((r) => r.kind === "skill" && pred(r) && r.listingChars !== undefined);
260
+ return m.length ? m.reduce((n, r) => n + carried(r), 0) : undefined;
261
+ };
262
+ const doc = {
263
+ v: 1, at: opts.now ?? Date.now(),
264
+ layers: L.reads.map((r) => r.layer),
265
+ rows,
266
+ totals: { skillChars: sum((r) => r.source !== "plugin"), pluginChars: sum((r) => r.source === "plugin"), unmeasured },
267
+ usage: { state: "absent", why: "Use counts are not read yet.", since30: addLocalDays(opts.now ?? Date.now(), -30) },
268
+ };
269
+ if (opts.repoId)
270
+ doc.repoId = opts.repoId;
271
+ const notes = [pl.note, "Bundled skills are not listed: no file names them."].filter(Boolean);
272
+ doc.hostNote = notes.join(" ");
273
+ return { doc, files };
274
+ }
275
+ //# sourceMappingURL=skillinventory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skillinventory.js","sourceRoot":"","sources":["../../src/skills/skillinventory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { SkillLayer, SwitchLevel } from "@waterplane/shared";
2
+ export type JsonMap = Record<string, unknown>;
3
+ export interface LayerRead {
4
+ layer: SkillLayer;
5
+ /** The two switch maps of this file (empty when absent or unreadable). */
6
+ skillOverrides: JsonMap;
7
+ enabledPlugins: JsonMap;
8
+ /** `skillListingMaxDescChars` when this file sets it. */
9
+ maxDesc?: number;
10
+ /** The absolute file. */
11
+ file: string;
12
+ }
13
+ export interface SkillLayers {
14
+ reads: LayerRead[];
15
+ /** Managed (policy) settings: read-only locks. */
16
+ policy: {
17
+ skillOverrides: JsonMap;
18
+ enabledPlugins: JsonMap;
19
+ };
20
+ maxDesc?: number;
21
+ }
22
+ /** `~/…` for a path under the home dir, else the path as is. */
23
+ export declare function displayPath(abs: string): string;
24
+ export declare function readLayer(level: SwitchLevel, file: string, display: string): LayerRead;
25
+ /** Where managed settings live (best effort, read-only). */
26
+ export declare function managedSettingsPath(platform?: NodeJS.Platform): string | null;
27
+ /** The global layer, and with a worktree the two repo layers. Order: global, repo-shared, repo-local. */
28
+ export declare function readSkillLayers(worktree?: string): SkillLayers;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The settings files the skills and plugins switch reads (docs/analysis/skills-switch/PLAN.md, P2).
3
+ *
4
+ * Read with `readFileSync` + `JSON.parse`, NEVER `readJsonGuarded`: that MOVES an unparseable file
5
+ * aside, and a settings file is the person's. An unreadable file is a layer saying so, and its
6
+ * maps count as empty (the write path refuses it, P3). Read-only here.
7
+ */
8
+ import { createHash } from "node:crypto";
9
+ import { readFileSync } from "node:fs";
10
+ import { homedir } from "node:os";
11
+ import { join } from "node:path";
12
+ import { claudeConfigDir } from "../claudeconfig.js";
13
+ const isObj = (v) => !!v && typeof v === "object" && !Array.isArray(v);
14
+ /** `~/…` for a path under the home dir, else the path as is. */
15
+ export function displayPath(abs) {
16
+ const h = homedir();
17
+ return abs === h ? "~" : abs.startsWith(h + "/") ? "~" + abs.slice(h.length) : abs;
18
+ }
19
+ export function readLayer(level, file, display) {
20
+ const empty = { skillOverrides: {}, enabledPlugins: {}, file };
21
+ let text;
22
+ try {
23
+ text = readFileSync(file, "utf8");
24
+ }
25
+ catch (e) {
26
+ if (e.code === "ENOENT")
27
+ return { layer: { level, path: display, rev: "absent", readable: true }, ...empty };
28
+ return { layer: { level, path: display, rev: "absent", readable: false, why: `${display} could not be read (${e.code ?? "error"}).` }, ...empty };
29
+ }
30
+ const rev = createHash("sha1").update(text).digest("hex");
31
+ let json;
32
+ try {
33
+ json = JSON.parse(text);
34
+ }
35
+ catch {
36
+ return { layer: { level, path: display, rev, readable: false, why: `${display} is not valid JSON, so nothing here reads or writes it.` }, ...empty };
37
+ }
38
+ if (!isObj(json))
39
+ return { layer: { level, path: display, rev, readable: false, why: `${display} is not a JSON object.` }, ...empty };
40
+ for (const k of ["skillOverrides", "enabledPlugins"]) {
41
+ if (k in json && !isObj(json[k]))
42
+ return { layer: { level, path: display, rev, readable: false, why: `${display} has a "${k}" that is not an object.` }, ...empty };
43
+ }
44
+ const md = json.skillListingMaxDescChars;
45
+ return {
46
+ layer: { level, path: display, rev, readable: true },
47
+ skillOverrides: json.skillOverrides ?? {},
48
+ enabledPlugins: json.enabledPlugins ?? {},
49
+ maxDesc: typeof md === "number" && md > 0 ? md : undefined,
50
+ file,
51
+ };
52
+ }
53
+ /** Where managed settings live (best effort, read-only). */
54
+ export function managedSettingsPath(platform = process.platform) {
55
+ if (platform === "darwin")
56
+ return "/Library/Application Support/ClaudeCode/managed-settings.json";
57
+ if (platform === "linux")
58
+ return "/etc/claude-code/managed-settings.json";
59
+ return null;
60
+ }
61
+ /** The global layer, and with a worktree the two repo layers. Order: global, repo-shared, repo-local. */
62
+ export function readSkillLayers(worktree) {
63
+ const reads = [readLayer("global", join(claudeConfigDir(), "settings.json"), displayPath(join(claudeConfigDir(), "settings.json")))];
64
+ if (worktree) {
65
+ reads.push(readLayer("repo-shared", join(worktree, ".claude", "settings.json"), ".claude/settings.json"));
66
+ reads.push(readLayer("repo-local", join(worktree, ".claude", "settings.local.json"), ".claude/settings.local.json"));
67
+ }
68
+ const mp = managedSettingsPath();
69
+ const m = mp ? readLayer("global", mp, mp) : null;
70
+ const maxDesc = [...reads, ...(m ? [m] : [])].map((r) => r.maxDesc).filter((n) => n !== undefined).pop(); // merged settings: the highest-precedence source wins (managed > local > shared > global)
71
+ return { reads, policy: { skillOverrides: m?.skillOverrides ?? {}, enabledPlugins: m?.enabledPlugins ?? {} }, maxDesc };
72
+ }
73
+ //# sourceMappingURL=skilllayers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skilllayers.js","sourceRoot":"","sources":["../../src/skills/skilllayers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Skills Recommend (P5, docs/analysis/skills-switch/PLAN.md): ONE cheap unattended call that
3
+ * suggests which skills and plugins to switch off for one repo. Spender rules (host-spenders):
4
+ * the single sidecar seam (`runSkillsTask`, claude flags none dropped, `--thinking disabled`,
5
+ * `--no-session-persistence`), the halt gate, and NOTHING APPLIES ITSELF - the answer is a list a
6
+ * person ticks. The model's text is DATA: this file validates every suggestion against the
7
+ * inventory and fills savings and counts itself.
8
+ */
9
+ import type { SkillInventoryDoc, SkillSuggestion, SkillRecommendResponse } from "@waterplane/shared";
10
+ import { type NameRequest, type NameRun } from "../sidecar.js";
11
+ export declare const MAX_SUGGESTIONS = 30;
12
+ export declare const SKILLS_SYSTEM_DEFAULT: string;
13
+ export interface RecommendDeps {
14
+ run?: (req: NameRequest) => Promise<NameRun>;
15
+ /** Overrides the sidecar plan lookup (tests). */
16
+ refused?: () => string | null;
17
+ }
18
+ interface InRow {
19
+ id: string;
20
+ kind: "skill" | "plugin";
21
+ source?: string;
22
+ state: string;
23
+ chars?: number;
24
+ tok?: number;
25
+ uses30?: number;
26
+ usesAll?: number;
27
+ typed30?: number;
28
+ typedAll?: number;
29
+ referencedBy: string[];
30
+ desc?: string;
31
+ }
32
+ /** Build the model's input rows. Exported for tests. */
33
+ export declare function recommendRows(doc: SkillInventoryDoc, files: Record<string, string>, wt: string): InRow[];
34
+ /** Validate the model's text against the inventory. Exported for tests. */
35
+ export declare function validateSuggestions(text: string, doc: SkillInventoryDoc, rows: InRow[]): {
36
+ suggestions: SkillSuggestion[];
37
+ note?: string;
38
+ dropped: number;
39
+ } | null;
40
+ /** `doc` is the repo inventory with usage filled in by the route; `files` maps skill id -> SKILL.md. */
41
+ export declare function recommendSkills(wt: string, doc: SkillInventoryDoc, files: Record<string, string>, deps?: RecommendDeps): Promise<SkillRecommendResponse>;
42
+ export {};
@@ -0,0 +1,171 @@
1
+ import { savingsOf } from "@waterplane/shared";
2
+ import { readFileSync } from "node:fs";
3
+ import { basename } from "node:path";
4
+ import { env } from "../env.js";
5
+ import { haltRefusal } from "../halt.js";
6
+ import { promptText } from "../prompts.js";
7
+ import { runSkillsTask, sidecarPlan } from "../sidecar.js";
8
+ import { repoReferences } from "./skillrefs.js";
9
+ const MODEL = env("SKILLS_MODEL") || env("SUMMARY_MODEL") || "haiku";
10
+ const TIMEOUT_MS = Number(env("SKILLS_TIMEOUT_MS") || 60_000);
11
+ const INPUT_CAP = 24_000;
12
+ export const MAX_SUGGESTIONS = 30;
13
+ const MAX_REASON = 140;
14
+ const RANK = { on: 0, "name-only": 1, "user-invocable-only": 2, off: 3 };
15
+ const TO_SET = new Set(["name-only", "user-invocable-only", "off"]);
16
+ export const SKILLS_SYSTEM_DEFAULT = "You help a person trim the skills and plugins their coding agent lists on every turn. You get rows " +
17
+ "with weight and use counts for ONE repo. Suggest only items that cost context and that this repo " +
18
+ "does not use: weigh chars, uses in the last 30 days, uses all time, and referencedBy. Never suggest an " +
19
+ "item with a non-empty referencedBy. Prefer `name-only` for something occasionally useful, `off` for " +
20
+ "something unused or irrelevant to this repo, `user-invocable-only` for something the person types " +
21
+ "but the model should not pick. For a plugin only `off`. Counts are for this repo only: say so in the " +
22
+ "reason, never claim a skill is useless in general. At most 30 suggestions, reasons under 140 " +
23
+ "characters, plain words. Output one JSON object and nothing else. Shape: " +
24
+ '{"suggestions":[{"kind":"skill|plugin","id":"...","to":"name-only|user-invocable-only|off","reason":"..."}],"note":"optional one sentence"}';
25
+ function descOf(file) {
26
+ if (!file)
27
+ return undefined;
28
+ try {
29
+ const m = /^---\r?\n([\s\S]*?)\r?\n---/.exec(readFileSync(file, "utf8"));
30
+ const d = m && /^description:(.*)$/m.exec(m[1]);
31
+ const t = d?.[1]?.trim().replace(/^["'>|-]/, "").trim();
32
+ return t ? t.slice(0, 120) : undefined;
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ }
38
+ /** Build the model's input rows. Exported for tests. */
39
+ export function recommendRows(doc, files, wt) {
40
+ const skills = doc.rows.filter((r) => r.kind === "skill");
41
+ const plugins = doc.rows.filter((r) => r.kind === "plugin");
42
+ const names = [...new Set([...skills.filter((s) => s.source !== "plugin").map((s) => s.id), ...plugins.map((p) => p.name)])];
43
+ const own = {};
44
+ for (const s of skills)
45
+ if (files[s.id])
46
+ own[s.id] = files[s.id];
47
+ const refs = repoReferences(wt, names, own);
48
+ const rows = [];
49
+ for (const s of skills) {
50
+ if (s.source === "plugin" || !s.switchable || s.from === "locked")
51
+ continue;
52
+ rows.push({
53
+ id: s.id, kind: "skill", source: s.source, state: s.effective, chars: s.listingChars,
54
+ tok: s.listingChars === undefined ? undefined : Math.round(s.listingChars / 4),
55
+ uses30: s.uses?.d30, usesAll: s.uses?.all, typed30: s.uses?.typed30, typedAll: s.uses?.typedAll,
56
+ referencedBy: (refs[s.id] ?? []).map((f) => basename(f)), desc: descOf(files[s.id]),
57
+ });
58
+ }
59
+ for (const p of plugins) {
60
+ if (p.from === "locked")
61
+ continue;
62
+ const mine = skills.filter((s) => s.plugin === p.id);
63
+ const sum = (f) => mine.some((s) => s.uses) ? mine.reduce((a, s) => a + (f(s) ?? 0), 0) : undefined;
64
+ rows.push({
65
+ id: p.id, kind: "plugin", state: p.enabled ? "on" : "off", chars: p.listingChars,
66
+ tok: p.listingChars === undefined ? undefined : Math.round(p.listingChars / 4),
67
+ uses30: sum((s) => s.uses?.d30), usesAll: sum((s) => s.uses?.all),
68
+ typed30: sum((s) => s.uses?.typed30), typedAll: sum((s) => s.uses?.typedAll),
69
+ referencedBy: (refs[p.name] ?? []).map((f) => basename(f)),
70
+ });
71
+ }
72
+ return rows;
73
+ }
74
+ function parseJson(text) {
75
+ const t = text.trim();
76
+ const fenced = /^```(?:json)?[ \t]*\r?\n([\s\S]*?)\n```$/.exec(t);
77
+ try {
78
+ return JSON.parse(fenced ? fenced[1] : t);
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ }
84
+ /** Validate the model's text against the inventory. Exported for tests. */
85
+ export function validateSuggestions(text, doc, rows) {
86
+ const j = parseJson(text);
87
+ if (!j || typeof j !== "object" || !Array.isArray(j.suggestions))
88
+ return null;
89
+ const byKey = new Map(doc.rows.map((r) => [`${r.kind}:${r.id}`, r]));
90
+ const inRow = new Map(rows.map((r) => [`${r.kind}:${r.id}`, r]));
91
+ const seen = new Set();
92
+ const out = [];
93
+ let dropped = 0;
94
+ for (const raw of j.suggestions) {
95
+ const s = raw;
96
+ const key = `${String(s?.kind)}:${String(s?.id)}`;
97
+ const row = byKey.get(key);
98
+ const given = inRow.get(key);
99
+ const to = String(s?.to);
100
+ if (out.length >= MAX_SUGGESTIONS || !row || !given || seen.has(key) || !TO_SET.has(to) || typeof s.reason !== "string") {
101
+ dropped++;
102
+ continue;
103
+ }
104
+ if (given.referencedBy.length) {
105
+ dropped++;
106
+ continue;
107
+ }
108
+ if (row.kind === "plugin") {
109
+ if (to !== "off" || !row.enabled) {
110
+ dropped++;
111
+ continue;
112
+ }
113
+ }
114
+ else if (!row.switchable || RANK[row.effective] >= RANK[to]) {
115
+ dropped++;
116
+ continue;
117
+ }
118
+ seen.add(key);
119
+ const change = { kind: row.kind, id: row.id, to: row.kind === "plugin" ? false : to };
120
+ const sv = savingsOf([row], [change]);
121
+ out.push({
122
+ kind: row.kind, id: row.id, to: to, reason: s.reason.trim().slice(0, MAX_REASON),
123
+ ...(sv.unmeasured ? {} : { savedChars: sv.chars }),
124
+ ...(given.uses30 !== undefined ? { uses30: given.uses30 } : {}),
125
+ ...(given.usesAll !== undefined ? { usesAll: given.usesAll } : {}),
126
+ });
127
+ }
128
+ const note = typeof j.note === "string" && j.note.trim() ? j.note.trim().slice(0, 300) : undefined;
129
+ return { suggestions: out, ...(note ? { note } : {}), dropped };
130
+ }
131
+ const none = (error, extra = {}) => ({ ok: false, suggestions: [], dropped: 0, error, ...extra });
132
+ /** `doc` is the repo inventory with usage filled in by the route; `files` maps skill id -> SKILL.md. */
133
+ export async function recommendSkills(wt, doc, files, deps = {}) {
134
+ const halted = haltRefusal();
135
+ if (halted)
136
+ return none(halted);
137
+ if (doc.usage.state === "absent")
138
+ return none(`Cannot recommend: there are no use counts to go on. ${doc.usage.why ?? "The usage scan found nothing."}`);
139
+ if (doc.usage.state !== "ready" || doc.usage.refreshing)
140
+ return none("Counting uses is still running. Try again in a moment.");
141
+ const plan = deps.refused ? deps.refused() : (() => { const p = sidecarPlan("skills"); return p.engine === "refused" ? p.reason : null; })();
142
+ if (plan)
143
+ return none(plan);
144
+ let rows = recommendRows(doc, files, wt);
145
+ if (!rows.length)
146
+ return { ok: true, suggestions: [], dropped: 0, note: "Nothing here can be switched." };
147
+ const wrap = (r) => JSON.stringify({
148
+ repo: basename(wt), window: { d30: "last 30 days", all: "all time" }, rows: r,
149
+ });
150
+ // Heaviest first, then cut to the input cap: the rows that cost most are the ones worth a call.
151
+ rows = [...rows].sort((a, b) => (b.chars ?? 0) - (a.chars ?? 0));
152
+ while (rows.length > 1 && wrap(rows).length > INPUT_CAP)
153
+ rows.pop();
154
+ const run = await (deps.run ?? runSkillsTask)({
155
+ cwd: wt, prompt: wrap(rows), system: promptText("skills-recommend", SKILLS_SYSTEM_DEFAULT),
156
+ model: MODEL, timeoutMs: TIMEOUT_MS, persist: false,
157
+ });
158
+ const u = run.usage;
159
+ const spend = { model: MODEL, costUsd: run.usd, inputTokens: u ? u.inTok + u.cacheRead + u.cacheWrite : undefined, outputTokens: u?.outTok };
160
+ if (run.limited)
161
+ return none(run.detail || "The account is out of quota. Nothing was suggested.", { limited: true, spend });
162
+ if (run.signedOut)
163
+ return none(run.detail || "Claude is signed out on this desktop.", { spend });
164
+ if (run.failed)
165
+ return none(run.detail || "No suggestions came back.", { spend });
166
+ const v = validateSuggestions(run.text, doc, rows);
167
+ if (!v)
168
+ return none("The answer was not in a shape this screen can use. Nothing was changed.", { spend });
169
+ return { ok: true, ...v, spend };
170
+ }
171
+ //# sourceMappingURL=skillrecommend.js.map