synapse-mcp 1.0.0 → 1.0.2

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 (413) hide show
  1. package/README.md +1820 -147
  2. package/dist/constants.d.ts +10 -4
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +18 -8
  5. package/dist/constants.js.map +1 -1
  6. package/dist/events/emitter.d.ts +63 -0
  7. package/dist/events/emitter.d.ts.map +1 -0
  8. package/dist/events/emitter.js +112 -0
  9. package/dist/events/emitter.js.map +1 -0
  10. package/dist/events/index.d.ts +3 -0
  11. package/dist/events/index.d.ts.map +1 -0
  12. package/dist/events/index.js +3 -0
  13. package/dist/events/index.js.map +1 -0
  14. package/dist/events/types.d.ts +51 -0
  15. package/dist/events/types.d.ts.map +1 -0
  16. package/dist/events/types.js +3 -0
  17. package/dist/events/types.js.map +1 -0
  18. package/dist/formatters/compose.d.ts +185 -0
  19. package/dist/formatters/compose.d.ts.map +1 -0
  20. package/dist/formatters/compose.js +397 -0
  21. package/dist/formatters/compose.js.map +1 -0
  22. package/dist/formatters/container.d.ts +84 -0
  23. package/dist/formatters/container.d.ts.map +1 -0
  24. package/dist/formatters/container.js +323 -0
  25. package/dist/formatters/container.js.map +1 -0
  26. package/dist/formatters/diagnostics.d.ts +20 -0
  27. package/dist/formatters/diagnostics.d.ts.map +1 -0
  28. package/dist/formatters/diagnostics.js +73 -0
  29. package/dist/formatters/diagnostics.js.map +1 -0
  30. package/dist/formatters/docker.d.ts +139 -0
  31. package/dist/formatters/docker.d.ts.map +1 -0
  32. package/dist/formatters/docker.js +216 -0
  33. package/dist/formatters/docker.js.map +1 -0
  34. package/dist/formatters/host.d.ts +137 -0
  35. package/dist/formatters/host.d.ts.map +1 -0
  36. package/dist/formatters/host.js +198 -0
  37. package/dist/formatters/host.js.map +1 -0
  38. package/dist/formatters/index.d.ts +17 -270
  39. package/dist/formatters/index.d.ts.map +1 -1
  40. package/dist/formatters/index.js +21 -456
  41. package/dist/formatters/index.js.map +1 -1
  42. package/dist/formatters/scout.d.ts +424 -0
  43. package/dist/formatters/scout.d.ts.map +1 -0
  44. package/dist/formatters/scout.js +687 -0
  45. package/dist/formatters/scout.js.map +1 -0
  46. package/dist/formatters/strategy.d.ts +105 -0
  47. package/dist/formatters/strategy.d.ts.map +1 -0
  48. package/dist/formatters/strategy.js +120 -0
  49. package/dist/formatters/strategy.js.map +1 -0
  50. package/dist/formatters/utils.d.ts +84 -0
  51. package/dist/formatters/utils.d.ts.map +1 -0
  52. package/dist/formatters/utils.js +129 -0
  53. package/dist/formatters/utils.js.map +1 -0
  54. package/dist/health-rate-limiter.d.ts +59 -0
  55. package/dist/health-rate-limiter.d.ts.map +1 -0
  56. package/dist/health-rate-limiter.js +159 -0
  57. package/dist/health-rate-limiter.js.map +1 -0
  58. package/dist/index.js +61 -100
  59. package/dist/index.js.map +1 -1
  60. package/dist/middleware/async-handler.d.ts +62 -0
  61. package/dist/middleware/async-handler.d.ts.map +1 -0
  62. package/dist/middleware/async-handler.js +58 -0
  63. package/dist/middleware/async-handler.js.map +1 -0
  64. package/dist/middleware/auth.d.ts +32 -0
  65. package/dist/middleware/auth.d.ts.map +1 -0
  66. package/dist/middleware/auth.js +63 -0
  67. package/dist/middleware/auth.js.map +1 -0
  68. package/dist/middleware/csrf-protection.d.ts +58 -0
  69. package/dist/middleware/csrf-protection.d.ts.map +1 -0
  70. package/dist/middleware/csrf-protection.js +123 -0
  71. package/dist/middleware/csrf-protection.js.map +1 -0
  72. package/dist/middleware/error-handler.d.ts +49 -0
  73. package/dist/middleware/error-handler.d.ts.map +1 -0
  74. package/dist/middleware/error-handler.js +90 -0
  75. package/dist/middleware/error-handler.js.map +1 -0
  76. package/dist/middleware/error-mapper.d.ts +44 -0
  77. package/dist/middleware/error-mapper.d.ts.map +1 -0
  78. package/dist/middleware/error-mapper.js +127 -0
  79. package/dist/middleware/error-mapper.js.map +1 -0
  80. package/dist/middleware/index.d.ts +13 -0
  81. package/dist/middleware/index.d.ts.map +1 -0
  82. package/dist/middleware/index.js +13 -0
  83. package/dist/middleware/index.js.map +1 -0
  84. package/dist/middleware/request-id.d.ts +22 -0
  85. package/dist/middleware/request-id.d.ts.map +1 -0
  86. package/dist/middleware/request-id.js +31 -0
  87. package/dist/middleware/request-id.js.map +1 -0
  88. package/dist/middleware/types.d.ts +33 -0
  89. package/dist/middleware/types.d.ts.map +1 -0
  90. package/dist/middleware/types.js +2 -0
  91. package/dist/middleware/types.js.map +1 -0
  92. package/dist/schemas/common.d.ts +205 -8
  93. package/dist/schemas/common.d.ts.map +1 -1
  94. package/dist/schemas/common.js +290 -17
  95. package/dist/schemas/common.js.map +1 -1
  96. package/dist/schemas/flux/compose.d.ts +307 -44
  97. package/dist/schemas/flux/compose.d.ts.map +1 -1
  98. package/dist/schemas/flux/compose.js +74 -48
  99. package/dist/schemas/flux/compose.js.map +1 -1
  100. package/dist/schemas/flux/container.d.ts +423 -56
  101. package/dist/schemas/flux/container.d.ts.map +1 -1
  102. package/dist/schemas/flux/container.js +83 -61
  103. package/dist/schemas/flux/container.js.map +1 -1
  104. package/dist/schemas/flux/docker.d.ts +254 -37
  105. package/dist/schemas/flux/docker.d.ts.map +1 -1
  106. package/dist/schemas/flux/docker.js +69 -39
  107. package/dist/schemas/flux/docker.js.map +1 -1
  108. package/dist/schemas/flux/host.d.ts +312 -29
  109. package/dist/schemas/flux/host.d.ts.map +1 -1
  110. package/dist/schemas/flux/host.js +74 -31
  111. package/dist/schemas/flux/host.js.map +1 -1
  112. package/dist/schemas/flux/index.d.ts +503 -11
  113. package/dist/schemas/flux/index.d.ts.map +1 -1
  114. package/dist/schemas/flux/index.js +34 -70
  115. package/dist/schemas/flux/index.js.map +1 -1
  116. package/dist/schemas/host-config.d.ts +76 -0
  117. package/dist/schemas/host-config.d.ts.map +1 -0
  118. package/dist/schemas/host-config.js +105 -0
  119. package/dist/schemas/host-config.js.map +1 -0
  120. package/dist/schemas/scout/index.d.ts +80 -23
  121. package/dist/schemas/scout/index.d.ts.map +1 -1
  122. package/dist/schemas/scout/index.js +26 -11
  123. package/dist/schemas/scout/index.js.map +1 -1
  124. package/dist/schemas/scout/logs.d.ts +17 -5
  125. package/dist/schemas/scout/logs.d.ts.map +1 -1
  126. package/dist/schemas/scout/logs.js +41 -31
  127. package/dist/schemas/scout/logs.js.map +1 -1
  128. package/dist/schemas/scout/simple.d.ts +126 -11
  129. package/dist/schemas/scout/simple.d.ts.map +1 -1
  130. package/dist/schemas/scout/simple.js +112 -57
  131. package/dist/schemas/scout/simple.js.map +1 -1
  132. package/dist/schemas/scout/zfs.d.ts +17 -5
  133. package/dist/schemas/scout/zfs.d.ts.map +1 -1
  134. package/dist/schemas/scout/zfs.js +34 -25
  135. package/dist/schemas/scout/zfs.js.map +1 -1
  136. package/dist/services/cache-layer.d.ts +160 -0
  137. package/dist/services/cache-layer.d.ts.map +1 -0
  138. package/dist/services/cache-layer.js +138 -0
  139. package/dist/services/cache-layer.js.map +1 -0
  140. package/dist/services/compose-cache.d.ts +75 -0
  141. package/dist/services/compose-cache.d.ts.map +1 -0
  142. package/dist/services/compose-cache.js +178 -0
  143. package/dist/services/compose-cache.js.map +1 -0
  144. package/dist/services/compose-discovery.d.ts +46 -0
  145. package/dist/services/compose-discovery.d.ts.map +1 -0
  146. package/dist/services/compose-discovery.js +219 -0
  147. package/dist/services/compose-discovery.js.map +1 -0
  148. package/dist/services/compose-project-lister.d.ts +27 -0
  149. package/dist/services/compose-project-lister.d.ts.map +1 -0
  150. package/dist/services/compose-project-lister.js +71 -0
  151. package/dist/services/compose-project-lister.js.map +1 -0
  152. package/dist/services/compose-scanner.d.ts +63 -0
  153. package/dist/services/compose-scanner.d.ts.map +1 -0
  154. package/dist/services/compose-scanner.js +253 -0
  155. package/dist/services/compose-scanner.js.map +1 -0
  156. package/dist/services/compose.d.ts +64 -28
  157. package/dist/services/compose.d.ts.map +1 -1
  158. package/dist/services/compose.js +220 -98
  159. package/dist/services/compose.js.map +1 -1
  160. package/dist/services/config-loader.d.ts +23 -0
  161. package/dist/services/config-loader.d.ts.map +1 -0
  162. package/dist/services/config-loader.js +124 -0
  163. package/dist/services/config-loader.js.map +1 -0
  164. package/dist/services/config-service.d.ts +38 -0
  165. package/dist/services/config-service.d.ts.map +1 -0
  166. package/dist/services/config-service.js +225 -0
  167. package/dist/services/config-service.js.map +1 -0
  168. package/dist/services/container-host-map-cache.d.ts +121 -0
  169. package/dist/services/container-host-map-cache.d.ts.map +1 -0
  170. package/dist/services/container-host-map-cache.js +188 -0
  171. package/dist/services/container-host-map-cache.js.map +1 -0
  172. package/dist/services/container.d.ts +194 -6
  173. package/dist/services/container.d.ts.map +1 -1
  174. package/dist/services/container.js +386 -11
  175. package/dist/services/container.js.map +1 -1
  176. package/dist/services/diagnostics.d.ts +57 -0
  177. package/dist/services/diagnostics.d.ts.map +1 -0
  178. package/dist/services/diagnostics.js +271 -0
  179. package/dist/services/diagnostics.js.map +1 -0
  180. package/dist/services/docker/container-service.d.ts +123 -0
  181. package/dist/services/docker/container-service.d.ts.map +1 -0
  182. package/dist/services/docker/container-service.js +347 -0
  183. package/dist/services/docker/container-service.js.map +1 -0
  184. package/dist/services/docker/image-service.d.ts +82 -0
  185. package/dist/services/docker/image-service.d.ts.map +1 -0
  186. package/dist/services/docker/image-service.js +193 -0
  187. package/dist/services/docker/image-service.js.map +1 -0
  188. package/dist/services/docker/index.d.ts +80 -0
  189. package/dist/services/docker/index.d.ts.map +1 -0
  190. package/dist/services/docker/index.js +103 -0
  191. package/dist/services/docker/index.js.map +1 -0
  192. package/dist/services/docker/network-service.d.ts +22 -0
  193. package/dist/services/docker/network-service.d.ts.map +1 -0
  194. package/dist/services/docker/network-service.js +43 -0
  195. package/dist/services/docker/network-service.js.map +1 -0
  196. package/dist/services/docker/system-service.d.ts +49 -0
  197. package/dist/services/docker/system-service.d.ts.map +1 -0
  198. package/dist/services/docker/system-service.js +215 -0
  199. package/dist/services/docker/system-service.js.map +1 -0
  200. package/dist/services/docker/utils/client-factory.d.ts +56 -0
  201. package/dist/services/docker/utils/client-factory.d.ts.map +1 -0
  202. package/dist/services/docker/utils/client-factory.js +139 -0
  203. package/dist/services/docker/utils/client-factory.js.map +1 -0
  204. package/dist/services/docker/utils/client-manager.d.ts +88 -0
  205. package/dist/services/docker/utils/client-manager.d.ts.map +1 -0
  206. package/dist/services/docker/utils/client-manager.js +124 -0
  207. package/dist/services/docker/utils/client-manager.js.map +1 -0
  208. package/dist/services/docker/utils/exec-handler.d.ts +94 -0
  209. package/dist/services/docker/utils/exec-handler.d.ts.map +1 -0
  210. package/dist/services/docker/utils/exec-handler.js +197 -0
  211. package/dist/services/docker/utils/exec-handler.js.map +1 -0
  212. package/dist/services/docker/utils/formatters.d.ts +13 -0
  213. package/dist/services/docker/utils/formatters.d.ts.map +1 -0
  214. package/dist/services/docker/utils/formatters.js +33 -0
  215. package/dist/services/docker/utils/formatters.js.map +1 -0
  216. package/dist/services/docker/utils/log-parser.d.ts +10 -0
  217. package/dist/services/docker/utils/log-parser.d.ts.map +1 -0
  218. package/dist/services/docker/utils/log-parser.js +48 -0
  219. package/dist/services/docker/utils/log-parser.js.map +1 -0
  220. package/dist/services/docker/utils/stats-calculator.d.ts +68 -0
  221. package/dist/services/docker/utils/stats-calculator.d.ts.map +1 -0
  222. package/dist/services/docker/utils/stats-calculator.js +61 -0
  223. package/dist/services/docker/utils/stats-calculator.js.map +1 -0
  224. package/dist/services/docker/volume-service.d.ts +22 -0
  225. package/dist/services/docker/volume-service.d.ts.map +1 -0
  226. package/dist/services/docker/volume-service.js +48 -0
  227. package/dist/services/docker/volume-service.js.map +1 -0
  228. package/dist/services/docker-interfaces.d.ts +283 -0
  229. package/dist/services/docker-interfaces.d.ts.map +1 -0
  230. package/dist/services/docker-interfaces.js +13 -0
  231. package/dist/services/docker-interfaces.js.map +1 -0
  232. package/dist/services/docker.d.ts +42 -5
  233. package/dist/services/docker.d.ts.map +1 -1
  234. package/dist/services/docker.js +335 -127
  235. package/dist/services/docker.js.map +1 -1
  236. package/dist/services/file-service.d.ts +6 -2
  237. package/dist/services/file-service.d.ts.map +1 -1
  238. package/dist/services/file-service.js +156 -52
  239. package/dist/services/file-service.js.map +1 -1
  240. package/dist/services/host-config-repository.d.ts +133 -0
  241. package/dist/services/host-config-repository.d.ts.map +1 -0
  242. package/dist/services/host-config-repository.js +323 -0
  243. package/dist/services/host-config-repository.js.map +1 -0
  244. package/dist/services/host-resolver.d.ts +49 -0
  245. package/dist/services/host-resolver.d.ts.map +1 -0
  246. package/dist/services/host-resolver.js +176 -0
  247. package/dist/services/host-resolver.js.map +1 -0
  248. package/dist/services/interfaces.d.ts +61 -194
  249. package/dist/services/interfaces.d.ts.map +1 -1
  250. package/dist/services/local-executor.d.ts +31 -0
  251. package/dist/services/local-executor.d.ts.map +1 -0
  252. package/dist/services/local-executor.js +71 -0
  253. package/dist/services/local-executor.js.map +1 -0
  254. package/dist/services/ssh-config-loader.d.ts +35 -0
  255. package/dist/services/ssh-config-loader.d.ts.map +1 -0
  256. package/dist/services/ssh-config-loader.js +218 -0
  257. package/dist/services/ssh-config-loader.js.map +1 -0
  258. package/dist/services/ssh-pool.d.ts +26 -1
  259. package/dist/services/ssh-pool.d.ts.map +1 -1
  260. package/dist/services/ssh-pool.js +166 -25
  261. package/dist/services/ssh-pool.js.map +1 -1
  262. package/dist/services/ssh-service.d.ts +3 -0
  263. package/dist/services/ssh-service.d.ts.map +1 -1
  264. package/dist/services/ssh-service.js +53 -31
  265. package/dist/services/ssh-service.js.map +1 -1
  266. package/dist/services/ssh.d.ts +2 -6
  267. package/dist/services/ssh.d.ts.map +1 -1
  268. package/dist/services/ssh.js +9 -40
  269. package/dist/services/ssh.js.map +1 -1
  270. package/dist/tools/definitions/flux.d.ts +13 -0
  271. package/dist/tools/definitions/flux.d.ts.map +1 -0
  272. package/dist/tools/definitions/flux.js +101 -0
  273. package/dist/tools/definitions/flux.js.map +1 -0
  274. package/dist/tools/definitions/index.d.ts +8 -0
  275. package/dist/tools/definitions/index.d.ts.map +1 -0
  276. package/dist/tools/definitions/index.js +8 -0
  277. package/dist/tools/definitions/index.js.map +1 -0
  278. package/dist/tools/definitions/scout.d.ts +13 -0
  279. package/dist/tools/definitions/scout.d.ts.map +1 -0
  280. package/dist/tools/definitions/scout.js +78 -0
  281. package/dist/tools/definitions/scout.js.map +1 -0
  282. package/dist/tools/flux.d.ts +16 -8
  283. package/dist/tools/flux.d.ts.map +1 -1
  284. package/dist/tools/flux.js +27 -66
  285. package/dist/tools/flux.js.map +1 -1
  286. package/dist/tools/handlers/base-handler.d.ts +172 -0
  287. package/dist/tools/handlers/base-handler.d.ts.map +1 -0
  288. package/dist/tools/handlers/base-handler.js +234 -0
  289. package/dist/tools/handlers/base-handler.js.map +1 -0
  290. package/dist/tools/handlers/compose-handlers.d.ts +108 -0
  291. package/dist/tools/handlers/compose-handlers.d.ts.map +1 -0
  292. package/dist/tools/handlers/compose-handlers.js +293 -0
  293. package/dist/tools/handlers/compose-handlers.js.map +1 -0
  294. package/dist/tools/handlers/compose-utils.d.ts +35 -0
  295. package/dist/tools/handlers/compose-utils.d.ts.map +1 -0
  296. package/dist/tools/handlers/compose-utils.js +76 -0
  297. package/dist/tools/handlers/compose-utils.js.map +1 -0
  298. package/dist/tools/handlers/compose.d.ts +23 -0
  299. package/dist/tools/handlers/compose.d.ts.map +1 -0
  300. package/dist/tools/handlers/compose.js +125 -0
  301. package/dist/tools/handlers/compose.js.map +1 -0
  302. package/dist/tools/handlers/container.d.ts +23 -0
  303. package/dist/tools/handlers/container.d.ts.map +1 -0
  304. package/dist/tools/handlers/container.js +333 -0
  305. package/dist/tools/handlers/container.js.map +1 -0
  306. package/dist/tools/handlers/docker.d.ts +24 -0
  307. package/dist/tools/handlers/docker.d.ts.map +1 -0
  308. package/dist/tools/handlers/docker.js +155 -0
  309. package/dist/tools/handlers/docker.js.map +1 -0
  310. package/dist/tools/handlers/host.d.ts +23 -0
  311. package/dist/tools/handlers/host.d.ts.map +1 -0
  312. package/dist/tools/handlers/host.js +196 -0
  313. package/dist/tools/handlers/host.js.map +1 -0
  314. package/dist/tools/handlers/scout-logs.d.ts +24 -0
  315. package/dist/tools/handlers/scout-logs.d.ts.map +1 -0
  316. package/dist/tools/handlers/scout-logs.js +119 -0
  317. package/dist/tools/handlers/scout-logs.js.map +1 -0
  318. package/dist/tools/handlers/scout-simple.d.ts +23 -0
  319. package/dist/tools/handlers/scout-simple.d.ts.map +1 -0
  320. package/dist/tools/handlers/scout-simple.js +286 -0
  321. package/dist/tools/handlers/scout-simple.js.map +1 -0
  322. package/dist/tools/handlers/scout-zfs.d.ts +23 -0
  323. package/dist/tools/handlers/scout-zfs.d.ts.map +1 -0
  324. package/dist/tools/handlers/scout-zfs.js +82 -0
  325. package/dist/tools/handlers/scout-zfs.js.map +1 -0
  326. package/dist/tools/index.d.ts +32 -2
  327. package/dist/tools/index.d.ts.map +1 -1
  328. package/dist/tools/index.js +41 -35
  329. package/dist/tools/index.js.map +1 -1
  330. package/dist/tools/registry.d.ts +135 -0
  331. package/dist/tools/registry.d.ts.map +1 -0
  332. package/dist/tools/registry.js +151 -0
  333. package/dist/tools/registry.js.map +1 -0
  334. package/dist/tools/scout.d.ts +16 -8
  335. package/dist/tools/scout.d.ts.map +1 -1
  336. package/dist/tools/scout.js +36 -78
  337. package/dist/tools/scout.js.map +1 -1
  338. package/dist/types.d.ts +629 -1
  339. package/dist/types.d.ts.map +1 -1
  340. package/dist/types.js.map +1 -1
  341. package/dist/utils/command-security.d.ts +82 -0
  342. package/dist/utils/command-security.d.ts.map +1 -0
  343. package/dist/utils/command-security.js +122 -0
  344. package/dist/utils/command-security.js.map +1 -0
  345. package/dist/utils/error-sanitization.d.ts +77 -0
  346. package/dist/utils/error-sanitization.d.ts.map +1 -0
  347. package/dist/utils/error-sanitization.js +107 -0
  348. package/dist/utils/error-sanitization.js.map +1 -0
  349. package/dist/utils/errors.d.ts +30 -6
  350. package/dist/utils/errors.d.ts.map +1 -1
  351. package/dist/utils/errors.js +91 -12
  352. package/dist/utils/errors.js.map +1 -1
  353. package/dist/utils/help-handler.d.ts +23 -0
  354. package/dist/utils/help-handler.d.ts.map +1 -0
  355. package/dist/utils/help-handler.js +21 -0
  356. package/dist/utils/help-handler.js.map +1 -0
  357. package/dist/utils/help.d.ts +1 -1
  358. package/dist/utils/help.d.ts.map +1 -1
  359. package/dist/utils/help.js +57 -16
  360. package/dist/utils/help.js.map +1 -1
  361. package/dist/utils/host-utils.d.ts +31 -0
  362. package/dist/utils/host-utils.d.ts.map +1 -0
  363. package/dist/utils/host-utils.js +80 -0
  364. package/dist/utils/host-utils.js.map +1 -0
  365. package/dist/utils/index.d.ts +8 -2
  366. package/dist/utils/index.d.ts.map +1 -1
  367. package/dist/utils/index.js +8 -2
  368. package/dist/utils/index.js.map +1 -1
  369. package/dist/utils/init-detection.d.ts +36 -0
  370. package/dist/utils/init-detection.d.ts.map +1 -0
  371. package/dist/utils/init-detection.js +79 -0
  372. package/dist/utils/init-detection.js.map +1 -0
  373. package/dist/utils/logger.d.ts +11 -0
  374. package/dist/utils/logger.d.ts.map +1 -0
  375. package/dist/utils/logger.js +32 -0
  376. package/dist/utils/logger.js.map +1 -0
  377. package/dist/utils/pagination.d.ts +20 -0
  378. package/dist/utils/pagination.d.ts.map +1 -0
  379. package/dist/utils/pagination.js +29 -0
  380. package/dist/utils/pagination.js.map +1 -0
  381. package/dist/utils/path-security.d.ts +132 -18
  382. package/dist/utils/path-security.d.ts.map +1 -1
  383. package/dist/utils/path-security.js +164 -35
  384. package/dist/utils/path-security.js.map +1 -1
  385. package/dist/utils/sorting.d.ts +33 -0
  386. package/dist/utils/sorting.d.ts.map +1 -0
  387. package/dist/utils/sorting.js +57 -0
  388. package/dist/utils/sorting.js.map +1 -0
  389. package/dist/utils/text-filters.d.ts +13 -0
  390. package/dist/utils/text-filters.d.ts.map +1 -0
  391. package/dist/utils/text-filters.js +18 -0
  392. package/dist/utils/text-filters.js.map +1 -0
  393. package/dist/utils/time.d.ts +11 -0
  394. package/dist/utils/time.d.ts.map +1 -0
  395. package/dist/utils/time.js +13 -0
  396. package/dist/utils/time.js.map +1 -0
  397. package/dist/utils/validation.d.ts +25 -0
  398. package/dist/utils/validation.d.ts.map +1 -0
  399. package/dist/utils/validation.js +56 -0
  400. package/dist/utils/validation.js.map +1 -0
  401. package/package.json +45 -19
  402. package/dist/schemas/discriminator.d.ts +0 -20
  403. package/dist/schemas/discriminator.d.ts.map +0 -1
  404. package/dist/schemas/discriminator.js +0 -25
  405. package/dist/schemas/discriminator.js.map +0 -1
  406. package/dist/schemas/unified.d.ts +0 -674
  407. package/dist/schemas/unified.d.ts.map +0 -1
  408. package/dist/schemas/unified.js +0 -453
  409. package/dist/schemas/unified.js.map +0 -1
  410. package/dist/tools/unified.d.ts +0 -7
  411. package/dist/tools/unified.d.ts.map +0 -1
  412. package/dist/tools/unified.js +0 -827
  413. package/dist/tools/unified.js.map +0 -1
