hunter-harness 0.1.3 → 0.2.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 (566) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +11 -0
  3. package/dist/bin.js +891 -271
  4. package/package.json +1 -1
  5. package/resources/harness/bundles/general/claude-code/.harness-build.json +6 -0
  6. package/resources/harness/{general → bundles/general/claude-code}/agents/harness-reviewer.md +2 -2
  7. package/resources/harness/{general → bundles/general/claude-code}/harness-archive/SKILL.md +1 -1
  8. package/resources/harness/{java → bundles/general/claude-code}/harness-codebase-map/SKILL.md +1 -1
  9. package/resources/harness/{java → bundles/general/claude-code}/harness-knowledge-ingest/SKILL.md +1 -1
  10. package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/reference.md +1 -1
  11. package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-query/SKILL.md +1 -1
  12. package/resources/harness/{general → bundles/general/claude-code}/harness-plan/SKILL.md +1 -1
  13. package/resources/harness/{java → bundles/general/claude-code}/harness-review/SKILL.md +8 -4
  14. package/resources/harness/{general → bundles/general/claude-code}/harness-review/checklist.md +3 -3
  15. package/resources/harness/{general → bundles/general/claude-code}/harness-run/SKILL.md +1 -1
  16. package/resources/harness/{general → bundles/general/claude-code}/harness-run/checklist.md +1 -1
  17. package/resources/harness/{general → bundles/general/claude-code}/harness-run/reference.md +2 -2
  18. package/resources/harness/{general → bundles/general/claude-code}/harness-submit/SKILL.md +1 -1
  19. package/resources/harness/{java → bundles/general/claude-code}/harness-sync/SKILL.md +2 -2
  20. package/resources/harness/{general → bundles/general/claude-code}/harness-sync/reference.md +7 -7
  21. package/resources/harness/{general → bundles/general/claude-code}/harness-test/SKILL.md +1 -1
  22. package/resources/harness/{general → bundles/general/claude-code}/harness-test/checklist.md +1 -1
  23. package/resources/harness/{java → bundles/general/claude-code}/scripts/harness_archive.py +2300 -2300
  24. package/resources/harness/{general → bundles/general/claude-code}/scripts/harness_deploy.py +74 -13
  25. package/resources/harness/{general → bundles/general/claude-code}/scripts/harness_events.py +680 -680
  26. package/resources/harness/{general → bundles/general/claude-code}/scripts/harness_ledger.py +660 -660
  27. package/resources/harness/{java → bundles/general/claude-code}/scripts/harness_preflight.py +765 -765
  28. package/resources/harness/{general → bundles/general/claude-code}/scripts/harness_service.py +1331 -1331
  29. package/resources/harness/bundles/general/codebuddy/.harness-build.json +6 -0
  30. package/resources/harness/bundles/general/codebuddy/agents/harness-evaluator.md +94 -0
  31. package/resources/harness/bundles/general/codebuddy/agents/harness-explorer.md +53 -0
  32. package/resources/harness/bundles/general/codebuddy/agents/harness-reviewer.md +52 -0
  33. package/resources/harness/bundles/general/codebuddy/harness-archive/SKILL.md +198 -0
  34. package/resources/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +95 -0
  35. package/resources/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +229 -0
  36. package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/reference.md +1 -1
  37. package/resources/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +147 -0
  38. package/resources/harness/bundles/general/codebuddy/harness-plan/SKILL.md +109 -0
  39. package/resources/harness/bundles/general/codebuddy/harness-review/SKILL.md +142 -0
  40. package/resources/harness/{java → bundles/general/codebuddy}/harness-review/checklist.md +3 -3
  41. package/resources/harness/bundles/general/codebuddy/harness-run/SKILL.md +113 -0
  42. package/resources/harness/bundles/general/codebuddy/harness-run/checklist.md +259 -0
  43. package/resources/harness/bundles/general/codebuddy/harness-run/reference.md +834 -0
  44. package/resources/harness/bundles/general/codebuddy/harness-submit/SKILL.md +142 -0
  45. package/resources/harness/bundles/general/codebuddy/harness-sync/SKILL.md +65 -0
  46. package/resources/harness/{java → bundles/general/codebuddy}/harness-sync/reference.md +7 -7
  47. package/resources/harness/bundles/general/codebuddy/harness-test/SKILL.md +160 -0
  48. package/resources/harness/bundles/general/codebuddy/harness-test/checklist.md +319 -0
  49. package/resources/harness/bundles/general/codebuddy/harness-test/reference.md +791 -0
  50. package/resources/harness/{general → bundles/general/codebuddy}/scripts/harness_archive.py +2300 -2300
  51. package/resources/harness/{java → bundles/general/codebuddy}/scripts/harness_deploy.py +74 -13
  52. package/resources/harness/{java → bundles/general/codebuddy}/scripts/harness_events.py +680 -680
  53. package/resources/harness/{java → bundles/general/codebuddy}/scripts/harness_ledger.py +660 -660
  54. package/resources/harness/{general → bundles/general/codebuddy}/scripts/harness_preflight.py +765 -765
  55. package/resources/harness/{java → bundles/general/codebuddy}/scripts/harness_service.py +1331 -1331
  56. package/resources/harness/bundles/general/codex/.harness-build.json +6 -0
  57. package/resources/harness/bundles/general/codex/CONTEXT.md +65 -0
  58. package/resources/harness/bundles/general/codex/README.md +478 -0
  59. package/resources/harness/bundles/general/codex/harness-archive/SKILL.md +198 -0
  60. package/resources/harness/bundles/general/codex/harness-archive/checklist.md +52 -0
  61. package/resources/harness/bundles/general/codex/harness-archive/reference.md +103 -0
  62. package/resources/harness/bundles/general/codex/harness-archive/scripts/gen-manifest.ps1 +31 -0
  63. package/resources/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +171 -0
  64. package/resources/harness/bundles/general/codex/harness-archive/templates/summary-data-template.json +128 -0
  65. package/resources/harness/bundles/general/codex/harness-codebase-map/SKILL.md +95 -0
  66. package/resources/harness/bundles/general/codex/harness-codebase-map/checklist.md +126 -0
  67. package/resources/harness/bundles/general/codex/harness-codebase-map/reference.md +364 -0
  68. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
  69. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/CONCERNS.md +49 -0
  70. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/CONVENTIONS.md +57 -0
  71. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
  72. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/STACK.md +55 -0
  73. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/STRUCTURE.md +69 -0
  74. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/TESTING.md +64 -0
  75. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/map-manifest.schema.json +73 -0
  76. package/resources/harness/bundles/general/codex/harness-codebase-map/templates/map-summary.md +64 -0
  77. package/resources/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +229 -0
  78. package/resources/harness/bundles/general/codex/harness-knowledge-ingest/design.md +842 -0
  79. package/resources/harness/bundles/general/codex/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
  80. package/resources/harness/bundles/general/codex/harness-knowledge-ingest/mcp-config.example.json +10 -0
  81. package/resources/harness/bundles/general/codex/harness-knowledge-ingest/reference.md +309 -0
  82. package/resources/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
  83. package/resources/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
  84. package/resources/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +147 -0
  85. package/resources/harness/bundles/general/codex/harness-plan/SKILL.md +109 -0
  86. package/resources/harness/bundles/general/codex/harness-plan/checklist.md +243 -0
  87. package/resources/harness/bundles/general/codex/harness-plan/protocols.md +124 -0
  88. package/resources/harness/bundles/general/codex/harness-plan/reference.md +376 -0
  89. package/resources/harness/bundles/general/codex/harness-review/SKILL.md +137 -0
  90. package/resources/harness/bundles/general/codex/harness-review/checklist.md +124 -0
  91. package/resources/harness/bundles/general/codex/harness-review/protocols.md +68 -0
  92. package/resources/harness/bundles/general/codex/harness-review/reference.md +86 -0
  93. package/resources/harness/bundles/general/codex/harness-run/SKILL.md +113 -0
  94. package/resources/harness/bundles/general/codex/harness-run/checklist.md +259 -0
  95. package/resources/harness/bundles/general/codex/harness-run/protocols.md +78 -0
  96. package/resources/harness/bundles/general/codex/harness-run/reference.md +834 -0
  97. package/resources/harness/bundles/general/codex/harness-submit/SKILL.md +142 -0
  98. package/resources/harness/bundles/general/codex/harness-submit/checklist.md +407 -0
  99. package/resources/harness/bundles/general/codex/harness-submit/reference.md +152 -0
  100. package/resources/harness/bundles/general/codex/harness-sync/SKILL.md +65 -0
  101. package/resources/harness/bundles/general/codex/harness-sync/reference.md +153 -0
  102. package/resources/harness/bundles/general/codex/harness-test/SKILL.md +160 -0
  103. package/resources/harness/bundles/general/codex/harness-test/checklist.md +319 -0
  104. package/resources/harness/bundles/general/codex/harness-test/pitfalls.md +260 -0
  105. package/resources/harness/bundles/general/codex/harness-test/reference.md +791 -0
  106. package/resources/harness/bundles/general/codex/protocols/archive-report-protocol.md +175 -0
  107. package/resources/harness/bundles/general/codex/protocols/evidence-based-reporting-protocol.md +134 -0
  108. package/resources/harness/bundles/general/codex/protocols/ledger-protocol.md +270 -0
  109. package/resources/harness/bundles/general/codex/protocols/powershell-protocol.md +181 -0
  110. package/resources/harness/bundles/general/codex/protocols/report-pipeline-protocol.md +150 -0
  111. package/resources/harness/bundles/general/codex/protocols/sensitive-info-protocol.md +92 -0
  112. package/resources/harness/bundles/general/codex/protocols/state-layout-protocol.md +131 -0
  113. package/resources/harness/bundles/general/codex/protocols/submit-protocol.md +78 -0
  114. package/resources/harness/bundles/general/codex/scripts/harness_archive.py +2319 -0
  115. package/resources/harness/bundles/general/codex/scripts/harness_deploy.py +674 -0
  116. package/resources/harness/bundles/general/codex/scripts/harness_events.py +680 -0
  117. package/resources/harness/bundles/general/codex/scripts/harness_ledger.py +671 -0
  118. package/resources/harness/bundles/general/codex/scripts/harness_preflight.py +780 -0
  119. package/resources/harness/bundles/general/codex/scripts/harness_service.py +1331 -0
  120. package/resources/harness/bundles/general/cursor/.harness-build.json +6 -0
  121. package/resources/harness/bundles/general/cursor/CONTEXT.md +65 -0
  122. package/resources/harness/bundles/general/cursor/README.md +478 -0
  123. package/resources/harness/bundles/general/cursor/harness-archive/SKILL.md +198 -0
  124. package/resources/harness/bundles/general/cursor/harness-archive/checklist.md +52 -0
  125. package/resources/harness/bundles/general/cursor/harness-archive/reference.md +103 -0
  126. package/resources/harness/bundles/general/cursor/harness-archive/scripts/gen-manifest.ps1 +31 -0
  127. package/resources/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +171 -0
  128. package/resources/harness/bundles/general/cursor/harness-archive/templates/summary-data-template.json +128 -0
  129. package/resources/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +95 -0
  130. package/resources/harness/bundles/general/cursor/harness-codebase-map/checklist.md +126 -0
  131. package/resources/harness/bundles/general/cursor/harness-codebase-map/reference.md +364 -0
  132. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
  133. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/CONCERNS.md +49 -0
  134. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/CONVENTIONS.md +57 -0
  135. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
  136. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/STACK.md +55 -0
  137. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/STRUCTURE.md +69 -0
  138. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/TESTING.md +64 -0
  139. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/map-manifest.schema.json +73 -0
  140. package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/map-summary.md +64 -0
  141. package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +229 -0
  142. package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/design.md +842 -0
  143. package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
  144. package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/mcp-config.example.json +10 -0
  145. package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/reference.md +309 -0
  146. package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
  147. package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
  148. package/resources/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +147 -0
  149. package/resources/harness/bundles/general/cursor/harness-plan/SKILL.md +109 -0
  150. package/resources/harness/bundles/general/cursor/harness-plan/checklist.md +243 -0
  151. package/resources/harness/bundles/general/cursor/harness-plan/protocols.md +124 -0
  152. package/resources/harness/bundles/general/cursor/harness-plan/reference.md +376 -0
  153. package/resources/harness/bundles/general/cursor/harness-review/SKILL.md +137 -0
  154. package/resources/harness/bundles/general/cursor/harness-review/checklist.md +124 -0
  155. package/resources/harness/bundles/general/cursor/harness-review/protocols.md +68 -0
  156. package/resources/harness/bundles/general/cursor/harness-review/reference.md +86 -0
  157. package/resources/harness/bundles/general/cursor/harness-run/SKILL.md +113 -0
  158. package/resources/harness/bundles/general/cursor/harness-run/checklist.md +259 -0
  159. package/resources/harness/bundles/general/cursor/harness-run/protocols.md +78 -0
  160. package/resources/harness/bundles/general/cursor/harness-run/reference.md +834 -0
  161. package/resources/harness/bundles/general/cursor/harness-submit/SKILL.md +142 -0
  162. package/resources/harness/bundles/general/cursor/harness-submit/checklist.md +407 -0
  163. package/resources/harness/bundles/general/cursor/harness-submit/reference.md +152 -0
  164. package/resources/harness/bundles/general/cursor/harness-sync/SKILL.md +65 -0
  165. package/resources/harness/bundles/general/cursor/harness-sync/reference.md +153 -0
  166. package/resources/harness/bundles/general/cursor/harness-test/SKILL.md +160 -0
  167. package/resources/harness/bundles/general/cursor/harness-test/checklist.md +319 -0
  168. package/resources/harness/bundles/general/cursor/harness-test/pitfalls.md +260 -0
  169. package/resources/harness/bundles/general/cursor/harness-test/reference.md +791 -0
  170. package/resources/harness/bundles/general/cursor/protocols/archive-report-protocol.md +175 -0
  171. package/resources/harness/bundles/general/cursor/protocols/evidence-based-reporting-protocol.md +134 -0
  172. package/resources/harness/bundles/general/cursor/protocols/ledger-protocol.md +270 -0
  173. package/resources/harness/bundles/general/cursor/protocols/powershell-protocol.md +181 -0
  174. package/resources/harness/bundles/general/cursor/protocols/report-pipeline-protocol.md +150 -0
  175. package/resources/harness/bundles/general/cursor/protocols/sensitive-info-protocol.md +92 -0
  176. package/resources/harness/bundles/general/cursor/protocols/state-layout-protocol.md +131 -0
  177. package/resources/harness/bundles/general/cursor/protocols/submit-protocol.md +78 -0
  178. package/resources/harness/bundles/general/cursor/scripts/harness_archive.py +2319 -0
  179. package/resources/harness/bundles/general/cursor/scripts/harness_deploy.py +674 -0
  180. package/resources/harness/bundles/general/cursor/scripts/harness_events.py +680 -0
  181. package/resources/harness/bundles/general/cursor/scripts/harness_ledger.py +671 -0
  182. package/resources/harness/bundles/general/cursor/scripts/harness_preflight.py +780 -0
  183. package/resources/harness/bundles/general/cursor/scripts/harness_service.py +1331 -0
  184. package/resources/harness/bundles/java/claude-code/.harness-build.json +6 -0
  185. package/resources/harness/bundles/java/claude-code/CONTEXT.md +65 -0
  186. package/resources/harness/bundles/java/claude-code/README.md +478 -0
  187. package/resources/harness/{java → bundles/java/claude-code}/agents/harness-reviewer.md +2 -2
  188. package/resources/harness/{java → bundles/java/claude-code}/harness-apidoc/SKILL.md +1 -1
  189. package/resources/harness/{java → bundles/java/claude-code}/harness-archive/SKILL.md +1 -1
  190. package/resources/harness/bundles/java/claude-code/harness-archive/checklist.md +52 -0
  191. package/resources/harness/bundles/java/claude-code/harness-archive/reference.md +103 -0
  192. package/resources/harness/bundles/java/claude-code/harness-archive/scripts/gen-manifest.ps1 +31 -0
  193. package/resources/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +171 -0
  194. package/resources/harness/bundles/java/claude-code/harness-archive/templates/summary-data-template.json +128 -0
  195. package/resources/harness/{general → bundles/java/claude-code}/harness-codebase-map/SKILL.md +1 -1
  196. package/resources/harness/bundles/java/claude-code/harness-codebase-map/checklist.md +126 -0
  197. package/resources/harness/bundles/java/claude-code/harness-codebase-map/reference.md +364 -0
  198. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
  199. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/CONCERNS.md +49 -0
  200. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/CONVENTIONS.md +57 -0
  201. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
  202. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/STACK.md +55 -0
  203. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/STRUCTURE.md +69 -0
  204. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/TESTING.md +64 -0
  205. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/map-manifest.schema.json +73 -0
  206. package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/map-summary.md +64 -0
  207. package/resources/harness/{general → bundles/java/claude-code}/harness-knowledge-ingest/SKILL.md +1 -1
  208. package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/design.md +842 -0
  209. package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
  210. package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/mcp-config.example.json +10 -0
  211. package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/reference.md +309 -0
  212. package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
  213. package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
  214. package/resources/harness/{java → bundles/java/claude-code}/harness-knowledge-query/SKILL.md +1 -1
  215. package/resources/harness/{java → bundles/java/claude-code}/harness-package/SKILL.md +1 -1
  216. package/resources/harness/{java → bundles/java/claude-code}/harness-package/reference.md +1 -1
  217. package/resources/harness/{java → bundles/java/claude-code}/harness-plan/SKILL.md +1 -1
  218. package/resources/harness/bundles/java/claude-code/harness-plan/checklist.md +243 -0
  219. package/resources/harness/bundles/java/claude-code/harness-plan/protocols.md +124 -0
  220. package/resources/harness/bundles/java/claude-code/harness-plan/reference.md +376 -0
  221. package/resources/harness/{general → bundles/java/claude-code}/harness-review/SKILL.md +8 -4
  222. package/resources/harness/bundles/java/claude-code/harness-review/checklist.md +124 -0
  223. package/resources/harness/bundles/java/claude-code/harness-review/protocols.md +68 -0
  224. package/resources/harness/bundles/java/claude-code/harness-review/reference.md +86 -0
  225. package/resources/harness/{java → bundles/java/claude-code}/harness-run/SKILL.md +1 -1
  226. package/resources/harness/{java → bundles/java/claude-code}/harness-run/checklist.md +1 -1
  227. package/resources/harness/bundles/java/claude-code/harness-run/protocols.md +78 -0
  228. package/resources/harness/{java → bundles/java/claude-code}/harness-run/reference.md +2 -2
  229. package/resources/harness/{java → bundles/java/claude-code}/harness-submit/SKILL.md +1 -1
  230. package/resources/harness/bundles/java/claude-code/harness-submit/checklist.md +407 -0
  231. package/resources/harness/bundles/java/claude-code/harness-submit/reference.md +152 -0
  232. package/resources/harness/{general → bundles/java/claude-code}/harness-sync/SKILL.md +2 -2
  233. package/resources/harness/bundles/java/claude-code/harness-sync/reference.md +153 -0
  234. package/resources/harness/{java → bundles/java/claude-code}/harness-test/SKILL.md +1 -1
  235. package/resources/harness/{java → bundles/java/claude-code}/harness-test/checklist.md +316 -316
  236. package/resources/harness/bundles/java/claude-code/harness-test/pitfalls.md +260 -0
  237. package/resources/harness/{java → bundles/java/claude-code}/harness-test/reference.md +788 -788
  238. package/resources/harness/bundles/java/claude-code/protocols/archive-report-protocol.md +175 -0
  239. package/resources/harness/bundles/java/claude-code/protocols/evidence-based-reporting-protocol.md +134 -0
  240. package/resources/harness/bundles/java/claude-code/protocols/ledger-protocol.md +270 -0
  241. package/resources/harness/bundles/java/claude-code/protocols/powershell-protocol.md +181 -0
  242. package/resources/harness/bundles/java/claude-code/protocols/report-pipeline-protocol.md +150 -0
  243. package/resources/harness/bundles/java/claude-code/protocols/sensitive-info-protocol.md +92 -0
  244. package/resources/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +131 -0
  245. package/resources/harness/bundles/java/claude-code/protocols/submit-protocol.md +78 -0
  246. package/resources/harness/bundles/java/claude-code/scripts/harness_archive.py +2319 -0
  247. package/resources/harness/bundles/java/claude-code/scripts/harness_deploy.py +674 -0
  248. package/resources/harness/bundles/java/claude-code/scripts/harness_events.py +680 -0
  249. package/resources/harness/bundles/java/claude-code/scripts/harness_ledger.py +671 -0
  250. package/resources/harness/bundles/java/claude-code/scripts/harness_preflight.py +780 -0
  251. package/resources/harness/bundles/java/claude-code/scripts/harness_service.py +1331 -0
  252. package/resources/harness/bundles/java/codebuddy/.harness-build.json +6 -0
  253. package/resources/harness/bundles/java/codebuddy/CONTEXT.md +65 -0
  254. package/resources/harness/bundles/java/codebuddy/README.md +478 -0
  255. package/resources/harness/bundles/java/codebuddy/agents/harness-evaluator.md +94 -0
  256. package/resources/harness/bundles/java/codebuddy/agents/harness-explorer.md +53 -0
  257. package/resources/harness/bundles/java/codebuddy/agents/harness-reviewer.md +52 -0
  258. package/resources/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +68 -0
  259. package/resources/harness/bundles/java/codebuddy/harness-apidoc/checklist.md +142 -0
  260. package/resources/harness/bundles/java/codebuddy/harness-apidoc/reference.md +233 -0
  261. package/resources/harness/bundles/java/codebuddy/harness-archive/SKILL.md +198 -0
  262. package/resources/harness/bundles/java/codebuddy/harness-archive/checklist.md +52 -0
  263. package/resources/harness/bundles/java/codebuddy/harness-archive/reference.md +103 -0
  264. package/resources/harness/bundles/java/codebuddy/harness-archive/scripts/gen-manifest.ps1 +31 -0
  265. package/resources/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +171 -0
  266. package/resources/harness/bundles/java/codebuddy/harness-archive/templates/summary-data-template.json +128 -0
  267. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +95 -0
  268. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/checklist.md +126 -0
  269. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/reference.md +364 -0
  270. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
  271. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/CONCERNS.md +49 -0
  272. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/CONVENTIONS.md +57 -0
  273. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
  274. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/STACK.md +55 -0
  275. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/STRUCTURE.md +69 -0
  276. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/TESTING.md +64 -0
  277. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/map-manifest.schema.json +73 -0
  278. package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/map-summary.md +64 -0
  279. package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +229 -0
  280. package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/design.md +842 -0
  281. package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
  282. package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/mcp-config.example.json +10 -0
  283. package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/reference.md +309 -0
  284. package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
  285. package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
  286. package/resources/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +147 -0
  287. package/resources/harness/bundles/java/codebuddy/harness-package/SKILL.md +69 -0
  288. package/resources/harness/bundles/java/codebuddy/harness-package/checklist.md +322 -0
  289. package/resources/harness/bundles/java/codebuddy/harness-package/reference.md +210 -0
  290. package/resources/harness/bundles/java/codebuddy/harness-plan/SKILL.md +109 -0
  291. package/resources/harness/bundles/java/codebuddy/harness-plan/checklist.md +243 -0
  292. package/resources/harness/bundles/java/codebuddy/harness-plan/protocols.md +124 -0
  293. package/resources/harness/bundles/java/codebuddy/harness-plan/reference.md +376 -0
  294. package/resources/harness/bundles/java/codebuddy/harness-review/SKILL.md +142 -0
  295. package/resources/harness/bundles/java/codebuddy/harness-review/checklist.md +124 -0
  296. package/resources/harness/bundles/java/codebuddy/harness-review/protocols.md +68 -0
  297. package/resources/harness/bundles/java/codebuddy/harness-review/reference.md +86 -0
  298. package/resources/harness/bundles/java/codebuddy/harness-run/SKILL.md +129 -0
  299. package/resources/harness/bundles/java/codebuddy/harness-run/checklist.md +250 -0
  300. package/resources/harness/bundles/java/codebuddy/harness-run/protocols.md +78 -0
  301. package/resources/harness/bundles/java/codebuddy/harness-run/reference.md +814 -0
  302. package/resources/harness/bundles/java/codebuddy/harness-submit/SKILL.md +149 -0
  303. package/resources/harness/bundles/java/codebuddy/harness-submit/checklist.md +407 -0
  304. package/resources/harness/bundles/java/codebuddy/harness-submit/reference.md +152 -0
  305. package/resources/harness/bundles/java/codebuddy/harness-sync/SKILL.md +65 -0
  306. package/resources/harness/bundles/java/codebuddy/harness-sync/reference.md +153 -0
  307. package/resources/harness/bundles/java/codebuddy/harness-test/SKILL.md +172 -0
  308. package/resources/harness/bundles/java/codebuddy/harness-test/checklist.md +317 -0
  309. package/resources/harness/bundles/java/codebuddy/harness-test/pitfalls-java.md +16 -0
  310. package/resources/harness/bundles/java/codebuddy/harness-test/pitfalls.md +260 -0
  311. package/resources/harness/bundles/java/codebuddy/harness-test/reference.md +788 -0
  312. package/resources/harness/bundles/java/codebuddy/protocols/archive-report-protocol.md +175 -0
  313. package/resources/harness/bundles/java/codebuddy/protocols/evidence-based-reporting-protocol.md +134 -0
  314. package/resources/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +270 -0
  315. package/resources/harness/bundles/java/codebuddy/protocols/powershell-protocol.md +181 -0
  316. package/resources/harness/bundles/java/codebuddy/protocols/report-pipeline-protocol.md +150 -0
  317. package/resources/harness/bundles/java/codebuddy/protocols/sensitive-info-protocol.md +92 -0
  318. package/resources/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +131 -0
  319. package/resources/harness/bundles/java/codebuddy/protocols/submit-protocol.md +78 -0
  320. package/resources/harness/bundles/java/codebuddy/scripts/harness_archive.py +2319 -0
  321. package/resources/harness/bundles/java/codebuddy/scripts/harness_deploy.py +674 -0
  322. package/resources/harness/bundles/java/codebuddy/scripts/harness_events.py +680 -0
  323. package/resources/harness/bundles/java/codebuddy/scripts/harness_ledger.py +671 -0
  324. package/resources/harness/bundles/java/codebuddy/scripts/harness_preflight.py +780 -0
  325. package/resources/harness/bundles/java/codebuddy/scripts/harness_service.py +1331 -0
  326. package/resources/harness/bundles/java/codex/.harness-build.json +6 -0
  327. package/resources/harness/bundles/java/codex/CONTEXT.md +65 -0
  328. package/resources/harness/bundles/java/codex/README.md +478 -0
  329. package/resources/harness/bundles/java/codex/harness-apidoc/SKILL.md +68 -0
  330. package/resources/harness/bundles/java/codex/harness-apidoc/checklist.md +142 -0
  331. package/resources/harness/bundles/java/codex/harness-apidoc/reference.md +233 -0
  332. package/resources/harness/bundles/java/codex/harness-archive/SKILL.md +198 -0
  333. package/resources/harness/bundles/java/codex/harness-archive/checklist.md +52 -0
  334. package/resources/harness/bundles/java/codex/harness-archive/reference.md +103 -0
  335. package/resources/harness/bundles/java/codex/harness-archive/scripts/gen-manifest.ps1 +31 -0
  336. package/resources/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +171 -0
  337. package/resources/harness/bundles/java/codex/harness-archive/templates/summary-data-template.json +128 -0
  338. package/resources/harness/bundles/java/codex/harness-codebase-map/SKILL.md +95 -0
  339. package/resources/harness/bundles/java/codex/harness-codebase-map/checklist.md +126 -0
  340. package/resources/harness/bundles/java/codex/harness-codebase-map/reference.md +364 -0
  341. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
  342. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/CONCERNS.md +49 -0
  343. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/CONVENTIONS.md +57 -0
  344. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
  345. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/STACK.md +55 -0
  346. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/STRUCTURE.md +69 -0
  347. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/TESTING.md +64 -0
  348. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/map-manifest.schema.json +73 -0
  349. package/resources/harness/bundles/java/codex/harness-codebase-map/templates/map-summary.md +64 -0
  350. package/resources/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +229 -0
  351. package/resources/harness/bundles/java/codex/harness-knowledge-ingest/design.md +842 -0
  352. package/resources/harness/bundles/java/codex/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
  353. package/resources/harness/bundles/java/codex/harness-knowledge-ingest/mcp-config.example.json +10 -0
  354. package/resources/harness/bundles/java/codex/harness-knowledge-ingest/reference.md +309 -0
  355. package/resources/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
  356. package/resources/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
  357. package/resources/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +147 -0
  358. package/resources/harness/bundles/java/codex/harness-package/SKILL.md +69 -0
  359. package/resources/harness/bundles/java/codex/harness-package/checklist.md +322 -0
  360. package/resources/harness/bundles/java/codex/harness-package/reference.md +210 -0
  361. package/resources/harness/bundles/java/codex/harness-plan/SKILL.md +109 -0
  362. package/resources/harness/bundles/java/codex/harness-plan/checklist.md +243 -0
  363. package/resources/harness/bundles/java/codex/harness-plan/protocols.md +124 -0
  364. package/resources/harness/bundles/java/codex/harness-plan/reference.md +376 -0
  365. package/resources/harness/bundles/java/codex/harness-review/SKILL.md +137 -0
  366. package/resources/harness/bundles/java/codex/harness-review/checklist.md +124 -0
  367. package/resources/harness/bundles/java/codex/harness-review/protocols.md +68 -0
  368. package/resources/harness/bundles/java/codex/harness-review/reference.md +86 -0
  369. package/resources/harness/bundles/java/codex/harness-run/SKILL.md +129 -0
  370. package/resources/harness/bundles/java/codex/harness-run/checklist.md +250 -0
  371. package/resources/harness/bundles/java/codex/harness-run/protocols.md +78 -0
  372. package/resources/harness/bundles/java/codex/harness-run/reference.md +814 -0
  373. package/resources/harness/bundles/java/codex/harness-submit/SKILL.md +149 -0
  374. package/resources/harness/bundles/java/codex/harness-submit/checklist.md +407 -0
  375. package/resources/harness/bundles/java/codex/harness-submit/reference.md +152 -0
  376. package/resources/harness/bundles/java/codex/harness-sync/SKILL.md +65 -0
  377. package/resources/harness/bundles/java/codex/harness-sync/reference.md +153 -0
  378. package/resources/harness/bundles/java/codex/harness-test/SKILL.md +172 -0
  379. package/resources/harness/bundles/java/codex/harness-test/checklist.md +317 -0
  380. package/resources/harness/bundles/java/codex/harness-test/pitfalls-java.md +16 -0
  381. package/resources/harness/bundles/java/codex/harness-test/pitfalls.md +260 -0
  382. package/resources/harness/bundles/java/codex/harness-test/reference.md +788 -0
  383. package/resources/harness/bundles/java/codex/protocols/archive-report-protocol.md +175 -0
  384. package/resources/harness/bundles/java/codex/protocols/evidence-based-reporting-protocol.md +134 -0
  385. package/resources/harness/bundles/java/codex/protocols/ledger-protocol.md +270 -0
  386. package/resources/harness/bundles/java/codex/protocols/powershell-protocol.md +181 -0
  387. package/resources/harness/bundles/java/codex/protocols/report-pipeline-protocol.md +150 -0
  388. package/resources/harness/bundles/java/codex/protocols/sensitive-info-protocol.md +92 -0
  389. package/resources/harness/bundles/java/codex/protocols/state-layout-protocol.md +131 -0
  390. package/resources/harness/bundles/java/codex/protocols/submit-protocol.md +78 -0
  391. package/resources/harness/bundles/java/codex/scripts/harness_archive.py +2319 -0
  392. package/resources/harness/bundles/java/codex/scripts/harness_deploy.py +674 -0
  393. package/resources/harness/bundles/java/codex/scripts/harness_events.py +680 -0
  394. package/resources/harness/bundles/java/codex/scripts/harness_ledger.py +671 -0
  395. package/resources/harness/bundles/java/codex/scripts/harness_preflight.py +780 -0
  396. package/resources/harness/bundles/java/codex/scripts/harness_service.py +1331 -0
  397. package/resources/harness/bundles/java/cursor/.harness-build.json +6 -0
  398. package/resources/harness/bundles/java/cursor/CONTEXT.md +65 -0
  399. package/resources/harness/bundles/java/cursor/README.md +478 -0
  400. package/resources/harness/bundles/java/cursor/harness-apidoc/SKILL.md +68 -0
  401. package/resources/harness/bundles/java/cursor/harness-apidoc/checklist.md +142 -0
  402. package/resources/harness/bundles/java/cursor/harness-apidoc/reference.md +233 -0
  403. package/resources/harness/bundles/java/cursor/harness-archive/SKILL.md +198 -0
  404. package/resources/harness/bundles/java/cursor/harness-archive/checklist.md +52 -0
  405. package/resources/harness/bundles/java/cursor/harness-archive/reference.md +103 -0
  406. package/resources/harness/bundles/java/cursor/harness-archive/scripts/gen-manifest.ps1 +31 -0
  407. package/resources/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +171 -0
  408. package/resources/harness/bundles/java/cursor/harness-archive/templates/summary-data-template.json +128 -0
  409. package/resources/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +95 -0
  410. package/resources/harness/bundles/java/cursor/harness-codebase-map/checklist.md +126 -0
  411. package/resources/harness/bundles/java/cursor/harness-codebase-map/reference.md +364 -0
  412. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
  413. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/CONCERNS.md +49 -0
  414. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/CONVENTIONS.md +57 -0
  415. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
  416. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/STACK.md +55 -0
  417. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/STRUCTURE.md +69 -0
  418. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/TESTING.md +64 -0
  419. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/map-manifest.schema.json +73 -0
  420. package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/map-summary.md +64 -0
  421. package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +229 -0
  422. package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/design.md +842 -0
  423. package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
  424. package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/mcp-config.example.json +10 -0
  425. package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/reference.md +309 -0
  426. package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
  427. package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
  428. package/resources/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +147 -0
  429. package/resources/harness/bundles/java/cursor/harness-package/SKILL.md +69 -0
  430. package/resources/harness/bundles/java/cursor/harness-package/checklist.md +322 -0
  431. package/resources/harness/bundles/java/cursor/harness-package/reference.md +210 -0
  432. package/resources/harness/bundles/java/cursor/harness-plan/SKILL.md +109 -0
  433. package/resources/harness/bundles/java/cursor/harness-plan/checklist.md +243 -0
  434. package/resources/harness/bundles/java/cursor/harness-plan/protocols.md +124 -0
  435. package/resources/harness/bundles/java/cursor/harness-plan/reference.md +376 -0
  436. package/resources/harness/bundles/java/cursor/harness-review/SKILL.md +137 -0
  437. package/resources/harness/bundles/java/cursor/harness-review/checklist.md +124 -0
  438. package/resources/harness/bundles/java/cursor/harness-review/protocols.md +68 -0
  439. package/resources/harness/bundles/java/cursor/harness-review/reference.md +86 -0
  440. package/resources/harness/bundles/java/cursor/harness-run/SKILL.md +129 -0
  441. package/resources/harness/bundles/java/cursor/harness-run/checklist.md +250 -0
  442. package/resources/harness/bundles/java/cursor/harness-run/protocols.md +78 -0
  443. package/resources/harness/bundles/java/cursor/harness-run/reference.md +814 -0
  444. package/resources/harness/bundles/java/cursor/harness-submit/SKILL.md +149 -0
  445. package/resources/harness/bundles/java/cursor/harness-submit/checklist.md +407 -0
  446. package/resources/harness/bundles/java/cursor/harness-submit/reference.md +152 -0
  447. package/resources/harness/bundles/java/cursor/harness-sync/SKILL.md +65 -0
  448. package/resources/harness/bundles/java/cursor/harness-sync/reference.md +153 -0
  449. package/resources/harness/bundles/java/cursor/harness-test/SKILL.md +172 -0
  450. package/resources/harness/bundles/java/cursor/harness-test/checklist.md +317 -0
  451. package/resources/harness/bundles/java/cursor/harness-test/pitfalls-java.md +16 -0
  452. package/resources/harness/bundles/java/cursor/harness-test/pitfalls.md +260 -0
  453. package/resources/harness/bundles/java/cursor/harness-test/reference.md +788 -0
  454. package/resources/harness/bundles/java/cursor/protocols/archive-report-protocol.md +175 -0
  455. package/resources/harness/bundles/java/cursor/protocols/evidence-based-reporting-protocol.md +134 -0
  456. package/resources/harness/bundles/java/cursor/protocols/ledger-protocol.md +270 -0
  457. package/resources/harness/bundles/java/cursor/protocols/powershell-protocol.md +181 -0
  458. package/resources/harness/bundles/java/cursor/protocols/report-pipeline-protocol.md +150 -0
  459. package/resources/harness/bundles/java/cursor/protocols/sensitive-info-protocol.md +92 -0
  460. package/resources/harness/bundles/java/cursor/protocols/state-layout-protocol.md +131 -0
  461. package/resources/harness/bundles/java/cursor/protocols/submit-protocol.md +78 -0
  462. package/resources/harness/bundles/java/cursor/scripts/harness_archive.py +2319 -0
  463. package/resources/harness/bundles/java/cursor/scripts/harness_deploy.py +674 -0
  464. package/resources/harness/bundles/java/cursor/scripts/harness_events.py +680 -0
  465. package/resources/harness/bundles/java/cursor/scripts/harness_ledger.py +671 -0
  466. package/resources/harness/bundles/java/cursor/scripts/harness_preflight.py +780 -0
  467. package/resources/harness/bundles/java/cursor/scripts/harness_service.py +1331 -0
  468. package/resources/harness/manifests/{general.json → general/claude-code.json} +27 -26
  469. package/resources/harness/manifests/general/codebuddy.json +277 -0
  470. package/resources/harness/manifests/general/codex.json +265 -0
  471. package/resources/harness/manifests/general/cursor.json +265 -0
  472. package/resources/harness/manifests/{java.json → java/claude-code.json} +31 -30
  473. package/resources/harness/manifests/java/codebuddy.json +305 -0
  474. package/resources/harness/manifests/java/codex.json +293 -0
  475. package/resources/harness/manifests/java/cursor.json +293 -0
  476. package/resources/harness/general/.harness-build.json +0 -5
  477. package/resources/harness/java/.harness-build.json +0 -5
  478. /package/resources/harness/{general → bundles/general/claude-code}/CONTEXT.md +0 -0
  479. /package/resources/harness/{general → bundles/general/claude-code}/README.md +0 -0
  480. /package/resources/harness/{general → bundles/general/claude-code}/agents/harness-evaluator.md +0 -0
  481. /package/resources/harness/{general → bundles/general/claude-code}/agents/harness-explorer.md +0 -0
  482. /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/checklist.md +0 -0
  483. /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/reference.md +0 -0
  484. /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/scripts/gen-manifest.ps1 +0 -0
  485. /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/templates/render-summary.mjs +0 -0
  486. /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/templates/summary-data-template.json +0 -0
  487. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/checklist.md +0 -0
  488. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/reference.md +0 -0
  489. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/ARCHITECTURE.md +0 -0
  490. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/CONCERNS.md +0 -0
  491. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/CONVENTIONS.md +0 -0
  492. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/INTEGRATIONS.md +0 -0
  493. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/STACK.md +0 -0
  494. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/STRUCTURE.md +0 -0
  495. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/TESTING.md +0 -0
  496. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/map-manifest.schema.json +0 -0
  497. /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/map-summary.md +0 -0
  498. /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/design.md +0 -0
  499. /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -0
  500. /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/mcp-config.example.json +0 -0
  501. /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -0
  502. /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -0
  503. /package/resources/harness/{general → bundles/general/claude-code}/harness-plan/checklist.md +0 -0
  504. /package/resources/harness/{general → bundles/general/claude-code}/harness-plan/protocols.md +0 -0
  505. /package/resources/harness/{general → bundles/general/claude-code}/harness-plan/reference.md +0 -0
  506. /package/resources/harness/{general → bundles/general/claude-code}/harness-review/protocols.md +0 -0
  507. /package/resources/harness/{general → bundles/general/claude-code}/harness-review/reference.md +0 -0
  508. /package/resources/harness/{general → bundles/general/claude-code}/harness-run/protocols.md +0 -0
  509. /package/resources/harness/{general → bundles/general/claude-code}/harness-submit/checklist.md +0 -0
  510. /package/resources/harness/{general → bundles/general/claude-code}/harness-submit/reference.md +0 -0
  511. /package/resources/harness/{general → bundles/general/claude-code}/harness-test/pitfalls.md +0 -0
  512. /package/resources/harness/{general → bundles/general/claude-code}/harness-test/reference.md +0 -0
  513. /package/resources/harness/{general → bundles/general/claude-code}/protocols/archive-report-protocol.md +0 -0
  514. /package/resources/harness/{general → bundles/general/claude-code}/protocols/evidence-based-reporting-protocol.md +0 -0
  515. /package/resources/harness/{general → bundles/general/claude-code}/protocols/ledger-protocol.md +0 -0
  516. /package/resources/harness/{general → bundles/general/claude-code}/protocols/powershell-protocol.md +0 -0
  517. /package/resources/harness/{general → bundles/general/claude-code}/protocols/report-pipeline-protocol.md +0 -0
  518. /package/resources/harness/{general → bundles/general/claude-code}/protocols/sensitive-info-protocol.md +0 -0
  519. /package/resources/harness/{general → bundles/general/claude-code}/protocols/state-layout-protocol.md +0 -0
  520. /package/resources/harness/{general → bundles/general/claude-code}/protocols/submit-protocol.md +0 -0
  521. /package/resources/harness/{java → bundles/general/codebuddy}/CONTEXT.md +0 -0
  522. /package/resources/harness/{java → bundles/general/codebuddy}/README.md +0 -0
  523. /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/checklist.md +0 -0
  524. /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/reference.md +0 -0
  525. /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/scripts/gen-manifest.ps1 +0 -0
  526. /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/templates/render-summary.mjs +0 -0
  527. /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/templates/summary-data-template.json +0 -0
  528. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/checklist.md +0 -0
  529. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/reference.md +0 -0
  530. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/ARCHITECTURE.md +0 -0
  531. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/CONCERNS.md +0 -0
  532. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/CONVENTIONS.md +0 -0
  533. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/INTEGRATIONS.md +0 -0
  534. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/STACK.md +0 -0
  535. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/STRUCTURE.md +0 -0
  536. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/TESTING.md +0 -0
  537. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/map-manifest.schema.json +0 -0
  538. /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/map-summary.md +0 -0
  539. /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/design.md +0 -0
  540. /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -0
  541. /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/mcp-config.example.json +0 -0
  542. /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -0
  543. /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -0
  544. /package/resources/harness/{java → bundles/general/codebuddy}/harness-plan/checklist.md +0 -0
  545. /package/resources/harness/{java → bundles/general/codebuddy}/harness-plan/protocols.md +0 -0
  546. /package/resources/harness/{java → bundles/general/codebuddy}/harness-plan/reference.md +0 -0
  547. /package/resources/harness/{java → bundles/general/codebuddy}/harness-review/protocols.md +0 -0
  548. /package/resources/harness/{java → bundles/general/codebuddy}/harness-review/reference.md +0 -0
  549. /package/resources/harness/{java → bundles/general/codebuddy}/harness-run/protocols.md +0 -0
  550. /package/resources/harness/{java → bundles/general/codebuddy}/harness-submit/checklist.md +0 -0
  551. /package/resources/harness/{java → bundles/general/codebuddy}/harness-submit/reference.md +0 -0
  552. /package/resources/harness/{java → bundles/general/codebuddy}/harness-test/pitfalls.md +0 -0
  553. /package/resources/harness/{java → bundles/general/codebuddy}/protocols/archive-report-protocol.md +0 -0
  554. /package/resources/harness/{java → bundles/general/codebuddy}/protocols/evidence-based-reporting-protocol.md +0 -0
  555. /package/resources/harness/{java → bundles/general/codebuddy}/protocols/ledger-protocol.md +0 -0
  556. /package/resources/harness/{java → bundles/general/codebuddy}/protocols/powershell-protocol.md +0 -0
  557. /package/resources/harness/{java → bundles/general/codebuddy}/protocols/report-pipeline-protocol.md +0 -0
  558. /package/resources/harness/{java → bundles/general/codebuddy}/protocols/sensitive-info-protocol.md +0 -0
  559. /package/resources/harness/{java → bundles/general/codebuddy}/protocols/state-layout-protocol.md +0 -0
  560. /package/resources/harness/{java → bundles/general/codebuddy}/protocols/submit-protocol.md +0 -0
  561. /package/resources/harness/{java → bundles/java/claude-code}/agents/harness-evaluator.md +0 -0
  562. /package/resources/harness/{java → bundles/java/claude-code}/agents/harness-explorer.md +0 -0
  563. /package/resources/harness/{java → bundles/java/claude-code}/harness-apidoc/checklist.md +0 -0
  564. /package/resources/harness/{java → bundles/java/claude-code}/harness-apidoc/reference.md +0 -0
  565. /package/resources/harness/{java → bundles/java/claude-code}/harness-package/checklist.md +0 -0
  566. /package/resources/harness/{java → bundles/java/claude-code}/harness-test/pitfalls-java.md +0 -0
