kastell 2.1.0 → 2.2.1

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 (501) hide show
  1. package/.claude-plugin/marketplace.json +18 -0
  2. package/.claude-plugin/plugin.json +39 -0
  3. package/CHANGELOG.md +1266 -1216
  4. package/LICENSE +201 -201
  5. package/NOTICE +5 -5
  6. package/README.md +1 -1
  7. package/README.tr.md +1 -1
  8. package/bin/kastell +2 -2
  9. package/bin/kastell-mcp +5 -5
  10. package/dist/adapters/coolify.js +92 -92
  11. package/dist/adapters/dokploy.js +99 -99
  12. package/dist/adapters/shared.d.ts.map +1 -1
  13. package/dist/adapters/shared.js +4 -2
  14. package/dist/adapters/shared.js.map +1 -1
  15. package/dist/commands/add.d.ts.map +1 -1
  16. package/dist/commands/add.js +6 -9
  17. package/dist/commands/add.js.map +1 -1
  18. package/dist/commands/auth.d.ts.map +1 -1
  19. package/dist/commands/auth.js +12 -12
  20. package/dist/commands/auth.js.map +1 -1
  21. package/dist/commands/doctor.d.ts +1 -0
  22. package/dist/commands/doctor.d.ts.map +1 -1
  23. package/dist/commands/doctor.js +23 -8
  24. package/dist/commands/doctor.js.map +1 -1
  25. package/dist/commands/evidence.d.ts.map +1 -1
  26. package/dist/commands/evidence.js +8 -9
  27. package/dist/commands/evidence.js.map +1 -1
  28. package/dist/commands/fix.d.ts +1 -0
  29. package/dist/commands/fix.d.ts.map +1 -1
  30. package/dist/commands/fix.js +24 -5
  31. package/dist/commands/fix.js.map +1 -1
  32. package/dist/commands/init.d.ts.map +1 -1
  33. package/dist/commands/init.js +4 -7
  34. package/dist/commands/init.js.map +1 -1
  35. package/dist/commands/interactive/backup-maintenance.d.ts +8 -0
  36. package/dist/commands/interactive/backup-maintenance.d.ts.map +1 -0
  37. package/dist/commands/interactive/backup-maintenance.js +120 -0
  38. package/dist/commands/interactive/backup-maintenance.js.map +1 -0
  39. package/dist/commands/interactive/index.d.ts +4 -0
  40. package/dist/commands/interactive/index.d.ts.map +1 -0
  41. package/dist/commands/interactive/index.js +94 -0
  42. package/dist/commands/interactive/index.js.map +1 -0
  43. package/dist/commands/interactive/menu.d.ts +23 -0
  44. package/dist/commands/interactive/menu.d.ts.map +1 -0
  45. package/dist/commands/interactive/menu.js +121 -0
  46. package/dist/commands/interactive/menu.js.map +1 -0
  47. package/dist/commands/interactive/monitoring.d.ts +5 -0
  48. package/dist/commands/interactive/monitoring.d.ts.map +1 -0
  49. package/dist/commands/interactive/monitoring.js +96 -0
  50. package/dist/commands/interactive/monitoring.js.map +1 -0
  51. package/dist/commands/interactive/plugins.d.ts +2 -0
  52. package/dist/commands/interactive/plugins.d.ts.map +1 -0
  53. package/dist/commands/interactive/plugins.js +30 -0
  54. package/dist/commands/interactive/plugins.js.map +1 -0
  55. package/dist/commands/interactive/security.d.ts +9 -0
  56. package/dist/commands/interactive/security.d.ts.map +1 -0
  57. package/dist/commands/interactive/security.js +535 -0
  58. package/dist/commands/interactive/security.js.map +1 -0
  59. package/dist/commands/interactive/server-management.d.ts +5 -0
  60. package/dist/commands/interactive/server-management.d.ts.map +1 -0
  61. package/dist/commands/interactive/server-management.js +79 -0
  62. package/dist/commands/interactive/server-management.js.map +1 -0
  63. package/dist/commands/interactive/shared.d.ts +12 -0
  64. package/dist/commands/interactive/shared.d.ts.map +1 -0
  65. package/dist/commands/interactive/shared.js +30 -0
  66. package/dist/commands/interactive/shared.js.map +1 -0
  67. package/dist/commands/interactive.d.ts.map +1 -1
  68. package/dist/commands/interactive.js +29 -0
  69. package/dist/commands/interactive.js.map +1 -1
  70. package/dist/commands/lock.js +1 -1
  71. package/dist/commands/lock.js.map +1 -1
  72. package/dist/commands/plugin.d.ts +8 -0
  73. package/dist/commands/plugin.d.ts.map +1 -0
  74. package/dist/commands/plugin.js +87 -0
  75. package/dist/commands/plugin.js.map +1 -0
  76. package/dist/commands/regression.d.ts.map +1 -1
  77. package/dist/commands/regression.js +1 -2
  78. package/dist/commands/regression.js.map +1 -1
  79. package/dist/commands/restart.d.ts.map +1 -1
  80. package/dist/commands/restart.js +3 -2
  81. package/dist/commands/restart.js.map +1 -1
  82. package/dist/commands/schedule.js +2 -2
  83. package/dist/commands/schedule.js.map +1 -1
  84. package/dist/core/audit/checkIds.d.ts +516 -0
  85. package/dist/core/audit/checkIds.d.ts.map +1 -0
  86. package/dist/core/audit/checkIds.js +515 -0
  87. package/dist/core/audit/checkIds.js.map +1 -0
  88. package/dist/core/audit/checks/accounts.d.ts.map +1 -1
  89. package/dist/core/audit/checks/accounts.js +23 -22
  90. package/dist/core/audit/checks/accounts.js.map +1 -1
  91. package/dist/core/audit/checks/auth.d.ts.map +1 -1
  92. package/dist/core/audit/checks/auth.js +23 -22
  93. package/dist/core/audit/checks/auth.js.map +1 -1
  94. package/dist/core/audit/checks/backup.d.ts.map +1 -1
  95. package/dist/core/audit/checks/backup.js +9 -8
  96. package/dist/core/audit/checks/backup.js.map +1 -1
  97. package/dist/core/audit/checks/banners.d.ts.map +1 -1
  98. package/dist/core/audit/checks/banners.js +7 -6
  99. package/dist/core/audit/checks/banners.js.map +1 -1
  100. package/dist/core/audit/checks/boot.d.ts.map +1 -1
  101. package/dist/core/audit/checks/boot.js +12 -11
  102. package/dist/core/audit/checks/boot.js.map +1 -1
  103. package/dist/core/audit/checks/cloudmeta.d.ts.map +1 -1
  104. package/dist/core/audit/checks/cloudmeta.js +7 -6
  105. package/dist/core/audit/checks/cloudmeta.js.map +1 -1
  106. package/dist/core/audit/checks/crypto.d.ts +0 -5
  107. package/dist/core/audit/checks/crypto.d.ts.map +1 -1
  108. package/dist/core/audit/checks/crypto.js +20 -19
  109. package/dist/core/audit/checks/crypto.js.map +1 -1
  110. package/dist/core/audit/checks/ddos.d.ts.map +1 -1
  111. package/dist/core/audit/checks/ddos.js +9 -8
  112. package/dist/core/audit/checks/ddos.js.map +1 -1
  113. package/dist/core/audit/checks/dns.d.ts.map +1 -1
  114. package/dist/core/audit/checks/dns.js +9 -8
  115. package/dist/core/audit/checks/dns.js.map +1 -1
  116. package/dist/core/audit/checks/docker.d.ts.map +1 -1
  117. package/dist/core/audit/checks/docker.js +65 -64
  118. package/dist/core/audit/checks/docker.js.map +1 -1
  119. package/dist/core/audit/checks/fileintegrity.d.ts.map +1 -1
  120. package/dist/core/audit/checks/fileintegrity.js +11 -10
  121. package/dist/core/audit/checks/fileintegrity.js.map +1 -1
  122. package/dist/core/audit/checks/filesystem.d.ts.map +1 -1
  123. package/dist/core/audit/checks/filesystem.js +21 -20
  124. package/dist/core/audit/checks/filesystem.js.map +1 -1
  125. package/dist/core/audit/checks/firewall.d.ts.map +1 -1
  126. package/dist/core/audit/checks/firewall.js +18 -17
  127. package/dist/core/audit/checks/firewall.js.map +1 -1
  128. package/dist/core/audit/checks/httpHeaders.d.ts.map +1 -1
  129. package/dist/core/audit/checks/httpHeaders.js +7 -6
  130. package/dist/core/audit/checks/httpHeaders.js.map +1 -1
  131. package/dist/core/audit/checks/incidentready.d.ts.map +1 -1
  132. package/dist/core/audit/checks/incidentready.js +13 -12
  133. package/dist/core/audit/checks/incidentready.js.map +1 -1
  134. package/dist/core/audit/checks/kernel.d.ts.map +1 -1
  135. package/dist/core/audit/checks/kernel.js +32 -31
  136. package/dist/core/audit/checks/kernel.js.map +1 -1
  137. package/dist/core/audit/checks/logging.d.ts.map +1 -1
  138. package/dist/core/audit/checks/logging.js +21 -20
  139. package/dist/core/audit/checks/logging.js.map +1 -1
  140. package/dist/core/audit/checks/mac.d.ts.map +1 -1
  141. package/dist/core/audit/checks/mac.js +11 -10
  142. package/dist/core/audit/checks/mac.js.map +1 -1
  143. package/dist/core/audit/checks/malware.d.ts.map +1 -1
  144. package/dist/core/audit/checks/malware.js +12 -11
  145. package/dist/core/audit/checks/malware.js.map +1 -1
  146. package/dist/core/audit/checks/memory.d.ts.map +1 -1
  147. package/dist/core/audit/checks/memory.js +12 -11
  148. package/dist/core/audit/checks/memory.js.map +1 -1
  149. package/dist/core/audit/checks/network.d.ts.map +1 -1
  150. package/dist/core/audit/checks/network.js +22 -21
  151. package/dist/core/audit/checks/network.js.map +1 -1
  152. package/dist/core/audit/checks/nginx.d.ts.map +1 -1
  153. package/dist/core/audit/checks/nginx.js +17 -16
  154. package/dist/core/audit/checks/nginx.js.map +1 -1
  155. package/dist/core/audit/checks/resourcelimits.d.ts.map +1 -1
  156. package/dist/core/audit/checks/resourcelimits.js +9 -8
  157. package/dist/core/audit/checks/resourcelimits.js.map +1 -1
  158. package/dist/core/audit/checks/scheduling.d.ts.map +1 -1
  159. package/dist/core/audit/checks/scheduling.js +13 -12
  160. package/dist/core/audit/checks/scheduling.js.map +1 -1
  161. package/dist/core/audit/checks/secrets.d.ts.map +1 -1
  162. package/dist/core/audit/checks/secrets.js +16 -15
  163. package/dist/core/audit/checks/secrets.js.map +1 -1
  164. package/dist/core/audit/checks/services.d.ts.map +1 -1
  165. package/dist/core/audit/checks/services.js +26 -25
  166. package/dist/core/audit/checks/services.js.map +1 -1
  167. package/dist/core/audit/checks/ssh.d.ts.map +1 -1
  168. package/dist/core/audit/checks/ssh.js +23 -22
  169. package/dist/core/audit/checks/ssh.js.map +1 -1
  170. package/dist/core/audit/checks/supplychain.d.ts.map +1 -1
  171. package/dist/core/audit/checks/supplychain.js +13 -12
  172. package/dist/core/audit/checks/supplychain.js.map +1 -1
  173. package/dist/core/audit/checks/time.d.ts.map +1 -1
  174. package/dist/core/audit/checks/time.js +10 -9
  175. package/dist/core/audit/checks/time.js.map +1 -1
  176. package/dist/core/audit/checks/tls.d.ts.map +1 -1
  177. package/dist/core/audit/checks/tls.js +9 -8
  178. package/dist/core/audit/checks/tls.js.map +1 -1
  179. package/dist/core/audit/checks/updates.d.ts.map +1 -1
  180. package/dist/core/audit/checks/updates.js +12 -11
  181. package/dist/core/audit/checks/updates.js.map +1 -1
  182. package/dist/core/audit/compliance/categories/index.d.ts +3 -0
  183. package/dist/core/audit/compliance/categories/index.d.ts.map +1 -0
  184. package/dist/core/audit/compliance/categories/index.js +737 -0
  185. package/dist/core/audit/compliance/categories/index.js.map +1 -0
  186. package/dist/core/audit/compliance/helpers.d.ts +17 -0
  187. package/dist/core/audit/compliance/helpers.d.ts.map +1 -0
  188. package/dist/core/audit/compliance/helpers.js +40 -0
  189. package/dist/core/audit/compliance/helpers.js.map +1 -0
  190. package/dist/core/audit/compliance/mapper.d.ts +4 -16
  191. package/dist/core/audit/compliance/mapper.d.ts.map +1 -1
  192. package/dist/core/audit/compliance/mapper.js +3 -776
  193. package/dist/core/audit/compliance/mapper.js.map +1 -1
  194. package/dist/core/audit/fix-history.d.ts +16 -7
  195. package/dist/core/audit/fix-history.d.ts.map +1 -1
  196. package/dist/core/audit/fix-history.js +25 -2
  197. package/dist/core/audit/fix-history.js.map +1 -1
  198. package/dist/core/audit/fix.d.ts +17 -2
  199. package/dist/core/audit/fix.d.ts.map +1 -1
  200. package/dist/core/audit/fix.js +115 -42
  201. package/dist/core/audit/fix.js.map +1 -1
  202. package/dist/core/audit/formatters/badge.js +20 -20
  203. package/dist/core/audit/index.d.ts.map +1 -1
  204. package/dist/core/audit/index.js +3 -2
  205. package/dist/core/audit/index.js.map +1 -1
  206. package/dist/core/audit/snapshot.d.ts.map +1 -1
  207. package/dist/core/audit/snapshot.js +6 -2
  208. package/dist/core/audit/snapshot.js.map +1 -1
  209. package/dist/core/audit/types.d.ts +11 -1
  210. package/dist/core/audit/types.d.ts.map +1 -1
  211. package/dist/core/audit/watch.d.ts.map +1 -1
  212. package/dist/core/audit/watch.js +3 -2
  213. package/dist/core/audit/watch.js.map +1 -1
  214. package/dist/core/backup.d.ts.map +1 -1
  215. package/dist/core/backup.js +10 -5
  216. package/dist/core/backup.js.map +1 -1
  217. package/dist/core/bot/handlers.d.ts.map +1 -1
  218. package/dist/core/bot/handlers.js +2 -17
  219. package/dist/core/bot/handlers.js.map +1 -1
  220. package/dist/core/completions.d.ts.map +1 -1
  221. package/dist/core/completions.js +632 -610
  222. package/dist/core/completions.js.map +1 -1
  223. package/dist/core/deploy.d.ts.map +1 -1
  224. package/dist/core/deploy.js +7 -4
  225. package/dist/core/deploy.js.map +1 -1
  226. package/dist/core/doctor-fix.d.ts +1 -1
  227. package/dist/core/doctor-fix.d.ts.map +1 -1
  228. package/dist/core/doctor-fix.js +17 -2
  229. package/dist/core/doctor-fix.js.map +1 -1
  230. package/dist/core/doctor.d.ts.map +1 -1
  231. package/dist/core/doctor.js +2 -1
  232. package/dist/core/doctor.js.map +1 -1
  233. package/dist/core/firewall.d.ts +0 -1
  234. package/dist/core/firewall.d.ts.map +1 -1
  235. package/dist/core/firewall.js +2 -13
  236. package/dist/core/firewall.js.map +1 -1
  237. package/dist/core/lock/auth.d.ts +7 -0
  238. package/dist/core/lock/auth.d.ts.map +1 -0
  239. package/dist/core/lock/auth.js +59 -0
  240. package/dist/core/lock/auth.js.map +1 -0
  241. package/dist/core/lock/docker.d.ts +4 -0
  242. package/dist/core/lock/docker.d.ts.map +1 -0
  243. package/dist/core/lock/docker.js +28 -0
  244. package/dist/core/lock/docker.js.map +1 -0
  245. package/dist/core/lock/index.d.ts +11 -0
  246. package/dist/core/lock/index.d.ts.map +1 -0
  247. package/dist/core/lock/index.js +247 -0
  248. package/dist/core/lock/index.js.map +1 -0
  249. package/dist/core/lock/monitoring.d.ts +4 -0
  250. package/dist/core/lock/monitoring.d.ts.map +1 -0
  251. package/dist/core/lock/monitoring.js +55 -0
  252. package/dist/core/lock/monitoring.js.map +1 -0
  253. package/dist/core/lock/network.d.ts +6 -0
  254. package/dist/core/lock/network.d.ts.map +1 -0
  255. package/dist/core/lock/network.js +59 -0
  256. package/dist/core/lock/network.js.map +1 -0
  257. package/dist/core/lock/ssh.d.ts +5 -0
  258. package/dist/core/lock/ssh.d.ts.map +1 -0
  259. package/dist/core/lock/ssh.js +49 -0
  260. package/dist/core/lock/ssh.js.map +1 -0
  261. package/dist/core/lock/system.d.ts +9 -0
  262. package/dist/core/lock/system.d.ts.map +1 -0
  263. package/dist/core/lock/system.js +80 -0
  264. package/dist/core/lock/system.js.map +1 -0
  265. package/dist/core/lock/types.d.ts +41 -0
  266. package/dist/core/lock/types.d.ts.map +1 -0
  267. package/dist/core/lock/types.js +2 -0
  268. package/dist/core/lock/types.js.map +1 -0
  269. package/dist/core/maintain.d.ts.map +1 -1
  270. package/dist/core/maintain.js +3 -1
  271. package/dist/core/maintain.js.map +1 -1
  272. package/dist/core/manage.d.ts.map +1 -1
  273. package/dist/core/manage.js +7 -4
  274. package/dist/core/manage.js.map +1 -1
  275. package/dist/core/notify.d.ts.map +1 -1
  276. package/dist/core/notify.js +2 -1
  277. package/dist/core/notify.js.map +1 -1
  278. package/dist/core/notifyStore.d.ts.map +1 -1
  279. package/dist/core/notifyStore.js +3 -1
  280. package/dist/core/notifyStore.js.map +1 -1
  281. package/dist/core/plugin.d.ts +23 -0
  282. package/dist/core/plugin.d.ts.map +1 -0
  283. package/dist/core/plugin.js +107 -0
  284. package/dist/core/plugin.js.map +1 -0
  285. package/dist/core/provision.d.ts.map +1 -1
  286. package/dist/core/provision.js +9 -4
  287. package/dist/core/provision.js.map +1 -1
  288. package/dist/core/scheduleManager.d.ts +2 -1
  289. package/dist/core/scheduleManager.d.ts.map +1 -1
  290. package/dist/core/scheduleManager.js +13 -7
  291. package/dist/core/scheduleManager.js.map +1 -1
  292. package/dist/index.js +34 -2
  293. package/dist/index.js.map +1 -1
  294. package/dist/mcp/index.js +5 -9
  295. package/dist/mcp/index.js.map +1 -1
  296. package/dist/mcp/schemas/audit.d.ts +34 -0
  297. package/dist/mcp/schemas/audit.d.ts.map +1 -0
  298. package/dist/mcp/schemas/audit.js +23 -0
  299. package/dist/mcp/schemas/audit.js.map +1 -0
  300. package/dist/mcp/schemas/common.d.ts +16 -0
  301. package/dist/mcp/schemas/common.d.ts.map +1 -0
  302. package/dist/mcp/schemas/common.js +14 -0
  303. package/dist/mcp/schemas/common.js.map +1 -0
  304. package/dist/mcp/schemas/health.d.ts +14 -0
  305. package/dist/mcp/schemas/health.d.ts.map +1 -0
  306. package/dist/mcp/schemas/health.js +13 -0
  307. package/dist/mcp/schemas/health.js.map +1 -0
  308. package/dist/mcp/schemas/index.d.ts +5 -0
  309. package/dist/mcp/schemas/index.d.ts.map +1 -0
  310. package/dist/mcp/schemas/index.js +5 -0
  311. package/dist/mcp/schemas/index.js.map +1 -0
  312. package/dist/mcp/schemas/server.d.ts +18 -0
  313. package/dist/mcp/schemas/server.d.ts.map +1 -0
  314. package/dist/mcp/schemas/server.js +16 -0
  315. package/dist/mcp/schemas/server.js.map +1 -0
  316. package/dist/mcp/server.d.ts.map +1 -1
  317. package/dist/mcp/server.js +71 -40
  318. package/dist/mcp/server.js.map +1 -1
  319. package/dist/mcp/tools/serverAudit.d.ts +63 -1
  320. package/dist/mcp/tools/serverAudit.d.ts.map +1 -1
  321. package/dist/mcp/tools/serverAudit.js +63 -6
  322. package/dist/mcp/tools/serverAudit.js.map +1 -1
  323. package/dist/mcp/tools/serverBackup.d.ts +100 -2
  324. package/dist/mcp/tools/serverBackup.d.ts.map +1 -1
  325. package/dist/mcp/tools/serverBackup.handlers.d.ts.map +1 -1
  326. package/dist/mcp/tools/serverBackup.handlers.js +9 -0
  327. package/dist/mcp/tools/serverBackup.handlers.js.map +1 -1
  328. package/dist/mcp/tools/serverBackup.js +74 -0
  329. package/dist/mcp/tools/serverBackup.js.map +1 -1
  330. package/dist/mcp/tools/serverCompare.d.ts +33 -0
  331. package/dist/mcp/tools/serverCompare.d.ts.map +1 -1
  332. package/dist/mcp/tools/serverCompare.js +45 -2
  333. package/dist/mcp/tools/serverCompare.js.map +1 -1
  334. package/dist/mcp/tools/serverDoctor.d.ts +14 -0
  335. package/dist/mcp/tools/serverDoctor.d.ts.map +1 -1
  336. package/dist/mcp/tools/serverDoctor.js +16 -1
  337. package/dist/mcp/tools/serverDoctor.js.map +1 -1
  338. package/dist/mcp/tools/serverEvidence.d.ts +13 -0
  339. package/dist/mcp/tools/serverEvidence.d.ts.map +1 -1
  340. package/dist/mcp/tools/serverEvidence.js +17 -2
  341. package/dist/mcp/tools/serverEvidence.js.map +1 -1
  342. package/dist/mcp/tools/serverExplain.d.ts +17 -0
  343. package/dist/mcp/tools/serverExplain.d.ts.map +1 -1
  344. package/dist/mcp/tools/serverExplain.js +33 -1
  345. package/dist/mcp/tools/serverExplain.js.map +1 -1
  346. package/dist/mcp/tools/serverFix.d.ts +78 -0
  347. package/dist/mcp/tools/serverFix.d.ts.map +1 -1
  348. package/dist/mcp/tools/serverFix.js +87 -0
  349. package/dist/mcp/tools/serverFix.js.map +1 -1
  350. package/dist/mcp/tools/serverFleet.d.ts +24 -1
  351. package/dist/mcp/tools/serverFleet.d.ts.map +1 -1
  352. package/dist/mcp/tools/serverFleet.js +24 -1
  353. package/dist/mcp/tools/serverFleet.js.map +1 -1
  354. package/dist/mcp/tools/serverGuard.d.ts +12 -0
  355. package/dist/mcp/tools/serverGuard.d.ts.map +1 -1
  356. package/dist/mcp/tools/serverGuard.js +16 -0
  357. package/dist/mcp/tools/serverGuard.js.map +1 -1
  358. package/dist/mcp/tools/serverInfo.d.ts +77 -1
  359. package/dist/mcp/tools/serverInfo.d.ts.map +1 -1
  360. package/dist/mcp/tools/serverInfo.js +77 -4
  361. package/dist/mcp/tools/serverInfo.js.map +1 -1
  362. package/dist/mcp/tools/serverLock.d.ts +10 -0
  363. package/dist/mcp/tools/serverLock.d.ts.map +1 -1
  364. package/dist/mcp/tools/serverLock.js +15 -3
  365. package/dist/mcp/tools/serverLock.js.map +1 -1
  366. package/dist/mcp/tools/serverLogs.d.ts +43 -0
  367. package/dist/mcp/tools/serverLogs.d.ts.map +1 -1
  368. package/dist/mcp/tools/serverLogs.js +28 -0
  369. package/dist/mcp/tools/serverLogs.js.map +1 -1
  370. package/dist/mcp/tools/serverMaintain.d.ts +47 -0
  371. package/dist/mcp/tools/serverMaintain.d.ts.map +1 -1
  372. package/dist/mcp/tools/serverMaintain.js +75 -41
  373. package/dist/mcp/tools/serverMaintain.js.map +1 -1
  374. package/dist/mcp/tools/serverManage.d.ts +50 -0
  375. package/dist/mcp/tools/serverManage.d.ts.map +1 -1
  376. package/dist/mcp/tools/serverManage.js +49 -0
  377. package/dist/mcp/tools/serverManage.js.map +1 -1
  378. package/dist/mcp/tools/serverPlugin.d.ts +30 -0
  379. package/dist/mcp/tools/serverPlugin.d.ts.map +1 -0
  380. package/dist/mcp/tools/serverPlugin.js +47 -0
  381. package/dist/mcp/tools/serverPlugin.js.map +1 -0
  382. package/dist/mcp/tools/serverProvision.d.ts +22 -0
  383. package/dist/mcp/tools/serverProvision.d.ts.map +1 -1
  384. package/dist/mcp/tools/serverProvision.js +22 -2
  385. package/dist/mcp/tools/serverProvision.js.map +1 -1
  386. package/dist/mcp/tools/serverSecure.d.ts +120 -0
  387. package/dist/mcp/tools/serverSecure.d.ts.map +1 -1
  388. package/dist/mcp/tools/serverSecure.handlers.d.ts.map +1 -1
  389. package/dist/mcp/tools/serverSecure.handlers.js +39 -98
  390. package/dist/mcp/tools/serverSecure.handlers.js.map +1 -1
  391. package/dist/mcp/tools/serverSecure.js +101 -0
  392. package/dist/mcp/tools/serverSecure.js.map +1 -1
  393. package/dist/mcp/utils.d.ts +1 -0
  394. package/dist/mcp/utils.d.ts.map +1 -1
  395. package/dist/mcp/utils.js +5 -1
  396. package/dist/mcp/utils.js.map +1 -1
  397. package/dist/plugin/loader.d.ts +10 -0
  398. package/dist/plugin/loader.d.ts.map +1 -0
  399. package/dist/plugin/loader.js +88 -0
  400. package/dist/plugin/loader.js.map +1 -0
  401. package/dist/plugin/registry.d.ts +16 -0
  402. package/dist/plugin/registry.d.ts.map +1 -0
  403. package/dist/plugin/registry.js +101 -0
  404. package/dist/plugin/registry.js.map +1 -0
  405. package/dist/plugin/sdk/constants.d.ts +3 -0
  406. package/dist/plugin/sdk/constants.d.ts.map +1 -0
  407. package/dist/plugin/sdk/constants.js +3 -0
  408. package/dist/plugin/sdk/constants.js.map +1 -0
  409. package/dist/plugin/sdk/types.d.ts +29 -0
  410. package/dist/plugin/sdk/types.d.ts.map +1 -0
  411. package/dist/plugin/sdk/types.js +2 -0
  412. package/dist/plugin/sdk/types.js.map +1 -0
  413. package/dist/plugin/validate.d.ts +3 -0
  414. package/dist/plugin/validate.d.ts.map +1 -0
  415. package/dist/plugin/validate.js +31 -0
  416. package/dist/plugin/validate.js.map +1 -0
  417. package/dist/providers/base.d.ts.map +1 -1
  418. package/dist/providers/base.js +2 -1
  419. package/dist/providers/base.js.map +1 -1
  420. package/dist/providers/linode.d.ts +1 -0
  421. package/dist/providers/linode.d.ts.map +1 -1
  422. package/dist/providers/linode.js +4 -0
  423. package/dist/providers/linode.js.map +1 -1
  424. package/dist/utils/cloudInit.js +58 -58
  425. package/dist/utils/config.d.ts +3 -0
  426. package/dist/utils/config.d.ts.map +1 -1
  427. package/dist/utils/config.js +11 -6
  428. package/dist/utils/config.js.map +1 -1
  429. package/dist/utils/encryption.d.ts.map +1 -1
  430. package/dist/utils/encryption.js +4 -1
  431. package/dist/utils/encryption.js.map +1 -1
  432. package/dist/utils/errorMapper.d.ts.map +1 -1
  433. package/dist/utils/errorMapper.js +2 -1
  434. package/dist/utils/errorMapper.js.map +1 -1
  435. package/dist/utils/errors.d.ts +1 -0
  436. package/dist/utils/errors.d.ts.map +1 -1
  437. package/dist/utils/errors.js +3 -0
  438. package/dist/utils/errors.js.map +1 -1
  439. package/dist/utils/migration.d.ts.map +1 -1
  440. package/dist/utils/migration.js +25 -14
  441. package/dist/utils/migration.js.map +1 -1
  442. package/dist/utils/paths.d.ts +4 -0
  443. package/dist/utils/paths.d.ts.map +1 -1
  444. package/dist/utils/paths.js +4 -0
  445. package/dist/utils/paths.js.map +1 -1
  446. package/dist/utils/safeMode.d.ts.map +1 -1
  447. package/dist/utils/safeMode.js +3 -2
  448. package/dist/utils/safeMode.js.map +1 -1
  449. package/dist/utils/secureWrite.d.ts.map +1 -1
  450. package/dist/utils/secureWrite.js +2 -1
  451. package/dist/utils/secureWrite.js.map +1 -1
  452. package/dist/utils/securityLogger.d.ts.map +1 -1
  453. package/dist/utils/securityLogger.js +7 -3
  454. package/dist/utils/securityLogger.js.map +1 -1
  455. package/dist/utils/version.d.ts +4 -0
  456. package/dist/utils/version.d.ts.map +1 -0
  457. package/dist/utils/version.js +22 -0
  458. package/dist/utils/version.js.map +1 -0
  459. package/dist/utils/yamlConfig.d.ts.map +1 -1
  460. package/dist/utils/yamlConfig.js +3 -2
  461. package/dist/utils/yamlConfig.js.map +1 -1
  462. package/kastell-plugin/.claude-plugin/plugin.json +20 -0
  463. package/kastell-plugin/.mcp.json +8 -0
  464. package/kastell-plugin/README.md +113 -0
  465. package/kastell-plugin/agents/.gitkeep +0 -0
  466. package/kastell-plugin/agents/kastell-auditor.md +77 -0
  467. package/kastell-plugin/agents/scripts/bucket_mapper.sh +101 -0
  468. package/kastell-plugin/agents/scripts/trend_report.sh +91 -0
  469. package/kastell-plugin/hooks/destroy-block.cjs +31 -0
  470. package/kastell-plugin/hooks/hooks.json +57 -0
  471. package/kastell-plugin/hooks/pre-commit-audit-guard.cjs +75 -0
  472. package/kastell-plugin/hooks/session-audit.cjs +86 -0
  473. package/kastell-plugin/hooks/session-log.cjs +56 -0
  474. package/kastell-plugin/hooks/stop-quality-check.cjs +72 -0
  475. package/kastell-plugin/skills/.gitkeep +0 -0
  476. package/kastell-plugin/skills/kastell-careful/SKILL.md +64 -0
  477. package/kastell-plugin/skills/kastell-ops/SKILL.md +139 -0
  478. package/kastell-plugin/skills/kastell-ops/references/commands.md +45 -0
  479. package/kastell-plugin/skills/kastell-ops/references/mcp-tools.md +50 -0
  480. package/kastell-plugin/skills/kastell-ops/references/patterns.md +145 -0
  481. package/kastell-plugin/skills/kastell-ops/references/pitfalls.md +136 -0
  482. package/kastell-plugin/skills/kastell-ops/scripts/check_coverage.sh +101 -0
  483. package/kastell-plugin/skills/kastell-ops/scripts/fleet_report.sh +73 -0
  484. package/kastell-plugin/skills/kastell-ops/scripts/parse_audit.sh +76 -0
  485. package/kastell-plugin/skills/kastell-research/SKILL.md +90 -0
  486. package/kastell-plugin/skills/kastell-scaffold/SKILL.md +104 -0
  487. package/kastell-plugin/skills/kastell-scaffold/references/template-audit-check.md +150 -0
  488. package/kastell-plugin/skills/kastell-scaffold/references/template-command.md +80 -0
  489. package/kastell-plugin/skills/kastell-scaffold/references/template-mcp-tool.md +72 -0
  490. package/kastell-plugin/skills/kastell-scaffold/references/template-provider.md +67 -0
  491. package/kastell-plugin/skills/kastell-scaffold/scripts/scaffold.sh +180 -0
  492. package/kastell-plugin/skills/kastell-scaffold/templates/check-test.ts.tpl +27 -0
  493. package/kastell-plugin/skills/kastell-scaffold/templates/check.ts.tpl +50 -0
  494. package/kastell-plugin/skills/kastell-scaffold/templates/command-core.ts.tpl +18 -0
  495. package/kastell-plugin/skills/kastell-scaffold/templates/command-test.ts.tpl +17 -0
  496. package/kastell-plugin/skills/kastell-scaffold/templates/command.ts.tpl +25 -0
  497. package/kastell-plugin/skills/kastell-scaffold/templates/mcp-tool-test.ts.tpl +30 -0
  498. package/kastell-plugin/skills/kastell-scaffold/templates/mcp-tool.ts.tpl +29 -0
  499. package/kastell-plugin/skills/kastell-scaffold/templates/provider-test.ts.tpl +34 -0
  500. package/kastell-plugin/skills/kastell-scaffold/templates/provider.ts.tpl +32 -0
  501. package/package.json +122 -113
