metaharness 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/analyze-repo.d.ts +74 -0
  4. package/dist/analyze-repo.d.ts.map +1 -0
  5. package/dist/analyze-repo.js +329 -0
  6. package/dist/analyze-repo.js.map +1 -0
  7. package/dist/audit-cmd.d.ts +6 -0
  8. package/dist/audit-cmd.d.ts.map +1 -0
  9. package/dist/audit-cmd.js +139 -0
  10. package/dist/audit-cmd.js.map +1 -0
  11. package/dist/bin.d.ts +3 -0
  12. package/dist/bin.d.ts.map +1 -0
  13. package/dist/bin.js +8 -0
  14. package/dist/bin.js.map +1 -0
  15. package/dist/compare-cmd.d.ts +56 -0
  16. package/dist/compare-cmd.d.ts.map +1 -0
  17. package/dist/compare-cmd.js +173 -0
  18. package/dist/compare-cmd.js.map +1 -0
  19. package/dist/completions-cmd.d.ts +6 -0
  20. package/dist/completions-cmd.d.ts.map +1 -0
  21. package/dist/completions-cmd.js +171 -0
  22. package/dist/completions-cmd.js.map +1 -0
  23. package/dist/diag.d.ts +76 -0
  24. package/dist/diag.d.ts.map +1 -0
  25. package/dist/diag.js +349 -0
  26. package/dist/diag.js.map +1 -0
  27. package/dist/eject.d.ts +33 -0
  28. package/dist/eject.d.ts.map +1 -0
  29. package/dist/eject.js +147 -0
  30. package/dist/eject.js.map +1 -0
  31. package/dist/export-config.d.ts +25 -0
  32. package/dist/export-config.d.ts.map +1 -0
  33. package/dist/export-config.js +134 -0
  34. package/dist/export-config.js.map +1 -0
  35. package/dist/external-template.d.ts +19 -0
  36. package/dist/external-template.d.ts.map +1 -0
  37. package/dist/external-template.js +37 -0
  38. package/dist/external-template.js.map +1 -0
  39. package/dist/federate.d.ts +37 -0
  40. package/dist/federate.d.ts.map +1 -0
  41. package/dist/federate.js +167 -0
  42. package/dist/federate.js.map +1 -0
  43. package/dist/genome-scorers.d.ts +33 -0
  44. package/dist/genome-scorers.d.ts.map +1 -0
  45. package/dist/genome-scorers.js +115 -0
  46. package/dist/genome-scorers.js.map +1 -0
  47. package/dist/genome.d.ts +28 -0
  48. package/dist/genome.d.ts.map +1 -0
  49. package/dist/genome.js +219 -0
  50. package/dist/genome.js.map +1 -0
  51. package/dist/harness-bin.d.ts +3 -0
  52. package/dist/harness-bin.d.ts.map +1 -0
  53. package/dist/harness-bin.js +17 -0
  54. package/dist/harness-bin.js.map +1 -0
  55. package/dist/index.d.ts +79 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +409 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/manifest.d.ts +55 -0
  60. package/dist/manifest.d.ts.map +1 -0
  61. package/dist/manifest.js +62 -0
  62. package/dist/manifest.js.map +1 -0
  63. package/dist/mcp-cmd.d.ts +19 -0
  64. package/dist/mcp-cmd.d.ts.map +1 -0
  65. package/dist/mcp-cmd.js +179 -0
  66. package/dist/mcp-cmd.js.map +1 -0
  67. package/dist/mcp-scan.d.ts +25 -0
  68. package/dist/mcp-scan.d.ts.map +1 -0
  69. package/dist/mcp-scan.js +132 -0
  70. package/dist/mcp-scan.js.map +1 -0
  71. package/dist/oia-manifest.d.ts +97 -0
  72. package/dist/oia-manifest.d.ts.map +1 -0
  73. package/dist/oia-manifest.js +241 -0
  74. package/dist/oia-manifest.js.map +1 -0
  75. package/dist/publish-cmd.d.ts +9 -0
  76. package/dist/publish-cmd.d.ts.map +1 -0
  77. package/dist/publish-cmd.js +56 -0
  78. package/dist/publish-cmd.js.map +1 -0
  79. package/dist/publish.d.ts +55 -0
  80. package/dist/publish.d.ts.map +1 -0
  81. package/dist/publish.js +104 -0
  82. package/dist/publish.js.map +1 -0
  83. package/dist/registry.d.ts +60 -0
  84. package/dist/registry.d.ts.map +1 -0
  85. package/dist/registry.js +67 -0
  86. package/dist/registry.js.map +1 -0
  87. package/dist/rename.d.ts +26 -0
  88. package/dist/rename.d.ts.map +1 -0
  89. package/dist/rename.js +86 -0
  90. package/dist/rename.js.map +1 -0
  91. package/dist/renderer.d.ts +39 -0
  92. package/dist/renderer.d.ts.map +1 -0
  93. package/dist/renderer.js +75 -0
  94. package/dist/renderer.js.map +1 -0
  95. package/dist/sbom-cmd.d.ts +6 -0
  96. package/dist/sbom-cmd.d.ts.map +1 -0
  97. package/dist/sbom-cmd.js +125 -0
  98. package/dist/sbom-cmd.js.map +1 -0
  99. package/dist/score.d.ts +32 -0
  100. package/dist/score.d.ts.map +1 -0
  101. package/dist/score.js +381 -0
  102. package/dist/score.js.map +1 -0
  103. package/dist/secrets.d.ts +27 -0
  104. package/dist/secrets.d.ts.map +1 -0
  105. package/dist/secrets.js +228 -0
  106. package/dist/secrets.js.map +1 -0
  107. package/dist/subcommands.d.ts +32 -0
  108. package/dist/subcommands.d.ts.map +1 -0
  109. package/dist/subcommands.js +335 -0
  110. package/dist/subcommands.js.map +1 -0
  111. package/dist/tarball.d.ts +14 -0
  112. package/dist/tarball.d.ts.map +1 -0
  113. package/dist/tarball.js +121 -0
  114. package/dist/tarball.js.map +1 -0
  115. package/dist/threat-model.d.ts +32 -0
  116. package/dist/threat-model.d.ts.map +1 -0
  117. package/dist/threat-model.js +236 -0
  118. package/dist/threat-model.js.map +1 -0
  119. package/dist/upgrade-cmd.d.ts +9 -0
  120. package/dist/upgrade-cmd.d.ts.map +1 -0
  121. package/dist/upgrade-cmd.js +90 -0
  122. package/dist/upgrade-cmd.js.map +1 -0
  123. package/dist/upgrade.d.ts +37 -0
  124. package/dist/upgrade.d.ts.map +1 -0
  125. package/dist/upgrade.js +124 -0
  126. package/dist/upgrade.js.map +1 -0
  127. package/dist/validate.d.ts +7 -0
  128. package/dist/validate.d.ts.map +1 -0
  129. package/dist/validate.js +240 -0
  130. package/dist/validate.js.map +1 -0
  131. package/dist/walker.d.ts +24 -0
  132. package/dist/walker.d.ts.map +1 -0
  133. package/dist/walker.js +76 -0
  134. package/dist/walker.js.map +1 -0
  135. package/dist/witness-client.d.ts +40 -0
  136. package/dist/witness-client.d.ts.map +1 -0
  137. package/dist/witness-client.js +99 -0
  138. package/dist/witness-client.js.map +1 -0
  139. package/dist/wizard.d.ts +37 -0
  140. package/dist/wizard.d.ts.map +1 -0
  141. package/dist/wizard.js +137 -0
  142. package/dist/wizard.js.map +1 -0
  143. package/dist/writer.d.ts +13 -0
  144. package/dist/writer.d.ts.map +1 -0
  145. package/dist/writer.js +43 -0
  146. package/dist/writer.js.map +1 -0
  147. package/package.json +114 -0
  148. package/templates/catalog.def.mjs +542 -0
  149. package/templates/catalog.json +1274 -0
  150. package/templates/minimal/.claude/settings.json.tmpl +18 -0
  151. package/templates/minimal/CLAUDE.md.tmpl +23 -0
  152. package/templates/minimal/README.md.tmpl +20 -0
  153. package/templates/minimal/manifest.json +16 -0
  154. package/templates/minimal/package.json.tmpl +30 -0
  155. package/templates/minimal/src/init.ts.tmpl +21 -0
  156. package/templates/vertical_advertising/.claude/commands/doctor.md.tmpl +12 -0
  157. package/templates/vertical_advertising/.claude/settings.json.tmpl +33 -0
  158. package/templates/vertical_advertising/.claude/skills/media-plan/SKILL.md.tmpl +13 -0
  159. package/templates/vertical_advertising/CLAUDE.md.tmpl +30 -0
  160. package/templates/vertical_advertising/README.md.tmpl +29 -0
  161. package/templates/vertical_advertising/manifest.json +81 -0
  162. package/templates/vertical_advertising/package.json.tmpl +30 -0
  163. package/templates/vertical_advertising/src/agents/copywriter.ts.tmpl +7 -0
  164. package/templates/vertical_advertising/src/agents/media-planner.ts.tmpl +7 -0
  165. package/templates/vertical_advertising/src/agents/performance-analyst.ts.tmpl +7 -0
  166. package/templates/vertical_advertising/src/init.ts.tmpl +21 -0
  167. package/templates/vertical_agentics/.claude/commands/doctor.md.tmpl +12 -0
  168. package/templates/vertical_agentics/.claude/settings.json.tmpl +33 -0
  169. package/templates/vertical_agentics/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
  170. package/templates/vertical_agentics/.claude/skills/run-swarm/SKILL.md.tmpl +14 -0
  171. package/templates/vertical_agentics/CLAUDE.md.tmpl +32 -0
  172. package/templates/vertical_agentics/README.md.tmpl +30 -0
  173. package/templates/vertical_agentics/manifest.json +91 -0
  174. package/templates/vertical_agentics/package.json.tmpl +30 -0
  175. package/templates/vertical_agentics/src/agents/critic.ts.tmpl +7 -0
  176. package/templates/vertical_agentics/src/agents/orchestrator.ts.tmpl +7 -0
  177. package/templates/vertical_agentics/src/agents/planner.ts.tmpl +7 -0
  178. package/templates/vertical_agentics/src/agents/worker.ts.tmpl +7 -0
  179. package/templates/vertical_agentics/src/init.ts.tmpl +21 -0
  180. package/templates/vertical_ai/.claude/commands/doctor.md.tmpl +12 -0
  181. package/templates/vertical_ai/.claude/settings.json.tmpl +35 -0
  182. package/templates/vertical_ai/.claude/skills/eval-report/SKILL.md.tmpl +13 -0
  183. package/templates/vertical_ai/CLAUDE.md.tmpl +31 -0
  184. package/templates/vertical_ai/README.md.tmpl +30 -0
  185. package/templates/vertical_ai/manifest.json +86 -0
  186. package/templates/vertical_ai/package.json.tmpl +30 -0
  187. package/templates/vertical_ai/src/agents/data-curator.ts.tmpl +7 -0
  188. package/templates/vertical_ai/src/agents/deployer.ts.tmpl +7 -0
  189. package/templates/vertical_ai/src/agents/evaluator.ts.tmpl +7 -0
  190. package/templates/vertical_ai/src/agents/trainer.ts.tmpl +7 -0
  191. package/templates/vertical_ai/src/init.ts.tmpl +21 -0
  192. package/templates/vertical_business/.claude/commands/doctor.md.tmpl +12 -0
  193. package/templates/vertical_business/.claude/settings.json.tmpl +33 -0
  194. package/templates/vertical_business/.claude/skills/quarterly-plan/SKILL.md.tmpl +13 -0
  195. package/templates/vertical_business/CLAUDE.md.tmpl +30 -0
  196. package/templates/vertical_business/README.md.tmpl +29 -0
  197. package/templates/vertical_business/manifest.json +81 -0
  198. package/templates/vertical_business/package.json.tmpl +30 -0
  199. package/templates/vertical_business/src/agents/analyst.ts.tmpl +7 -0
  200. package/templates/vertical_business/src/agents/ops-coordinator.ts.tmpl +7 -0
  201. package/templates/vertical_business/src/agents/strategist.ts.tmpl +7 -0
  202. package/templates/vertical_business/src/init.ts.tmpl +21 -0
  203. package/templates/vertical_coding/.claude/commands/doctor.md.tmpl +12 -0
  204. package/templates/vertical_coding/.claude/commands/review-diff.md.tmpl +10 -0
  205. package/templates/vertical_coding/.claude/settings.json.tmpl +40 -0
  206. package/templates/vertical_coding/.claude/skills/plan-change/SKILL.md.tmpl +15 -0
  207. package/templates/vertical_coding/CLAUDE.md.tmpl +32 -0
  208. package/templates/vertical_coding/README.md.tmpl +30 -0
  209. package/templates/vertical_coding/manifest.json +91 -0
  210. package/templates/vertical_coding/package.json.tmpl +30 -0
  211. package/templates/vertical_coding/src/agents/architect.ts.tmpl +7 -0
  212. package/templates/vertical_coding/src/agents/implementer.ts.tmpl +7 -0
  213. package/templates/vertical_coding/src/agents/reviewer.ts.tmpl +7 -0
  214. package/templates/vertical_coding/src/agents/test-writer.ts.tmpl +7 -0
  215. package/templates/vertical_coding/src/init.ts.tmpl +21 -0
  216. package/templates/vertical_crm/.claude/commands/doctor.md.tmpl +12 -0
  217. package/templates/vertical_crm/.claude/settings.json.tmpl +33 -0
  218. package/templates/vertical_crm/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
  219. package/templates/vertical_crm/CLAUDE.md.tmpl +30 -0
  220. package/templates/vertical_crm/README.md.tmpl +29 -0
  221. package/templates/vertical_crm/manifest.json +81 -0
  222. package/templates/vertical_crm/package.json.tmpl +30 -0
  223. package/templates/vertical_crm/src/agents/account-manager.ts.tmpl +7 -0
  224. package/templates/vertical_crm/src/agents/churn-watcher.ts.tmpl +7 -0
  225. package/templates/vertical_crm/src/agents/lead-qualifier.ts.tmpl +7 -0
  226. package/templates/vertical_crm/src/init.ts.tmpl +21 -0
  227. package/templates/vertical_devops/.claude/settings.json.tmpl +36 -0
  228. package/templates/vertical_devops/CLAUDE.md.tmpl +34 -0
  229. package/templates/vertical_devops/README.md.tmpl +27 -0
  230. package/templates/vertical_devops/manifest.json +22 -0
  231. package/templates/vertical_devops/package.json.tmpl +26 -0
  232. package/templates/vertical_devops/runbooks/README.md.tmpl +32 -0
  233. package/templates/vertical_devops/src/agents/escalator.ts.tmpl +19 -0
  234. package/templates/vertical_devops/src/agents/postmortem.ts.tmpl +23 -0
  235. package/templates/vertical_devops/src/agents/responder.ts.tmpl +14 -0
  236. package/templates/vertical_devops/src/agents/runbook-runner.ts.tmpl +17 -0
  237. package/templates/vertical_devops/src/init.ts.tmpl +23 -0
  238. package/templates/vertical_education/.claude/commands/doctor.md.tmpl +12 -0
  239. package/templates/vertical_education/.claude/commands/mastery-report.md.tmpl +12 -0
  240. package/templates/vertical_education/.claude/settings.json.tmpl +45 -0
  241. package/templates/vertical_education/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
  242. package/templates/vertical_education/.claude/skills/teach-next/SKILL.md.tmpl +16 -0
  243. package/templates/vertical_education/CLAUDE.md.tmpl +33 -0
  244. package/templates/vertical_education/README.md.tmpl +30 -0
  245. package/templates/vertical_education/manifest.json +96 -0
  246. package/templates/vertical_education/package.json.tmpl +30 -0
  247. package/templates/vertical_education/src/agents/explainer.ts.tmpl +7 -0
  248. package/templates/vertical_education/src/agents/grader.ts.tmpl +7 -0
  249. package/templates/vertical_education/src/agents/quiz-master.ts.tmpl +7 -0
  250. package/templates/vertical_education/src/agents/tutor.ts.tmpl +7 -0
  251. package/templates/vertical_education/src/init.ts.tmpl +21 -0
  252. package/templates/vertical_exotic/.claude/commands/doctor.md.tmpl +12 -0
  253. package/templates/vertical_exotic/.claude/settings.json.tmpl +44 -0
  254. package/templates/vertical_exotic/.claude/skills/evolve/SKILL.md.tmpl +14 -0
  255. package/templates/vertical_exotic/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
  256. package/templates/vertical_exotic/CLAUDE.md.tmpl +31 -0
  257. package/templates/vertical_exotic/README.md.tmpl +29 -0
  258. package/templates/vertical_exotic/manifest.json +86 -0
  259. package/templates/vertical_exotic/package.json.tmpl +30 -0
  260. package/templates/vertical_exotic/src/agents/experimenter.ts.tmpl +7 -0
  261. package/templates/vertical_exotic/src/agents/federator.ts.tmpl +7 -0
  262. package/templates/vertical_exotic/src/agents/hypothesizer.ts.tmpl +7 -0
  263. package/templates/vertical_exotic/src/init.ts.tmpl +21 -0
  264. package/templates/vertical_gaming/.claude/commands/design-doc-diff.md.tmpl +13 -0
  265. package/templates/vertical_gaming/.claude/commands/doctor.md.tmpl +12 -0
  266. package/templates/vertical_gaming/.claude/settings.json.tmpl +45 -0
  267. package/templates/vertical_gaming/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
  268. package/templates/vertical_gaming/.claude/skills/playtest-recap/SKILL.md.tmpl +16 -0
  269. package/templates/vertical_gaming/CLAUDE.md.tmpl +33 -0
  270. package/templates/vertical_gaming/README.md.tmpl +30 -0
  271. package/templates/vertical_gaming/manifest.json +96 -0
  272. package/templates/vertical_gaming/package.json.tmpl +30 -0
  273. package/templates/vertical_gaming/src/agents/balance-critic.ts.tmpl +7 -0
  274. package/templates/vertical_gaming/src/agents/economy-modeler.ts.tmpl +7 -0
  275. package/templates/vertical_gaming/src/agents/narrative-keeper.ts.tmpl +7 -0
  276. package/templates/vertical_gaming/src/agents/playtest-reader.ts.tmpl +7 -0
  277. package/templates/vertical_gaming/src/init.ts.tmpl +21 -0
  278. package/templates/vertical_health/.claude/commands/doctor.md.tmpl +12 -0
  279. package/templates/vertical_health/.claude/settings.json.tmpl +33 -0
  280. package/templates/vertical_health/.claude/skills/wellness-intake/SKILL.md.tmpl +15 -0
  281. package/templates/vertical_health/CLAUDE.md.tmpl +30 -0
  282. package/templates/vertical_health/README.md.tmpl +29 -0
  283. package/templates/vertical_health/manifest.json +81 -0
  284. package/templates/vertical_health/package.json.tmpl +30 -0
  285. package/templates/vertical_health/src/agents/care-coordinator.ts.tmpl +7 -0
  286. package/templates/vertical_health/src/agents/intake.ts.tmpl +7 -0
  287. package/templates/vertical_health/src/agents/triage.ts.tmpl +7 -0
  288. package/templates/vertical_health/src/init.ts.tmpl +21 -0
  289. package/templates/vertical_legal/.claude/settings.json.tmpl +10 -0
  290. package/templates/vertical_legal/CLAUDE.md.tmpl +24 -0
  291. package/templates/vertical_legal/README.md.tmpl +21 -0
  292. package/templates/vertical_legal/manifest.json +20 -0
  293. package/templates/vertical_legal/package.json.tmpl +13 -0
  294. package/templates/vertical_legal/src/agents/citation-checker.ts.tmpl +7 -0
  295. package/templates/vertical_legal/src/agents/redline.ts.tmpl +7 -0
  296. package/templates/vertical_legal/src/agents/risk-rater.ts.tmpl +8 -0
  297. package/templates/vertical_legal/src/init.ts.tmpl +13 -0
  298. package/templates/vertical_marketing/.claude/commands/doctor.md.tmpl +12 -0
  299. package/templates/vertical_marketing/.claude/settings.json.tmpl +33 -0
  300. package/templates/vertical_marketing/.claude/skills/campaign-brief/SKILL.md.tmpl +13 -0
  301. package/templates/vertical_marketing/CLAUDE.md.tmpl +30 -0
  302. package/templates/vertical_marketing/README.md.tmpl +29 -0
  303. package/templates/vertical_marketing/manifest.json +81 -0
  304. package/templates/vertical_marketing/package.json.tmpl +30 -0
  305. package/templates/vertical_marketing/src/agents/content-creator.ts.tmpl +7 -0
  306. package/templates/vertical_marketing/src/agents/seo-analyst.ts.tmpl +7 -0
  307. package/templates/vertical_marketing/src/agents/strategist.ts.tmpl +7 -0
  308. package/templates/vertical_marketing/src/init.ts.tmpl +21 -0
  309. package/templates/vertical_repo-maintainer/.claude/commands/doctor.md.tmpl +12 -0
  310. package/templates/vertical_repo-maintainer/.claude/commands/release-check.md.tmpl +13 -0
  311. package/templates/vertical_repo-maintainer/.claude/commands/repo-triage.md.tmpl +16 -0
  312. package/templates/vertical_repo-maintainer/.claude/settings.json.tmpl +44 -0
  313. package/templates/vertical_repo-maintainer/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
  314. package/templates/vertical_repo-maintainer/.claude/skills/plan-change/SKILL.md.tmpl +15 -0
  315. package/templates/vertical_repo-maintainer/CLAUDE.md.tmpl +34 -0
  316. package/templates/vertical_repo-maintainer/README.md.tmpl +30 -0
  317. package/templates/vertical_repo-maintainer/manifest.json +101 -0
  318. package/templates/vertical_repo-maintainer/package.json.tmpl +30 -0
  319. package/templates/vertical_repo-maintainer/src/agents/benchmarker.ts.tmpl +7 -0
  320. package/templates/vertical_repo-maintainer/src/agents/maintainer.ts.tmpl +7 -0
  321. package/templates/vertical_repo-maintainer/src/agents/release.ts.tmpl +7 -0
  322. package/templates/vertical_repo-maintainer/src/agents/security.ts.tmpl +7 -0
  323. package/templates/vertical_repo-maintainer/src/init.ts.tmpl +21 -0
  324. package/templates/vertical_research/.claude/settings.json.tmpl +9 -0
  325. package/templates/vertical_research/CLAUDE.md.tmpl +33 -0
  326. package/templates/vertical_research/README.md.tmpl +17 -0
  327. package/templates/vertical_research/manifest.json +23 -0
  328. package/templates/vertical_research/package.json.tmpl +13 -0
  329. package/templates/vertical_research/src/agents/citer.ts.tmpl +8 -0
  330. package/templates/vertical_research/src/agents/fact-checker.ts.tmpl +8 -0
  331. package/templates/vertical_research/src/agents/scout.ts.tmpl +7 -0
  332. package/templates/vertical_research/src/agents/source-grader.ts.tmpl +10 -0
  333. package/templates/vertical_research/src/agents/synthesizer.ts.tmpl +8 -0
  334. package/templates/vertical_research/src/agents/web-searcher.ts.tmpl +6 -0
  335. package/templates/vertical_research/src/init.ts.tmpl +13 -0
  336. package/templates/vertical_ruview/.claude/commands/doctor.md.tmpl +12 -0
  337. package/templates/vertical_ruview/.claude/settings.json.tmpl +33 -0
  338. package/templates/vertical_ruview/.claude/skills/index-and-ask/SKILL.md.tmpl +15 -0
  339. package/templates/vertical_ruview/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
  340. package/templates/vertical_ruview/CLAUDE.md.tmpl +31 -0
  341. package/templates/vertical_ruview/README.md.tmpl +29 -0
  342. package/templates/vertical_ruview/manifest.json +86 -0
  343. package/templates/vertical_ruview/package.json.tmpl +30 -0
  344. package/templates/vertical_ruview/src/agents/indexer.ts.tmpl +7 -0
  345. package/templates/vertical_ruview/src/agents/retriever.ts.tmpl +7 -0
  346. package/templates/vertical_ruview/src/agents/reviewer.ts.tmpl +7 -0
  347. package/templates/vertical_ruview/src/init.ts.tmpl +21 -0
  348. package/templates/vertical_sales/.claude/commands/doctor.md.tmpl +12 -0
  349. package/templates/vertical_sales/.claude/commands/pipeline-report.md.tmpl +13 -0
  350. package/templates/vertical_sales/.claude/settings.json.tmpl +45 -0
  351. package/templates/vertical_sales/.claude/skills/memory-inspect/SKILL.md.tmpl +14 -0
  352. package/templates/vertical_sales/.claude/skills/qualify-lead/SKILL.md.tmpl +15 -0
  353. package/templates/vertical_sales/CLAUDE.md.tmpl +33 -0
  354. package/templates/vertical_sales/README.md.tmpl +30 -0
  355. package/templates/vertical_sales/manifest.json +96 -0
  356. package/templates/vertical_sales/package.json.tmpl +30 -0
  357. package/templates/vertical_sales/src/agents/closer.ts.tmpl +7 -0
  358. package/templates/vertical_sales/src/agents/demo-coach.ts.tmpl +7 -0
  359. package/templates/vertical_sales/src/agents/prospector.ts.tmpl +7 -0
  360. package/templates/vertical_sales/src/agents/qualifier.ts.tmpl +7 -0
  361. package/templates/vertical_sales/src/init.ts.tmpl +21 -0
  362. package/templates/vertical_support/.claude/settings.json.tmpl +25 -0
  363. package/templates/vertical_support/CLAUDE.md.tmpl +34 -0
  364. package/templates/vertical_support/README.md.tmpl +16 -0
  365. package/templates/vertical_support/kb/README.md.tmpl +23 -0
  366. package/templates/vertical_support/manifest.json +22 -0
  367. package/templates/vertical_support/package.json.tmpl +24 -0
  368. package/templates/vertical_support/src/agents/escalator.ts.tmpl +6 -0
  369. package/templates/vertical_support/src/agents/kb-searcher.ts.tmpl +6 -0
  370. package/templates/vertical_support/src/agents/responder.ts.tmpl +7 -0
  371. package/templates/vertical_support/src/agents/triager.ts.tmpl +6 -0
  372. package/templates/vertical_support/src/init.ts.tmpl +16 -0
  373. package/templates/vertical_trading/.claude/settings.json.tmpl +20 -0
  374. package/templates/vertical_trading/CLAUDE.md.tmpl +24 -0
  375. package/templates/vertical_trading/README.md.tmpl +17 -0
  376. package/templates/vertical_trading/manifest.json +22 -0
  377. package/templates/vertical_trading/package.json.tmpl +13 -0
  378. package/templates/vertical_trading/src/agents/executor.ts.tmpl +8 -0
  379. package/templates/vertical_trading/src/agents/market-watcher.ts.tmpl +7 -0
  380. package/templates/vertical_trading/src/agents/postmortem.ts.tmpl +8 -0
  381. package/templates/vertical_trading/src/agents/risk-checker.ts.tmpl +11 -0
  382. package/templates/vertical_trading/src/agents/signal-gen.ts.tmpl +8 -0
  383. package/templates/vertical_trading/src/init.ts.tmpl +20 -0