package/dist/bin.js CHANGED
@@ -567,16 +567,29 @@ import { z as z9 } from "zod";
567
567
  var projectIdSchema = z9.string().regex(/^prj_[A-Za-z0-9_-]+$/);
568
568
  var tokenEnvSchema = z9.string().regex(/^[A-Z_][A-Z0-9_]*$/);
569
569
  var httpsUrlSchema = z9.url().refine((value) => new URL(value).protocol === "https:", "server URL must use HTTPS");
570
+ var HARNESS_AGENT_ORDER = [
571
+ "claude-code",
572
+ "codex",
573
+ "cursor",
574
+ "codebuddy"
575
+ ];
576
+ var harnessAgentSchema = z9.enum(HARNESS_AGENT_ORDER);
577
+ var codebuddySurfaceSchema = z9.enum(["both", "ide", "cli"]);
578
+ function sortHarnessAgents(agents) {
579
+ return HARNESS_AGENT_ORDER.filter((agent) => agents.includes(agent));
580
+ }
570
581
  var adapterNameSchema = z9.enum([
571
582
  "claude-code",
572
583
  "codex",
573
584
  "cursor",
585
+ "codebuddy",
574
586
  "generic",
575
587
  "mcp"
576
588
  ]);
577
589
  var initConfigSchema = z9.object({
578
- adapter: adapterNameSchema,
590
+ agents: z9.array(harnessAgentSchema).min(1),
579
591
  profile: z9.enum(["general", "java"]),
592
+ codebuddy_surface: codebuddySurfaceSchema.default("both"),
580
593
  server_url: httpsUrlSchema.nullable().optional(),
581
594
  token_env: tokenEnvSchema.nullable().optional(),
582
595
  project_id: projectIdSchema.nullable().optional(),
@@ -603,7 +616,12 @@ var projectConfigSchema = z9.object({
603
616
  }).strict(),
604
617
  adapters: z9.object({
605
618
  enabled: z9.array(adapterNameSchema).min(1)
606
- }).strict()
619
+ }).strict(),
620
+ adapter_options: z9.object({
621
+ codebuddy: z9.object({
622
+ surface: codebuddySurfaceSchema
623
+ }).strict()
624
+ }).strict().optional()
607
625
  }).strict();