@@ -0,0 +1,150 @@
1
+ # Template: Audit Check — $1
2
+
3
+ ## Files to Create/Modify
4
+
5
+ 1. `src/core/audit/checks/$1.ts` — check definitions + parser
6
+ 2. `src/core/audit/commands.ts` — SSH batch section
7
+ 3. `src/core/audit/checks/index.ts` — registry entry
8
+ 4. `src/core/audit/compliance/mapper.ts` — compliance mapping (optional)
9
+ 5. `src/__tests__/core/audit/checks/$1.test.ts` — test file
10
+
11
+ ## Step 1: Check File
12
+
13
+ ```typescript
14
+ // src/core/audit/checks/$1.ts
15
+ import type { AuditCheck, CheckParser } from "../../types.js";
16
+
17
+ interface $1CheckDef {
18
+ id: string; // "CATEGORY-CHECK-NAME" (uppercase, hyphen-separated)
19
+ name: string; // Human-readable description
20
+ severity: "critical" | "warning" | "info";
21
+ check: (output: string) => { passed: boolean; currentValue: string };
22
+ expectedValue: string;
23
+ fixCommand: string;
24
+ explain: string;
25
+ }
26
+
27
+ const $1_CHECKS: $1CheckDef[] = [
28
+ {
29
+ id: "CAT-CHECK-ONE",
30
+ name: "Check description",
31
+ severity: "warning",
32
+ check: (output) => {
33
+ const match = output.includes("SENTINEL_PASS");
34
+ return { passed: match, currentValue: match ? "configured" : "not found" };
35
+ },
36
+ expectedValue: "configured",
37
+ fixCommand: "command to fix",
38
+ explain: "Why this matters and what the fix does.",
39
+ },
40
+ ];
41
+
42
+ export const parse$1Checks: CheckParser = (
43
+ sectionOutput: string,
44
+ _platform: string,
45
+ ): AuditCheck[] => {
46
+ // Conditional category: return [] if not applicable (excluded from score)
47
+ if (!sectionOutput || sectionOutput.includes("SKIP_MARKER")) {
48
+ return [];
49
+ }
50
+
51
+ return $1_CHECKS.map((def) => {
52
+ const { passed, currentValue } = def.check(sectionOutput);
53
+ return {
54
+ id: def.id,
55
+ category: "Category Name", // MUST match CHECK_REGISTRY.name exactly
56
+ name: def.name,
57
+ severity: def.severity,
58
+ passed,
59
+ currentValue,
60
+ expectedValue: def.expectedValue,
61
+ fixCommand: def.fixCommand,
62
+ explain: def.explain,
63
+ };
64
+ });
65
+ };
66
+ ```
67
+
68
+ ## Step 2: SSH Batch Section
69
+
70
+ `src/core/audit/commands.ts` — add bash commands that run on the server.
71
+
72
+ ```typescript
73
+ function new$1Section(): string {
74
+ return [
75
+ NAMED_SEP("$1UPPER"), // MUST match CHECK_REGISTRY.sectionName exactly
76
+ `command1 || echo 'N/A'`,
77
+ `command2 || echo 'N/A'`,
78
+ ].join("\n");
79
+ }
80
+ ```
81
+
82
+ Add to the correct batch array:
83
+ - `BATCH_FAST` — fast commands (<1s)
84
+ - `BATCH_MEDIUM` — medium commands (1-5s)
85
+ - `BATCH_SLOW` — slow commands (5s+, e.g., `nginx -T`)
86
+
87
+ **Sentinel matching is critical:** `NAMED_SEP("FOO")` produces `---SECTION:FOO---`. This string MUST match `CHECK_REGISTRY.sectionName` exactly.
88
+
89
+ For conditional categories, add a skip marker as first command:
90
+ ```bash
91
+ command -v nginx >/dev/null 2>&1 || echo 'NGINX_NOT_INSTALLED'
92
+ ```
93
+
94
+ ## Step 3: Registry
95
+
96
+ ```typescript
97
+ // src/core/audit/checks/index.ts
98
+ import { parse$1Checks } from "./$1.js";
99
+
100
+ export const CHECK_REGISTRY: CategoryEntry[] = [
101
+ // ... existing categories ...
102
+ { name: "Category Name", sectionName: "$1UPPER", parser: parse$1Checks },
103
+ ];
104
+ ```
105
+
106
+ **Triple-check:**
107
+ - [ ] `sectionName` === `NAMED_SEP()` parameter
108
+ - [ ] `name` === check file's `category` string
109
+ - [ ] Import path has `.js` extension (ESM)
110
+
111
+ ## Step 4: Compliance Mapping (Optional)
112
+
113
+ ```typescript
114
+ // src/core/audit/compliance/mapper.ts
115
+ export const COMPLIANCE_MAP: Record<string, ComplianceRef[]> = {
116
+ // ─── $1 ────────────────────────────────────────
117
+ "CAT-CHECK-ONE": [
118
+ cis("5.x.x", "Control description", "full"),
119
+ pci("x.x.x", "PCI control", "partial"),
120
+ ],
121
+ };
122
+ ```
123
+
124
+ Helpers: `cis()`, `pci()`, `hipaa()`. Coverage: `"full"` or `"partial"`.
125
+
126
+ ## Severity Guide
127
+
128
+ | Severity | When | Score weight |
129
+ |----------|------|-------------|
130
+ | `critical` | Exploitable, immediate fix required | 3x |
131
+ | `warning` | Risk exists but not urgent | 2x |
132
+ | `info` | Best practice, informational | 1x |
133
+
134
+ ## Anti-Patterns
135
+
136
+ - **DON'T:** Typo in sentinel strings — parser silently returns empty array, no error
137
+ - **DON'T:** Throw exceptions in `check()` — no try/catch wrapper, entire category breaks
138
+ - **DON'T:** Reuse check ID across categories — compliance mapping will conflict
139
+ - **DON'T:** Multi-step scripts in `fixCommand` — keep it one-line, reference `kastell` command if needed
140
+ - **DON'T:** Forget `|| echo 'N/A'` fallback in SSH commands — parser breaks if command missing
141
+
142
+ ## Next Steps
143
+
144
+ - [ ] Choose correct audit category (30 categories exist)
145
+ - [ ] Assign unique check key: `<CATEGORY>-NN` pattern
146
+ - [ ] Verify `passed` logic matches `currentValue` evaluation
147
+ - [ ] Add SSH command to category batch (avoid extra SSH round-trips)
148
+ - [ ] Write test: mock SSH output, verify correct passed/failed
149
+ - [ ] Run: `npm test -- --testPathPattern=audit`
150
+ - [ ] Verify check count: `kastell audit --json | jq '.summary.totalChecks'`
@@ -0,0 +1,80 @@
1
+ # Template: CLI Command — $1
2
+
3
+ ## Files to Create
4
+
5
+ 1. `src/commands/$1.ts` — thin wrapper (parse args, call core, display result)
6
+ 2. `src/core/$1.ts` — all business logic (no UI imports)
7
+ 3. `src/__tests__/core/$1.test.ts` — test the core function, not the command
8
+
9
+ ## Command File (thin wrapper)
10
+
11
+ ```typescript
12
+ // src/commands/$1.ts
13
+ import { program } from 'commander';
14
+ import chalk from 'chalk';
15
+ import ora from 'ora';
16
+ import { $1Core } from '../core/$1.js';
17
+
18
+ program
19
+ .command('$1')
20
+ .description('TODO: describe what this command does')
21
+ .option('--server <name>', 'Target server name or IP')
22
+ .option('--json', 'Output as JSON')
23
+ .action(async (options) => {
24
+ const spinner = ora('Running $1...').start();
25
+ try {
26
+ const result = await $1Core(options);
27
+ spinner.succeed('Done');
28
+ if (options.json) {
29
+ console.log(JSON.stringify(result, null, 2));
30
+ } else {
31
+ console.log(chalk.green(result.message));
32
+ }
33
+ } catch (error) {
34
+ spinner.fail(error instanceof Error ? error.message : 'Unknown error');
35
+ process.exitCode = 1;
36
+ }
37
+ });
38
+ ```
39
+
40
+ ## Core File (all logic here)
41
+
42
+ ```typescript
43
+ // src/core/$1.ts
44
+ export interface $1Options { server?: string; json?: boolean; }
45
+ export interface $1Result { success: boolean; message: string; }
46
+
47
+ export async function $1Core(options: $1Options): Promise<$1Result> {
48
+ // ALL business logic here. NO chalk/ora/UI imports.
49
+ // assertValidIp() before SSH. getAdapter(platform) for platform ops.
50
+ // withProviderErrorHandling() for provider calls.
51
+ throw new Error('Not implemented');
52
+ }
53
+ ```
54
+
55
+ ## Test File
56
+
57
+ ```typescript
58
+ // src/__tests__/core/$1.test.ts
59
+ import { $1Core } from '../../core/$1.js';
60
+ jest.mock('../../utils/ssh.js');
61
+
62
+ describe('$1Core', () => {
63
+ beforeEach(() => jest.resetAllMocks());
64
+
65
+ it('should TODO: describe expected behavior', async () => {
66
+ const result = await $1Core({ server: 'test-server' });
67
+ expect(result.success).toBe(true);
68
+ });
69
+ });
70
+ ```
71
+
72
+ ## Next Steps
73
+
74
+ - [ ] Register command in `src/index.ts`
75
+ - [ ] Write tests first (TDD: test core function, not command)
76
+ - [ ] Add `isSafeMode()` check if operation is destructive
77
+ - [ ] Add `assertValidIp()` before any SSH operation
78
+ - [ ] Use `getAdapter(platform)` for platform-specific operations (never import adapters directly)
79
+ - [ ] Run `npm run build && npm test && npm run lint`
80
+ - [ ] Update README.md command table
@@ -0,0 +1,72 @@
1
+ # Template: MCP Tool — $1
2
+
3
+ ## Files to Create
4
+
5
+ 1. `src/mcp/tools/$1.ts` — Zod schema + handler
6
+ 2. Update `src/mcp/server.ts` — import + registerTool()
7
+ 3. `src/__tests__/mcp/$1.test.ts` — test handler function
8
+
9
+ ## Tool File (Zod schema + handler)
10
+
11
+ ```typescript
12
+ // src/mcp/tools/$1.ts
13
+ import { z } from 'zod';
14
+ import type { McpResponse } from '../types.js';
15
+
16
+ // IMPORTANT: Schema is a flat object, NOT wrapped in z.object()
17
+ // The SDK wraps it automatically
18
+ export const $1Schema = {
19
+ server: z.string().optional().describe('Server name or IP. Auto-selected if only one server exists.'),
20
+ action: z.enum(['TODO']).describe('TODO: describe actions'),
21
+ };
22
+
23
+ export async function handle$1(params: {
24
+ server?: string;
25
+ action: string;
26
+ }): Promise<McpResponse> {
27
+ // Delegate to core function (NOT direct SSH/provider calls)
28
+ // Example: const result = await someCoreFunction(params);
29
+
30
+ return {
31
+ content: [
32
+ {
33
+ type: 'text' as const,
34
+ text: JSON.stringify({ success: true }, null, 2),
35
+ },
36
+ ],
37
+ };
38
+ }
39
+ ```
40
+
41
+ ## Server Registration
42
+
43
+ ```typescript
44
+ // In src/mcp/server.ts
45
+ import { $1Schema, handle$1 } from './tools/$1.js';
46
+
47
+ server.registerTool('$1', {
48
+ description: 'TODO: 50-150 tokens. What it does. Actions. Constraints. Requirements.',
49
+ inputSchema: $1Schema,
50
+ annotations: {
51
+ title: 'TODO: Human-readable title',
52
+ readOnlyHint: false, // true if read-only
53
+ destructiveHint: false, // true if destructive
54
+ idempotentHint: false, // true if idempotent
55
+ openWorldHint: true,
56
+ },
57
+ }, async (params) => {
58
+ return handle$1(params);
59
+ });
60
+ ```
61
+
62
+ ## Next Steps
63
+
64
+ - [ ] Define Zod schema as flat object (NOT z.object() wrapper)
65
+ - [ ] Handler delegates to core/ functions (not direct SSH/provider)
66
+ - [ ] Add `server` param as `.optional()` with standard description
67
+ - [ ] Set annotations correctly (readOnlyHint, destructiveHint)
68
+ - [ ] Write description: "What it does. Actions: 'x' does Y. Constraints. For Z, use other_tool instead."
69
+ - [ ] Add SAFE_MODE check if destructive: `if (isSafeMode()) throw ...`
70
+ - [ ] Write test: call handler directly with mock params
71
+ - [ ] Run `npm run build && npm test && npm run lint`
72
+ - [ ] Update README.md MCP tools table
@@ -0,0 +1,67 @@
1
+ # Template: Provider — $1
2
+
3
+ ## Files to Create
4
+
5
+ 1. `src/providers/$1.ts` — provider implementation (extends BaseProvider)
6
+ 2. Update `src/constants.ts` — add to PROVIDER_REGISTRY
7
+ 3. `src/__tests__/providers/$1.test.ts` — test with mocked API calls
8
+
9
+ ## Provider Implementation
10
+
11
+ ```typescript
12
+ // src/providers/$1.ts
13
+ import {
14
+ BaseProvider,
15
+ type ProviderServer,
16
+ type CreateServerParams,
17
+ type ProviderResponse,
18
+ } from './base.js';
19
+
20
+ export class $1Provider extends BaseProvider {
21
+ constructor(token: string) {
22
+ super(token, 'https://api.$1.com/v1'); // adjust API base URL
23
+ }
24
+
25
+ async listServers(): Promise<ProviderResponse<ProviderServer[]>> {
26
+ return this.request<ProviderServer[]>('GET', '/servers');
27
+ }
28
+
29
+ async createServer(params: CreateServerParams): Promise<ProviderResponse<ProviderServer>> {
30
+ return this.request<ProviderServer>('POST', '/servers', { body: params });
31
+ }
32
+
33
+ async deleteServer(serverId: string): Promise<ProviderResponse<void>> {
34
+ return this.request<void>('DELETE', `/servers/${serverId}`);
35
+ }
36
+
37
+ async getServer(serverId: string): Promise<ProviderResponse<ProviderServer>> {
38
+ return this.request<ProviderServer>('GET', `/servers/${serverId}`);
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## PROVIDER_REGISTRY Entry
44
+
45
+ ```typescript
46
+ // In src/constants.ts — add to PROVIDER_REGISTRY (single source of truth)
47
+ import { $1Provider } from './providers/$1.js';
48
+
49
+ export const PROVIDER_REGISTRY = {
50
+ // ... existing providers
51
+ $1: {
52
+ name: '$1',
53
+ envKey: '$1_TOKEN', // e.g., 'OVHCLOUD_TOKEN'
54
+ class: $1Provider,
55
+ },
56
+ };
57
+ ```
58
+
59
+ ## Next Steps
60
+
61
+ - [ ] Register in `PROVIDER_REGISTRY` (src/constants.ts) — single source of truth
62
+ - [ ] Implement `stripSensitiveData()` to remove API tokens from error responses
63
+ - [ ] Use `assertValidIp()` before any SSH operation
64
+ - [ ] Use `withProviderErrorHandling()` HOF for API error consistency
65
+ - [ ] Write tests with mocked axios (mock `axios.create()` → `jest.fn(() => axios)`)
66
+ - [ ] Add "Getting Your API Token" section to README.md
67
+ - [ ] Run `npm run build && npm test && npm run lint`
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env bash
2
+ # scaffold.sh — Generate Kastell component boilerplate from templates.
3
+ # Usage: scaffold.sh <type> <name> [--dry-run]
4
+ # type: command | check | provider | mcp-tool
5
+ # name: kebab-case component name (e.g., server-migrate, filesystem-perms)
6
+ #
7
+ # Ersin criterion: This script runs without an LLM. Deterministic file generation.
8
+
9
+ set -euo pipefail
10
+
11
+ # ── Resolve script directory (works in symlink/Git Bash/etc) ──
12
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+ TEMPLATE_DIR="$SCRIPT_DIR/../templates"
14
+ PROJECT_ROOT="${PROJECT_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
15
+
16
+ # ── Colors ──
17
+ RED='\033[0;31m'
18
+ GREEN='\033[0;32m'
19
+ YELLOW='\033[1;33m'
20
+ CYAN='\033[0;36m'
21
+ NC='\033[0m' # No Color
22
+
23
+ info() { echo -e "${CYAN}ℹ${NC} $*"; }
24
+ ok() { echo -e "${GREEN}✓${NC} $*"; }
25
+ warn() { echo -e "${YELLOW}⚠${NC} $*"; }
26
+ err() { echo -e "${RED}✗${NC} $*" >&2; }
27
+
28
+ # ── Args ──
29
+ TYPE="${1:-}"
30
+ NAME="${2:-}"
31
+ DRY_RUN=false
32
+ for arg in "$@"; do [[ "$arg" == "--dry-run" ]] && DRY_RUN=true; done
33
+
34
+ if [[ -z "$TYPE" || -z "$NAME" ]]; then
35
+ echo "Usage: scaffold.sh <type> <name> [--dry-run]"
36
+ echo " type: command | check | provider | mcp-tool"
37
+ echo " name: kebab-case (e.g., server-migrate)"
38
+ exit 1
39
+ fi
40
+
41
+ # Validate type
42
+ case "$TYPE" in
43
+ command|check|provider|mcp-tool) ;;
44
+ *) err "Unknown type: $TYPE (valid: command, check, provider, mcp-tool)"; exit 1 ;;
45
+ esac
46
+
47
+ # Validate name (kebab-case or snake_case, lowercase)
48
+ if [[ ! "$NAME" =~ ^[a-z][a-z0-9_-]*$ ]]; then
49
+ err "Invalid name: $NAME (must be lowercase kebab-case or snake_case)"
50
+ exit 1
51
+ fi
52
+
53
+ # ── Name transformations ──
54
+ to_pascal() {
55
+ echo "$1" | sed 's/[-_]/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1' | tr -d ' '
56
+ }
57
+
58
+ to_camel() {
59
+ local pascal
60
+ pascal=$(to_pascal "$1")
61
+ echo "$(echo "${pascal:0:1}" | tr 'A-Z' 'a-z')${pascal:1}"
62
+ }
63
+
64
+ to_upper() {
65
+ echo "$1" | tr '[:lower:]' '[:upper:]' | tr '-' '_'
66
+ }
67
+
68
+ NAME_PASCAL=$(to_pascal "$NAME")
69
+ NAME_CAMEL=$(to_camel "$NAME")
70
+ NAME_UPPER=$(to_upper "$NAME")
71
+
72
+ info "Scaffolding $TYPE: $NAME"
73
+ info " PascalCase: $NAME_PASCAL"
74
+ info " camelCase: $NAME_CAMEL"
75
+ info " UPPER: $NAME_UPPER"
76
+ echo ""
77
+
78
+ # ── Template processing ──
79
+ process_template() {
80
+ local tpl_file="$1"
81
+ local output_file="$2"
82
+
83
+ if [[ ! -f "$tpl_file" ]]; then
84
+ err "Template not found: $tpl_file"
85
+ return 1
86
+ fi
87
+
88
+ if [[ -f "$output_file" ]] && [[ "$DRY_RUN" == false ]]; then
89
+ err "File already exists: $output_file (won't overwrite)"
90
+ return 1
91
+ fi
92
+
93
+ local content
94
+ content=$(sed \
95
+ -e "s/__NAME__/$NAME/g" \
96
+ -e "s/__NAME_PASCAL__/$NAME_PASCAL/g" \
97
+ -e "s/__NAME_CAMEL__/$NAME_CAMEL/g" \
98
+ -e "s/__NAME_UPPER__/$NAME_UPPER/g" \
99
+ "$tpl_file")
100
+
101
+ if [[ "$DRY_RUN" == true ]]; then
102
+ warn "[dry-run] Would create: $output_file"
103
+ echo "$content"
104
+ echo "---"
105
+ else
106
+ mkdir -p "$(dirname "$output_file")"
107
+ echo "$content" > "$output_file"
108
+ ok "Created: $output_file"
109
+ fi
110
+ }
111
+
112
+ # ── File mapping per type ──
113
+ CREATED=0
114
+
115
+ case "$TYPE" in
116
+ command)
117
+ process_template "$TEMPLATE_DIR/command.ts.tpl" "$PROJECT_ROOT/src/commands/$NAME.ts" && ((CREATED++)) || true
118
+ process_template "$TEMPLATE_DIR/command-core.ts.tpl" "$PROJECT_ROOT/src/core/$NAME.ts" && ((CREATED++)) || true
119
+ process_template "$TEMPLATE_DIR/command-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/core/$NAME.test.ts" && ((CREATED++)) || true
120
+
121
+ echo ""
122
+ warn "Next steps:"
123
+ echo " 1. Register command in src/index.ts"
124
+ echo " 2. Implement core logic in src/core/$NAME.ts"
125
+ echo " 3. Add isSafeMode() check if destructive"
126
+ echo " 4. Run: npm run build && npm test && npm run lint"
127
+ echo " 5. Update README.md command table"
128
+ ;;
129
+
130
+ check)
131
+ process_template "$TEMPLATE_DIR/check.ts.tpl" "$PROJECT_ROOT/src/core/audit/checks/$NAME.ts" && ((CREATED++)) || true
132
+ process_template "$TEMPLATE_DIR/check-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/core/audit/checks/$NAME.test.ts" && ((CREATED++)) || true
133
+
134
+ echo ""
135
+ warn "Next steps:"
136
+ echo " 1. Add SSH section in src/core/audit/commands.ts:"
137
+ echo " NAMED_SEP(\"${NAME_UPPER}\") + bash commands"
138
+ echo " 2. Register in src/core/audit/checks/index.ts:"
139
+ echo " { name: \"$NAME_PASCAL\", sectionName: \"$NAME_UPPER\", parser: parse${NAME_PASCAL}Checks }"
140
+ echo " 3. Add compliance mapping in src/core/audit/compliance/mapper.ts (optional)"
141
+ echo " 4. Run: npm run build && npm test && npm run lint"
142
+ echo " 5. Test: kastell audit --list-checks | grep $NAME_UPPER"
143
+ ;;
144
+
145
+ provider)
146
+ process_template "$TEMPLATE_DIR/provider.ts.tpl" "$PROJECT_ROOT/src/providers/$NAME.ts" && ((CREATED++)) || true
147
+ process_template "$TEMPLATE_DIR/provider-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/providers/$NAME.test.ts" && ((CREATED++)) || true
148
+
149
+ echo ""
150
+ warn "Next steps:"
151
+ echo " 1. Add to PROVIDER_REGISTRY in src/constants.ts:"
152
+ echo " $NAME: { name: \"$NAME_PASCAL\", envKey: \"${NAME_UPPER}_TOKEN\", class: ${NAME_PASCAL}Provider }"
153
+ echo " 2. Implement API methods (adjust base URL)"
154
+ echo " 3. Add stripSensitiveData() token cleanup"
155
+ echo " 4. Run: npm run build && npm test && npm run lint"
156
+ echo " 5. Add 'Getting Your API Token' to README.md"
157
+ ;;
158
+
159
+ mcp-tool)
160
+ process_template "$TEMPLATE_DIR/mcp-tool.ts.tpl" "$PROJECT_ROOT/src/mcp/tools/$NAME.ts" && ((CREATED++)) || true
161
+ process_template "$TEMPLATE_DIR/mcp-tool-test.ts.tpl" "$PROJECT_ROOT/src/__tests__/mcp/$NAME.test.ts" && ((CREATED++)) || true
162
+
163
+ echo ""
164
+ warn "Next steps:"
165
+ echo " 1. Register in src/mcp/server.ts:"
166
+ echo " registerTool('$NAME', { schema: ${NAME_CAMEL}Schema, handler: handle${NAME_PASCAL} })"
167
+ echo " 2. Define Zod schema (flat object, NOT z.object() wrapper)"
168
+ echo " 3. Handler delegates to core/ (NOT direct SSH/provider)"
169
+ echo " 4. Add SAFE_MODE check if destructive"
170
+ echo " 5. Run: npm run build && npm test && npm run lint"
171
+ echo " 6. Update README.md MCP tools table"
172
+ ;;
173
+ esac
174
+
175
+ echo ""
176
+ if [[ "$DRY_RUN" == true ]]; then
177
+ info "[dry-run] No files were created."
178
+ else
179
+ ok "Scaffolded $CREATED file(s) for $TYPE: $NAME"
180
+ fi
@@ -0,0 +1,27 @@
1
+ import { parse__NAME_PASCAL__Checks } from "../../core/audit/checks/__NAME__.js";
2
+
3
+ describe("parse__NAME_PASCAL__Checks", () => {
4
+ beforeEach(() => jest.resetAllMocks());
5
+
6
+ it("returns checks when section output is valid", () => {
7
+ const result = parse__NAME_PASCAL__Checks("TODO_SENTINEL present", "linux");
8
+ expect(result.length).toBeGreaterThan(0);
9
+ expect(result[0].passed).toBe(true);
10
+ });
11
+
12
+ it("returns empty array when section output is empty", () => {
13
+ const result = parse__NAME_PASCAL__Checks("", "linux");
14
+ expect(result).toEqual([]);
15
+ });
16
+
17
+ it("returns empty array when skip marker present", () => {
18
+ const result = parse__NAME_PASCAL__Checks("SKIP_MARKER", "linux");
19
+ expect(result).toEqual([]);
20
+ });
21
+
22
+ it("returns failed check when sentinel missing", () => {
23
+ const result = parse__NAME_PASCAL__Checks("some other output", "linux");
24
+ expect(result.length).toBeGreaterThan(0);
25
+ expect(result[0].passed).toBe(false);
26
+ });
27
+ });
@@ -0,0 +1,50 @@
1
+ import type { AuditCheck, CheckParser } from "../../types.js";
2
+
3
+ interface __NAME_PASCAL__CheckDef {
4
+ id: string;
5
+ name: string;
6
+ severity: "critical" | "warning" | "info";
7
+ check: (output: string) => { passed: boolean; currentValue: string };
8
+ expectedValue: string;
9
+ fixCommand: string;
10
+ explain: string;
11
+ }
12
+
13
+ const __NAME_UPPER___CHECKS: __NAME_PASCAL__CheckDef[] = [
14
+ {
15
+ id: "__NAME_UPPER__-01",
16
+ name: "TODO: check description",
17
+ severity: "warning",
18
+ check: (output) => {
19
+ const match = output.includes("TODO_SENTINEL");
20
+ return { passed: match, currentValue: match ? "configured" : "not found" };
21
+ },
22
+ expectedValue: "configured",
23
+ fixCommand: "TODO: fix command",
24
+ explain: "TODO: why this matters",
25
+ },
26
+ ];
27
+
28
+ export const parse__NAME_PASCAL__Checks: CheckParser = (
29
+ sectionOutput: string,
30
+ _platform: string,
31
+ ): AuditCheck[] => {
32
+ if (!sectionOutput || sectionOutput.includes("SKIP_MARKER")) {
33
+ return [];
34
+ }
35
+
36
+ return __NAME_UPPER___CHECKS.map((def) => {
37
+ const { passed, currentValue } = def.check(sectionOutput);
38
+ return {
39
+ id: def.id,
40
+ category: "__NAME_PASCAL__",
41
+ name: def.name,
42
+ severity: def.severity,
43
+ passed,
44
+ currentValue,
45
+ expectedValue: def.expectedValue,
46
+ fixCommand: def.fixCommand,
47
+ explain: def.explain,
48
+ };
49
+ });
50
+ };
@@ -0,0 +1,18 @@
1
+ export interface __NAME_PASCAL__Options {
2
+ server?: string;
3
+ json?: boolean;
4
+ }
5
+
6
+ export interface __NAME_PASCAL__Result {
7
+ success: boolean;
8
+ message: string;
9
+ }
10
+
11
+ export async function __NAME_CAMEL__Core(
12
+ options: __NAME_PASCAL__Options,
13
+ ): Promise<__NAME_PASCAL__Result> {
14
+ // ALL business logic here. NO chalk/ora/UI imports.
15
+ // assertValidIp() before SSH. getAdapter(platform) for platform ops.
16
+ // withProviderErrorHandling() for provider calls.
17
+ throw new Error("Not implemented");
18
+ }
@@ -0,0 +1,17 @@
1
+ import { __NAME_CAMEL__Core } from "../../core/__NAME__.js";
2
+
3
+ jest.mock("../../utils/ssh.js");
4
+
5
+ describe("__NAME_CAMEL__Core", () => {
6
+ beforeEach(() => jest.resetAllMocks());
7
+
8
+ it("should TODO: describe expected behavior", async () => {
9
+ const result = await __NAME_CAMEL__Core({ server: "test-server" });
10
+ expect(result.success).toBe(true);
11
+ });
12
+
13
+ it("should handle missing server gracefully", async () => {
14
+ const result = await __NAME_CAMEL__Core({});
15
+ expect(result.success).toBe(false);
16
+ });
17
+ });