@@ -0,0 +1,236 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // `harness threat-model <path>` — 20th subcommand (iter 112). Priority 5 from
4
+ // the user's roadmap ("enterprise gold"). Surfaces the existing mcp-scan
5
+ // findings as a clean, scannable threat-model artifact ready for a PR review
6
+ // or security/compliance review.
7
+ //
8
+ // Output (the exact shape the user named):
9
+ // MCP Threat Model
10
+ // Allowed tools: 3
11
+ // Denied tools: 14
12
+ // Dangerous permissions: 0
13
+ // Secrets reachable: no
14
+ // Network access: no
15
+ // Shell access: no
16
+ // File write: no
17
+ //
18
+ // Modes: text (default) · --json · --bundle (ADR-031 schema-1 envelope) ·
19
+ // --out <file>.
20
+ //
21
+ // Verdict + exit code:
22
+ // - 0 — clean threat model (no dangerous perms, no secret exposure)
23
+ // - 1 — medium concerns (network OR file-write granted, OR no audit log)
24
+ // - 2 — high concerns (shell granted OR default-deny off OR secrets reachable)
25
+ import { existsSync, statSync, writeFileSync, readFileSync } from 'node:fs';
26
+ import { join, resolve } from 'node:path';
27
+ import { scanMcp } from './mcp-scan.js';
28
+ function safeReadJson(path) {
29
+ try {
30
+ if (!existsSync(path))
31
+ return null;
32
+ return JSON.parse(readFileSync(path, 'utf-8'));
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ export function buildThreatModel(dir, generatedAt = new Date().toISOString()) {
39
+ const root = resolve(dir);
40
+ const policy = safeReadJson(join(root, '.harness', 'mcp-policy.json'));
41
+ const settings = safeReadJson(join(root, '.claude', 'settings.json'));
42
+ const mcpInUse = policy != null || safeReadJson(join(root, '.mcp.json')) != null;
43
+ // mcp-scan returns the structured findings; we collapse to counters.
44
+ const scan = scanMcp(root);
45
+ const allow = settings?.permissions?.allow ?? [];
46
+ const deny = settings?.permissions?.deny ?? [];
47
+ const allowedTools = allow.length;
48
+ const deniedTools = deny.length;
49
+ const policyDefaultDeny = policy ? policy.defaultDeny === true : null;
50
+ const auditLog = policy ? policy.auditLog === true : null;
51
+ const shellAccess = policy?.allowShell === true;
52
+ const networkAccess = policy?.allowNetwork === true;
53
+ const fileWrite = policy?.allowFileWrite === true;
54
+ // "Secrets reachable" = there is no .env-blocking deny rule AND tools have
55
+ // some non-trivial read permission. Conservative: true if allow has any
56
+ // Read(*) rule and deny doesn't block .env.
57
+ const guardsEnv = deny.some((d) => /\.env/.test(d));
58
+ const hasReadAllow = allow.some((a) => /^Read/.test(a));
59
+ const secretsReachable = mcpInUse && !guardsEnv && hasReadAllow;
60
+ // Count "dangerous permissions" = high-severity findings from mcp-scan +
61
+ // the top-level boolean knobs the user named.
62
+ let dangerousPermissions = 0;
63
+ if (shellAccess)
64
+ dangerousPermissions++;
65
+ if (networkAccess)
66
+ dangerousPermissions++;
67
+ if (fileWrite)
68
+ dangerousPermissions++;
69
+ if (secretsReachable)
70
+ dangerousPermissions++;
71
+ if (policy && policyDefaultDeny === false)
72
+ dangerousPermissions++;
73
+ let verdict;
74
+ let exitCode;
75
+ if (shellAccess || policyDefaultDeny === false || secretsReachable) {
76
+ verdict = 'high';
77
+ exitCode = 2;
78
+ }
79
+ else if (networkAccess || fileWrite || (mcpInUse && auditLog === false)) {
80
+ verdict = 'medium';
81
+ exitCode = 1;
82
+ }
83
+ else {
84
+ verdict = 'clean';
85
+ exitCode = 0;
86
+ }
87
+ return {
88
+ schema: 1,
89
+ generatedAt,
90
+ dir: root,
91
+ mcpInUse,
92
+ allowedTools,
93
+ deniedTools,
94
+ dangerousPermissions,
95
+ secretsReachable,
96
+ networkAccess,
97
+ shellAccess,
98
+ fileWrite,
99
+ policyDefaultDeny,
100
+ auditLog,
101
+ findings: scan.findings.map((f) => ({ id: f.id, severity: f.severity, title: f.title })),
102
+ worst: scan.worst,
103
+ verdict,
104
+ exitCode,
105
+ };
106
+ }
107
+ // --- formatting ------------------------------------------------------------
108
+ function yn(b) {
109
+ return b ? 'yes' : 'no';
110
+ }
111
+ export function formatThreatModel(tm) {
112
+ const out = [];
113
+ out.push('MCP Threat Model');
114
+ out.push('');
115
+ if (!tm.mcpInUse) {
116
+ out.push(' mcp surface: off (no .mcp.json, no .harness/mcp-policy.json)');
117
+ out.push(' threat surface: none — MCP is not in use');
118
+ out.push('');
119
+ out.push('Verdict: clean (exit 0)');
120
+ return out;
121
+ }
122
+ out.push(` Allowed tools: ${tm.allowedTools}`);
123
+ out.push(` Denied tools: ${tm.deniedTools}`);
124
+ out.push(` Dangerous permissions: ${tm.dangerousPermissions}`);
125
+ out.push(` Secrets reachable: ${yn(tm.secretsReachable)}`);
126
+ out.push(` Network access: ${yn(tm.networkAccess)}`);
127
+ out.push(` Shell access: ${yn(tm.shellAccess)}`);
128
+ out.push(` File write: ${yn(tm.fileWrite)}`);
129
+ if (tm.policyDefaultDeny !== null) {
130
+ out.push(` Default-deny policy: ${yn(tm.policyDefaultDeny)}`);
131
+ }
132
+ if (tm.auditLog !== null) {
133
+ out.push(` Audit log: ${yn(tm.auditLog)}`);
134
+ }
135
+ if (tm.findings.length > 0) {
136
+ out.push('');
137
+ out.push('Findings:');
138
+ for (const f of tm.findings) {
139
+ out.push(` [${f.severity.toUpperCase().padEnd(6)}] ${f.id} — ${f.title}`);
140
+ }
141
+ }
142
+ out.push('');
143
+ out.push(`Verdict: ${tm.verdict} (exit ${tm.exitCode})`);
144
+ if (tm.verdict !== 'clean') {
145
+ out.push('Run: harness mcp-scan ' + tm.dir + ' # for the full finding list');
146
+ }
147
+ return out;
148
+ }
149
+ // --- sanitisation (ADR-031) ------------------------------------------------
150
+ const SECRET_RE = /(secret|token|key|password|passphrase)/i;
151
+ function sanitise(v) {
152
+ if (v == null)
153
+ return v;
154
+ if (Array.isArray(v))
155
+ return v.map(sanitise);
156
+ if (typeof v === 'object') {
157
+ const out = {};
158
+ for (const [k, val] of Object.entries(v)) {
159
+ out[k] = SECRET_RE.test(k) ? '[REDACTED]' : sanitise(val);
160
+ }
161
+ return out;
162
+ }
163
+ return v;
164
+ }
165
+ // --- dispatch --------------------------------------------------------------
166
+ function usage() {
167
+ return [
168
+ 'Usage: harness threat-model <path> [--out <file>] [--json] [--bundle]',
169
+ '',
170
+ ' MCP threat-model artifact — scannable in a PR or compliance review.',
171
+ ' Reports allowed/denied tools, dangerous permissions, secret reachability,',
172
+ ' network/shell/file-write grants, default-deny policy posture.',
173
+ '',
174
+ ' --out <file> Write the JSON artifact to <file>.',
175
+ ' --json Emit JSON to stdout instead of text.',
176
+ ' --bundle Emit the full report as an ADR-031 schema-1 envelope.',
177
+ ];
178
+ }
179
+ export async function threatModelCmd(args) {
180
+ const bundle = args.includes('--bundle');
181
+ const json = args.includes('--json');
182
+ let outPath = null;
183
+ const positional = [];
184
+ for (let i = 0; i < args.length; i++) {
185
+ const a = args[i];
186
+ if (a === '--out') {
187
+ outPath = args[++i] ?? null;
188
+ if (!outPath) {
189
+ const err = { schema: 1, error: 'missing-out-path', exitCode: 2 };
190
+ return { code: 2, lines: [bundle || json ? JSON.stringify(err, null, 2) : '--out requires a file path'] };
191
+ }
192
+ }
193
+ else if (a === '--bundle' || a === '--json') {
194
+ /* handled */
195
+ }
196
+ else if (a === '--help' || a === '-h') {
197
+ return { code: 0, lines: usage() };
198
+ }
199
+ else if (a && !a.startsWith('--')) {
200
+ positional.push(a);
201
+ }
202
+ else if (a) {
203
+ const err = { schema: 1, error: `unknown-flag-${a.replace(/^--?/, '')}`, exitCode: 2 };
204
+ return { code: 2, lines: [bundle || json ? JSON.stringify(err, null, 2) : `Unknown flag: ${a}`] };
205
+ }
206
+ }
207
+ if (positional.length === 0) {
208
+ return { code: 2, lines: usage() };
209
+ }
210
+ const dir = resolve(positional[0]);
211
+ if (!existsSync(dir) || !statSync(dir).isDirectory()) {
212
+ const generatedAt = new Date().toISOString();
213
+ const err = { schema: 1, generatedAt, error: 'not-a-directory', dir, exitCode: 2 };
214
+ if (bundle || json)
215
+ return { code: 2, lines: [JSON.stringify(err, null, 2)] };
216
+ return { code: 2, lines: [`harness threat-model: not a directory: ${dir}`] };
217
+ }
218
+ const tm = buildThreatModel(dir);
219
+ if (outPath) {
220
+ try {
221
+ writeFileSync(resolve(outPath), JSON.stringify(tm, null, 2) + '\n', 'utf-8');
222
+ }
223
+ catch (e) {
224
+ const err = { schema: 1, error: 'out-write-failed', detail: String(e), exitCode: 2 };
225
+ return { code: 2, lines: [bundle || json ? JSON.stringify(err, null, 2) : `harness threat-model: failed to write --out: ${String(e)}`] };
226
+ }
227
+ }
228
+ if (bundle) {
229
+ return { code: tm.exitCode, lines: [JSON.stringify(sanitise(tm), null, 2)] };
230
+ }
231
+ if (json) {
232
+ return { code: tm.exitCode, lines: [JSON.stringify(tm, null, 2)] };
233
+ }
234
+ return { code: tm.exitCode, lines: formatThreatModel(tm) };
235
+ }
236
+ //# sourceMappingURL=threat-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threat-model.js","sourceRoot":"","sources":["../src/threat-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type SubcommandResult = {
2
+ code: number;
3
+ lines: string[];
4
+ };
5
+ /**
6
+ * `harness upgrade [path] [--apply] [--conflict=inline|rej]`
7
+ */
8
+ export declare function upgradeCmd(args: string[]): Promise<SubcommandResult>;
9
+ //# sourceMappingURL=upgrade-cmd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-cmd.d.ts","sourceRoot":"","sources":["../src/upgrade-cmd.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAajE;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuE1E"}
@@ -0,0 +1,90 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // `harness upgrade [path] [--apply] [--conflict=inline|rej]` CLI subcommand.
4
+ //
5
+ // Re-renders the harness's template against the current generator
6
+ // version, computes the drift plan vs the manifest's recorded
7
+ // fingerprints, and either prints the plan (dry-run default) or
8
+ // applies it.
9
+ //
10
+ // Conflict handling:
11
+ // --conflict=inline (default) write Git-style conflict markers in-place
12
+ // --conflict=rej write the upstream version to `<file>.rej`
13
+ import { resolve, join } from 'node:path';
14
+ import { readFile } from 'node:fs/promises';
15
+ import { existsSync } from 'node:fs';
16
+ import { planUpgrade, formatPlan, applyPlan } from './upgrade.js';
17
+ import { walkTemplate, asFileMap } from './walker.js';
18
+ import { templateDir } from './index.js';
19
+ import { createHash } from 'node:crypto';
20
+ function sha256(s) {
21
+ return createHash('sha256').update(s, 'utf-8').digest('hex');
22
+ }
23
+ /**
24
+ * `harness upgrade [path] [--apply] [--conflict=inline|rej]`
25
+ */
26
+ export async function upgradeCmd(args) {
27
+ const positional = args.filter(a => !a.startsWith('--'));
28
+ const dir = resolve(positional[0] ?? process.cwd());
29
+ const apply = args.includes('--apply');
30
+ const conflictStyle = args.find(a => a.startsWith('--conflict='))?.slice('--conflict='.length) ?? 'inline';
31
+ const lines = [`harness upgrade — ${dir} ${apply ? '(APPLY)' : '(DRY-RUN)'}`];
32
+ if (!['inline', 'rej'].includes(conflictStyle)) {
33
+ lines.push(` --conflict=${conflictStyle} unsupported (use inline or rej)`);
34
+ return { code: 2, lines };
35
+ }
36
+ const manifestPath = join(dir, '.harness', 'manifest.json');
37
+ if (!existsSync(manifestPath)) {
38
+ lines.push(` no .harness/manifest.json at ${dir} — not a generated harness`);
39
+ return { code: 1, lines };
40
+ }
41
+ let manifest;
42
+ try {
43
+ manifest = JSON.parse(await readFile(manifestPath, 'utf-8'));
44
+ }
45
+ catch (e) {
46
+ lines.push(` manifest is not valid JSON: ${e instanceof Error ? e.message : e}`);
47
+ return { code: 1, lines };
48
+ }
49
+ // Re-render the template that produced this harness, with the same vars,
50
+ // to get the LATEST expected file map.
51
+ const tdir = templateDir(manifest.template);
52
+ if (!existsSync(tdir)) {
53
+ lines.push(` template "${manifest.template}" not found at ${tdir}`);
54
+ lines.push(` (the create-agent-harness package may have evolved the template id)`);
55
+ return { code: 1, lines };
56
+ }
57
+ const rendered = await walkTemplate(tdir, manifest.vars, { strict: false });
58
+ const upstreamFiles = asFileMap(rendered);
59
+ const upstreamFingerprints = {};
60
+ for (const [path, content] of Object.entries(upstreamFiles)) {
61
+ upstreamFingerprints[path] = sha256(content);
62
+ }
63
+ const plan = await planUpgrade(dir, upstreamFingerprints);
64
+ lines.push('');
65
+ for (const planLine of formatPlan(plan).split('\n'))
66
+ lines.push(' ' + planLine);
67
+ const total = plan.added.length + plan.removed.length + plan.changed.length;
68
+ if (total === 0) {
69
+ lines.push('', ' No drift — harness is up-to-date with the template.');
70
+ return { code: 0, lines };
71
+ }
72
+ const conflicts = plan.changed.filter(c => c.kind === 'conflict');
73
+ if (!apply) {
74
+ lines.push('', ` DRY-RUN: re-run with --apply to apply this plan.`);
75
+ if (conflicts.length > 0) {
76
+ lines.push(` ${conflicts.length} conflict(s) will use ${conflictStyle === 'inline' ? 'inline markers' : '.rej files'}.`);
77
+ }
78
+ return { code: 0, lines };
79
+ }
80
+ // APPLY
81
+ const modified = await applyPlan(dir, plan, upstreamFiles, { conflictStyle });
82
+ lines.push('', ` Modified ${modified.length} file(s).`);
83
+ if (conflicts.length > 0) {
84
+ lines.push(` ${conflicts.length} conflict(s) written using ${conflictStyle === 'inline' ? 'inline markers' : '.rej files'} — review manually.`);
85
+ return { code: 1, lines }; // non-zero so CI flags unresolved conflicts
86
+ }
87
+ lines.push(' Clean apply — no conflicts.');
88
+ return { code: 0, lines };
89
+ }
90
+ //# sourceMappingURL=upgrade-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-cmd.js","sourceRoot":"","sources":["../src/upgrade-cmd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export interface UpgradePlan {
2
+ /** Files that exist in old but not in new — should we delete them? */
3
+ removed: string[];
4
+ /** Files that are new in the upstream template. Safe to add. */
5
+ added: string[];
6
+ /** Files where the upstream version differs from what was generated. */
7
+ changed: Array<{
8
+ path: string;
9
+ /** 'clean' = local matches old (safe overwrite); 'conflict' = local diverged. */
10
+ kind: 'clean' | 'conflict';
11
+ }>;
12
+ }
13
+ /**
14
+ * Compute the upgrade plan without applying anything.
15
+ *
16
+ * @param projectDir — root of the harness install
17
+ * @param newFiles — fingerprint map for the LATEST template render
18
+ */
19
+ export declare function planUpgrade(projectDir: string, newFiles: Record<string, string>): Promise<UpgradePlan>;
20
+ /**
21
+ * Render a plan as a human-readable summary.
22
+ */
23
+ export declare function formatPlan(plan: UpgradePlan): string;
24
+ /**
25
+ * Write Git-style inline conflict markers into the local file.
26
+ * Used when planUpgrade reports a 'conflict' entry and the user wants
27
+ * inline markers (the default).
28
+ */
29
+ export declare function inlineConflictMarkers(local: string, upstream: string): string;
30
+ /**
31
+ * Apply an upgrade plan. Returns the list of paths actually modified.
32
+ * Best-effort — caller should review the plan first via formatPlan().
33
+ */
34
+ export declare function applyPlan(projectDir: string, plan: UpgradePlan, newContents: Record<string, string>, opts?: {
35
+ conflictStyle?: 'inline' | 'rej';
36
+ }): Promise<string[]>;
37
+ //# sourceMappingURL=upgrade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gEAAgE;IAChE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,wEAAwE;IACxE,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,iFAAiF;QACjF,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;KAC5B,CAAC,CAAC;CACJ;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,WAAW,CAAC,CAiCtB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAepD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,MAAM,CASR;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,WAAW,EACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAA;CAAO,GAC9C,OAAO,CAAC,MAAM,EAAE,CAAC,CA2BnB"}
@@ -0,0 +1,124 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // `harness upgrade` — copier-style regenerate-diff-merge.
4
+ //
5
+ // Algorithm (per ADR-008 + copier docs):
6
+ // 1. Read the existing .harness/manifest.json — the source of truth for
7
+ // what choices were made at generation time.
8
+ // 2. Re-run the scaffold with the SAME vars against the LATEST template
9
+ // version. Produce fresh fingerprints in-memory.
10
+ // 3. Diff old-fingerprints vs new-fingerprints to find changed/added/
11
+ // removed files.
12
+ // 4. For each changed file: compare CURRENT (on-disk) vs OLD (manifest)
13
+ // vs NEW (template). Three-way:
14
+ // - file unchanged from old -> overwrite with new
15
+ // - file changed from old, identical to new -> no-op
16
+ // - file changed from old, different from new -> CONFLICT
17
+ // 5. Write conflicts as inline Git markers (<<<<<<< current ======= new
18
+ // >>>>>>> upstream) OR as .rej files alongside, depending on user's
19
+ // preference. Default: inline markers.
20
+ import { readFile, writeFile } from 'node:fs/promises';
21
+ import { existsSync } from 'node:fs';
22
+ import { join } from 'node:path';
23
+ import { diffFingerprints, sha256 } from './manifest.js';
24
+ /**
25
+ * Compute the upgrade plan without applying anything.
26
+ *
27
+ * @param projectDir — root of the harness install
28
+ * @param newFiles — fingerprint map for the LATEST template render
29
+ */
30
+ export async function planUpgrade(projectDir, newFiles) {
31
+ const manifestPath = join(projectDir, '.harness', 'manifest.json');
32
+ if (!existsSync(manifestPath)) {
33
+ throw new Error(`No .harness/manifest.json at ${projectDir}. Was this directory created by create-agent-harness?`);
34
+ }
35
+ const m = JSON.parse(await readFile(manifestPath, 'utf-8'));
36
+ const oldFiles = m.files;
37
+ const diff = diffFingerprints(oldFiles, newFiles);
38
+ const plan = {
39
+ removed: diff.removed,
40
+ added: diff.added,
41
+ changed: [],
42
+ };
43
+ for (const path of diff.changed) {
44
+ const local = join(projectDir, ...path.split('/'));
45
+ let kind = 'clean';
46
+ if (existsSync(local)) {
47
+ const localHash = sha256(await readFile(local, 'utf-8'));
48
+ const oldHash = oldFiles[path];
49
+ if (localHash !== oldHash) {
50
+ // Local has diverged from the originally-generated content.
51
+ kind = 'conflict';
52
+ }
53
+ }
54
+ plan.changed.push({ path, kind });
55
+ }
56
+ return plan;
57
+ }
58
+ /**
59
+ * Render a plan as a human-readable summary.
60
+ */
61
+ export function formatPlan(plan) {
62
+ const lines = [];
63
+ lines.push(`Upgrade plan:`);
64
+ lines.push(` ${plan.added.length} added`);
65
+ lines.push(` ${plan.removed.length} removed`);
66
+ lines.push(` ${plan.changed.filter(c => c.kind === 'clean').length} clean-overwrite`);
67
+ lines.push(` ${plan.changed.filter(c => c.kind === 'conflict').length} conflict (will need manual resolution)`);
68
+ if (plan.changed.some(c => c.kind === 'conflict')) {
69
+ lines.push('');
70
+ lines.push('Conflicting files:');
71
+ for (const c of plan.changed.filter(x => x.kind === 'conflict')) {
72
+ lines.push(` - ${c.path}`);
73
+ }
74
+ }
75
+ return lines.join('\n');
76
+ }
77
+ /**
78
+ * Write Git-style inline conflict markers into the local file.
79
+ * Used when planUpgrade reports a 'conflict' entry and the user wants
80
+ * inline markers (the default).
81
+ */
82
+ export function inlineConflictMarkers(local, upstream) {
83
+ return [
84
+ '<<<<<<< current',
85
+ local,
86
+ '=======',
87
+ upstream,
88
+ '>>>>>>> upstream',
89
+ '',
90
+ ].join('\n');
91
+ }
92
+ /**
93
+ * Apply an upgrade plan. Returns the list of paths actually modified.
94
+ * Best-effort — caller should review the plan first via formatPlan().
95
+ */
96
+ export async function applyPlan(projectDir, plan, newContents, opts = {}) {
97
+ const modified = [];
98
+ const style = opts.conflictStyle ?? 'inline';
99
+ for (const path of plan.added) {
100
+ const target = join(projectDir, ...path.split('/'));
101
+ await writeFile(target, newContents[path] ?? '', 'utf-8');
102
+ modified.push(path);
103
+ }
104
+ for (const c of plan.changed) {
105
+ const target = join(projectDir, ...c.path.split('/'));
106
+ const upstream = newContents[c.path] ?? '';
107
+ if (c.kind === 'clean') {
108
+ await writeFile(target, upstream, 'utf-8');
109
+ modified.push(c.path);
110
+ }
111
+ else {
112
+ if (style === 'inline') {
113
+ const local = existsSync(target) ? await readFile(target, 'utf-8') : '';
114
+ await writeFile(target, inlineConflictMarkers(local, upstream), 'utf-8');
115
+ }
116
+ else {
117
+ await writeFile(target + '.rej', upstream, 'utf-8');
118
+ }
119
+ modified.push(c.path);
120
+ }
121
+ }
122
+ return modified;
123
+ }
124
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type SubcommandResult = {
2
+ code: number;
3
+ lines: string[];
4
+ };
5
+ /** Top-level dispatcher: `harness validate [path] [--skip-gcp] [--secret=NAME]`. */
6
+ export declare function validate(args: string[]): Promise<SubcommandResult>;
7
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AA0BA,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAsKjE,oFAAoF;AACpF,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+DxE"}