@@ -0,0 +1,687 @@
1
+ /**
2
+ * Scout (SSH) operation formatting utilities
3
+ *
4
+ * Provides consistent markdown formatting for file operations:
5
+ * read, list, tree, exec, find, transfer, and diff.
6
+ *
7
+ * ## STYLE.md Compliance
8
+ *
9
+ * All formatters follow STYLE.md specifications:
10
+ * - Section 3.1: Plain text titles (no markdown ## prefix)
11
+ * - Section 4.1: Canonical symbols only (✓✗⚠, NO emoji)
12
+ * - Section 3.6: Freshness timestamps for volatile operations (TODO: Phase 2.2)
13
+ * - Section 3.2: Summary lines (TODO: Phase 2.2)
14
+ *
15
+ * Symbol Legend:
16
+ * - ✓ = Success (command exit 0)
17
+ * - ✗ = Error (command exit non-zero)
18
+ * - ⚠ = Warning (truncation, non-fatal issues)
19
+ */
20
+ import { formatBytes } from "../services/docker/utils/formatters.js";
21
+ import { getTimestamp, truncateIfNeeded } from "./utils.js";
22
+ /**
23
+ * Format file read result as markdown
24
+ *
25
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
26
+ * Summary per STYLE.md 3.2: Pipe-separated segments
27
+ * Warning symbol: ⚠ (canonical non-emoji variant)
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const output = formatScoutReadMarkdown("squirts", "/etc/hostname", "squirts\n", 8, false);
32
+ * // Returns:
33
+ * // File Read: squirts:/etc/hostname
34
+ * // Size: 8.0 B | truncated: no
35
+ * //
36
+ * // ```
37
+ * // squirts
38
+ * // ```
39
+ * ```
40
+ */
41
+ export function formatScoutReadMarkdown(host, path, content, size, truncated) {
42
+ const lines = [
43
+ `File Read: ${host}:${path}`,
44
+ `Size: ${formatBytes(size)} | truncated: ${truncated ? "yes" : "no"}`,
45
+ "",
46
+ "```",
47
+ content,
48
+ "```",
49
+ ];
50
+ if (truncated) {
51
+ lines.push("");
52
+ lines.push("⚠ *File was truncated to fit size limit*");
53
+ }
54
+ return truncateIfNeeded(lines.join("\n"));
55
+ }
56
+ /**
57
+ * Format directory listing as markdown
58
+ *
59
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
60
+ * Summary per STYLE.md 3.2: Pipe-separated segments
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * formatScoutListMarkdown("squirts", "/etc", "file1\nfile2\nfile3");
65
+ * // Directory Listing: squirts:/etc
66
+ * // Items: 3
67
+ * //
68
+ * // ```
69
+ * // file1
70
+ * // file2
71
+ * // file3
72
+ * // ```
73
+ * ```
74
+ */
75
+ export function formatScoutListMarkdown(host, path, listing) {
76
+ const items = listing.split("\n").filter((l) => l.trim()).length;
77
+ return truncateIfNeeded([`Directory Listing: ${host}:${path}`, `Items: ${items}`, "", "```", listing, "```"].join("\n"));
78
+ }
79
+ /**
80
+ * Format tree output as markdown
81
+ *
82
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
83
+ * Summary per STYLE.md 3.2: Depth displayed as separate line
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * const output = formatScoutTreeMarkdown("squirts", "/opt", "dir1/\n file1\ndir2/", 2);
88
+ * // Returns:
89
+ * // Directory Tree: squirts:/opt
90
+ * // Depth: 2
91
+ * //
92
+ * // ```
93
+ * // dir1/
94
+ * // file1
95
+ * // dir2/
96
+ * // ```
97
+ * ```
98
+ */
99
+ export function formatScoutTreeMarkdown(host, path, tree, depth) {
100
+ return truncateIfNeeded([`Directory Tree: ${host}:${path}`, `Depth: ${depth}`, "", "```", tree, "```"].join("\n"));
101
+ }
102
+ /**
103
+ * Format command execution result as markdown
104
+ *
105
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
106
+ * Symbols per STYLE.md 4.1: ✓ for success, ✗ for error
107
+ * Freshness per STYLE.md 3.6: Command execution is volatile data
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * const output = formatScoutExecMarkdown("squirts", "/tmp", "uptime", "15:23:45 up 3 days", 0);
112
+ * // Returns:
113
+ * // ✓ Command Execution: squirts:/tmp
114
+ * // Exit: 0
115
+ * // As of (EST): 11:05:20 | 02/13/2026
116
+ * //
117
+ * // **Command:** `uptime`
118
+ * // **Exit:** 0
119
+ * //
120
+ * // **Output:**
121
+ * // ```
122
+ * // 15:23:45 up 3 days
123
+ * // ```
124
+ * ```
125
+ */
126
+ export function formatScoutExecMarkdown(host, path, command, stdout, exitCode) {
127
+ const statusSymbol = exitCode === 0 ? "✓" : "✗";
128
+ return truncateIfNeeded([
129
+ `${statusSymbol} Command Execution: ${host}:${path}`,
130
+ `Exit: ${exitCode}`,
131
+ getTimestamp(),
132
+ "",
133
+ `**Command:** \`${command}\``,
134
+ `**Exit:** ${exitCode}`,
135
+ "",
136
+ "**Output:**",
137
+ "```",
138
+ stdout,
139
+ "```",
140
+ ].join("\n"));
141
+ }
142
+ /**
143
+ * Format find results as markdown
144
+ *
145
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
146
+ * Summary per STYLE.md 3.2: Pattern and result count in pipe-separated format
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * const output = formatScoutFindMarkdown("squirts", "/opt", "*.log", "access.log\nerror.log");
151
+ * // Returns:
152
+ * // Find Results: squirts:/opt
153
+ * // Pattern: *.log | Results: 2
154
+ * //
155
+ * // **Pattern:** `*.log`
156
+ * // **Results:** 2 files
157
+ * //
158
+ * // ```
159
+ * // access.log
160
+ * // error.log
161
+ * // ```
162
+ * ```
163
+ */
164
+ export function formatScoutFindMarkdown(host, path, pattern, results) {
165
+ const lines = results.split("\n").filter((l) => l.trim());
166
+ return truncateIfNeeded([
167
+ `Find Results: ${host}:${path}`,
168
+ `Pattern: ${pattern} | Results: ${lines.length}`,
169
+ "",
170
+ `**Pattern:** \`${pattern}\``,
171
+ `**Results:** ${lines.length} files`,
172
+ "",
173
+ "```",
174
+ results,
175
+ "```",
176
+ ].join("\n"));
177
+ }
178
+ /**
179
+ * Format file transfer result as markdown
180
+ *
181
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
182
+ * Summary per STYLE.md 3.2: Source, target, and size in pipe-separated format
183
+ * Warning symbol: ⚠ (canonical non-emoji variant)
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * const output = formatScoutTransferMarkdown("squirts", "/data/backup.tar", "boops", "/backups/backup.tar", 10485760);
188
+ * // Returns:
189
+ * // File Transfer Complete
190
+ * // From: squirts | To: boops | Size: 10.0 MB
191
+ * //
192
+ * // **From:** squirts:/data/backup.tar
193
+ * // **To:** boops:/backups/backup.tar
194
+ * // **Size:** 10.0 MB
195
+ * ```
196
+ */
197
+ export function formatScoutTransferMarkdown(sourceHost, sourcePath, targetHost, targetPath, bytesTransferred, warning) {
198
+ const lines = [
199
+ "File Transfer Complete",
200
+ `From: ${sourceHost} | To: ${targetHost} | Size: ${formatBytes(bytesTransferred)}`,
201
+ "",
202
+ `**From:** ${sourceHost}:${sourcePath}`,
203
+ `**To:** ${targetHost}:${targetPath}`,
204
+ `**Size:** ${formatBytes(bytesTransferred)}`,
205
+ ];
206
+ if (warning) {
207
+ lines.push("");
208
+ lines.push(`⚠ ${warning}`);
209
+ }
210
+ return lines.join("\n");
211
+ }
212
+ /**
213
+ * Format file diff result as markdown
214
+ *
215
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
216
+ * Summary per STYLE.md 3.2: Both file paths in pipe-separated format
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * const output = formatScoutDiffMarkdown("squirts", "/etc/config.old", "boops", "/etc/config.new", "- old line\n+ new line");
221
+ * // Returns:
222
+ * // File Diff
223
+ * // File 1: squirts:/etc/config.old | File 2: boops:/etc/config.new
224
+ * //
225
+ * // **File 1:** squirts:/etc/config.old
226
+ * // **File 2:** boops:/etc/config.new
227
+ * //
228
+ * // ```diff
229
+ * // - old line
230
+ * // + new line
231
+ * // ```
232
+ * ```
233
+ */
234
+ export function formatScoutDiffMarkdown(host1, path1, host2, path2, diff) {
235
+ return truncateIfNeeded([
236
+ "File Diff",
237
+ `File 1: ${host1}:${path1} | File 2: ${host2}:${path2}`,
238
+ "",
239
+ `**File 1:** ${host1}:${path1}`,
240
+ `**File 2:** ${host2}:${path2}`,
241
+ "",
242
+ "```diff",
243
+ diff,
244
+ "```",
245
+ ].join("\n"));
246
+ }
247
+ /**
248
+ * Format list of hosts as markdown table
249
+ *
250
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
251
+ * Summary per STYLE.md 3.2: Host count
252
+ * Table format per STYLE.md 7.2: ASCII table with aligned columns
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * const output = formatScoutNodesMarkdown(["squirts", "boops", "nicks"]);
257
+ * // Returns:
258
+ * // Scout Nodes
259
+ * // Hosts: 3
260
+ * //
261
+ * // | Host |
262
+ * // |------|
263
+ * // | squirts |
264
+ * // | boops |
265
+ * // | nicks |
266
+ * ```
267
+ */
268
+ export function formatScoutNodesMarkdown(hosts) {
269
+ const lines = ["Scout Nodes", `Hosts: ${hosts.length}`, "", "| Host |", "|------|"];
270
+ for (const host of hosts) {
271
+ lines.push(`| ${host} |`);
272
+ }
273
+ return lines.join("\n");
274
+ }
275
+ /**
276
+ * Format process listing as markdown
277
+ *
278
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
279
+ * Summary per STYLE.md 3.2: Process count
280
+ * Freshness per STYLE.md 3.6: Process data is volatile
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * const output = formatScoutPsMarkdown("squirts", " PID COMMAND\n 1234 nginx\n 5678 node\n 9012 postgres");
285
+ * // Returns:
286
+ * // Process Listing: squirts
287
+ * // Processes: 3
288
+ * // As of (EST): 11:27:00 | 02/13/2026
289
+ * //
290
+ * // ```
291
+ * // PID COMMAND
292
+ * // 1234 nginx
293
+ * // 5678 node
294
+ * // 9012 postgres
295
+ * // ```
296
+ * ```
297
+ */
298
+ export function formatScoutPsMarkdown(host, processes) {
299
+ const lines = processes.split("\n").filter((l) => l.trim());
300
+ const processCount = lines.length > 1 ? lines.length - 1 : 0; // Subtract header line
301
+ return truncateIfNeeded([
302
+ `Process Listing: ${host}`,
303
+ `Processes: ${processCount}`,
304
+ getTimestamp(),
305
+ "",
306
+ "```",
307
+ processes,
308
+ "```",
309
+ ].join("\n"));
310
+ }
311
+ /**
312
+ * Format disk usage as markdown with warnings for high usage
313
+ *
314
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
315
+ * Summary per STYLE.md 3.2: Filesystem count
316
+ * Freshness per STYLE.md 3.6: Disk data is volatile
317
+ * Warning per STYLE.md 10.2: ⚠ for filesystems >85% usage
318
+ *
319
+ * @example
320
+ * ```ts
321
+ * const output = formatScoutDfMarkdown("squirts", "Filesystem Size Used Avail Use% Mounted on\n/dev/sda1 100G 90G 10G 90% /\n/dev/sdb1 50G 20G 30G 40% /data");
322
+ * // Returns:
323
+ * // Disk Usage: squirts
324
+ * // Filesystems: 2 ⚠
325
+ * // As of (EST): 11:28:20 | 02/13/2026
326
+ * //
327
+ * // ```
328
+ * // Filesystem Size Used Avail Use% Mounted on
329
+ * // /dev/sda1 100G 90G 10G 90% /
330
+ * // /dev/sdb1 50G 20G 30G 40% /data
331
+ * // ```
332
+ * //
333
+ * // ⚠ *One or more filesystems exceed 85% usage*
334
+ * ```
335
+ */
336
+ export function formatScoutDfMarkdown(host, diskUsage) {
337
+ const lines = diskUsage.split("\n").filter((l) => l.trim());
338
+ const fsCount = lines.length > 1 ? lines.length - 1 : 0; // Subtract header line
339
+ // Parse for high usage warnings (>85%)
340
+ const hasWarnings = lines.some((line) => {
341
+ const match = line.match(/(\d+)%/);
342
+ return match && Number.parseInt(match[1], 10) > 85;
343
+ });
344
+ const outputLines = [
345
+ `Disk Usage: ${host}`,
346
+ `Filesystems: ${fsCount}${hasWarnings ? " ⚠" : ""}`,
347
+ getTimestamp(),
348
+ "",
349
+ "```",
350
+ diskUsage,
351
+ "```",
352
+ ];
353
+ if (hasWarnings) {
354
+ outputLines.push("");
355
+ outputLines.push("⚠ *One or more filesystems exceed 85% usage*");
356
+ }
357
+ return truncateIfNeeded(outputLines.join("\n"));
358
+ }
359
+ /**
360
+ * Format syslog output as markdown
361
+ *
362
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
363
+ * Summary per STYLE.md 3.2: Lines count
364
+ * Freshness per STYLE.md 3.6: Log data is volatile
365
+ * Request echo per STYLE.md 3.5: Show lines requested and optional grep filter
366
+ *
367
+ * @example
368
+ * ```ts
369
+ * const output = formatScoutSyslogMarkdown("squirts", 50, "Feb 13 11:00:00 squirts sshd[1234]: Accepted key for user from 192.168.1.1\nFeb 13 11:01:00 squirts systemd[1]: Started session.", "sshd");
370
+ * // Returns:
371
+ * // Syslog: squirts
372
+ * // Lines requested: 50 | Returned: 2 | Filter: sshd
373
+ * // As of (EST): 11:29:50 | 02/13/2026
374
+ * //
375
+ * // ```
376
+ * // Feb 13 11:00:00 squirts sshd[1234]: Accepted key for user from 192.168.1.1
377
+ * // Feb 13 11:01:00 squirts systemd[1]: Started session.
378
+ * // ```
379
+ * ```
380
+ */
381
+ export function formatScoutSyslogMarkdown(host, linesRequested, logs, grepFilter) {
382
+ const lines = logs.split("\n").filter((l) => l.trim());
383
+ const actualLines = lines.length;
384
+ const outputLines = [
385
+ `Syslog: ${host}`,
386
+ `Lines requested: ${linesRequested} | Returned: ${actualLines}${grepFilter ? ` | Filter: ${grepFilter}` : ""}`,
387
+ getTimestamp(),
388
+ "",
389
+ "```",
390
+ logs,
391
+ "```",
392
+ ];
393
+ return truncateIfNeeded(outputLines.join("\n"));
394
+ }
395
+ /**
396
+ * Format journal (journalctl) output as markdown
397
+ *
398
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
399
+ * Summary per STYLE.md 3.2: Lines count
400
+ * Freshness per STYLE.md 3.6: Log data is volatile
401
+ * Request echo per STYLE.md 3.5: Show lines requested and optional grep filter
402
+ *
403
+ * @example
404
+ * ```ts
405
+ * const output = formatScoutJournalMarkdown("squirts", 50, "Feb 13 11:30:00 squirts systemd[1]: Started service\nFeb 13 11:31:00 squirts systemd[1]: Stopped service");
406
+ * // Returns:
407
+ * // Journal: squirts
408
+ * // Lines requested: 50 | Returned: 2
409
+ * // As of (EST): 11:30:20 | 02/13/2026
410
+ * //
411
+ * // ```
412
+ * // Feb 13 11:30:00 squirts systemd[1]: Started service
413
+ * // Feb 13 11:31:00 squirts systemd[1]: Stopped service
414
+ * // ```
415
+ * ```
416
+ */
417
+ export function formatScoutJournalMarkdown(host, linesRequested, logs, grepFilter) {
418
+ const lines = logs.split("\n").filter((l) => l.trim());
419
+ const actualLines = lines.length;
420
+ const outputLines = [
421
+ `Journal: ${host}`,
422
+ `Lines requested: ${linesRequested} | Returned: ${actualLines}${grepFilter ? ` | Filter: ${grepFilter}` : ""}`,
423
+ getTimestamp(),
424
+ "",
425
+ "```",
426
+ logs,
427
+ "```",
428
+ ];
429
+ return truncateIfNeeded(outputLines.join("\n"));
430
+ }
431
+ /**
432
+ * Format kernel ring buffer (dmesg) logs as markdown
433
+ *
434
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
435
+ * Summary per STYLE.md 3.2: Pipe-separated with request echo
436
+ * Request echo per STYLE.md 3.5: Shows lines requested parameter
437
+ * Freshness per STYLE.md 3.6: Volatile kernel log data
438
+ *
439
+ * @param host - Host name the logs are from
440
+ * @param linesRequested - Number of lines requested from dmesg
441
+ * @param logs - Raw dmesg log output
442
+ * @param grepFilter - Optional grep pattern applied to logs
443
+ * @returns Formatted markdown string
444
+ *
445
+ * @example
446
+ * ```typescript
447
+ * const output = formatScoutDmesgMarkdown("squirts", 100, "[ 0.000000] Linux version 6.1.0-generic\n[ 0.001234] Command line: BOOT_IMAGE=/boot/vmlinuz");
448
+ * // Dmesg: squirts
449
+ * // Lines requested: 100 | Returned: 2
450
+ * // As of (EST): 11:45:30 | 02/13/2026
451
+ * //
452
+ * // ```
453
+ * // [ 0.000000] Linux version 6.1.0-generic
454
+ * // [ 0.001234] Command line: BOOT_IMAGE=/boot/vmlinuz
455
+ * // ```
456
+ * ```
457
+ */
458
+ export function formatScoutDmesgMarkdown(host, linesRequested, logs, grepFilter) {
459
+ const lines = logs.split("\n").filter((l) => l.trim());
460
+ const actualLines = lines.length;
461
+ const outputLines = [
462
+ `Dmesg: ${host}`,
463
+ `Lines requested: ${linesRequested} | Returned: ${actualLines}${grepFilter ? ` | Filter: ${grepFilter}` : ""}`,
464
+ getTimestamp(),
465
+ "",
466
+ "```",
467
+ logs,
468
+ "```",
469
+ ];
470
+ return truncateIfNeeded(outputLines.join("\n"));
471
+ }
472
+ /**
473
+ * Format authentication logs as markdown
474
+ *
475
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
476
+ * Summary per STYLE.md 3.2: Pipe-separated with request echo
477
+ * Request echo per STYLE.md 3.5: Shows lines requested parameter
478
+ * Freshness per STYLE.md 3.6: Volatile authentication log data
479
+ *
480
+ * @param host - Host name the logs are from
481
+ * @param linesRequested - Number of lines requested from auth log
482
+ * @param logs - Raw authentication log output
483
+ * @param grepFilter - Optional grep pattern applied to logs
484
+ * @returns Formatted markdown string
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * const output = formatScoutAuthMarkdown("squirts", 50, "Feb 13 11:00:00 squirts sshd[1234]: Accepted publickey for user from 192.168.1.100\nFeb 13 11:00:05 squirts sshd[1234]: pam_unix(sshd:session): session opened");
489
+ * // Auth Logs: squirts
490
+ * // Lines requested: 50 | Returned: 2
491
+ * // As of (EST): 11:00:30 | 02/13/2026
492
+ * //
493
+ * // ```
494
+ * // Feb 13 11:00:00 squirts sshd[1234]: Accepted publickey for user from 192.168.1.100
495
+ * // Feb 13 11:00:05 squirts sshd[1234]: pam_unix(sshd:session): session opened
496
+ * // ```
497
+ * ```
498
+ */
499
+ export function formatScoutAuthMarkdown(host, linesRequested, logs, grepFilter) {
500
+ const lines = logs.split("\n").filter((l) => l.trim());
501
+ const actualLines = lines.length;
502
+ const outputLines = [
503
+ `Auth Logs: ${host}`,
504
+ `Lines requested: ${linesRequested} | Returned: ${actualLines}${grepFilter ? ` | Filter: ${grepFilter}` : ""}`,
505
+ getTimestamp(),
506
+ "",
507
+ "```",
508
+ logs,
509
+ "```",
510
+ ];
511
+ return truncateIfNeeded(outputLines.join("\n"));
512
+ }
513
+ /**
514
+ * Format ZFS pool list as markdown with health status symbols
515
+ *
516
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
517
+ * Summary per STYLE.md 3.2: Pipe-separated pool count
518
+ * Symbols per STYLE.md 4.1: ● for ONLINE, ⚠ for degraded, ✗ for faulted
519
+ *
520
+ * Health status mapping:
521
+ * - ONLINE → ● (healthy)
522
+ * - DEGRADED/UNAVAIL → ⚠ (warning)
523
+ * - FAULTED/OFFLINE/REMOVED → ✗ (error)
524
+ *
525
+ * @param host - Host name where pools exist
526
+ * @param pools - Raw zpool list output
527
+ * @returns Formatted markdown string with health symbols
528
+ *
529
+ * @example
530
+ * ```typescript
531
+ * const output = formatScoutZfsPoolsMarkdown("squirts", "NAME SIZE ALLOC FREE HEALTH ALTROOT\ntank 10.9T 8.2T 2.7T ONLINE -");
532
+ * // ZFS Pools: squirts
533
+ * // Pools: 1
534
+ * //
535
+ * // ```
536
+ * // NAME SIZE ALLOC FREE HEALTH STATUS
537
+ * // tank 10.9T 8.2T 2.7T ONLINE ●
538
+ * // ```
539
+ * ```
540
+ */
541
+ export function formatScoutZfsPoolsMarkdown(host, pools) {
542
+ const lines = pools.split("\n").filter((l) => l.trim());
543
+ const poolLines = lines.slice(1); // Skip header
544
+ const poolCount = poolLines.length;
545
+ // Add health symbols to each pool line
546
+ const annotatedLines = [`${lines[0]} STATUS`];
547
+ for (const line of poolLines) {
548
+ let symbol = "—";
549
+ if (line.includes("ONLINE"))
550
+ symbol = "●";
551
+ else if (line.includes("DEGRADED") || line.includes("UNAVAIL"))
552
+ symbol = "⚠";
553
+ else if (line.includes("FAULTED") || line.includes("OFFLINE") || line.includes("REMOVED"))
554
+ symbol = "✗";
555
+ annotatedLines.push(`${line} ${symbol}`);
556
+ }
557
+ const outputLines = [
558
+ `ZFS Pools: ${host}`,
559
+ `Pools: ${poolCount}`,
560
+ "",
561
+ "```",
562
+ ...annotatedLines,
563
+ "```",
564
+ ];
565
+ return truncateIfNeeded(outputLines.join("\n"));
566
+ }
567
+ /**
568
+ * Format ZFS datasets with usage warnings
569
+ *
570
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
571
+ * Summary per STYLE.md 3.2: Pipe-separated dataset count
572
+ * Warning per STYLE.md 10.2: ⚠ for datasets >85% used
573
+ *
574
+ * @param host - Host name where datasets exist
575
+ * @param datasets - Raw zfs list output
576
+ * @returns Formatted markdown string with usage warnings
577
+ *
578
+ * @example
579
+ * ```typescript
580
+ * const output = formatScoutZfsDatasetsMarkdown("squirts", "NAME USED AVAIL REFER MOUNTPOINT\ntank/media 9.3T 1.0T 9.3T /mnt/media");
581
+ * // ZFS Datasets: squirts
582
+ * // Datasets: 1 ⚠
583
+ * //
584
+ * // ```
585
+ * // NAME USED AVAIL REFER MOUNTPOINT
586
+ * // tank/media 9.3T 1.0T 9.3T /mnt/media
587
+ * // ```
588
+ * //
589
+ * // ⚠ *One or more datasets exceed 85% usage*
590
+ * ```
591
+ */
592
+ export function formatScoutZfsDatasetsMarkdown(host, datasets) {
593
+ const lines = datasets.split("\n").filter((l) => l.trim());
594
+ const datasetLines = lines.slice(1); // Skip header
595
+ const datasetCount = datasetLines.length;
596
+ // Check for high usage (>85%)
597
+ let hasWarnings = false;
598
+ for (const line of datasetLines) {
599
+ const parts = line.trim().split(/\s+/);
600
+ if (parts.length >= 3) {
601
+ const used = parts[1];
602
+ const avail = parts[2];
603
+ // Parse sizes (assume T/G/M/K suffixes)
604
+ const usedNum = parseSize(used);
605
+ const availNum = parseSize(avail);
606
+ if (usedNum + availNum > 0) {
607
+ const usagePercent = (usedNum / (usedNum + availNum)) * 100;
608
+ if (usagePercent > 85) {
609
+ hasWarnings = true;
610
+ break;
611
+ }
612
+ }
613
+ }
614
+ }
615
+ const outputLines = [
616
+ `ZFS Datasets: ${host}`,
617
+ `Datasets: ${datasetCount}${hasWarnings ? " ⚠" : ""}`,
618
+ "",
619
+ "```",
620
+ datasets,
621
+ "```",
622
+ ];
623
+ if (hasWarnings) {
624
+ outputLines.push("");
625
+ outputLines.push("⚠ *One or more datasets exceed 85% usage*");
626
+ }
627
+ return truncateIfNeeded(outputLines.join("\n"));
628
+ }
629
+ /**
630
+ * Format ZFS snapshots list as markdown
631
+ *
632
+ * Title format per STYLE.md 3.1: Plain text, no markdown ## prefix
633
+ * Summary per STYLE.md 3.2: Pipe-separated snapshot count
634
+ *
635
+ * @param host - Host name where snapshots exist
636
+ * @param snapshots - Raw zfs list -t snapshot output
637
+ * @returns Formatted markdown string
638
+ *
639
+ * @example
640
+ * ```typescript
641
+ * const output = formatScoutZfsSnapshotsMarkdown("squirts", "NAME USED REFER\ntank/media@2024-02-13 512M 8.2T");
642
+ * // ZFS Snapshots: squirts
643
+ * // Snapshots: 1
644
+ * //
645
+ * // ```
646
+ * // NAME USED REFER
647
+ * // tank/media@2024-02-13 512M 8.2T
648
+ * // ```
649
+ * ```
650
+ */
651
+ export function formatScoutZfsSnapshotsMarkdown(host, snapshots) {
652
+ const lines = snapshots.split("\n").filter((l) => l.trim());
653
+ const snapshotLines = lines.slice(1); // Skip header
654
+ const snapshotCount = snapshotLines.length;
655
+ const outputLines = [
656
+ `ZFS Snapshots: ${host}`,
657
+ `Snapshots: ${snapshotCount}`,
658
+ "",
659
+ "```",
660
+ snapshots,
661
+ "```",
662
+ ];
663
+ return truncateIfNeeded(outputLines.join("\n"));
664
+ }
665
+ /**
666
+ * Parse ZFS size string (e.g., "8.2T", "512M") to numeric bytes
667
+ * Used for usage percentage calculations
668
+ */
669
+ function parseSize(sizeStr) {
670
+ const match = sizeStr.trim().match(/^([\d.]+)\s*([BKMGTPEZ])?$/i);
671
+ if (!match)
672
+ return 0;
673
+ const [, numStr, suffix] = match;
674
+ const num = Number.parseFloat(numStr);
675
+ const multipliers = {
676
+ B: 1,
677
+ K: 1024,
678
+ M: 1024 ** 2,
679
+ G: 1024 ** 3,
680
+ T: 1024 ** 4,
681
+ P: 1024 ** 5,
682
+ E: 1024 ** 6,
683
+ Z: 1024 ** 7,
684
+ };
685
+ return num * (suffix ? multipliers[suffix.toUpperCase()] || 1 : 1);
686
+ }
687
+ //# sourceMappingURL=scout.js.map