608
626
 
609
627
  // ../contracts/dist/dashboard.js
@@ -817,8 +835,8 @@ async function assertNoSymlinks(root, relativePath) {
817
835
  for (const segment of normalized.split("/")) {
818
836
  current = join(current, segment);
819
837
  try {
820
- const stat6 = await lstat(current);
821
- if (stat6.isSymbolicLink()) {
838
+ const stat5 = await lstat(current);
839
+ if (stat5.isSymbolicLink()) {
822
840
  throw new UnsafePathError("symbolic links are not managed");
823
841
  }
824
842
  } catch (error) {
@@ -1063,12 +1081,12 @@ function renderBlock(content, newline) {
1063
1081
  return MANAGED_BLOCK_START + newline + normalized + newline + MANAGED_BLOCK_END;
1064
1082
  }
1065
1083
  function extractManagedBlock(content) {
1066
- if (validateMarkers(content) === "absent") {
1067
- return null;
1084
+ if (validateMarkers(content) === "present") {
1085
+ const start = content.indexOf(MANAGED_BLOCK_START) + MANAGED_BLOCK_START.length;
1086
+ const end = content.indexOf(MANAGED_BLOCK_END);
1087
+ return content.slice(start, end).replace(/^\r?\n/, "").replace(/\r?\n$/, "");
1068
1088
  }
1069
- const start = content.indexOf(MANAGED_BLOCK_START) + MANAGED_BLOCK_START.length;
1070
- const end = content.indexOf(MANAGED_BLOCK_END);
1071
- return content.slice(start, end).replace(/^\r?\n/, "").replace(/\r?\n$/, "");
1089
+ return extractSingleManagedBlockById(content)?.content ?? null;
1072
1090
  }
1073
1091
  function upsertManagedBlock(original, content) {
1074
1092
  const newline = original.includes("\r\n") ? "\r\n" : "\n";
@@ -1094,25 +1112,34 @@ function removeManagedBlock(original) {
1094
1112
  const after = original.slice(end).replace(/^(?:\r?\n){1,2}/, "");
1095
1113
  return before + after;
1096
1114
  }
1097
- function refreshManagedBlock(original, blockContent) {
1098
- const starts = markerCount(original, MANAGED_BLOCK_START);
1099
- const ends = markerCount(original, MANAGED_BLOCK_END);
1100
- const absent = starts === 0 && ends === 0;
1101
- const malformed = !absent && (starts !== 1 || ends !== 1 || original.indexOf(MANAGED_BLOCK_START) > original.indexOf(MANAGED_BLOCK_END));
1102
- if (malformed) {
1103
- return { content: original, action: "preserved_conflict", conflict: true };
1104
- }
1105
- const action = absent ? "appended" : "refreshed";
1106
- return { content: upsertManagedBlock(original, blockContent), action, conflict: false };
1107
- }
1108
1115
  function escapeRe(value) {
1109
1116
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1110
1117
  }
1111
1118
  var startById = (id) => `<!-- hunter-harness:start id=${id} -->`;
1112
1119
  var endById = (id) => `<!-- hunter-harness:end id=${id} -->`;
1120
+ function extractSingleManagedBlockById(content) {
1121
+ const matches = [...content.matchAll(/<!-- hunter-harness:start id=([A-Za-z0-9_-]+) -->/g)];
1122
+ if (matches.length !== 1)
1123
+ return null;
1124
+ const id = matches[0]?.[1];
1125
+ if (id === void 0)
1126
+ return null;
1127
+ const start = startById(id);
1128
+ const end = endById(id);
1129
+ if (markerCount(content, start) !== 1 || markerCount(content, end) !== 1 || content.indexOf(start) > content.indexOf(end)) {
1130
+ throw new Error("managed block markers are malformed or duplicated");
1131
+ }
1132
+ const bodyStart = content.indexOf(start) + start.length;
1133
+ const bodyEnd = content.indexOf(end);
1134
+ return {
1135
+ id,
1136
+ content: content.slice(bodyStart, bodyEnd).replace(/^\r?\n/, "").replace(/\r?\n$/, "")
1137
+ };
1138
+ }
1113
1139
  function upsertManagedBlockById(original, id, content) {
1114
1140
  const newline = original.includes("\r\n") ? "\r\n" : "\n";
1115
- const block = startById(id) + newline + content + newline + endById(id);
1141
+ const normalized = content.replace(/\r\n/g, "\n").replace(/\n/g, newline);
1142
+ const block = startById(id) + newline + normalized + newline + endById(id);
1116
1143
  const re = new RegExp(escapeRe(startById(id)) + "[\\s\\S]*?" + escapeRe(endById(id)));
1117
1144
  if (re.test(original)) {
1118
1145
  return original.replace(re, block);
@@ -1120,6 +1147,68 @@ function upsertManagedBlockById(original, id, content) {
1120
1147
  const separator = original.length === 0 ? "" : original.endsWith(newline) ? newline : newline + newline;
1121
1148
  return original + separator + block + newline;
1122
1149
  }
1150
+ function refreshManagedBlockById(original, id, blockContent, options = {}) {
1151
+ const idStart = startById(id);
1152
+ const idEnd = endById(id);
1153
+ const idStarts = markerCount(original, idStart);
1154
+ const idEnds = markerCount(original, idEnd);
1155
+ if (idStarts > 0 || idEnds > 0) {
1156
+ if (idStarts !== 1 || idEnds !== 1 || original.indexOf(idStart) > original.indexOf(idEnd)) {
1157
+ return { content: original, action: "preserved_conflict", conflict: true };
1158
+ }
1159
+ return {
1160
+ content: upsertManagedBlockById(original, id, blockContent),
1161
+ action: "refreshed",
1162
+ conflict: false
1163
+ };
1164
+ }
1165
+ const legacyStarts = markerCount(original, MANAGED_BLOCK_START);
1166
+ const legacyEnds = markerCount(original, MANAGED_BLOCK_END);
1167
+ const legacyAbsent = legacyStarts === 0 && legacyEnds === 0;
1168
+ const legacyMalformed = !legacyAbsent && (legacyStarts !== 1 || legacyEnds !== 1 || original.indexOf(MANAGED_BLOCK_START) > original.indexOf(MANAGED_BLOCK_END));
1169
+ if (legacyMalformed) {
1170
+ return { content: original, action: "preserved_conflict", conflict: true };
1171
+ }
1172
+ if (!legacyAbsent && options.upgradeLegacy === true) {
1173
+ const newline = original.includes("\r\n") ? "\r\n" : "\n";
1174
+ const normalized = blockContent.replace(/\r\n/g, "\n").replace(/\n/g, newline);
1175
+ const block = idStart + newline + normalized + newline + idEnd;
1176
+ const start = original.indexOf(MANAGED_BLOCK_START);
1177
+ const end = original.indexOf(MANAGED_BLOCK_END) + MANAGED_BLOCK_END.length;
1178
+ return {
1179
+ content: original.slice(0, start) + block + original.slice(end),
1180
+ action: "refreshed",
1181
+ conflict: false
1182
+ };
1183
+ }
1184
+ if (!legacyAbsent) {
1185
+ return {
1186
+ content: upsertManagedBlockById(original, id, blockContent),
1187
+ action: "appended",
1188
+ conflict: false
1189
+ };
1190
+ }
1191
+ return {
1192
+ content: upsertManagedBlockById(original, id, blockContent),
1193
+ action: "appended",
1194
+ conflict: false
1195
+ };
1196
+ }
1197
+ function removeManagedBlockById(original, id) {
1198
+ const idStart = startById(id);
1199
+ const idEnd = endById(id);
1200
+ if (markerCount(original, idStart) === 0 && markerCount(original, idEnd) === 0) {
1201
+ return original;
1202
+ }
1203
+ if (markerCount(original, idStart) !== 1 || markerCount(original, idEnd) !== 1 || original.indexOf(idStart) > original.indexOf(idEnd)) {
1204
+ throw new Error("managed block markers are malformed or duplicated");
1205
+ }
1206
+ const start = original.indexOf(idStart);
1207
+ const end = original.indexOf(idEnd) + idEnd.length;
1208
+ const before = original.slice(0, start).replace(/(?:\r?\n){2}$/, "\n");
1209
+ const after = original.slice(end).replace(/^(?:\r?\n){1,2}/, "");
1210
+ return before + after;
1211
+ }
1123
1212
 
1124
1213
  // ../core/dist/policy/file-policy.js
1125
1214
  var USER_MANAGED_BLOCK = {
@@ -1197,10 +1286,10 @@ function under(path, prefix) {
1197
1286
  }
1198
1287
  function classifyFile(input) {
1199
1288
  const path = normalizeManagedPath(input);
1200
- if (path === "CLAUDE.md" || path === "AGENTS.md") {
1289
+ if (path === "CLAUDE.md" || path === "AGENTS.md" || path === "CODEBUDDY.md") {
1201
1290
  return USER_MANAGED_BLOCK;
1202
1291
  }
1203
- if (under(path, ".claude/rules/") || under(path, ".claude/skills/harness-")) {
1292
+ if (under(path, ".claude/rules/") || under(path, ".claude/skills/harness-") || under(path, ".agents/skills/harness-") || under(path, ".cursor/skills/harness-") || under(path, ".codebuddy/skills/harness-") || under(path, ".codebuddy/agents/harness-")) {
1204
1293
  return USER_DIFF;
1205
1294
  }
1206
1295
  if (under(path, ".cursor/rules/") || under(path, ".agent-skills/")) {
@@ -1255,6 +1344,7 @@ function decideUpdate(policy, dirty) {
1255
1344
  }
1256
1345
 
1257
1346
  // ../core/dist/project/initialize.js
1347
+ import { createHash as createHash4 } from "node:crypto";
1258
1348
  import { readFile as readFile4, stat as stat2 } from "node:fs/promises";
1259
1349
  import { basename, join as join5, resolve as resolve3 } from "node:path";
1260
1350
  import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
@@ -1508,13 +1598,20 @@ async function runTransaction(projectRoot, rawOperations, options = {}) {
1508
1598
  return { transactionId, status: "committed" };
1509
1599
  }
1510
1600
 
1601
+ // ../core/dist/project/agent-adapters.js
1602
+ import { createHash as createHash2 } from "node:crypto";
1603
+
1511
1604
  // ../core/dist/project/managed-content.js
1605
+ var AGENTS_CORE_BLOCK_ID = "hunter-harness-core";
1606
+ var CLAUDE_BLOCK_ID = "hunter-harness-claude-code";
1607
+ var CODEBUDDY_BLOCK_ID = "hunter-harness-codebuddy";
1512
1608
  var AGENTS_MANAGED_BLOCK_CONTENT = [
1513
1609
  "# Hunter Harness",
1514
1610
  "",
1515
- "Use .harness/context-index.json to route rules, Knowledge, and codebase maps.",
1516
- "Treat .claude/skills/harness-* as editable adapter working copies.",
1517
- "Do not modify .harness/state or .harness/cache directly."
1611
+ "Use `.harness/context-index.json` to locate the instructions, skills, knowledge,",
1612
+ "and codebase map for the active agent.",
1613
+ "Treat installed `harness-*` skills as editable adapter working copies.",
1614
+ "Do not modify `.harness/state` or `.harness/cache` directly."
1518
1615
  ].join("\n");
1519
1616
  var CLAUDE_MANAGED_BLOCK_CONTENT = [
1520
1617
  "@AGENTS.md",
@@ -1526,54 +1623,61 @@ var CLAUDE_MANAGED_BLOCK_CONTENT = [
1526
1623
  "- Knowledge: .harness/knowledge/",
1527
1624
  "- Codebase map: .harness/codebase/map/"
1528
1625
  ].join("\n");
1626
+ var CODEBUDDY_MANAGED_BLOCK_CONTENT = [
1627
+ "# Hunter Harness",
1628
+ "",
1629
+ "Use `.harness/context-index.json` to locate the instructions, skills, knowledge,",
1630
+ "and codebase map for the active agent.",
1631
+ "Treat installed `harness-*` skills as editable adapter working copies.",
1632
+ "Do not modify `.harness/state` or `.harness/cache` directly.",
1633
+ "",
1634
+ "- Skills: .codebuddy/skills/harness-*/",
1635
+ "- Agents: .codebuddy/agents/harness-*.md",
1636
+ "- Knowledge: .harness/knowledge/",
1637
+ "- Codebase map: .harness/codebase/map/"
1638
+ ].join("\n");
1529
1639
  var HARNESS_GENERAL_RULES_CONTENT = "# Hunter Harness Rules\n\n- Report evidence honestly.\n- Do not execute destructive actions without confirmation.\n";
1530
1640
  var HARNESS_JAVA_RULES_CONTENT = "# Java Profile\n\n- Verify builds and tests with the project build tool.\n";
1641
+ var CURSOR_GENERAL_RULES_CONTENT = "---\ndescription: Hunter Harness project-wide safety and evidence rules\nglobs:\nalwaysApply: true\n---\n\n# Hunter Harness Rules\n\n- Report evidence honestly.\n- Do not execute destructive actions without confirmation.\n";
1642
+ var CURSOR_JAVA_RULES_CONTENT = "---\ndescription: Hunter Harness Java profile rules\nglobs:\nalwaysApply: true\n---\n\n# Java Profile\n\n- Verify builds and tests with the project build tool.\n";
1531
1643
 
1532
- // ../core/dist/project/profile-bundle.js
1533
- import { createHash as createHash2 } from "node:crypto";
1534
- import { readFile as readFile3, readdir as readdir2 } from "node:fs/promises";
1535
- import { join as join4 } from "node:path";
1536
- function isProfile(value) {
1537
- return value === "general" || value === "java";
1538
- }
1644
+ // ../core/dist/project/agent-adapters.js
1645
+ var AGENT_SOURCE_PATH = /^agents\/([^/]+\.md)$/;
1539
1646
  function validateRelativeBundlePath(path) {
1540
1647
  if (typeof path !== "string" || path.length === 0 || path.includes("\0") || path.startsWith("/") || path.startsWith("\\") || /^[A-Za-z]:/.test(path) || path.split("/").some((part) => part === "" || part === "." || part === "..")) {
1541
1648
  throw new Error("invalid Harness Bundle path");
1542
1649
  }
1543
1650
  }
1544
- async function loadProfileBundle(resourcesRoot, profile) {
1545
- const raw = JSON.parse(await readFile3(join4(resourcesRoot, "harness", "manifests", `${profile}.json`), "utf8"));
1546
- if (raw.schema_version !== 1 || raw.profile !== profile || typeof raw.bundle_version !== "string" || raw.generator !== "harness_deploy.py" || !Array.isArray(raw.files)) {
1547
- throw new Error(`invalid ${profile} Harness Bundle manifest`);
1548
- }
1549
- const files = /* @__PURE__ */ new Map();
1550
- for (const item2 of raw.files) {
1551
- validateRelativeBundlePath(item2.path);
1552
- if (typeof item2.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(item2.sha256) || files.has(item2.path)) {
1553
- throw new Error(`invalid ${profile} Harness Bundle manifest entry`);
1554
- }
1555
- const bytes = await readFile3(join4(resourcesRoot, "harness", profile, item2.path));
1556
- if (createHash2("sha256").update(bytes).digest("hex") !== item2.sha256) {
1557
- throw new Error(`Harness Bundle hash mismatch: ${item2.path}`);
1558
- }
1559
- files.set(item2.path, bytes);
1560
- }
1561
- return { manifest: raw, files };
1562
- }
1563
- async function managedBundleTargets(resourcesRoot, profile) {
1564
- const bundle = await loadProfileBundle(resourcesRoot, profile);
1565
- const targets = new Set(bundleTargetContents(bundle).keys());
1566
- if (profile === "java")
1567
- targets.add(".claude/rules/harness-profile-java.md");
1568
- return targets;
1651
+ function ruleTarget(sourcePath, targetPath, content) {
1652
+ return {
1653
+ source_path: sourcePath,
1654
+ target_path: normalizeManagedPath(targetPath),
1655
+ sha256: createHash2("sha256").update(content).digest("hex"),
1656
+ bytes: new TextEncoder().encode(content)
1657
+ };
1569
1658
  }
1570
- var AGENT_SOURCE_PATH = /^agents\/([^/]+\.md)$/;
1571
- function projectBundle(bundle) {
1659
+ function projectBundleFiles(bundle, skillsRoot, agentsRoot) {
1572
1660
  const records = [];
1573
1661
  for (const [sourcePath, bytes] of bundle.files) {
1574
1662
  validateRelativeBundlePath(sourcePath);
1575
1663
  const agent = AGENT_SOURCE_PATH.exec(sourcePath);
1576
- const projectedTarget = agent?.[1] !== void 0 ? `.claude/agents/${agent[1]}` : `.claude/skills/${sourcePath}`;
1664
+ if (agent?.[1] !== void 0) {
1665
+ if (agentsRoot === null)
1666
+ continue;
1667
+ const projectedTarget2 = `${agentsRoot}/${agent[1]}`;
1668
+ const manifestEntry2 = bundle.manifest.files.find((entry) => entry.path === sourcePath);
1669
+ if (manifestEntry2 === void 0) {
1670
+ throw new Error(`Harness Bundle missing manifest entry: ${sourcePath}`);
1671
+ }
1672
+ records.push({
1673
+ source_path: sourcePath,
1674
+ target_path: normalizeManagedPath(projectedTarget2),
1675
+ sha256: manifestEntry2.sha256,
1676
+ bytes
1677
+ });
1678
+ continue;
1679
+ }
1680
+ const projectedTarget = `${skillsRoot}/${sourcePath}`;
1577
1681
  const manifestEntry = bundle.manifest.files.find((entry) => entry.path === sourcePath);
1578
1682
  if (manifestEntry === void 0) {
1579
1683
  throw new Error(`Harness Bundle missing manifest entry: ${sourcePath}`);
@@ -1588,32 +1692,195 @@ function projectBundle(bundle) {
1588
1692
  assertNoCaseCollisions(records.map((record) => record.target_path));
1589
1693
  return records.sort((left, right) => left.target_path.localeCompare(right.target_path));
1590
1694
  }
1591
- function bundleTargetContents(bundle) {
1592
- return new Map(projectBundle(bundle).map((record) => [record.target_path, record.bytes]));
1593
- }
1594
- function ruleTarget(sourcePath, targetPath, content) {
1695
+ function makeAdapter(spec) {
1595
1696
  return {
1596
- source_path: sourcePath,
1597
- target_path: targetPath,
1598
- sha256: createHash2("sha256").update(content).digest("hex"),
1599
- bytes: new TextEncoder().encode(content)
1697
+ name: spec.name,
1698
+ skillsRoot: spec.skillsRoot,
1699
+ rulesRoot: spec.rulesRoot,
1700
+ agentsRoot: spec.agentsRoot,
1701
+ commandsRoot: spec.commandsRoot,
1702
+ supportsExecutableHooks: false,
1703
+ projectInstructionTargets() {
1704
+ return ["AGENTS.md", ...spec.extraInstructionFiles];
1705
+ },
1706
+ projectBundle(bundle) {
1707
+ return projectBundleFiles(bundle, spec.skillsRoot, spec.agentsRoot);
1708
+ },
1709
+ contextIndex(context) {
1710
+ const rules = [];
1711
+ if (spec.rulesRoot !== null && spec.ruleExt !== null) {
1712
+ rules.push(`${spec.rulesRoot}/harness-general${spec.ruleExt}`);
1713
+ if (context.profile === "java") {
1714
+ rules.push(`${spec.rulesRoot}/harness-profile-java${spec.ruleExt}`);
1715
+ }
1716
+ }
1717
+ return {
1718
+ instructions: spec.instructions,
1719
+ skills_root: spec.skillsRoot,
1720
+ rules
1721
+ };
1722
+ },
1723
+ pruneBoundaries() {
1724
+ const boundaries = [spec.skillsRoot];
1725
+ if (spec.agentsRoot !== null)
1726
+ boundaries.push(spec.agentsRoot);
1727
+ if (spec.rulesRoot !== null)
1728
+ boundaries.push(spec.rulesRoot);
1729
+ const top = spec.skillsRoot.split("/")[0];
1730
+ if (top !== void 0)
1731
+ boundaries.push(top);
1732
+ return boundaries;
1733
+ }
1600
1734
  };
1601
1735
  }
1602
- async function managedTargets(resourcesRoot, profile) {
1603
- const bundle = await loadProfileBundle(resourcesRoot, profile);
1604
- const records = projectBundle(bundle).map((record) => ({
1605
- source_path: record.source_path,
1606
- target_path: record.target_path,
1607
- sha256: record.sha256,
1608
- bytes: record.bytes
1609
- }));
1610
- records.push(ruleTarget("rules/harness-general.md", ".claude/rules/harness-general.md", HARNESS_GENERAL_RULES_CONTENT));
1611
- if (profile === "java") {
1612
- records.push(ruleTarget("rules/harness-profile-java.md", ".claude/rules/harness-profile-java.md", HARNESS_JAVA_RULES_CONTENT));
1736
+ var ADAPTERS = {
1737
+ "claude-code": makeAdapter({
1738
+ name: "claude-code",
1739
+ skillsRoot: ".claude/skills",
1740
+ rulesRoot: ".claude/rules",
1741
+ agentsRoot: ".claude/agents",
1742
+ commandsRoot: null,
1743
+ instructions: "CLAUDE.md",
1744
+ extraInstructionFiles: ["CLAUDE.md"],
1745
+ ruleExt: ".md"
1746
+ }),
1747
+ codex: makeAdapter({
1748
+ name: "codex",
1749
+ skillsRoot: ".agents/skills",
1750
+ rulesRoot: null,
1751
+ agentsRoot: null,
1752
+ commandsRoot: null,
1753
+ instructions: "AGENTS.md",
1754
+ extraInstructionFiles: [],
1755
+ ruleExt: null
1756
+ }),
1757
+ cursor: makeAdapter({
1758
+ name: "cursor",
1759
+ skillsRoot: ".cursor/skills",
1760
+ rulesRoot: ".cursor/rules",
1761
+ agentsRoot: null,
1762
+ commandsRoot: ".cursor/commands",
1763
+ instructions: "AGENTS.md",
1764
+ extraInstructionFiles: [],
1765
+ ruleExt: ".mdc"
1766
+ }),
1767
+ codebuddy: makeAdapter({
1768
+ name: "codebuddy",
1769
+ skillsRoot: ".codebuddy/skills",
1770
+ rulesRoot: null,
1771
+ agentsRoot: ".codebuddy/agents",
1772
+ commandsRoot: ".codebuddy/commands",
1773
+ instructions: "CODEBUDDY.md",
1774
+ extraInstructionFiles: ["CODEBUDDY.md"],
1775
+ ruleExt: null
1776
+ })
1777
+ };
1778
+ function getAdapter(name) {
1779
+ return ADAPTERS[name];
1780
+ }
1781
+ function getAdapters(names) {
1782
+ return HARNESS_AGENT_ORDER.filter((n) => names.includes(n)).map(getAdapter);
1783
+ }
1784
+ function managedTargetsFor(adapter, bundle, context) {
1785
+ const records = [...adapter.projectBundle(bundle, context)];
1786
+ if (adapter.name === "claude-code") {
1787
+ records.push(ruleTarget("rules/harness-general.md", ".claude/rules/harness-general.md", HARNESS_GENERAL_RULES_CONTENT));
1788
+ if (context.profile === "java") {
1789
+ records.push(ruleTarget("rules/harness-profile-java.md", ".claude/rules/harness-profile-java.md", HARNESS_JAVA_RULES_CONTENT));
1790
+ }
1791
+ } else if (adapter.name === "cursor") {
1792
+ records.push(ruleTarget("rules/harness-general.mdc", ".cursor/rules/harness-general.mdc", CURSOR_GENERAL_RULES_CONTENT));
1793
+ if (context.profile === "java") {
1794
+ records.push(ruleTarget("rules/harness-profile-java.mdc", ".cursor/rules/harness-profile-java.mdc", CURSOR_JAVA_RULES_CONTENT));
1795
+ }
1613
1796
  }
1614
1797
  assertNoCaseCollisions(records.map((record) => record.target_path));
1615
1798
  return records.sort((left, right) => left.target_path.localeCompare(right.target_path));
1616
1799
  }
1800
+
1801
+ // ../core/dist/project/profile-bundle.js
1802
+ import { createHash as createHash3 } from "node:crypto";
1803
+ import { readFile as readFile3, readdir as readdir2 } from "node:fs/promises";
1804
+ import { join as join4 } from "node:path";
1805
+ var AdapterBundleError = class extends Error {
1806
+ code;
1807
+ exitCode = 7;
1808
+ constructor(code, message) {
1809
+ super(message);
1810
+ this.code = code;
1811
+ this.name = "AdapterBundleError";
1812
+ }
1813
+ };
1814
+ function isEnoent(error) {
1815
+ return error !== null && typeof error === "object" && "code" in error && error.code === "ENOENT";
1816
+ }
1817
+ function isProfile(value) {
1818
+ return value === "general" || value === "java";
1819
+ }
1820
+ function isAgent(value) {
1821
+ return value === "claude-code" || value === "codex" || value === "cursor" || value === "codebuddy";
1822
+ }
1823
+ function validateRelativeBundlePath2(path) {
1824
+ if (typeof path !== "string" || path.length === 0 || path.includes("\0") || path.startsWith("/") || path.startsWith("\\") || /^[A-Za-z]:/.test(path) || path.split("/").some((part) => part === "" || part === "." || part === "..")) {
1825
+ throw new Error("invalid Harness Bundle path");
1826
+ }
1827
+ }
1828
+ async function loadAgentBundle(resourcesRoot, profile, agent) {
1829
+ const manifestPath = join4(resourcesRoot, "harness", "manifests", profile, `${agent}.json`);
1830
+ let manifestText;
1831
+ try {
1832
+ manifestText = await readFile3(manifestPath, "utf8");
1833
+ } catch (error) {
1834
+ if (isEnoent(error)) {
1835
+ throw new AdapterBundleError("ADAPTER_BUNDLE_MISSING", `offline Harness Bundle manifest missing: ${profile}/${agent}`);
1836
+ }
1837
+ throw error;
1838
+ }
1839
+ let raw;
1840
+ try {
1841
+ raw = JSON.parse(manifestText);
1842
+ } catch {
1843
+ throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `unparseable ${profile}/${agent} Harness Bundle manifest`);
1844
+ }
1845
+ if (raw.schema_version !== 2 || raw.profile !== profile || raw.adapter !== agent || typeof raw.bundle_version !== "string" || raw.generator !== "harness_deploy.py" || !Array.isArray(raw.files)) {
1846
+ throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `invalid ${profile}/${agent} Harness Bundle manifest`);
1847
+ }
1848
+ const files = /* @__PURE__ */ new Map();
1849
+ for (const item2 of raw.files) {
1850
+ try {
1851
+ validateRelativeBundlePath2(item2.path);
1852
+ } catch {
1853
+ throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `invalid ${profile}/${agent} Harness Bundle path`);
1854
+ }
1855
+ if (typeof item2.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(item2.sha256) || files.has(item2.path)) {
1856
+ throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `invalid ${profile}/${agent} Harness Bundle manifest entry`);
1857
+ }
1858
+ let bytes;
1859
+ try {
1860
+ bytes = await readFile3(join4(resourcesRoot, "harness", "bundles", profile, agent, item2.path));
1861
+ } catch (error) {
1862
+ if (isEnoent(error)) {
1863
+ throw new AdapterBundleError("ADAPTER_BUNDLE_MISSING", `offline Harness Bundle file missing: ${profile}/${agent}/${item2.path}`);
1864
+ }
1865
+ throw error;
1866
+ }
1867
+ if (createHash3("sha256").update(bytes).digest("hex") !== item2.sha256) {
1868
+ throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `Harness Bundle hash mismatch: ${profile}/${agent}/${item2.path}`);
1869
+ }
1870
+ files.set(item2.path, bytes);
1871
+ }
1872
+ return { manifest: raw, files };
1873
+ }
1874
+ async function managedBundleTargets(resourcesRoot, profile, agent = "claude-code") {
1875
+ const bundle = await loadAgentBundle(resourcesRoot, profile, agent);
1876
+ const adapter = getAdapter(agent);
1877
+ const context = { profile, codebuddySurface: "both" };
1878
+ const targets = new Set(adapter.projectBundle(bundle, context).map((t) => t.target_path));
1879
+ if (profile === "java" && agent === "claude-code") {
1880
+ targets.add(".claude/rules/harness-profile-java.md");
1881
+ }
1882
+ return targets;
1883
+ }
1617
1884
  function parseHarnessProfile(value) {
1618
1885
  return isProfile(value) ? value : null;
1619
1886
  }
@@ -1622,21 +1889,25 @@ function parseMigrationManifest(raw) {
1622
1889
  throw new Error("invalid Harness migration manifest");
1623
1890
  }
1624
1891
  const record = raw;
1625
- if (record.schema_version !== 1 || !isProfile(record.profile) || typeof record.bundle_version !== "string" || !/^sha256:[a-f0-9]{64}$/.test(String(record.bundle_manifest_hash)) || !Array.isArray(record.projection)) {
1892
+ const schemaVersion = record.schema_version;
1893
+ if (schemaVersion !== 1 && schemaVersion !== 2 || !isProfile(record.profile) || typeof record.bundle_version !== "string" || !/^sha256:[a-f0-9]{64}$/.test(String(record.bundle_manifest_hash)) || !Array.isArray(record.projection)) {
1626
1894
  throw new Error("invalid Harness migration manifest");
1627
1895
  }
1896
+ const adapter = schemaVersion === 1 ? "claude-code" : isAgent(record.adapter) ? record.adapter : (() => {
1897
+ throw new Error("invalid Harness migration manifest adapter");
1898
+ })();
1628
1899
  const projection = [];
1629
1900
  for (const entry of record.projection) {
1630
1901
  if (entry === null || typeof entry !== "object") {
1631
1902
  throw new Error("invalid Harness migration manifest entry");
1632
1903
  }
1633
1904
  const item2 = entry;
1634
- validateRelativeBundlePath(item2.source_path);
1905
+ validateRelativeBundlePath2(item2.source_path);
1635
1906
  if (typeof item2.target_path !== "string" || typeof item2.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(item2.sha256)) {
1636
1907
  throw new Error("invalid Harness migration manifest entry");
1637
1908
  }
1638
1909
  const targetPath = normalizeManagedPath(item2.target_path);
1639
- if (!targetPath.startsWith(".claude/")) {
1910
+ if (schemaVersion === 1 && !targetPath.startsWith(".claude/")) {
1640
1911
  throw new Error("invalid Harness migration manifest target");
1641
1912
  }
1642
1913
  projection.push({
@@ -1647,8 +1918,9 @@ function parseMigrationManifest(raw) {
1647
1918
  }
1648
1919
  assertNoCaseCollisions(projection.map((item2) => item2.target_path));
1649
1920
  return {
1650
- schema_version: 1,
1921
+ schema_version: schemaVersion,
1651
1922
  profile: record.profile,
1923
+ adapter,
1652
1924
  bundle_version: record.bundle_version,
1653
1925
  bundle_manifest_hash: record.bundle_manifest_hash,
1654
1926
  projection
@@ -1697,17 +1969,37 @@ function uuidV7(now = Date.now()) {
1697
1969
  const byte8 = bytes[8] ?? 0;
1698
1970
  bytes[6] = byte6 & 15 | 112;
1699
1971
  bytes[8] = byte8 & 63 | 128;
1700
- const hex = bytes.toString("hex");
1972
+ const hex2 = bytes.toString("hex");
1701
1973
  return [
1702
- hex.slice(0, 8),
1703
- hex.slice(8, 12),
1704
- hex.slice(12, 16),
1705
- hex.slice(16, 20),
1706
- hex.slice(20)
1974
+ hex2.slice(0, 8),
1975
+ hex2.slice(8, 12),
1976
+ hex2.slice(12, 16),
1977
+ hex2.slice(16, 20),
1978
+ hex2.slice(20)
1707
1979
  ].join("-");
1708
1980
  }
1709
1981
 
1710
1982
  // ../core/dist/project/initialize.js
1983
+ var TargetCollisionError = class extends Error {
1984
+ code = "TARGET_COLLISION";
1985
+ exitCode = 7;
1986
+ constructor(targetPath) {
1987
+ super(`TARGET_COLLISION: conflicting bytes for ${targetPath}`);
1988
+ this.name = "TargetCollisionError";
1989
+ }
1990
+ };
1991
+ function hex(bytes) {
1992
+ return createHash4("sha256").update(bytes).digest("hex");
1993
+ }
1994
+ function bytesEqual(left, right) {
1995
+ if (left.byteLength !== right.byteLength)
1996
+ return false;
1997
+ for (let i = 0; i < left.byteLength; i += 1) {
1998
+ if (left[i] !== right[i])
1999
+ return false;
2000
+ }
2001
+ return true;
2002
+ }
1711
2003
  async function readOptional(path) {
1712
2004
  try {
1713
2005
  return await readFile4(path, "utf8");
@@ -1738,14 +2030,76 @@ async function operationFor(root, path, content) {
1738
2030
  return await exists2(join5(root, path)) ? { operation: "modify", path, content } : { operation: "add", path, content };
1739
2031
  }
1740
2032
  var INSTALLED_BUNDLE_PATH = ".harness/state/local/installed-harness-bundle.json";
2033
+ function mergeOwnedTargets(owned) {
2034
+ const byTarget = /* @__PURE__ */ new Map();
2035
+ for (const item2 of owned) {
2036
+ const list = byTarget.get(item2.target_path) ?? [];
2037
+ list.push(item2);
2038
+ byTarget.set(item2.target_path, list);
2039
+ }
2040
+ const merged = [];
2041
+ for (const [targetPath, items] of [...byTarget.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
2042
+ const first = items[0];
2043
+ if (first === void 0) {
2044
+ throw new Error(`missing projected targets for ${targetPath}`);
2045
+ }
2046
+ for (const item2 of items.slice(1)) {
2047
+ if (!bytesEqual(first.bytes, item2.bytes) || first.sha256 !== item2.sha256) {
2048
+ throw new TargetCollisionError(targetPath);
2049
+ }
2050
+ }
2051
+ const owners = new Set(items.map((item2) => item2.owner));
2052
+ merged.push({
2053
+ owner: owners.size === 1 ? first.owner : "shared",
2054
+ source_path: first.source_path,
2055
+ target_path: targetPath,
2056
+ sha256: first.sha256,
2057
+ bytes: first.bytes
2058
+ });
2059
+ }
2060
+ return merged.sort((left, right) => {
2061
+ const byTarget2 = left.target_path.localeCompare(right.target_path);
2062
+ return byTarget2 !== 0 ? byTarget2 : left.source_path.localeCompare(right.source_path);
2063
+ });
2064
+ }
1741
2065
  async function initializeProject(options) {
1742
2066
  const root = resolve3(options.projectRoot);
1743
2067
  const config = initConfigSchema.parse(options.config);
1744
2068
  const existing = await existingProjectConfig(root);
1745
2069
  const profile = config.profile;
1746
- const bundle = await loadProfileBundle(options.resourcesRoot, profile);
1747
- const managed = await managedTargets(options.resourcesRoot, profile);
1748
- const bundleHash = sha256Bytes(canonicalJson(bundle.manifest.files));
2070
+ const enabledAgents = sortHarnessAgents(config.agents);
2071
+ const surface = config.codebuddy_surface;
2072
+ const adapterContext = { profile, codebuddySurface: surface };
2073
+ const owned = [];
2074
+ const manifests = [];
2075
+ const adaptersIndex = {};
2076
+ const skillBundles = {};
2077
+ let primaryBundleHash = "";
2078
+ let primaryRegistryVersion = "";
2079
+ for (const agent of enabledAgents) {
2080
+ const bundle = await loadAgentBundle(options.resourcesRoot, profile, agent);
2081
+ const adapter = getAdapter(agent);
2082
+ const targets = managedTargetsFor(adapter, bundle, adapterContext);
2083
+ const bundleHash = sha256Bytes(canonicalJson(bundle.manifest.files));
2084
+ if (primaryBundleHash === "") {
2085
+ primaryBundleHash = bundleHash;
2086
+ primaryRegistryVersion = bundle.manifest.bundle_version;
2087
+ }
2088
+ manifests.push({
2089
+ adapter: agent,
2090
+ bundle_version: bundle.manifest.bundle_version,
2091
+ bundle_manifest_hash: bundleHash
2092
+ });
2093
+ skillBundles[agent] = {
2094
+ registry_version: bundle.manifest.bundle_version,
2095
+ bundle_hash: bundleHash
2096
+ };
2097
+ adaptersIndex[agent] = adapter.contextIndex(adapterContext);
2098
+ for (const target of targets) {
2099
+ owned.push({ ...target, owner: agent });
2100
+ }
2101
+ }
2102
+ const mergedTargets = mergeOwnedTargets(owned);
1749
2103
  const projectConfig = projectConfigSchema.parse({
1750
2104
  harness: { name: "hunter-harness", schema_version: 1 },
1751
2105
  project: {
@@ -1759,7 +2113,8 @@ async function initializeProject(options) {
1759
2113
  url: config.server_url ?? existing?.server.url ?? null,
1760
2114
  token_env: config.token_env ?? existing?.server.token_env ?? "HUNTER_HARNESS_TOKEN"
1761
2115
  },
1762
- adapters: { enabled: [config.adapter] }
2116
+ adapters: { enabled: enabledAgents },
2117
+ ...enabledAgents.includes("codebuddy") ? { adapter_options: { codebuddy: { surface: config.codebuddy_surface } } } : {}
1763
2118
  });
1764
2119
  const baseline = baselineManifestSchema.parse({
1765
2120
  schema_version: 1,
@@ -1768,8 +2123,15 @@ async function initializeProject(options) {
1768
2123
  artifact_manifest_hash: null,
1769
2124
  files: {}
1770
2125
  });
1771
- const agentsContent = upsertManagedBlock(await readOptional(join5(root, "AGENTS.md")), AGENTS_MANAGED_BLOCK_CONTENT);
1772
- const claudeContent = upsertManagedBlock(await readOptional(join5(root, "CLAUDE.md")), CLAUDE_MANAGED_BLOCK_CONTENT);
2126
+ const managedBlocks = [];
2127
+ let agentsContent = await readOptional(join5(root, "AGENTS.md"));
2128
+ agentsContent = upsertManagedBlockById(agentsContent, AGENTS_CORE_BLOCK_ID, AGENTS_MANAGED_BLOCK_CONTENT);
2129
+ managedBlocks.push({
2130
+ owner: "shared",
2131
+ target_path: "AGENTS.md",
2132
+ block_id: AGENTS_CORE_BLOCK_ID,
2133
+ content_sha256: hex(AGENTS_MANAGED_BLOCK_CONTENT)
2134
+ });
1773
2135
  const files = /* @__PURE__ */ new Map([
1774
2136
  [
1775
2137
  ".harness/project.yaml",
@@ -1782,38 +2144,64 @@ async function initializeProject(options) {
1782
2144
  [
1783
2145
  ".harness/context-index.json",
1784
2146
  JSON.stringify({
1785
- schema_version: 1,
1786
- project: { claude_md: "CLAUDE.md", agents_md: "AGENTS.md" },
1787
- rules: [".claude/rules/harness-general.md"],
2147
+ schema_version: 2,
2148
+ project: {
2149
+ shared_instructions: "AGENTS.md",
2150
+ adapters: adaptersIndex
2151
+ },
1788
2152
  knowledge: { index: ".harness/knowledge/index.json" },
1789
2153
  codebase: { map: ".harness/codebase/map", status: "missing" },
1790
- skill_bundle: {
1791
- registry_version: bundle.manifest.bundle_version,
1792
- bundle_hash: bundleHash
1793
- }
2154
+ skill_bundles: skillBundles
1794
2155
  }, null, 2) + "\n"
1795
2156
  ],
1796
2157
  [
1797
2158
  ".harness/knowledge/index.json",
1798
2159
  JSON.stringify({ schema_version: 1, generated_at: null, entries: [] }, null, 2) + "\n"
1799
2160
  ],
1800
- ["AGENTS.md", agentsContent],
1801
- ["CLAUDE.md", claudeContent]
2161
+ ["AGENTS.md", agentsContent]
1802
2162
  ]);
1803
- for (const target of managed) {
2163
+ if (enabledAgents.includes("claude-code")) {
2164
+ let claudeContent = await readOptional(join5(root, "CLAUDE.md"));
2165
+ claudeContent = upsertManagedBlockById(claudeContent, CLAUDE_BLOCK_ID, CLAUDE_MANAGED_BLOCK_CONTENT);
2166
+ files.set("CLAUDE.md", claudeContent);
2167
+ managedBlocks.push({
2168
+ owner: "claude-code",
2169
+ target_path: "CLAUDE.md",
2170
+ block_id: CLAUDE_BLOCK_ID,
2171
+ content_sha256: hex(CLAUDE_MANAGED_BLOCK_CONTENT)
2172
+ });
2173
+ }
2174
+ if (enabledAgents.includes("codebuddy")) {
2175
+ let codebuddyContent = await readOptional(join5(root, "CODEBUDDY.md"));
2176
+ codebuddyContent = upsertManagedBlockById(codebuddyContent, CODEBUDDY_BLOCK_ID, CODEBUDDY_MANAGED_BLOCK_CONTENT);
2177
+ files.set("CODEBUDDY.md", codebuddyContent);
2178
+ managedBlocks.push({
2179
+ owner: "codebuddy",
2180
+ target_path: "CODEBUDDY.md",
2181
+ block_id: CODEBUDDY_BLOCK_ID,
2182
+ content_sha256: hex(CODEBUDDY_MANAGED_BLOCK_CONTENT)
2183
+ });
2184
+ }
2185
+ for (const target of mergedTargets) {
1804
2186
  files.set(target.target_path, target.bytes);
1805
2187
  }
2188
+ managedBlocks.sort((left, right) => {
2189
+ const byTarget = left.target_path.localeCompare(right.target_path);
2190
+ return byTarget !== 0 ? byTarget : left.block_id.localeCompare(right.block_id);
2191
+ });
1806
2192
  const installedState = {
1807
- schema_version: 2,
2193
+ schema_version: 3,
1808
2194
  profile,
1809
- bundle_version: bundle.manifest.bundle_version,
1810
- bundle_manifest_hash: bundleHash,
2195
+ adapters: enabledAgents,
1811
2196
  installed_at: (/* @__PURE__ */ new Date()).toISOString(),
1812
- files: managed.map((target) => ({
2197
+ manifests,
2198
+ files: mergedTargets.map((target) => ({
2199
+ owner: target.owner,
1813
2200
  source_path: target.source_path,
1814
2201
  target_path: target.target_path,
1815
2202
  sha256: target.sha256
1816
- })).sort((left, right) => left.target_path.localeCompare(right.target_path))
2203
+ })),
2204
+ managed_blocks: managedBlocks
1817
2205
  };
1818
2206
  files.set(INSTALLED_BUNDLE_PATH, JSON.stringify(installedState, null, 2) + "\n");
1819
2207
  const paths = [...files.keys()].sort((left, right) => left.localeCompare(right));
@@ -1824,32 +2212,21 @@ async function initializeProject(options) {
1824
2212
  return {
1825
2213
  projectConfig,
1826
2214
  paths,
1827
- bundleHash,
1828
- registryVersion: bundle.manifest.bundle_version
2215
+ bundleHash: primaryBundleHash,
2216
+ registryVersion: primaryRegistryVersion
1829
2217
  };
1830
2218
  }
1831
2219
 
1832
2220
  // ../core/dist/project/refresh.js
1833
- import { createHash as createHash3 } from "node:crypto";
1834
- import { readFile as readFile5, readdir as readdir3, rmdir, stat as stat3 } from "node:fs/promises";
2221
+ import { createHash as createHash5 } from "node:crypto";
2222
+ import { readFile as readFile5, readdir as readdir3, rmdir } from "node:fs/promises";
1835
2223
  import { dirname as dirname3, join as join6, resolve as resolve4 } from "node:path";
1836
2224
  import { parse as parseYaml3, stringify as stringifyYaml2 } from "yaml";
1837
2225
  var INSTALLED_STATE_PATH = ".harness/state/local/installed-harness-bundle.json";
1838
2226
  var CONTEXT_INDEX_PATH = ".harness/context-index.json";
1839
- async function exists3(path) {
1840
- try {
1841
- await stat3(path);
1842
- return true;
1843
- } catch (error) {
1844
- if (error instanceof Error && "code" in error && error.code === "ENOENT") {
1845
- return false;
1846
- }
1847
- throw error;
1848
- }
1849
- }
1850
2227
  async function fileHex(path) {
1851
2228
  try {
1852
- return createHash3("sha256").update(await readFile5(path)).digest("hex");
2229
+ return createHash5("sha256").update(await readFile5(path)).digest("hex");
1853
2230
  } catch (error) {
1854
2231
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
1855
2232
  return null;
@@ -1870,17 +2247,17 @@ async function readOptionalText(path) {
1870
2247
  async function readInstalledState(root) {
1871
2248
  const content = await readOptionalText(join6(root, INSTALLED_STATE_PATH));
1872
2249
  if (content === "") {
1873
- return { profile: null, schemaVersion: null, trusted: /* @__PURE__ */ new Map() };
2250
+ return { profile: null, schemaVersion: null, adapters: [], trusted: /* @__PURE__ */ new Map() };
1874
2251
  }
1875
2252
  let parsed;
1876
2253
  try {
1877
2254
  parsed = JSON.parse(content);
1878
2255
  } catch {
1879
- return { profile: null, schemaVersion: null, trusted: /* @__PURE__ */ new Map() };
2256
+ return { profile: null, schemaVersion: null, adapters: [], trusted: /* @__PURE__ */ new Map() };
1880
2257
  }
1881
2258
  const profile = parseHarnessProfile(parsed.profile);
1882
2259
  const trusted = /* @__PURE__ */ new Map();
1883
- if (parsed.schema_version === 2 && Array.isArray(parsed.files)) {
2260
+ if ((parsed.schema_version === 2 || parsed.schema_version === 3) && Array.isArray(parsed.files)) {
1884
2261
  for (const entry of parsed.files) {
1885
2262
  if (entry !== null && typeof entry === "object" && "target_path" in entry && "sha256" in entry) {
1886
2263
  const target = entry.target_path;
@@ -1891,7 +2268,9 @@ async function readInstalledState(root) {
1891
2268
  }
1892
2269
  }
1893
2270
  }
1894
- return { profile, schemaVersion: typeof parsed.schema_version === "number" ? parsed.schema_version : null, trusted };
2271
+ const schemaVersion = typeof parsed.schema_version === "number" ? parsed.schema_version : null;
2272
+ const adapters = schemaVersion === 3 && Array.isArray(parsed.adapters) ? sortHarnessAgents(parsed.adapters.filter((value) => value === "claude-code" || value === "codex" || value === "cursor" || value === "codebuddy")) : schemaVersion === 1 || schemaVersion === 2 ? ["claude-code"] : [];
2273
+ return { profile, schemaVersion, adapters, trusted };
1895
2274
  }
1896
2275
  async function readContextIndexBundleHash(root) {
1897
2276
  const content = await readOptionalText(join6(root, CONTEXT_INDEX_PATH));
@@ -1905,16 +2284,11 @@ async function readContextIndexBundleHash(root) {
1905
2284
  return null;
1906
2285
  }
1907
2286
  }
1908
- async function pruneEmptyParentDirs(root, deletedPaths) {
1909
- const claudeRoot = join6(root, ".claude");
1910
- const boundaries = /* @__PURE__ */ new Set([
1911
- claudeRoot,
1912
- join6(claudeRoot, "skills"),
1913
- join6(claudeRoot, "agents")
1914
- ]);
2287
+ async function pruneEmptyParentDirs(root, deletedPaths, boundaryPaths) {
2288
+ const boundaries = new Set(boundaryPaths.map((path) => join6(root, path)));
1915
2289
  for (const deleted of deletedPaths) {
1916
2290
  let dir = dirname3(join6(root, deleted));
1917
- while (dir.startsWith(claudeRoot) && !boundaries.has(dir)) {
2291
+ while (dir.startsWith(root) && !boundaries.has(dir)) {
1918
2292
  let entries;
1919
2293
  try {
1920
2294
  entries = await readdir3(dir);
@@ -1954,82 +2328,130 @@ function conflict(target, reason, oldSha, incomingSha) {
1954
2328
  function sortByTarget(items) {
1955
2329
  return [...items].sort((left, right) => left.target_path.localeCompare(right.target_path));
1956
2330
  }
1957
- async function refreshMarkdownBlock(root, fileName, blockContent, ops, conflicts, preserved) {
1958
- const original = await readOptionalText(join6(root, fileName));
1959
- const current = original === "" ? null : createHash3("sha256").update(original).digest("hex");
1960
- const refresh = refreshManagedBlock(original, blockContent);
1961
- const synthetic = {
1962
- source_path: fileName,
1963
- target_path: fileName,
1964
- sha256: createHash3("sha256").update(blockContent).digest("hex"),
1965
- bytes: new TextEncoder().encode(blockContent)
1966
- };
1967
- if (refresh.conflict) {
1968
- preserved.push(item(synthetic, "preserve", "MALFORMED_MANAGED_BLOCK", current, synthetic.sha256));
1969
- conflicts.push(conflict(synthetic, "MALFORMED_MANAGED_BLOCK", current, synthetic.sha256));
1970
- return;
1971
- }
1972
- if (refresh.content === original) {
1973
- return;
1974
- }
1975
- ops.push({
1976
- operation: original === "" ? "add" : "modify",
1977
- path: fileName,
1978
- content: refresh.content
1979
- });
1980
- }
1981
- async function reconcileContextIndex(root, bundleVersion, bundleManifestHash) {
2331
+ async function reconcileContextIndex(root, profile, agents, manifests, codebuddySurface2) {
1982
2332
  const existing = await readOptionalText(join6(root, CONTEXT_INDEX_PATH));
1983
- let record = {};
1984
- if (existing !== "") {
1985
- try {
1986
- record = JSON.parse(existing);
1987
- } catch {
1988
- record = {};
1989
- }
1990
- }
1991
- if (Object.keys(record).length === 0) {
1992
- record = {
1993
- schema_version: 1,
1994
- project: { claude_md: "CLAUDE.md", agents_md: "AGENTS.md" },
1995
- rules: [".claude/rules/harness-general.md"],
1996
- knowledge: { index: ".harness/knowledge/index.json" },
1997
- codebase: { map: ".harness/codebase/map", status: "missing" }
1998
- };
1999
- }
2000
- record.skill_bundle = {
2001
- registry_version: bundleVersion,
2002
- bundle_hash: bundleManifestHash
2333
+ const context = { profile, codebuddySurface: codebuddySurface2 };
2334
+ const record = {
2335
+ schema_version: 2,
2336
+ project: {
2337
+ shared_instructions: "AGENTS.md",
2338
+ adapters: Object.fromEntries(agents.map((agent) => [
2339
+ agent,
2340
+ getAdapter(agent).contextIndex(context)
2341
+ ]))
2342
+ },
2343
+ knowledge: { index: ".harness/knowledge/index.json" },
2344
+ codebase: { map: ".harness/codebase/map", status: "missing" },
2345
+ skill_bundles: Object.fromEntries(manifests.map((manifest) => [
2346
+ manifest.adapter,
2347
+ { registry_version: manifest.bundle_version, bundle_hash: manifest.bundle_manifest_hash }
2348
+ ]))
2003
2349
  };
2350
+ const next = JSON.stringify(record, null, 2) + "\n";
2351
+ if (existing === next)
2352
+ return null;
2004
2353
  return {
2005
2354
  operation: existing === "" ? "add" : "modify",
2006
2355
  path: CONTEXT_INDEX_PATH,
2007
- content: JSON.stringify(record, null, 2) + "\n"
2356
+ content: next
2008
2357
  };
2009
2358
  }
2010
- async function profileTransitionOperation(root, previousProfile, profile) {
2011
- if (previousProfile === null || previousProfile === profile)
2359
+ async function projectTransitionOperation(root, previousProfile, profile, oldAgents, agents, codebuddySurface2) {
2360
+ if (previousProfile === profile && oldAgents.length === agents.length && oldAgents.every((agent, index) => agent === agents[index]))
2012
2361
  return null;
2013
2362
  const path = ".harness/project.yaml";
2014
2363
  const content = await readOptionalText(join6(root, path));
2015
- const project = projectConfigSchema.parse(parseYaml3(content));
2364
+ if (content === "")
2365
+ return null;
2366
+ const project = parseYaml3(content);
2016
2367
  return {
2017
2368
  operation: "modify",
2018
2369
  path,
2019
2370
  content: stringifyYaml2({
2020
2371
  ...project,
2021
- project: { ...project.project, profiles: [profile] }
2372
+ project: { ...project.project, profiles: [profile] },
2373
+ adapters: { enabled: agents },
2374
+ ...agents.includes("codebuddy") ? { adapter_options: { codebuddy: { surface: codebuddySurface2 } } } : { adapter_options: void 0 }
2022
2375
  }, { sortMapEntries: true })
2023
2376
  };
2024
2377
  }
2378
+ function mergeTargets(targets) {
2379
+ const grouped = /* @__PURE__ */ new Map();
2380
+ for (const target of targets) {
2381
+ grouped.set(target.target_path, [...grouped.get(target.target_path) ?? [], target]);
2382
+ }
2383
+ return [...grouped.entries()].map(([path, values]) => {
2384
+ const first = values[0];
2385
+ if (first === void 0)
2386
+ throw new TargetCollisionError(path);
2387
+ if (values.some((value) => value.sha256 !== first.sha256))
2388
+ throw new TargetCollisionError(path);
2389
+ const owner = new Set(values.map((value) => value.owner)).size === 1 ? first.owner : "shared";
2390
+ return { ...first, owner };
2391
+ }).sort((left, right) => left.target_path.localeCompare(right.target_path));
2392
+ }
2393
+ async function reconcileMarkdownBlock(root, fileName, blockId, content, remove, ops, conflicts, preserved) {
2394
+ const original = await readOptionalText(join6(root, fileName));
2395
+ const synthetic = {
2396
+ source_path: fileName,
2397
+ target_path: fileName,
2398
+ sha256: createHash5("sha256").update(content).digest("hex"),
2399
+ bytes: new TextEncoder().encode(content)
2400
+ };
2401
+ let next;
2402
+ try {
2403
+ if (remove) {
2404
+ const hasId = original.includes(`<!-- hunter-harness:start id=${blockId} -->`);
2405
+ next = hasId ? removeManagedBlockById(original, blockId) : removeManagedBlock(original);
2406
+ } else {
2407
+ const refreshed = refreshManagedBlockById(original, blockId, content, { upgradeLegacy: true });
2408
+ if (refreshed.conflict)
2409
+ throw new Error("managed block conflict");
2410
+ next = refreshed.content;
2411
+ }
2412
+ } catch {
2413
+ const current = original === "" ? null : createHash5("sha256").update(original).digest("hex");
2414
+ preserved.push(item(synthetic, "preserve", "MALFORMED_MANAGED_BLOCK", current, synthetic.sha256));
2415
+ conflicts.push(conflict(synthetic, "MALFORMED_MANAGED_BLOCK", current, synthetic.sha256));
2416
+ return;
2417
+ }
2418
+ if (next !== original)
2419
+ ops.push({
2420
+ operation: original === "" ? "add" : "modify",
2421
+ path: fileName,
2422
+ content: next
2423
+ });
2424
+ }
2425
+ function stateWithoutInstalledAt(value) {
2426
+ if (value === null || typeof value !== "object" || Array.isArray(value))
2427
+ return value;
2428
+ const copy = { ...value };
2429
+ delete copy.installed_at;
2430
+ return copy;
2431
+ }
2025
2432
  async function refreshProject(options) {
2026
2433
  const root = resolve4(options.projectRoot);
2027
2434
  const profile = options.profile;
2028
- const newManaged = await managedTargets(options.resourcesRoot, profile);
2029
- const newBundle = await loadProfileBundle(options.resourcesRoot, profile);
2030
- const bundleManifestHash = sha256Bytes(canonicalJson(newBundle.manifest.files));
2031
2435
  const installed = await readInstalledState(root);
2032
2436
  const previousProfile = installed.profile;
2437
+ const agents = sortHarnessAgents(options.agents);
2438
+ const oldAgents = installed.adapters.length > 0 ? installed.adapters : ["claude-code"];
2439
+ const codebuddySurface2 = options.codebuddySurface ?? "both";
2440
+ const context = { profile, codebuddySurface: codebuddySurface2 };
2441
+ const owned = [];
2442
+ const manifests = [];
2443
+ for (const agent of agents) {
2444
+ const bundle = await loadAgentBundle(options.resourcesRoot, profile, agent);
2445
+ manifests.push({
2446
+ adapter: agent,
2447
+ bundle_version: bundle.manifest.bundle_version,
2448
+ bundle_manifest_hash: sha256Bytes(canonicalJson(bundle.manifest.files))
2449
+ });
2450
+ for (const target of managedTargetsFor(getAdapter(agent), bundle, context)) {
2451
+ owned.push({ ...target, owner: agent });
2452
+ }
2453
+ }
2454
+ const newManaged = mergeTargets(owned);
2033
2455
  let trusted = installed.trusted;
2034
2456
  let migrationOldPaths = null;
2035
2457
  if (installed.schemaVersion === 1) {
@@ -2056,9 +2478,14 @@ async function refreshProject(options) {
2056
2478
  });
2057
2479
  }
2058
2480
  }
2059
- } else if (previousProfile !== null && previousProfile !== profile) {
2060
- const oldManaged = await managedTargets(options.resourcesRoot, previousProfile);
2061
- oldOnly = oldManaged.filter((target) => !newTargetSet.has(target.target_path));
2481
+ } else if (previousProfile !== null) {
2482
+ const oldContext = { profile: previousProfile, codebuddySurface: codebuddySurface2 };
2483
+ const oldTargets = [];
2484
+ for (const agent of oldAgents) {
2485
+ const bundle = await loadAgentBundle(options.resourcesRoot, previousProfile, agent);
2486
+ oldTargets.push(...managedTargetsFor(getAdapter(agent), bundle, oldContext));
2487
+ }
2488
+ oldOnly = oldTargets.filter((target) => !newTargetSet.has(target.target_path));
2062
2489
  }
2063
2490
  const applied = [];
2064
2491
  const removed = [];
@@ -2073,12 +2500,12 @@ async function refreshProject(options) {
2073
2500
  if (current === null) {
2074
2501
  applied.push(item(target, "add", "MISSING_TARGET", null, incoming));
2075
2502
  ops.push({ operation: "add", path: target.target_path, content: target.bytes });
2076
- newStateFiles.push({ source_path: target.source_path, target_path: target.target_path, sha256: incoming });
2503
+ newStateFiles.push({ owner: target.owner, source_path: target.source_path, target_path: target.target_path, sha256: incoming });
2077
2504
  continue;
2078
2505
  }
2079
2506
  if (current === incoming) {
2080
2507
  unchanged.push(item(target, "unchanged", "ALREADY_CURRENT", current, incoming));
2081
- newStateFiles.push({ source_path: target.source_path, target_path: target.target_path, sha256: incoming });
2508
+ newStateFiles.push({ owner: target.owner, source_path: target.source_path, target_path: target.target_path, sha256: incoming });
2082
2509
  continue;
2083
2510
  }
2084
2511
  const trustedHash = trusted.get(target.target_path);
@@ -2086,13 +2513,13 @@ async function refreshProject(options) {
2086
2513
  const reason = options.forceManaged ? "FORCE_MANAGED" : "BASELINE_CLEAN";
2087
2514
  applied.push(item(target, "replace", reason, current, incoming));
2088
2515
  ops.push({ operation: "modify", path: target.target_path, content: target.bytes });
2089
- newStateFiles.push({ source_path: target.source_path, target_path: target.target_path, sha256: incoming });
2516
+ newStateFiles.push({ owner: target.owner, source_path: target.source_path, target_path: target.target_path, sha256: incoming });
2090
2517
  } else {
2091
2518
  const reason = trustedHash === void 0 ? "LEGACY_BASELINE_UNKNOWN" : "LOCAL_MODIFICATION";
2092
2519
  preserved.push(item(target, "preserve", reason, current, incoming));
2093
2520
  conflicts.push(conflict(target, reason, current, incoming));
2094
2521
  if (trustedHash !== void 0) {
2095
- newStateFiles.push({ source_path: target.source_path, target_path: target.target_path, sha256: trustedHash });
2522
+ newStateFiles.push({ owner: target.owner, source_path: target.source_path, target_path: target.target_path, sha256: trustedHash });
2096
2523
  }
2097
2524
  }
2098
2525
  }
@@ -2101,7 +2528,7 @@ async function refreshProject(options) {
2101
2528
  if (current === null) {
2102
2529
  continue;
2103
2530
  }
2104
- const trustedHash = trusted.get(target.target_path);
2531
+ const trustedHash = target.sha256 !== "" ? target.sha256 : void 0;
2105
2532
  const clean = trustedHash !== void 0 && current === trustedHash;
2106
2533
  if (clean || options.forceManaged) {
2107
2534
  const reason = clean ? "BASELINE_CLEAN" : "FORCE_MANAGED";
@@ -2113,28 +2540,60 @@ async function refreshProject(options) {
2113
2540
  conflicts.push(conflict(target, reason, current, null));
2114
2541
  }
2115
2542
  }
2116
- await refreshMarkdownBlock(root, "AGENTS.md", AGENTS_MANAGED_BLOCK_CONTENT, ops, conflicts, preserved);
2117
- await refreshMarkdownBlock(root, "CLAUDE.md", CLAUDE_MANAGED_BLOCK_CONTENT, ops, conflicts, preserved);
2118
- const profileOperation = await profileTransitionOperation(root, previousProfile, profile);
2119
- if (profileOperation !== null)
2120
- ops.push(profileOperation);
2121
- ops.push(await reconcileContextIndex(root, newBundle.manifest.bundle_version, bundleManifestHash));
2543
+ await reconcileMarkdownBlock(root, "AGENTS.md", AGENTS_CORE_BLOCK_ID, AGENTS_MANAGED_BLOCK_CONTENT, false, ops, conflicts, preserved);
2544
+ await reconcileMarkdownBlock(root, "CLAUDE.md", CLAUDE_BLOCK_ID, CLAUDE_MANAGED_BLOCK_CONTENT, !agents.includes("claude-code"), ops, conflicts, preserved);
2545
+ await reconcileMarkdownBlock(root, "CODEBUDDY.md", CODEBUDDY_BLOCK_ID, CODEBUDDY_MANAGED_BLOCK_CONTENT, !agents.includes("codebuddy"), ops, conflicts, preserved);
2546
+ const projectOperation = await projectTransitionOperation(root, previousProfile, profile, oldAgents, agents, codebuddySurface2);
2547
+ if (projectOperation !== null)
2548
+ ops.push(projectOperation);
2549
+ const contextOperation = await reconcileContextIndex(root, profile, agents, manifests, codebuddySurface2);
2550
+ if (contextOperation !== null)
2551
+ ops.push(contextOperation);
2552
+ const managedBlocks = [
2553
+ {
2554
+ owner: "shared",
2555
+ target_path: "AGENTS.md",
2556
+ block_id: AGENTS_CORE_BLOCK_ID,
2557
+ content_sha256: createHash5("sha256").update(AGENTS_MANAGED_BLOCK_CONTENT).digest("hex")
2558
+ },
2559
+ ...agents.includes("claude-code") ? [{
2560
+ owner: "claude-code",
2561
+ target_path: "CLAUDE.md",
2562
+ block_id: CLAUDE_BLOCK_ID,
2563
+ content_sha256: createHash5("sha256").update(CLAUDE_MANAGED_BLOCK_CONTENT).digest("hex")
2564
+ }] : [],
2565
+ ...agents.includes("codebuddy") ? [{
2566
+ owner: "codebuddy",
2567
+ target_path: "CODEBUDDY.md",
2568
+ block_id: CODEBUDDY_BLOCK_ID,
2569
+ content_sha256: createHash5("sha256").update(CODEBUDDY_MANAGED_BLOCK_CONTENT).digest("hex")
2570
+ }] : []
2571
+ ].sort((left, right) => left.target_path.localeCompare(right.target_path) || left.block_id.localeCompare(right.block_id));
2122
2572
  const installedState = {
2123
- schema_version: 2,
2573
+ schema_version: 3,
2124
2574
  profile,
2125
- bundle_version: newBundle.manifest.bundle_version,
2126
- bundle_manifest_hash: bundleManifestHash,
2575
+ adapters: agents,
2127
2576
  installed_at: (/* @__PURE__ */ new Date()).toISOString(),
2128
- files: newStateFiles.sort((left, right) => left.target_path.localeCompare(right.target_path))
2577
+ manifests,
2578
+ files: newStateFiles.sort((left, right) => left.target_path.localeCompare(right.target_path) || left.source_path.localeCompare(right.source_path)),
2579
+ managed_blocks: managedBlocks
2129
2580
  };
2130
- ops.push({
2131
- operation: await exists3(join6(root, INSTALLED_STATE_PATH)) ? "modify" : "add",
2132
- path: INSTALLED_STATE_PATH,
2133
- content: JSON.stringify(installedState, null, 2) + "\n"
2134
- });
2581
+ const existingState = await readOptionalText(join6(root, INSTALLED_STATE_PATH));
2582
+ let existingParsed = null;
2583
+ try {
2584
+ existingParsed = existingState === "" ? null : JSON.parse(existingState);
2585
+ } catch {
2586
+ }
2587
+ if (JSON.stringify(stateWithoutInstalledAt(existingParsed)) !== JSON.stringify(stateWithoutInstalledAt(installedState))) {
2588
+ ops.push({
2589
+ operation: existingState === "" ? "add" : "modify",
2590
+ path: INSTALLED_STATE_PATH,
2591
+ content: JSON.stringify(installedState, null, 2) + "\n"
2592
+ });
2593
+ }
2135
2594
  if (!options.dryRun) {
2136
2595
  await runTransaction(root, ops, { kind: "refresh" });
2137
- await pruneEmptyParentDirs(root, removed.map((item2) => item2.target_path));
2596
+ await pruneEmptyParentDirs(root, removed.map((item2) => item2.target_path), getAdapters([.../* @__PURE__ */ new Set([...agents, ...oldAgents])]).flatMap((adapter) => adapter.pruneBoundaries(context)));
2138
2597
  }
2139
2598
  return {
2140
2599
  profile,
@@ -2519,18 +2978,16 @@ var PushWorkflowError = class extends Error {
2519
2978
  this.code = code;
2520
2979
  }
2521
2980
  };
2522
- var MANAGED_ROOTS = [
2523
- ".claude/rules",
2981
+ var SHARED_MANAGED_ROOTS = [
2524
2982
  ".harness/knowledge",
2525
2983
  ".harness/codebase"
2526
2984
  ];
2527
- var MANAGED_FILES = [
2528
- "CLAUDE.md",
2985
+ var SHARED_MANAGED_FILES = [
2529
2986
  "AGENTS.md",
2530
2987
  ".harness/project.yaml",
2531
2988
  ".harness/context-index.json"
2532
2989
  ];
2533
- async function exists4(path) {
2990
+ async function exists3(path) {
2534
2991
  try {
2535
2992
  await lstat2(path);
2536
2993
  return true;
@@ -2542,7 +2999,7 @@ async function exists4(path) {
2542
2999
  }
2543
3000
  }
2544
3001
  async function walkFiles(root, current, output) {
2545
- if (!await exists4(current)) {
3002
+ if (!await exists3(current)) {
2546
3003
  return;
2547
3004
  }
2548
3005
  for (const item2 of await readdir4(current, { withFileTypes: true })) {
@@ -2557,23 +3014,50 @@ async function walkFiles(root, current, output) {
2557
3014
  }
2558
3015
  }
2559
3016
  }
2560
- async function managedFiles(projectRoot) {
3017
+ function enabledHarnessAgents(project) {
3018
+ return project.adapters.enabled.flatMap((agent) => {
3019
+ const parsed = harnessAgentSchema.safeParse(agent);
3020
+ return parsed.success ? [parsed.data] : [];
3021
+ });
3022
+ }
3023
+ async function walkHarnessEntries(root, directory, output) {
3024
+ if (!await exists3(directory))
3025
+ return;
3026
+ for (const item2 of await readdir4(directory, { withFileTypes: true })) {
3027
+ if (item2.name.startsWith("harness-")) {
3028
+ const path = join9(directory, item2.name);
3029
+ if (item2.isDirectory()) {
3030
+ await walkFiles(root, path, output);
3031
+ } else if (item2.isFile()) {
3032
+ output.push(normalizeManagedPath(relative(root, path).replaceAll("\\", "/")));
3033
+ }
3034
+ }
3035
+ }
3036
+ }
3037
+ async function managedFiles(projectRoot, project) {
2561
3038
  const root = resolve5(projectRoot);
2562
3039
  const paths = [];
2563
- for (const path of MANAGED_FILES) {
2564
- if (await exists4(join9(root, path))) {
3040
+ const adapters = getAdapters(enabledHarnessAgents(project));
3041
+ const managedFiles2 = [
3042
+ ...SHARED_MANAGED_FILES,
3043
+ ...adapters.some((adapter) => adapter.name === "claude-code") ? ["CLAUDE.md"] : [],
3044
+ ...adapters.some((adapter) => adapter.name === "codebuddy") ? ["CODEBUDDY.md"] : []
3045
+ ];
3046
+ for (const path of managedFiles2) {
3047
+ if (await exists3(join9(root, path))) {
2565
3048
  paths.push(path);
2566
3049
  }
2567
3050
  }
2568
- for (const path of MANAGED_ROOTS) {
3051
+ for (const path of SHARED_MANAGED_ROOTS) {
2569
3052
  await walkFiles(root, join9(root, path), paths);
2570
3053
  }
2571
- const skillsRoot = join9(root, ".claude", "skills");
2572
- if (await exists4(skillsRoot)) {
2573
- for (const item2 of await readdir4(skillsRoot, { withFileTypes: true })) {
2574
- if (item2.isDirectory() && item2.name.startsWith("harness-")) {
2575
- await walkFiles(root, join9(skillsRoot, item2.name), paths);
2576
- }
3054
+ for (const adapter of adapters) {
3055
+ if (adapter.rulesRoot !== null) {
3056
+ await walkFiles(root, join9(root, adapter.rulesRoot), paths);
3057
+ }
3058
+ await walkHarnessEntries(root, join9(root, adapter.skillsRoot), paths);
3059
+ if (adapter.agentsRoot !== null) {
3060
+ await walkHarnessEntries(root, join9(root, adapter.agentsRoot), paths);
2577
3061
  }
2578
3062
  }
2579
3063
  const result = {};
@@ -2693,8 +3177,8 @@ async function pushProject(options) {
2693
3177
  let project = await readProject(root);
2694
3178
  let baseline = await readBaseline(root);
2695
3179
  const profile = parseHarnessProfile(project.project.profiles[0]);
2696
- const installedPaths = profile === null ? /* @__PURE__ */ new Set() : await managedBundleTargets(options.resourcesRoot, profile);
2697
- let preview = makePreview(baseline, await managedFiles(root), options.confirmedProjectLocal ?? [], installedPaths);
3180
+ const installedPaths = profile === null ? /* @__PURE__ */ new Set() : new Set(await Promise.all(enabledHarnessAgents(project).map((agent) => managedBundleTargets(options.resourcesRoot, profile, agent))).then((targets) => targets.flatMap((target) => [...target])));
3181
+ let preview = makePreview(baseline, await managedFiles(root, project), options.confirmedProjectLocal ?? [], installedPaths);
2698
3182
  if (preview.blocked) {
2699
3183
  throw new PushWorkflowError("sensitive information scan blocked the proposal", 6, "SENSITIVE_CONTENT_BLOCKED");
2700
3184
  }
@@ -2734,7 +3218,7 @@ async function pushProject(options) {
2734
3218
  let workflow = priorWorkflow?.local_project_key === project.project.local_project_key ? priorWorkflow : newWorkflowState(project, clientId);
2735
3219
  workflow.client_id = clientId;
2736
3220
  await atomicWriteJson(workflowPath, workflow);
2737
- preview = makePreview(baseline, await managedFiles(root), options.confirmedProjectLocal ?? [], installedPaths, workflow.created_at);
3221
+ preview = makePreview(baseline, await managedFiles(root, project), options.confirmedProjectLocal ?? [], installedPaths, workflow.created_at);
2738
3222
  const requestId = workflow.request_id;
2739
3223
  const client = new HunterHarnessApiClient({
2740
3224
  serverUrl: parsedServerUrl.toString(),
@@ -2752,7 +3236,7 @@ async function pushProject(options) {
2752
3236
  ({ project, baseline } = await bindProject(root, project, baseline, resolved.project_id));
2753
3237
  workflow.project_id = resolved.project_id;
2754
3238
  await atomicWriteJson(workflowPath, workflow);
2755
- preview = makePreview(baseline, await managedFiles(root), options.confirmedProjectLocal ?? [], installedPaths, workflow.created_at);
3239
+ preview = makePreview(baseline, await managedFiles(root, project), options.confirmedProjectLocal ?? [], installedPaths, workflow.created_at);
2756
3240
  if (preview.blocked) {
2757
3241
  throw new PushWorkflowError("sensitive information scan blocked the proposal", 6, "SENSITIVE_CONTENT_BLOCKED");
2758
3242
  }
@@ -2948,7 +3432,7 @@ var AGENT_DESCRIPTORS = {
2948
3432
  var INSTALLABLE_AGENTS = Object.keys(AGENT_DESCRIPTORS).filter((agent) => AGENT_DESCRIPTORS[agent]?.installable === true);
2949
3433
 
2950
3434
  // ../core/dist/transaction/recovery.js
2951
- import { readFile as readFile10, readdir as readdir6, rm as rm6, stat as stat4 } from "node:fs/promises";
3435
+ import { readFile as readFile10, readdir as readdir6, rm as rm6, stat as stat3 } from "node:fs/promises";
2952
3436
  import { join as join11 } from "node:path";
2953
3437
  async function recoverTransaction(projectRoot, transactionId) {
2954
3438
  const journal = JSON.parse(await readFile10(join11(stateLayout(projectRoot).transactions, transactionId, "journal.json"), "utf8"));
@@ -2995,7 +3479,7 @@ async function pendingTransactions(projectRoot) {
2995
3479
  }
2996
3480
  async function pathExists(path) {
2997
3481
  try {
2998
- await stat4(path);
3482
+ await stat3(path);
2999
3483
  return true;
3000
3484
  } catch (error) {
3001
3485
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -3014,8 +3498,8 @@ async function rollbackLatestCommittedUpdate(projectRoot) {
3014
3498
  const after = JSON.parse(await readFile10(join11(transactionRoot, "after", "manifest.json"), "utf8"));
3015
3499
  for (const entry of after) {
3016
3500
  const target = join11(projectRoot, entry.path);
3017
- const exists6 = await pathExists(target);
3018
- if (exists6 !== entry.exists || exists6 && await sha256File(target) !== entry.hash) {
3501
+ const exists5 = await pathExists(target);
3502
+ if (exists5 !== entry.exists || exists5 && await sha256File(target) !== entry.hash) {
3019
3503
  throw new Error("cannot rollback dirty path: " + entry.path);
3020
3504
  }
3021
3505
  }
@@ -3027,15 +3511,15 @@ async function rollbackLatestCommittedUpdate(projectRoot) {
3027
3511
  }
3028
3512
  seen.add(snapshot.path);
3029
3513
  const target = join11(projectRoot, snapshot.path);
3030
- const exists6 = await pathExists(target);
3514
+ const exists5 = await pathExists(target);
3031
3515
  if (snapshot.existed && snapshot.snapshot_name !== null) {
3032
3516
  const content = await readFile10(join11(transactionRoot, "before", snapshot.snapshot_name));
3033
3517
  operations.push({
3034
- operation: exists6 ? "modify" : "add",
3518
+ operation: exists5 ? "modify" : "add",
3035
3519
  path: snapshot.path,
3036
3520
  content
3037
3521
  });
3038
- } else if (exists6) {
3522
+ } else if (exists5) {
3039
3523
  operations.push({ operation: "delete", path: snapshot.path });
3040
3524
  }
3041
3525
  }
@@ -3308,7 +3792,8 @@ async function updateProject(options) {
3308
3792
  equivalent = finalContent === sourceContent;
3309
3793
  } else if (incoming !== null) {
3310
3794
  const incomingBlock = extractManagedBlock(incoming) ?? incoming.trim();
3311
- const blockId = operation.operation === "add" || operation.operation === "modify" ? operation.block_id : void 0;
3795
+ const incomingId = extractSingleManagedBlockById(incoming)?.id;
3796
+ const blockId = operation.operation === "add" || operation.operation === "modify" ? operation.block_id ?? incomingId : void 0;
3312
3797
  finalContent = blockId !== void 0 ? upsertManagedBlockById(targetContent ?? "", blockId, incomingBlock) : upsertManagedBlock(targetContent ?? "", incomingBlock);
3313
3798
  equivalent = finalContent === targetContent;
3314
3799
  }
@@ -3416,19 +3901,82 @@ import { isAbsolute as isAbsolute2, join as join13 } from "node:path";
3416
3901
  import { readFile as readFile12 } from "node:fs/promises";
3417
3902
  var InitConfigurationError = class extends Error {
3418
3903
  exitCode;
3419
- constructor(message, exitCode = 3, options) {
3904
+ code;
3905
+ constructor(message, exitCode = 3, code = "INIT_CONFIG_INVALID", options) {
3420
3906
  super(message, options);
3421
3907
  this.name = "InitConfigurationError";
3422
3908
  this.exitCode = exitCode;
3909
+ this.code = code;
3423
3910
  }
3424
3911
  };
3912
+ function harnessErrorInfo(error) {
3913
+ const info = {};
3914
+ if (error === null || typeof error !== "object") return info;
3915
+ const record = error;
3916
+ if (typeof record.code === "string") info.code = record.code;
3917
+ if (typeof record.exitCode === "number") {
3918
+ info.exitCode = record.exitCode;
3919
+ }
3920
+ return info;
3921
+ }
3922
+ var AGENT_BY_INDEX = {
3923
+ "1": "claude-code",
3924
+ "2": "codex",
3925
+ "3": "cursor",
3926
+ "4": "codebuddy"
3927
+ };
3425
3928
  function normalizeProfile(value) {
3426
3929
  if (value === void 0) return void 0;
3427
3930
  if (value === "" || value === "1" || value === "general") return "general";
3428
3931
  if (value === "2" || value === "java") return "java";
3429
3932
  throw new InitConfigurationError("\u914D\u7F6E\u7C7B\u578B\u5FC5\u987B\u4E3A general \u6216 java");
3430
3933
  }
3431
- async function resolveInitConfig(cwd, flags, promptMissing) {
3934
+ function parseAgentsInput(raw) {
3935
+ const trimmed = raw.trim();
3936
+ if (trimmed === "") return ["claude-code"];
3937
+ if (trimmed === "all") return [...HARNESS_AGENT_ORDER];
3938
+ const agents = [];
3939
+ for (const token of trimmed.split(",")) {
3940
+ const value = token.trim();
3941
+ const byIndex = AGENT_BY_INDEX[value];
3942
+ if (byIndex !== void 0) {
3943
+ agents.push(byIndex);
3944
+ continue;
3945
+ }
3946
+ const byName = harnessAgentSchema.safeParse(value);
3947
+ if (byName.success) {
3948
+ agents.push(byName.data);
3949
+ continue;
3950
+ }
3951
+ throw new InitConfigurationError(`\u672A\u77E5 Agent\uFF1A${value}`, 3, "AGENT_UNSUPPORTED");
3952
+ }
3953
+ if (agents.length === 0) {
3954
+ throw new InitConfigurationError("Agent \u5217\u8868\u4E3A\u7A7A", 3, "AGENTS_REQUIRED");
3955
+ }
3956
+ return sortHarnessAgents(agents);
3957
+ }
3958
+ function parseAgentsFromConfig(value) {
3959
+ if (!Array.isArray(value) || value.length === 0) {
3960
+ throw new InitConfigurationError("Agent \u5217\u8868\u4E3A\u7A7A", 3, "AGENTS_REQUIRED");
3961
+ }
3962
+ const agents = [];
3963
+ for (const item2 of value) {
3964
+ const parsed = harnessAgentSchema.safeParse(item2);
3965
+ if (!parsed.success) {
3966
+ throw new InitConfigurationError(
3967
+ `\u672A\u77E5 Agent\uFF1A${String(item2)}`,
3968
+ 3,
3969
+ "AGENT_UNSUPPORTED"
3970
+ );
3971
+ }
3972
+ agents.push(parsed.data);
3973
+ }
3974
+ return sortHarnessAgents(agents);
3975
+ }
3976
+ function hasOwn(record, key) {
3977
+ return Object.prototype.hasOwnProperty.call(record, key);
3978
+ }
3979
+ async function resolveInitConfig(cwd, flags, prompts = {}, warnings = []) {
3432
3980
  let fileConfig = {};
3433
3981
  if (flags.config !== void 0) {
3434
3982
  const path = isAbsolute2(flags.config) ? flags.config : join13(cwd, flags.config);
@@ -3438,20 +3986,58 @@ async function resolveInitConfig(cwd, flags, promptMissing) {
3438
3986
  throw new InitConfigurationError(
3439
3987
  "unable to read init config: " + (error instanceof Error ? error.message : String(error)),
3440
3988
  3,
3989
+ "INIT_CONFIG_INVALID",
3441
3990
  { cause: error }
3442
3991
  );
3443
3992
  }
3444
3993
  }
3445
- const configuredAdapter = fileConfig.adapter ?? flags.adapter ?? "claude-code";
3446
- if (configuredAdapter !== "claude-code") {
3447
- throw new InitConfigurationError("only claude-code is supported");
3994
+ const hasConfigAgents = hasOwn(fileConfig, "agents");
3995
+ const hasConfigAdapter = hasOwn(fileConfig, "adapter");
3996
+ if (hasConfigAgents && hasConfigAdapter) {
3997
+ throw new InitConfigurationError(
3998
+ "\u914D\u7F6E\u4E0D\u80FD\u540C\u65F6\u5305\u542B agents \u4E0E adapter",
3999
+ 3,
4000
+ "AGENT_OPTIONS_CONFLICT"
4001
+ );
4002
+ }
4003
+ let agents;
4004
+ if (hasConfigAgents) {
4005
+ agents = parseAgentsFromConfig(fileConfig.agents);
4006
+ } else if (hasConfigAdapter) {
4007
+ if (fileConfig.adapter !== "claude-code") {
4008
+ throw new InitConfigurationError(
4009
+ `\u672A\u77E5 Agent\uFF1A${String(fileConfig.adapter)}`,
4010
+ 3,
4011
+ "AGENT_UNSUPPORTED"
4012
+ );
4013
+ }
4014
+ agents = ["claude-code"];
4015
+ warnings.push(
4016
+ 'DEPRECATION: init config field "adapter" is deprecated; use "agents" instead'
4017
+ );
4018
+ } else if (flags.agents !== void 0) {
4019
+ agents = parseAgentsInput(flags.agents);
4020
+ } else if (prompts.agents !== void 0) {
4021
+ agents = parseAgentsInput(await prompts.agents());
4022
+ } else {
4023
+ agents = ["claude-code"];
4024
+ }
4025
+ const surfaceFromConfig = hasOwn(fileConfig, "codebuddy_surface");
4026
+ const surfaceFromFlags = flags.codebuddySurface !== void 0;
4027
+ if ((surfaceFromConfig || surfaceFromFlags) && !agents.includes("codebuddy")) {
4028
+ throw new InitConfigurationError(
4029
+ "\u672A\u9009\u62E9 CodeBuddy \u65F6\u4E0D\u80FD\u6307\u5B9A codebuddy_surface",
4030
+ 3,
4031
+ "CODEBUDDY_SURFACE_UNUSED"
4032
+ );
3448
4033
  }
3449
4034
  const profile = normalizeProfile(
3450
- fileConfig.profile ?? flags.profile ?? (promptMissing === void 0 ? void 0 : await promptMissing())
4035
+ fileConfig.profile ?? flags.profile ?? (prompts.profile === void 0 ? void 0 : await prompts.profile())
3451
4036
  );
3452
4037
  const candidate = {
3453
- adapter: "claude-code",
4038
+ agents,
3454
4039
  profile,
4040
+ codebuddy_surface: fileConfig.codebuddy_surface ?? flags.codebuddySurface ?? "both",
3455
4041
  server_url: fileConfig.server_url ?? flags.serverUrl ?? null,
3456
4042
  token_env: fileConfig.token_env ?? flags.tokenEnv ?? "HUNTER_HARNESS_TOKEN",
3457
4043
  project_id: fileConfig.project_id ?? null,
@@ -3464,7 +4050,8 @@ async function resolveInitConfig(cwd, flags, promptMissing) {
3464
4050
  if (!parsed.success) {
3465
4051
  throw new InitConfigurationError(
3466
4052
  "init config schema validation failed: " + parsed.error.message,
3467
- 7
4053
+ 7,
4054
+ "INIT_CONFIG_INVALID"
3468
4055
  );
3469
4056
  }
3470
4057
  return parsed.data;
@@ -3503,6 +4090,16 @@ function parseProfile(value, current) {
3503
4090
  if (value === "2" || value === "java") return "java";
3504
4091
  throw new Error("\u914D\u7F6E\u7C7B\u578B\u5FC5\u987B\u4E3A general \u6216 java");
3505
4092
  }
4093
+ function refreshAgents(config) {
4094
+ const agents = sortHarnessAgents(config.adapters.enabled.flatMap((agent) => {
4095
+ const parsed = harnessAgentSchema.safeParse(agent);
4096
+ return parsed.success ? [parsed.data] : [];
4097
+ }));
4098
+ return agents.length > 0 ? agents : ["claude-code"];
4099
+ }
4100
+ function codebuddySurface(config) {
4101
+ return config.adapter_options?.codebuddy?.surface ?? "both";
4102
+ }
3506
4103
  function summarize(result) {
3507
4104
  const items = [
3508
4105
  ...result.applied.map((item2) => ({ ...item2, status: result.dry_run ? "planned" : "applied" })),
@@ -3570,20 +4167,25 @@ async function runRefresh(options, dependencies) {
3570
4167
  }
3571
4168
  const currentProfile = detection.config.project.profiles[0] ?? "general";
3572
4169
  let targetProfile;
4170
+ let targetAgents;
3573
4171
  try {
3574
4172
  targetProfile = parseProfile(options.profile, currentProfile);
4173
+ targetAgents = options.agents === void 0 ? refreshAgents(detection.config) : parseAgentsInput(options.agents);
3575
4174
  } catch (error) {
3576
4175
  const message = error instanceof Error ? error.message : String(error);
3577
- dependencies.stderr(message + "\n");
3578
- return 3;
4176
+ const code = error instanceof InitConfigurationError ? error.code : void 0;
4177
+ dependencies.stderr((code === void 0 ? "" : code + ": ") + message + "\n");
4178
+ return error instanceof InitConfigurationError ? error.exitCode : 3;
3579
4179
  }
3580
4180
  const dryRun = options.dryRun === true;
3581
- if (targetProfile !== currentProfile && !dryRun) {
4181
+ if ((targetProfile !== currentProfile || targetAgents.some((agent, index) => agent !== refreshAgents(detection.config)[index]) || targetAgents.length !== refreshAgents(detection.config).length) && !dryRun) {
3582
4182
  try {
3583
4183
  const preview = await refreshProject({
3584
4184
  projectRoot: dependencies.cwd,
3585
4185
  resourcesRoot: dependencies.resourcesRoot,
3586
4186
  profile: targetProfile,
4187
+ agents: targetAgents,
4188
+ codebuddySurface: codebuddySurface(detection.config),
3587
4189
  dryRun: true,
3588
4190
  forceManaged: options.forceManaged === true
3589
4191
  });
@@ -3618,6 +4220,8 @@ async function runRefresh(options, dependencies) {
3618
4220
  projectRoot: dependencies.cwd,
3619
4221
  resourcesRoot: dependencies.resourcesRoot,
3620
4222
  profile: targetProfile,
4223
+ agents: targetAgents,
4224
+ codebuddySurface: codebuddySurface(detection.config),
3621
4225
  dryRun,
3622
4226
  forceManaged: options.forceManaged === true
3623
4227
  });
@@ -3635,8 +4239,11 @@ async function runRefresh(options, dependencies) {
3635
4239
  }
3636
4240
  return output.exit_code;
3637
4241
  } catch (error) {
4242
+ const info = harnessErrorInfo(error);
4243
+ const exitCode = info.exitCode ?? 1;
4244
+ const code = info.code;
3638
4245
  const message = error instanceof Error ? error.message : String(error);
3639
- dependencies.stderr(message + "\n");
4246
+ dependencies.stderr((code !== void 0 ? code + ": " : "") + message + "\n");
3640
4247
  if (options.json === true) {
3641
4248
  dependencies.stdout(serializeCliResult({
3642
4249
  schema_version: 1,
@@ -3644,15 +4251,15 @@ async function runRefresh(options, dependencies) {
3644
4251
  request_id: requestId,
3645
4252
  dry_run: dryRun,
3646
4253
  ok: false,
3647
- exit_code: 1,
4254
+ exit_code: exitCode,
3648
4255
  project_id: null,
3649
4256
  summary: { applied: 0, removed: 0, preserved: 0, unchanged: 0, conflicts: 0 },
3650
4257
  items: [],
3651
4258
  warnings: [],
3652
- errors: [{ message }]
4259
+ errors: [{ ...code === void 0 ? {} : { code }, message }]
3653
4260
  }));
3654
4261
  }
3655
- return 1;
4262
+ return exitCode;
3656
4263
  }
3657
4264
  }
3658
4265
 
@@ -3663,13 +4270,23 @@ function otherProfile(current) {
3663
4270
  async function runFirstInstall(options, dependencies) {
3664
4271
  const requestId = uuidV7();
3665
4272
  try {
4273
+ const warnings = [];
3666
4274
  const config = await resolveInitConfig(
3667
4275
  dependencies.cwd,
3668
4276
  options,
3669
- options.nonInteractive === true ? void 0 : () => dependencies.prompt(
3670
- "\u8BF7\u9009\u62E9 Harness \u7C7B\u578B\uFF1A\n1. \u901A\u7528\uFF08\u9ED8\u8BA4\uFF09\n2. Java\n\u8BF7\u8F93\u5165 1 \u6216 2 [1]: "
3671
- ).then((answer) => answer.trim())
4277
+ options.nonInteractive === true ? {} : {
4278
+ agents: () => dependencies.prompt(
4279
+ "\u8BF7\u9009\u62E9\u76EE\u6807 Agent\uFF08\u53EF\u591A\u9009\uFF0C\u4F7F\u7528\u9017\u53F7\u5206\u9694\uFF09\n 1. Claude Code\n 2. Codex\n 3. Cursor\n 4. CodeBuddy\n\u8BF7\u8F93\u5165\u7F16\u53F7 [1]: "
4280
+ ).then((answer) => answer.trim()),
4281
+ profile: () => dependencies.prompt(
4282
+ "\u8BF7\u9009\u62E9 Harness \u7C7B\u578B\uFF1A\n1. \u901A\u7528\uFF08\u9ED8\u8BA4\uFF09\n2. Java\n\u8BF7\u8F93\u5165 1 \u6216 2 [1]: "
4283
+ ).then((answer) => answer.trim())
4284
+ },
4285
+ warnings
3672
4286
  );
4287
+ for (const warning of warnings) {
4288
+ dependencies.stderr(warning + "\n");
4289
+ }
3673
4290
  if (options.nonInteractive === true && options.yes !== true && options.dryRun !== true) {
3674
4291
  dependencies.stderr("\u975E\u4EA4\u4E92\u6A21\u5F0F\u6267\u884C\u5199\u5165\u64CD\u4F5C\u9700\u8981 --yes\n");
3675
4292
  return 2;
@@ -3696,9 +4313,11 @@ async function runFirstInstall(options, dependencies) {
3696
4313
  dependencies.stdout(options.json === true ? serializeCliResult(output) : "Hunter Harness \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u5171\u5904\u7406 " + result.paths.length + " \u4E2A\u6587\u4EF6\u3002\n");
3697
4314
  return 0;
3698
4315
  } catch (error) {
3699
- const exitCode = error instanceof InitConfigurationError ? error.exitCode : 1;
4316
+ const info = harnessErrorInfo(error);
4317
+ const exitCode = info.exitCode ?? 1;
4318
+ const code = info.code;
3700
4319
  const message = error instanceof Error ? error.message : String(error);
3701
- dependencies.stderr(message + "\n");
4320
+ dependencies.stderr((code !== void 0 ? code + ": " : "") + message + "\n");
3702
4321
  if (options.json === true) {
3703
4322
  dependencies.stdout(serializeCliResult({
3704
4323
  schema_version: 1,
@@ -3711,7 +4330,7 @@ async function runFirstInstall(options, dependencies) {
3711
4330
  summary: { planned: 0, applied: 0 },
3712
4331
  items: [],
3713
4332
  warnings: [],
3714
- errors: [{ message }]
4333
+ errors: [{ ...code === void 0 ? {} : { code }, message }]
3715
4334
  }));
3716
4335
  }
3717
4336
  return exitCode;
@@ -3719,6 +4338,7 @@ async function runFirstInstall(options, dependencies) {
3719
4338
  }
3720
4339
  async function runExistingProject(options, dependencies, currentProfile) {
3721
4340
  const refreshOptions = {};
4341
+ if (options.agents !== void 0) refreshOptions.agents = options.agents;
3722
4342
  if (options.profile !== void 0) refreshOptions.profile = options.profile;
3723
4343
  if (options.nonInteractive !== void 0) refreshOptions.nonInteractive = options.nonInteractive;
3724
4344
  if (options.yes !== void 0) refreshOptions.yes = options.yes;
@@ -4006,18 +4626,18 @@ async function runUpdate(options, dependencies) {
4006
4626
  }
4007
4627
 
4008
4628
  // src/commands/recovery.ts
4009
- import { stat as stat5 } from "node:fs/promises";
4629
+ import { stat as stat4 } from "node:fs/promises";
4010
4630
  import { join as join15 } from "node:path";
4011
- async function exists5(path) {
4631
+ async function exists4(path) {
4012
4632
  try {
4013
- await stat5(path);
4633
+ await stat4(path);
4014
4634
  return true;
4015
4635
  } catch {
4016
4636
  return false;
4017
4637
  }
4018
4638
  }
4019
4639
  function explicitConfigure(options) {
4020
- return options.adapter !== void 0 || options.profile !== void 0 || options.config !== void 0 || options.serverUrl !== void 0 || options.tokenEnv !== void 0;
4640
+ return options.agents !== void 0 || options.adapter !== void 0 || options.profile !== void 0 || options.config !== void 0 || options.serverUrl !== void 0 || options.tokenEnv !== void 0;
4021
4641
  }
4022
4642
  async function runRecoveryMenuIfApplicable(options, dependencies) {
4023
4643
  const pending = await pendingTransactions(dependencies.cwd);
@@ -4067,7 +4687,7 @@ async function runRecoveryMenuIfApplicable(options, dependencies) {
4067
4687
  return 5;
4068
4688
  }
4069
4689
  }
4070
- const initialized = await exists5(join15(dependencies.cwd, ".harness", "project.yaml"));
4690
+ const initialized = await exists4(join15(dependencies.cwd, ".harness", "project.yaml"));
4071
4691
  if (!initialized || options.nonInteractive === true || explicitConfigure(options)) {
4072
4692
  return null;
4073
4693
  }
@@ -4131,7 +4751,7 @@ function defaultDependencies(overrides) {
4131
4751
  };
4132
4752
  }
4133
4753
  function addCommonOptions(command) {
4134
- return command.option("--dry-run").option("--yes").option("--json").option("--server-url <url>").option("--token-env <ENV_NAME>").option("--non-interactive");
4754
+ return command.option("--dry-run").option("--yes").option("--json").option("--server-url <url>").option("--token-env <ENV_NAME>").option("--non-interactive").option("--agents <csv>").option("--codebuddy-surface <surface>");
4135
4755
  }
4136
4756
  async function runCli(argv, overrides = {}) {
4137
4757
  const dependencies = defaultDependencies(overrides);