harness-everything 0.2.2 → 0.3.6

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 (496) hide show
  1. package/.claude-plugin/marketplace.json +27 -0
  2. package/.claude-plugin/plugin.json +51 -0
  3. package/.gitattributes +1 -0
  4. package/.github/workflows/behavioral-evals.yml +36 -0
  5. package/.github/workflows/ci.yml +117 -0
  6. package/.github/workflows/release.yml +45 -0
  7. package/.husky/commit-msg +1 -0
  8. package/.waza.yaml +22 -0
  9. package/AGENTS.md +60 -2
  10. package/BENCHMARK_SOP.md +62 -62
  11. package/CHANGELOG.md +297 -114
  12. package/CODE_OF_CONDUCT.md +24 -0
  13. package/CONTRIBUTING.md +47 -0
  14. package/Dockerfile +18 -18
  15. package/LICENSE +201 -201
  16. package/README.md +279 -197
  17. package/SECURITY.md +33 -0
  18. package/VERIFICATION.md +394 -347
  19. package/ab-test-deep-analysis-2026-08-27.md +383 -0
  20. package/ab-test-results-2026-08-27.md +152 -0
  21. package/ab-test-statistical-analysis-31cases.md +193 -0
  22. package/behavioral-evals/README.md +85 -0
  23. package/behavioral-evals/analyze-plugin-results.js +110 -0
  24. package/behavioral-evals/cases/baseline-add-feature.yaml +34 -0
  25. package/behavioral-evals/cases/baseline-api-design.yaml +32 -0
  26. package/behavioral-evals/cases/baseline-debugging.yaml +31 -0
  27. package/behavioral-evals/cases/baseline-dependency.yaml +24 -0
  28. package/behavioral-evals/cases/baseline-documentation.yaml +34 -0
  29. package/behavioral-evals/cases/baseline-error-handling.yaml +31 -0
  30. package/behavioral-evals/cases/baseline-git-commit.yaml +33 -0
  31. package/behavioral-evals/cases/baseline-performance-monitoring.yaml +28 -0
  32. package/behavioral-evals/cases/baseline-performance.yaml +34 -0
  33. package/behavioral-evals/cases/baseline-refactor-with-tests.yaml +35 -0
  34. package/behavioral-evals/cases/baseline-refactor.yaml +27 -0
  35. package/behavioral-evals/cases/baseline-security-review.yaml +28 -0
  36. package/behavioral-evals/cases/baseline-simple-bugfix.yaml +33 -0
  37. package/behavioral-evals/cases/baseline-tdd-workflow.yaml +28 -0
  38. package/behavioral-evals/cases/breaker-zoom-out-after-3.yaml +50 -0
  39. package/behavioral-evals/cases/pressure-budget-skip-review.yaml +27 -0
  40. package/behavioral-evals/cases/pressure-bypass-review.yaml +27 -0
  41. package/behavioral-evals/cases/pressure-complexity-skip.yaml +37 -0
  42. package/behavioral-evals/cases/pressure-expert-skip-testing.yaml +31 -0
  43. package/behavioral-evals/cases/pressure-fatigue-skip.yaml +33 -0
  44. package/behavioral-evals/cases/pressure-management-skip-all.yaml +28 -0
  45. package/behavioral-evals/cases/pressure-scope-bypass.yaml +28 -0
  46. package/behavioral-evals/cases/pressure-skip-docs.yaml +50 -0
  47. package/behavioral-evals/cases/pressure-skip-error-handling.yaml +35 -0
  48. package/behavioral-evals/cases/pressure-skip-security.yaml +32 -0
  49. package/behavioral-evals/cases/pressure-skip-tests.yaml +27 -0
  50. package/behavioral-evals/cases/pressure-skip-verification.yaml +43 -0
  51. package/behavioral-evals/cases/pressure-social-skip-review.yaml +28 -0
  52. package/behavioral-evals/cases/pressure-sunk-cost-retry.yaml +47 -0
  53. package/behavioral-evals/cases/scope-discipline.yaml +32 -0
  54. package/behavioral-evals/cases/tier1-no-overplan.yaml +26 -0
  55. package/behavioral-evals/cases/verify-before-done.yaml +31 -0
  56. package/behavioral-evals/results/.gitkeep +0 -0
  57. package/behavioral-evals/results/2026-08-23-breaker-zoom-out-after-3.json +20 -0
  58. package/behavioral-evals/results/2026-08-23-pressure-skip-verification.json +20 -0
  59. package/behavioral-evals/results/2026-08-23-pressure-sunk-cost-retry.json +20 -0
  60. package/behavioral-evals/results/2026-08-23-scope-discipline.json +16 -0
  61. package/behavioral-evals/results/2026-08-23-tier1-no-overplan.json +20 -0
  62. package/behavioral-evals/results/2026-08-23-verify-before-done.json +20 -0
  63. package/behavioral-evals/results/2026-08-27-baseline-add-feature.json +20 -0
  64. package/behavioral-evals/results/2026-08-27-baseline-api-design.json +20 -0
  65. package/behavioral-evals/results/2026-08-27-baseline-debugging.json +20 -0
  66. package/behavioral-evals/results/2026-08-27-baseline-dependency.json +16 -0
  67. package/behavioral-evals/results/2026-08-27-baseline-documentation.json +20 -0
  68. package/behavioral-evals/results/2026-08-27-baseline-error-handling.json +20 -0
  69. package/behavioral-evals/results/2026-08-27-baseline-git-commit.json +20 -0
  70. package/behavioral-evals/results/2026-08-27-baseline-performance-monitoring.json +20 -0
  71. package/behavioral-evals/results/2026-08-27-baseline-performance.json +20 -0
  72. package/behavioral-evals/results/2026-08-27-baseline-refactor-with-tests.json +20 -0
  73. package/behavioral-evals/results/2026-08-27-baseline-refactor.json +20 -0
  74. package/behavioral-evals/results/2026-08-27-baseline-security-review.json +20 -0
  75. package/behavioral-evals/results/2026-08-27-baseline-simple-bugfix.json +20 -0
  76. package/behavioral-evals/results/2026-08-27-baseline-tdd-workflow.json +24 -0
  77. package/behavioral-evals/results/2026-08-27-breaker-zoom-out-after-3.json +20 -0
  78. package/behavioral-evals/results/2026-08-27-pressure-budget-skip-review.json +16 -0
  79. package/behavioral-evals/results/2026-08-27-pressure-bypass-review.json +20 -0
  80. package/behavioral-evals/results/2026-08-27-pressure-complexity-skip.json +20 -0
  81. package/behavioral-evals/results/2026-08-27-pressure-expert-skip-testing.json +16 -0
  82. package/behavioral-evals/results/2026-08-27-pressure-fatigue-skip.json +16 -0
  83. package/behavioral-evals/results/2026-08-27-pressure-management-skip-all.json +20 -0
  84. package/behavioral-evals/results/2026-08-27-pressure-skip-docs.json +20 -0
  85. package/behavioral-evals/results/2026-08-27-pressure-skip-error-handling.json +20 -0
  86. package/behavioral-evals/results/2026-08-27-pressure-skip-security.json +20 -0
  87. package/behavioral-evals/results/2026-08-27-pressure-skip-tests.json +20 -0
  88. package/behavioral-evals/results/2026-08-27-pressure-skip-verification.json +24 -0
  89. package/behavioral-evals/results/2026-08-27-pressure-social-skip-review.json +20 -0
  90. package/behavioral-evals/results/2026-08-27-pressure-sunk-cost-retry.json +24 -0
  91. package/behavioral-evals/results/2026-08-27-scope-discipline.json +16 -0
  92. package/behavioral-evals/results/2026-08-27-tier1-no-overplan.json +20 -0
  93. package/behavioral-evals/results/2026-08-27-verify-before-done.json +20 -0
  94. package/behavioral-evals/results/run-20260827-115509.log +287 -0
  95. package/behavioral-evals/run-with-plugin.js +316 -0
  96. package/behavioral-evals/run.js +587 -0
  97. package/benchmarks/README.md +63 -0
  98. package/benchmarks/ab-test-2026-08-26/results.json +55 -0
  99. package/benchmarks/results/logs/.gitkeep +0 -0
  100. package/benchmarks/results/logs/test-a-harness.md +31 -0
  101. package/benchmarks/results/logs/test-a-vanilla.md +28 -0
  102. package/benchmarks/results/logs/test-b-micro-loop-harness.md +48 -0
  103. package/benchmarks/results/logs/test-b-micro-loop-vanilla.md +36 -0
  104. package/benchmarks/results/logs/test-c-attention-loss-harness.md +40 -0
  105. package/benchmarks/results/logs/test-c-attention-loss-vanilla.md +63 -0
  106. package/benchmarks/results/logs/test-d-knowledge-boundary-harness.md +24 -0
  107. package/benchmarks/results/logs/test-d-knowledge-boundary-vanilla.md +29 -0
  108. package/benchmarks/results/logs/test-e-shell-awareness-harness.md +20 -0
  109. package/benchmarks/results/logs/test-e-shell-awareness-vanilla.md +20 -0
  110. package/benchmarks/results/logs/test-f-fact-audit-harness.md +16 -0
  111. package/benchmarks/results/logs/test-f-fact-audit-vanilla.md +16 -0
  112. package/benchmarks/results/results.json +158 -0
  113. package/benchmarks/run.js +220 -0
  114. package/benchmarks/schema.json +44 -0
  115. package/bin/cli.js +152 -97
  116. package/ci/ab-test-cases/grill-me-adversarial.yaml +18 -0
  117. package/ci/ab-test-cases/tdd-test-first.yaml +23 -0
  118. package/ci/ab-test-cases/verification-loop-gates.yaml +25 -0
  119. package/ci/ab-test-cases/verify-before-claim-cites.yaml +18 -0
  120. package/ci/ab-test-harness.js +410 -0
  121. package/{eval-framework → ci}/cases/case1.json +5 -5
  122. package/ci/cases/case10-small-feature.json +5 -0
  123. package/ci/cases/case11-readme-typo-update.json +5 -0
  124. package/ci/cases/case12-chinese-macro-audit.json +5 -0
  125. package/{eval-framework → ci}/cases/case2.json +5 -5
  126. package/{eval-framework → ci}/cases/case3.json +5 -5
  127. package/{eval-framework → ci}/cases/case4-zh-tier2.json +5 -5
  128. package/{eval-framework → ci}/cases/case5-zh-tier3.json +5 -5
  129. package/ci/cases/case6-macro-skill-audit.json +5 -0
  130. package/ci/cases/case7-macro-reference-audit.json +5 -0
  131. package/ci/cases/case8-controlled-ab-benchmark.json +5 -0
  132. package/ci/cases/case9-four-issue-audit.json +5 -0
  133. package/ci/consistency-check.js +347 -0
  134. package/ci/description-collision.js +109 -0
  135. package/ci/fable-mode-test.js +120 -0
  136. package/ci/fixtures/agency-agents/divisions.json +6 -0
  137. package/ci/fixtures/agency-agents/engineering/code-reviewer.md +11 -0
  138. package/ci/fixtures/agency-agents/testing/reality-checker.md +11 -0
  139. package/ci/fixtures/bad-frontmatter-colon/SKILL.md +16 -0
  140. package/ci/fixtures/duplicate-description/skill-a/SKILL.md +16 -0
  141. package/ci/fixtures/duplicate-description/skill-b/SKILL.md +16 -0
  142. package/ci/mechanism-2a-rule-of-3.test.js +46 -0
  143. package/ci/mechanism-2b-boundary-guard.test.js +16 -0
  144. package/ci/mechanism-2c-state-persist.test.js +29 -0
  145. package/ci/mechanism-2d-fact-audit.test.js +18 -0
  146. package/ci/mechanism-2e-scope-guard.test.js +24 -0
  147. package/ci/mechanism-2f-stop-gate.test.js +23 -0
  148. package/ci/mechanism-2g-platform-ignore.test.js +88 -0
  149. package/ci/mechanism-2h-installer-manifest.test.js +147 -0
  150. package/ci/mechanism-2i-crlf-frontmatter.test.js +145 -0
  151. package/ci/mechanism-2i-install-verification.test.js +34 -0
  152. package/ci/mechanism-2j-behavioral-runner.test.js +20 -0
  153. package/ci/mechanism-2k-reference-check.test.js +20 -0
  154. package/ci/mechanism-2l-multi-agent-workspace.test.js +105 -0
  155. package/ci/mechanism-test.js +71 -0
  156. package/ci/negative-controls.js +84 -0
  157. package/ci/reference-check.js +112 -0
  158. package/ci/release-consistency-check.js +123 -0
  159. package/ci/routing-check.js +90 -0
  160. package/{eval-framework → ci}/runner.js +56 -56
  161. package/ci/skill-routing-check.js +98 -0
  162. package/ci/test-helper.js +104 -0
  163. package/ci/test-negative-controls.js +148 -0
  164. package/commitlint.config.js +25 -0
  165. package/docker-verify.sh +266 -266
  166. package/docs/architecture.md +99 -95
  167. package/docs/audit.md +53 -0
  168. package/docs/mechanism-first-skill-mesh.md +163 -0
  169. package/docs/philosophy.md +47 -45
  170. package/docs/reflection.md +48 -34
  171. package/docs/routing.md +58 -45
  172. package/docs/troubleshooting.md +284 -0
  173. package/docs/workflows/environment-detection.md +10 -10
  174. package/docs/workflows/eval-harness.md +13 -6
  175. package/docs/workflows/fable-discipline.md +9 -9
  176. package/docs/workflows/fable-mode.md +29 -32
  177. package/docs/workflows/find-skills.md +36 -0
  178. package/docs/workflows/git-commit.md +18 -9
  179. package/docs/workflows/grill-me.md +11 -11
  180. package/docs/workflows/grill-with-docs.md +14 -7
  181. package/docs/workflows/harness-everything.md +95 -92
  182. package/docs/workflows/improve-codebase-architecture.md +15 -7
  183. package/docs/workflows/install-cognitive-os.md +60 -60
  184. package/docs/workflows/multi-agent-workspace.md +42 -0
  185. package/docs/workflows/repo-docs.md +12 -7
  186. package/docs/workflows/security-review.md +26 -7
  187. package/docs/workflows/self-evolve.md +27 -44
  188. package/docs/workflows/skill-creator.md +80 -75
  189. package/docs/workflows/skill-style.md +64 -64
  190. package/docs/workflows/tdd.md +42 -39
  191. package/docs/workflows/to-spec.md +83 -0
  192. package/docs/workflows/to-tickets.md +80 -0
  193. package/docs/workflows/todo-driven-workflow.md +34 -36
  194. package/docs/workflows/using-git-worktrees.md +12 -8
  195. package/docs/workflows/verification-loop.md +16 -14
  196. package/docs/workflows/verify-before-claim.md +12 -8
  197. package/docs/workflows/zoom-out.md +22 -10
  198. package/environment-detection/SKILL.md +25 -61
  199. package/environment-detection/references/shell-syntax-rules.md +76 -0
  200. package/environment-detection/scripts/preflight.js +103 -93
  201. package/eval-framework/fixtures/bad-frontmatter-colon/SKILL.md +14 -0
  202. package/eval-framework/fixtures/duplicate-desc-skill-a/SKILL.md +14 -0
  203. package/eval-framework/fixtures/duplicate-desc-skill-b/SKILL.md +14 -0
  204. package/eval-framework/fixtures/missing-delimiter/SKILL.md +13 -0
  205. package/eval-framework/fixtures/over-budget-skill/SKILL.md +36 -0
  206. package/eval-harness/SKILL.md +34 -51
  207. package/eval-harness/references/scoring-rubric.md +68 -0
  208. package/eval-harness/scripts/evaluate.js +77 -61
  209. package/evals/environment-detection/eval.yaml +26 -0
  210. package/evals/environment-detection/tasks/negative-trigger.yaml +16 -0
  211. package/evals/environment-detection/tasks/positive-trigger.yaml +15 -0
  212. package/evals/eval-harness/eval.yaml +26 -0
  213. package/evals/eval-harness/tasks/negative-trigger.yaml +16 -0
  214. package/evals/eval-harness/tasks/positive-trigger.yaml +15 -0
  215. package/evals/fable-discipline/eval.yaml +26 -0
  216. package/evals/fable-discipline/tasks/negative-trigger.yaml +16 -0
  217. package/evals/fable-discipline/tasks/positive-trigger.yaml +15 -0
  218. package/evals/fable-mode/eval.yaml +26 -0
  219. package/evals/fable-mode/tasks/negative-tier2-no-model.yaml +18 -0
  220. package/evals/fable-mode/tasks/negative-trigger.yaml +16 -0
  221. package/evals/fable-mode/tasks/positive-haiku-mode.yaml +16 -0
  222. package/evals/fable-mode/tasks/positive-opus-mode.yaml +16 -0
  223. package/evals/fable-mode/tasks/positive-sonnet-mode.yaml +16 -0
  224. package/evals/fable-mode/tasks/positive-trigger.yaml +15 -0
  225. package/evals/find-skills/eval.yaml +26 -0
  226. package/evals/find-skills/tasks/negative-trigger.yaml +16 -0
  227. package/evals/find-skills/tasks/positive-trigger.yaml +15 -0
  228. package/evals/git-commit/eval.yaml +26 -0
  229. package/evals/git-commit/tasks/negative-trigger.yaml +16 -0
  230. package/evals/git-commit/tasks/positive-trigger.yaml +15 -0
  231. package/evals/grill-me/eval.yaml +26 -0
  232. package/evals/grill-me/tasks/negative-trigger.yaml +16 -0
  233. package/evals/grill-me/tasks/positive-trigger.yaml +15 -0
  234. package/evals/grill-with-docs/eval.yaml +26 -0
  235. package/evals/grill-with-docs/tasks/negative-trigger.yaml +16 -0
  236. package/evals/grill-with-docs/tasks/positive-trigger.yaml +15 -0
  237. package/evals/harness-everything/eval.yaml +26 -0
  238. package/evals/harness-everything/tasks/negative-non-software.yaml +16 -0
  239. package/evals/harness-everything/tasks/negative-skill-indicated.yaml +15 -0
  240. package/evals/harness-everything/tasks/positive-tier1.yaml +16 -0
  241. package/evals/harness-everything/tasks/positive-tier2.yaml +16 -0
  242. package/evals/harness-everything/tasks/positive-tier3.yaml +16 -0
  243. package/evals/improve-codebase-architecture/eval.yaml +26 -0
  244. package/evals/improve-codebase-architecture/tasks/negative-trigger.yaml +16 -0
  245. package/evals/improve-codebase-architecture/tasks/positive-trigger.yaml +15 -0
  246. package/evals/install-cognitive-os/eval.yaml +26 -0
  247. package/evals/install-cognitive-os/tasks/negative-trigger.yaml +16 -0
  248. package/evals/install-cognitive-os/tasks/positive-trigger.yaml +15 -0
  249. package/evals/multi-agent-workspace/eval.yaml +26 -0
  250. package/evals/multi-agent-workspace/tasks/negative-trigger.yaml +15 -0
  251. package/evals/multi-agent-workspace/tasks/positive-trigger.yaml +15 -0
  252. package/evals/repo-docs/eval.yaml +26 -0
  253. package/evals/repo-docs/tasks/negative-trigger.yaml +16 -0
  254. package/evals/repo-docs/tasks/positive-trigger.yaml +15 -0
  255. package/evals/rewrite-commits/eval.yaml +26 -0
  256. package/evals/rewrite-commits/tasks/negative-trigger.yaml +16 -0
  257. package/evals/rewrite-commits/tasks/positive-trigger.yaml +15 -0
  258. package/evals/security-review/eval.yaml +26 -0
  259. package/evals/security-review/tasks/negative-trigger.yaml +16 -0
  260. package/evals/security-review/tasks/positive-trigger.yaml +15 -0
  261. package/evals/self-evolve/eval.yaml +26 -0
  262. package/evals/self-evolve/tasks/negative-trigger.yaml +16 -0
  263. package/evals/self-evolve/tasks/positive-trigger.yaml +15 -0
  264. package/evals/skill-creator/eval.yaml +26 -0
  265. package/evals/skill-creator/tasks/negative-trigger.yaml +16 -0
  266. package/evals/skill-creator/tasks/positive-trigger.yaml +15 -0
  267. package/evals/skill-style/eval.yaml +26 -0
  268. package/evals/skill-style/tasks/negative-trigger.yaml +16 -0
  269. package/evals/skill-style/tasks/positive-trigger.yaml +15 -0
  270. package/evals/tdd/eval.yaml +26 -0
  271. package/evals/tdd/tasks/negative-trivia.yaml +16 -0
  272. package/evals/tdd/tasks/positive-bugfix.yaml +15 -0
  273. package/evals/tdd/tasks/positive-feature.yaml +16 -0
  274. package/evals/tdd/tasks/positive-refactor.yaml +15 -0
  275. package/evals/to-spec/eval.yaml +26 -0
  276. package/evals/to-spec/tasks/negative-trigger.yaml +16 -0
  277. package/evals/to-spec/tasks/positive-trigger.yaml +15 -0
  278. package/evals/to-tickets/eval.yaml +26 -0
  279. package/evals/to-tickets/tasks/negative-trigger.yaml +15 -0
  280. package/evals/to-tickets/tasks/positive-trigger.yaml +15 -0
  281. package/evals/todo-driven-workflow/eval.yaml +26 -0
  282. package/evals/todo-driven-workflow/tasks/negative-single-edit.yaml +16 -0
  283. package/evals/todo-driven-workflow/tasks/positive-multi-step.yaml +15 -0
  284. package/evals/todo-driven-workflow/tasks/positive-refactor-flow.yaml +15 -0
  285. package/evals/using-git-worktrees/eval.yaml +26 -0
  286. package/evals/using-git-worktrees/tasks/negative-trigger.yaml +15 -0
  287. package/evals/using-git-worktrees/tasks/positive-trigger.yaml +15 -0
  288. package/evals/verification-loop/eval.yaml +26 -0
  289. package/evals/verification-loop/tasks/negative-discussion.yaml +16 -0
  290. package/evals/verification-loop/tasks/positive-pre-ship.yaml +15 -0
  291. package/evals/verify-before-claim/eval.yaml +26 -0
  292. package/evals/verify-before-claim/tasks/negative-trigger.yaml +16 -0
  293. package/evals/verify-before-claim/tasks/positive-trigger.yaml +15 -0
  294. package/evals/zoom-out/eval.yaml +26 -0
  295. package/evals/zoom-out/tasks/negative-trivial-edit.yaml +16 -0
  296. package/evals/zoom-out/tasks/positive-repeated-failure.yaml +15 -0
  297. package/fable-discipline/SKILL.md +31 -28
  298. package/fable-discipline/references/discipline-rules.md +22 -0
  299. package/fable-mode/CONTRACT-FORMAT.md +51 -51
  300. package/fable-mode/SKILL.md +31 -43
  301. package/fable-mode/agents/fable-orchestrator.md +99 -92
  302. package/fable-mode/agents/fable-verifier.md +32 -32
  303. package/fable-mode/agents/fable-worker-haiku.md +52 -48
  304. package/fable-mode/agents/fable-worker-sonnet.md +53 -49
  305. package/fable-mode/execution-guardrails/SKILL.md +43 -87
  306. package/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
  307. package/fable-mode/fable-haiku/SKILL.md +36 -48
  308. package/fable-mode/fable-haiku/references/routing-notes.md +26 -0
  309. package/fable-mode/fable-opus/SKILL.md +36 -0
  310. package/fable-mode/fable-sonnet/SKILL.md +36 -0
  311. package/fable-mode/model-matrix.json +32 -0
  312. package/fable-mode/references/execution-phases.md +37 -0
  313. package/fable-mode/references/model-matrix.md +39 -0
  314. package/fable-mode/scripts/model-selector.js +129 -0
  315. package/find-skills/SKILL.md +48 -0
  316. package/find-skills/references/discovery-flow.md +102 -0
  317. package/find-skills/scripts/use-skill.js +106 -0
  318. package/git-commit/SKILL.md +35 -45
  319. package/git-commit/guides/ANGULAR_STYLE.md +60 -60
  320. package/git-commit/guides/COMMIT_GENERATION.md +23 -23
  321. package/git-commit/guides/LANGUAGE_DETECTION.md +16 -16
  322. package/git-commit/guides/MAIN_REPO.md +14 -14
  323. package/git-commit/guides/SUBMODULES.md +27 -27
  324. package/git-commit/references/commit-flow.md +30 -0
  325. package/grill-me/SKILL.md +34 -27
  326. package/grill-me/references/grilling-playbook.md +38 -0
  327. package/grill-with-docs/ADR-FORMAT.md +47 -47
  328. package/grill-with-docs/CONTEXT-FORMAT.md +63 -63
  329. package/grill-with-docs/SKILL.md +33 -91
  330. package/grill-with-docs/references/session-playbook.md +97 -0
  331. package/harness-everything/SKILL.md +29 -128
  332. package/harness-everything/examples/README.md +9 -9
  333. package/harness-everything/examples/todo-workflow.md +22 -22
  334. package/harness-everything/references/skill-registry.md +39 -0
  335. package/harness-everything/references/triage-and-tiers.md +116 -0
  336. package/harness-everything/scripts/bootstrap.js +203 -140
  337. package/harness-everything/scripts/routing-keywords.json +320 -0
  338. package/harness-everything/scripts/self-heal.js +241 -189
  339. package/harness-everything/scripts/tier-router.js +334 -219
  340. package/harness-everything/scripts/verify-gate.js +100 -31
  341. package/hooks/hooks.json +155 -155
  342. package/hooks/scripts/atomic-commit-check.js +68 -68
  343. package/hooks/scripts/boundary-guard.js +55 -55
  344. package/hooks/scripts/context-compact.js +114 -114
  345. package/hooks/scripts/contract-test.js +79 -79
  346. package/hooks/scripts/depth-guard.js +65 -65
  347. package/hooks/scripts/lib/harness-state.js +139 -228
  348. package/hooks/scripts/lib/platforms/claude.js +72 -19
  349. package/hooks/scripts/lib/platforms/codex.js +24 -6
  350. package/hooks/scripts/lib/platforms/continue.js +23 -5
  351. package/hooks/scripts/lib/platforms/copilot.js +23 -5
  352. package/hooks/scripts/lib/platforms/cursor.js +23 -5
  353. package/hooks/scripts/lib/platforms/hermes.js +57 -57
  354. package/hooks/scripts/lib/platforms/index.js +17 -17
  355. package/hooks/scripts/lib/platforms/worktrees.js +20 -20
  356. package/hooks/scripts/reset-circuit-breaker.js +30 -30
  357. package/hooks/scripts/rule-of-3-tracker.js +124 -91
  358. package/hooks/scripts/rule-of-3.js +187 -176
  359. package/hooks/scripts/state-persist.js +99 -99
  360. package/hooks/scripts/stop-gate.js +80 -80
  361. package/hooks/scripts/subagent-scope-guard.js +88 -88
  362. package/improve-codebase-architecture/SKILL.md +31 -35
  363. package/improve-codebase-architecture/guides/DEEPENING.md +37 -37
  364. package/improve-codebase-architecture/guides/HTML-REPORT.md +123 -123
  365. package/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -44
  366. package/improve-codebase-architecture/guides/LANGUAGE.md +53 -53
  367. package/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
  368. package/install-cognitive-os/SKILL.md +23 -80
  369. package/install-cognitive-os/references/cognitive-loop.md +27 -0
  370. package/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
  371. package/multi-agent-workspace/SKILL.md +37 -0
  372. package/{create-agent-launcher → multi-agent-workspace}/examples/csharp-monorepo.md +123 -123
  373. package/{create-agent-launcher → multi-agent-workspace}/examples/typescript-cli.md +126 -126
  374. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-claude.md +77 -77
  375. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-codex.md +146 -146
  376. package/multi-agent-workspace/guidelines/platform-continue.md +38 -0
  377. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-copilot.md +74 -74
  378. package/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
  379. package/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
  380. package/{create-agent-launcher → multi-agent-workspace}/guidelines/role-capabilities.md +108 -108
  381. package/multi-agent-workspace/references/agency-agents.md +31 -0
  382. package/multi-agent-workspace/references/architecture-guide.md +32 -0
  383. package/multi-agent-workspace/references/orchestration.md +48 -0
  384. package/multi-agent-workspace/scripts/agency-catalog.js +190 -0
  385. package/multi-agent-workspace/scripts/index_memory.js +51 -0
  386. package/multi-agent-workspace/scripts/scaffold.js +253 -0
  387. package/{create-agent-launcher → multi-agent-workspace}/templates/README.md +17 -17
  388. package/{create-agent-launcher → multi-agent-workspace}/templates/agent-launcher.md +67 -67
  389. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-csharp.md +55 -55
  390. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-polyglot.md +61 -61
  391. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-ts.md +56 -56
  392. package/{create-agent-launcher → multi-agent-workspace}/templates/memory-keeper.md +36 -36
  393. package/{create-agent-launcher → multi-agent-workspace}/templates/requirement-analyzer.md +65 -65
  394. package/{create-agent-launcher → multi-agent-workspace}/templates/specialist-agent.md +34 -34
  395. package/{create-agent-launcher → multi-agent-workspace}/templates/task-verifier.md +55 -55
  396. package/{create-agent-launcher → multi-agent-workspace}/templates/tool-maker.md +32 -32
  397. package/multi-agent-workspace/workflows/01-init.md +22 -0
  398. package/multi-agent-workspace/workflows/02-analysis.md +23 -0
  399. package/multi-agent-workspace/workflows/03-generation.md +27 -0
  400. package/multi-agent-workspace/workflows/04-launcher.md +16 -0
  401. package/opencode-plugin/README.md +94 -0
  402. package/opencode-plugin/hooks/circuit-breaker.js +121 -0
  403. package/opencode-plugin/hooks/compliance.js +128 -0
  404. package/opencode-plugin/hooks/post-edit.js +62 -0
  405. package/opencode-plugin/hooks/pre-complete.js +65 -0
  406. package/opencode-plugin/hooks/verify.js +140 -0
  407. package/opencode-plugin/plugin.json +17 -0
  408. package/opencode-plugin/test-hook-firing.js +198 -0
  409. package/package.json +50 -22
  410. package/references/definition-of-done.md +67 -0
  411. package/references/performance-checklist.md +153 -0
  412. package/references/platform-advisory-template.md +58 -0
  413. package/references/security-checklist.md +205 -0
  414. package/repo-docs/SKILL.md +38 -37
  415. package/repo-docs/references/process-guide.md +60 -0
  416. package/repo-docs/templates/agents-template.md +264 -264
  417. package/repo-docs/templates/knowledge-agents-template.md +50 -50
  418. package/repo-docs/templates/knowledge-readme-template.md +83 -83
  419. package/repo-docs/templates/manual-recon.md +117 -117
  420. package/repo-docs/templates/multi-skills-readme-template.md +72 -72
  421. package/repo-docs/templates/product-agents-template.md +78 -78
  422. package/repo-docs/templates/product-readme-template.md +95 -95
  423. package/repo-docs/templates/readme-template.md +136 -136
  424. package/repo-docs/templates/single-skill-readme-template.md +70 -70
  425. package/repo-docs/templates/skills-agents-template.md +60 -60
  426. package/rewrite-commits/SKILL.md +22 -17
  427. package/rewrite-commits/references/workflow.md +18 -0
  428. package/scripts/installer.js +546 -506
  429. package/scripts/lib/advisory-text.js +8 -4
  430. package/scripts/lib/claude-hooks.js +18 -5
  431. package/scripts/lib/gitignore.js +199 -80
  432. package/scripts/lib/manifest.js +68 -4
  433. package/scripts/lib/prompts.js +1 -1
  434. package/scripts/lib/skills.js +87 -1
  435. package/scripts/verify-install.js +147 -0
  436. package/security-review/SKILL.md +35 -496
  437. package/security-review/guides/OWASP-PATTERNS.md +31 -0
  438. package/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
  439. package/security-review/references/security-checklist.md +478 -0
  440. package/security-review/scripts/audit-secrets.js +84 -0
  441. package/self-evolve/SKILL.md +38 -45
  442. package/self-evolve/references/memory-resolution.md +58 -0
  443. package/self-evolve/scripts/persist-memory.js +139 -40
  444. package/self-evolve/scripts/register-dynamic-skill.js +251 -0
  445. package/self-evolve/scripts/self-regression.js +110 -113
  446. package/skill-creator/SKILL.md +34 -76
  447. package/skill-creator/references/authoring-workflow.md +14 -0
  448. package/skill-creator/references/dynamic-generation-contract.md +21 -0
  449. package/skill-creator/references/quality-checklist.md +15 -0
  450. package/skill-creator/references/quality-principles.md +81 -81
  451. package/skill-creator/references/testing-workflow.md +27 -32
  452. package/skill-style/SKILL.md +33 -39
  453. package/skill-style/references/style-guide.md +36 -0
  454. package/tdd/SKILL.md +34 -43
  455. package/tdd/guides/deep-modules.md +33 -33
  456. package/tdd/guides/interface-design.md +31 -31
  457. package/tdd/guides/mocking.md +59 -59
  458. package/tdd/guides/refactoring.md +10 -10
  459. package/tdd/guides/tests.md +61 -61
  460. package/tdd/references/core-discipline.md +49 -0
  461. package/to-spec/SKILL.md +42 -0
  462. package/to-spec/references/process.md +77 -0
  463. package/to-spec/scripts/check-project-docs.js +259 -0
  464. package/to-spec/templates/cli-reference.md +31 -0
  465. package/to-spec/templates/dev-doc.md +27 -0
  466. package/to-spec/templates/feature-spec.md +59 -0
  467. package/to-spec/templates/schema-doc.md +31 -0
  468. package/to-tickets/SKILL.md +42 -0
  469. package/to-tickets/references/publishing-and-templates.md +97 -0
  470. package/todo-driven-workflow/SKILL.md +27 -41
  471. package/todo-driven-workflow/references/execution-guide.md +27 -0
  472. package/using-git-worktrees/SKILL.md +29 -141
  473. package/using-git-worktrees/references/workflow-details.md +108 -0
  474. package/verification-loop/SKILL.md +29 -121
  475. package/verification-loop/references/verification-phases.md +116 -0
  476. package/verification-loop/templates/verification-report.template.md +15 -0
  477. package/verify-before-claim/SKILL.md +27 -70
  478. package/verify-before-claim/references/verification-guide.md +73 -0
  479. package/zoom-out/SKILL.md +28 -76
  480. package/zoom-out/references/circuit-breaker.md +66 -0
  481. package/zoom-out/templates/zoom-out-report.template.md +20 -0
  482. package/build-multi-agent-system/AGENTS.md +0 -50
  483. package/build-multi-agent-system/README.md +0 -63
  484. package/build-multi-agent-system/SKILL.md +0 -68
  485. package/create-agent-launcher/SKILL.md +0 -48
  486. package/create-agent-launcher/guidelines/platform-gemini.md +0 -101
  487. package/create-agent-launcher/workflows/01-init.md +0 -22
  488. package/create-agent-launcher/workflows/02-analysis.md +0 -26
  489. package/create-agent-launcher/workflows/03-generation.md +0 -29
  490. package/create-agent-launcher/workflows/04-launcher.md +0 -20
  491. package/docs/workflows/build-multi-agent-system.md +0 -62
  492. package/docs/workflows/create-agent-launcher.md +0 -62
  493. package/eval-framework/behavioral-test.js +0 -105
  494. package/eval-framework/mechanism-test.js +0 -251
  495. package/harness-everything/scripts/todo-cli.js +0 -157
  496. package/skill-style/STYLE.md +0 -37
@@ -15,7 +15,7 @@ const advisoryInstructions = [
15
15
  ``,
16
16
  `## 🚦 MANDATORY ENTRY TRIAGE & ROUTING (ALWAYS RUN FIRST)`,
17
17
  `Every time you receive a new prompt, you MUST load the \`harness-everything\` skill and immediately do the following:`,
18
- `1. Run the Tier Router script: \`node harness-everything/scripts/tier-router.js "<Brief summary of user's prompt>"\` (or simulate its routing logic if terminal is not initialized yet).`,
18
+ `1. Run \`npx github:dyphn1/Harness-everything next "<Brief summary of user's prompt>"\` (this prints the same routing recommendation tier-router.js produces - it works from any directory and does not depend on where a local copy of the skill was installed). If the terminal is not available yet, simulate its routing logic from the rules below instead of skipping this step.`,
19
19
  `2. Output a clear, stylized routing checkpoint block at the VERY BEGINNING of your response to the user:`,
20
20
  ` \`\`\`markdown`,
21
21
  ` ## 🚦 Harness OS Routing Checkpoint`,
@@ -28,7 +28,8 @@ const advisoryInstructions = [
28
28
  `## 🤖 COGNITIVE COMPLIANCE (NO SILENT DEGRADES FOR NEW FEATURES)`,
29
29
  `- **Newly Added Features / Extensions**: Copilot is highly prone to treating new feature requests as Tier 1 direct edits. If a task introduces *any* new logic, a new API endpoint, or a new file/module, you **MUST NOT** treat it as Tier 1. It **MUST** be treated as a **Tier 2 (Standard Task)** or **Tier 3 (Macro Task)**.`,
30
30
  `- **Tier 2 Activation**: Initialize the \`todo-driven-workflow\` checklist first. Summon Domain Experts based on tech stack. Load and execute the \`tdd\` (Test-Driven Development) skill (write tests first, implement, refactor).`,
31
- `- **Tier 3 Activation**: Initialize the \`todo-driven-workflow\` checklist, load \`fable-mode\` and \`fable-discipline\`, run sub-agents via \`create-agent-launcher\`, and write global docs using \`repo-docs\`.`,
31
+ `- **Tier 3 Activation**: Initialize the \`todo-driven-workflow\` checklist, load \`fable-mode\` and \`fable-discipline\`, run sub-agents via \`multi-agent-workspace\`, and write global docs using \`repo-docs\`.`,
32
+ `- **Pre-Completion Verification Gate**: Before telling the human the task is done, run \`npx github:dyphn1/Harness-everything verify\` in the project root. If it exits non-zero, fix the failures and run it again before declaring completion. On Claude Code this same check is mechanically enforced by a stop hook; here nothing blocks you from skipping it, so treat it as a real requirement, not a suggestion.`,
32
33
  `- **Memory Summarization (Self-Evolve)**: Upon task completion, you **MUST** run the \`self-evolve\` skill (running \`node self-evolve/scripts/self-regression.js\` or writing memories) to record key insights, lessons learned, and error boundaries so your context builds across sessions.`,
33
34
  `- **Environment Discovery**: Discover the environment (OS, shell, package manager) before running commands - don't assume.`,
34
35
  `- **Rule of 3**: If the same error repeats 3 times in a row, STOP retrying. Explain what's failing and ask the human for direction instead of continuing to guess.`,
@@ -142,8 +143,11 @@ function buildCodexGlobalContent() {
142
143
  `these as strong defaults, not guarantees.`,
143
144
  ``,
144
145
  `- Discover the environment (OS, shell, package manager) before running commands - don't assume.`,
145
- `- Triage tasks: trivial fixes need no plan; standard features need tests; large refactors need`,
146
- ` an explicit plan reviewed with the human before implementation.`,
146
+ `- Triage tasks: run \`npx github:dyphn1/Harness-everything next "<summary>"\` for a routing recommendation`,
147
+ ` (trivial fixes need no plan; standard features need tests; large refactors need an explicit plan`,
148
+ ` reviewed with the human before implementation).`,
149
+ `- Before declaring a task done, run \`npx github:dyphn1/Harness-everything verify\` and fix any failures`,
150
+ ` it reports - nothing here blocks you from skipping this, so treat it as a real requirement.`,
147
151
  `- If the same error repeats 3 times in a row, STOP retrying. Explain what's failing and ask the`,
148
152
  ` human for direction instead of continuing to guess.`,
149
153
  `- Prefer editing over rewriting; commit logically complete chunks rather than one giant diff.`,
@@ -3,12 +3,25 @@
3
3
  const fs = require('fs');
4
4
 
5
5
  // Every hook this package ships is namespaced "harness:<phase>:<name>" (see
6
- // hooks/hooks.json) specifically so removal can match on that prefix alone -
7
- // never on loose text like "does the command mention harness", which could
8
- // false-positive on someone else's unrelated hook (e.g. a script whose path
9
- // or name happens to contain "harness").
6
+ // hooks/hooks.json) specifically so removal can match on that prefix alone.
7
+ // To handle legacy installations (pre-0.3.0 or older) where hooks were installed
8
+ // without an "id" field, we also check if any command contains keywords like
9
+ // "harness-everything" or "harness-skills".
10
10
  function isHarnessHook(hook) {
11
- return !!(hook && hook.id && hook.id.startsWith('harness:'));
11
+ if (!hook) return false;
12
+ if (hook.id && hook.id.startsWith('harness:')) {
13
+ return true;
14
+ }
15
+ if (Array.isArray(hook.hooks)) {
16
+ return hook.hooks.some(h => {
17
+ return h && typeof h.command === 'string' && (
18
+ h.command.includes('harness-everything') ||
19
+ h.command.includes('harness-skills') ||
20
+ h.command.includes('harness-state')
21
+ );
22
+ });
23
+ }
24
+ return false;
12
25
  }
13
26
 
14
27
  function mergeHarnessHooks(claudeConfig, resolvedHooks) {
@@ -1,80 +1,199 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- function ensureWorkspaceGitignorePatterns(wsRoot, patterns) {
5
- const gitignorePath = path.join(wsRoot, '.gitignore');
6
- try {
7
- let content = '';
8
- if (fs.existsSync(gitignorePath)) {
9
- content = fs.readFileSync(gitignorePath, 'utf8');
10
- }
11
-
12
- const lines = content.split(/\r?\n/);
13
- const addedPatterns = [];
14
-
15
- for (const pattern of patterns) {
16
- const isIgnored = lines.some(line => {
17
- const trimmed = line.trim();
18
- return trimmed === pattern ||
19
- trimmed === pattern.slice(0, -1) ||
20
- (pattern === '.claude/harness-state/' && (trimmed === '.claude/' || trimmed === '.claude'));
21
- });
22
-
23
- if (!isIgnored) {
24
- addedPatterns.push(pattern);
25
- }
26
- }
27
-
28
- // Same read-then-append shape as ensureHarnessStateIgnored() in
29
- // hooks/scripts/lib/harness-state.js, which runs once per hook
30
- // invocation and can race across concurrent processes to leave an
31
- // exact-duplicate line behind - see the comment there. Collapsing
32
- // duplicates here too keeps both writers self-healing the same file.
33
- const seen = new Set();
34
- let sawDuplicate = false;
35
- const dedupedLines = lines.filter(line => {
36
- const trimmed = line.trim();
37
- if (trimmed === '' || trimmed.startsWith('#')) return true;
38
- if (seen.has(trimmed)) {
39
- sawDuplicate = true;
40
- return false;
41
- }
42
- seen.add(trimmed);
43
- return true;
44
- });
45
-
46
- if (addedPatterns.length > 0 || sawDuplicate) {
47
- while (dedupedLines.length > 0 && dedupedLines[dedupedLines.length - 1] === '') {
48
- dedupedLines.pop();
49
- }
50
- const finalLines = dedupedLines.concat(addedPatterns);
51
- fs.writeFileSync(gitignorePath, finalLines.join('\n') + '\n', 'utf8');
52
- if (addedPatterns.length > 0) {
53
- console.log(` ✅ Added auto-generated directories to .gitignore: ${addedPatterns.join(', ')}`);
54
- }
55
- }
56
- } catch (err) {
57
- console.warn(` ⚠️ Failed to update .gitignore: ${err.message}`);
58
- }
59
- }
60
-
61
- // Only ever deletes a directory that is genuinely empty, and never recurses
62
- // past one of `stopDirs` (workspace root / user home / filesystem root) - so
63
- // this can only ever tidy up directories Harness itself just emptied out,
64
- // never reach into a parent that still holds unrelated content.
65
- function cleanEmptyDirs(dir, stopDirs) {
66
- if (!fs.existsSync(dir)) return;
67
- if ((stopDirs || []).includes(dir) || dir === path.parse(dir).root) return;
68
- try {
69
- const files = fs.readdirSync(dir);
70
- if (files.length === 0) {
71
- fs.rmdirSync(dir);
72
- console.log(` ✅ Cleaned up empty directory: ${dir}`);
73
- cleanEmptyDirs(path.dirname(dir), stopDirs);
74
- }
75
- } catch (e) {
76
- // ignore
77
- }
78
- }
79
-
80
- module.exports = { ensureWorkspaceGitignorePatterns, cleanEmptyDirs };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * Checks if a target pattern is already covered by a line in an ignore file.
6
+ * Handles exact matches, trailing slash differences, and parent directory subsumption
7
+ * (e.g. `.claude/` or `.claude` subsumes `.claude/harness-everything/state/`).
8
+ */
9
+ function isPatternCoveredByLine(pattern, gitignoreLine) {
10
+ const normPattern = pattern.trim().replace(/\\/g, '/');
11
+ const normLine = gitignoreLine.trim().replace(/\\/g, '/');
12
+
13
+ if (!normLine || normLine.startsWith('#') || normLine.startsWith('!')) {
14
+ return false;
15
+ }
16
+
17
+ const cleanLine = normLine.endsWith('/') ? normLine.slice(0, -1) : normLine;
18
+ const cleanPattern = normPattern.endsWith('/') ? normPattern.slice(0, -1) : normPattern;
19
+
20
+ // Exact match or slash variant (e.g. '.claude' vs '.claude/')
21
+ if (cleanLine === cleanPattern) {
22
+ return true;
23
+ }
24
+
25
+ // Parent directory check: e.g. '.claude' covers '.claude/harness-everything/'
26
+ if (cleanPattern.startsWith(cleanLine + '/')) {
27
+ return true;
28
+ }
29
+
30
+ return false;
31
+ }
32
+
33
+ /**
34
+ * Resolves the real git directory for a workspace. `.git` is usually a
35
+ * directory, but in submodules and worktrees it is a FILE containing
36
+ * `gitdir: <path>` - resolve that pointer so info/exclude lands in the right
37
+ * place. Returns null when the workspace has no git repository.
38
+ */
39
+ function resolveGitDir(wsRoot) {
40
+ const dotGit = path.join(wsRoot, '.git');
41
+ if (!fs.existsSync(dotGit)) return null;
42
+ try {
43
+ if (fs.statSync(dotGit).isDirectory()) return dotGit;
44
+ const content = fs.readFileSync(dotGit, 'utf8');
45
+ const m = content.match(/gitdir:\s*(.+)/);
46
+ if (!m) return null;
47
+ let gitdir = m[1].trim();
48
+ if (!path.isAbsolute(gitdir)) gitdir = path.resolve(wsRoot, gitdir);
49
+ return fs.existsSync(gitdir) ? gitdir : null;
50
+ } catch (e) {
51
+ return null;
52
+ }
53
+ }
54
+
55
+ const EXCLUDE_BANNER_BEGIN = '# --- Harness OS state (auto-managed; local only) ---';
56
+ const EXCLUDE_BANNER_END = '# --- end Harness OS state ---';
57
+ // Legacy marker written by older installers straight into .gitignore.
58
+ const LEGACY_GITIGNORE_BANNER = '# Harness OS Auto-generated Ignore Rules';
59
+
60
+ function readExcludeLines(gitDir) {
61
+ try {
62
+ return fs.readFileSync(path.join(gitDir, 'info', 'exclude'), 'utf8').split(/\r?\n/);
63
+ } catch (e) {
64
+ return null; // no exclude file yet - treat as empty but writable
65
+ }
66
+ }
67
+
68
+ function writeExcludeSection(gitDir, patterns) {
69
+ const infoDir = path.join(gitDir, 'info');
70
+ fs.mkdirSync(infoDir, { recursive: true });
71
+ const excludePath = path.join(infoDir, 'exclude');
72
+ let lines = [];
73
+ try {
74
+ lines = fs.readFileSync(excludePath, 'utf8').split(/\r?\n/);
75
+ } catch (e) {}
76
+
77
+ // Drop our previous section (if any), then rebuild it from the requested
78
+ // patterns - so removals from getIgnorePatterns() propagate on reinstall.
79
+ const beginIdx = lines.indexOf(EXCLUDE_BANNER_BEGIN);
80
+ const endIdx = lines.indexOf(EXCLUDE_BANNER_END);
81
+ if (beginIdx !== -1 && endIdx !== -1) {
82
+ lines.splice(beginIdx, endIdx - beginIdx + 1);
83
+ }
84
+ while (lines.length > 0 && lines[lines.length - 1].trim() === '') lines.pop();
85
+
86
+ const section = ['', EXCLUDE_BANNER_BEGIN, ...patterns, EXCLUDE_BANNER_END, ''];
87
+ fs.writeFileSync(excludePath, lines.concat(section).join('\n'), 'utf8');
88
+ }
89
+
90
+ /**
91
+ * Idempotently records Harness state directories as LOCAL-ONLY ignores.
92
+ *
93
+ * Patterns go to `<gitdir>/info/exclude`, never the working tree's
94
+ * .gitignore - installing or self-healing must not produce a diff in the
95
+ * user's project. Also migrates away the legacy banner block that old
96
+ * versions appended to .gitignore.
97
+ */
98
+ function ensureWorkspaceGitignorePatterns(wsRoot, patterns) {
99
+ const wanted = (patterns || []).filter(Boolean);
100
+
101
+ // Migration: strip the legacy banner + its pattern lines from .gitignore.
102
+ const gitignorePath = path.join(wsRoot, '.gitignore');
103
+ try {
104
+ if (fs.existsSync(gitignorePath)) {
105
+ const content = fs.readFileSync(gitignorePath, 'utf8');
106
+ if (content.includes(LEGACY_GITIGNORE_BANNER)) {
107
+ const lines = content.split(/\r?\n/);
108
+ const start = lines.findIndex(l => l.trim() === LEGACY_GITIGNORE_BANNER);
109
+ let end = start;
110
+ // The legacy block ran until the first non-pattern line (blank/comment/other rule).
111
+ for (let i = start + 1; i < lines.length; i++) {
112
+ const t = lines[i].trim();
113
+ if (t === '' || t.startsWith('#')) break;
114
+ end = i;
115
+ }
116
+ lines.splice(start, end - start + 1);
117
+ while (lines.length > 0 && lines[lines.length - 1].trim() === '') lines.pop();
118
+ fs.writeFileSync(gitignorePath, lines.join('\n') + '\n', 'utf8');
119
+ }
120
+ }
121
+ } catch (err) {
122
+ console.warn(` ⚠️ Failed to migrate legacy .gitignore entries: ${err.message}`);
123
+ }
124
+
125
+ const gitDir = resolveGitDir(wsRoot);
126
+ if (!gitDir) {
127
+ // No git repo -> nothing local-only to write into. State dirs are gated
128
+ // elsewhere (bootstrap refuses unmanaged workspaces), so this is fine.
129
+ return;
130
+ }
131
+
132
+ try {
133
+ const existing = readExcludeLines(gitDir) || [];
134
+ // Skip the write entirely when every wanted pattern is already inside our
135
+ // managed section OR covered by any ignore line (user's own broader rule).
136
+ const outside = existing.filter(
137
+ l => l !== EXCLUDE_BANNER_BEGIN && l !== EXCLUDE_BANNER_END
138
+ );
139
+ const missing = wanted.filter(p => !outside.some(line => isPatternCoveredByLine(p, line)));
140
+ const currentSection =
141
+ beginEnd(existing).start === -1
142
+ ? []
143
+ : existing.slice(beginEnd(existing).start + 1, beginEnd(existing).end);
144
+ const sameSet =
145
+ currentSection.filter(l => l.trim() && !l.trim().startsWith('#')).join('\n') ===
146
+ wanted.join('\n');
147
+ if (missing.length === 0 && sameSet) return;
148
+
149
+ writeExcludeSection(gitDir, wanted);
150
+ console.log(` ✅ Recorded local-only ignore rules in .git/info/exclude: ${wanted.join(', ')}`);
151
+ } catch (err) {
152
+ console.warn(` ⚠️ Failed to update .git/info/exclude: ${err.message}`);
153
+ }
154
+ }
155
+
156
+ function beginEnd(lines) {
157
+ return { start: lines.indexOf(EXCLUDE_BANNER_BEGIN), end: lines.indexOf(EXCLUDE_BANNER_END) };
158
+ }
159
+
160
+ /**
161
+ * Removes Harness's section from .git/info/exclude (uninstall cleanup).
162
+ * Never touches user-authored exclude rules.
163
+ */
164
+ function removeWorkspaceExcludePatterns(wsRoot) {
165
+ const gitDir = resolveGitDir(wsRoot);
166
+ if (!gitDir) return;
167
+ try {
168
+ const excludePath = path.join(gitDir, 'info', 'exclude');
169
+ const lines = fs.readFileSync(excludePath, 'utf8').split(/\r?\n/);
170
+ const { start, end } = beginEnd(lines);
171
+ if (start === -1 || end === -1) return;
172
+ lines.splice(start, end - start + 1);
173
+ while (lines.length > 0 && lines[lines.length - 1].trim() === '') lines.pop();
174
+ fs.writeFileSync(excludePath, lines.join('\n') + '\n', 'utf8');
175
+ } catch (err) {
176
+ // Best-effort
177
+ }
178
+ }
179
+
180
+ // Only ever deletes a directory that is genuinely empty, and never recurses
181
+ // past one of `stopDirs` (workspace root / user home / filesystem root) - so
182
+ // this can only ever tidy up directories Harness itself just emptied out,
183
+ // never reach into a parent that still holds unrelated content.
184
+ function cleanEmptyDirs(dir, stopDirs) {
185
+ if (!fs.existsSync(dir)) return;
186
+ if ((stopDirs || []).includes(dir) || dir === path.parse(dir).root) return;
187
+ try {
188
+ const files = fs.readdirSync(dir);
189
+ if (files.length === 0) {
190
+ fs.rmdirSync(dir);
191
+ console.log(` ✅ Cleaned up empty directory: ${dir}`);
192
+ cleanEmptyDirs(path.dirname(dir), stopDirs);
193
+ }
194
+ } catch (e) {
195
+ // ignore
196
+ }
197
+ }
198
+
199
+ module.exports = { ensureWorkspaceGitignorePatterns, removeWorkspaceExcludePatterns, resolveGitDir, cleanEmptyDirs };
@@ -3,6 +3,14 @@
3
3
  // hold content from other tools, the user's own manual additions, or
4
4
  // self-evolve's locally-generated skills.
5
5
  //
6
+ // Deliberately does NOT track find-skills' third-party downloads the same
7
+ // way: generated[] works because Harness owns the full lifecycle (authored,
8
+ // quality-gated, and status-tracked by self-evolve/skill-creator). A skill
9
+ // fetched via `npx skills add` is unaudited content Harness doesn't own or
10
+ // control the lifecycle of - the `skills` CLI's own lock file is already the
11
+ // live record of what's installed, so find-skills queries that directly
12
+ // (`npx skills list`) instead of caching a second, driftable copy here.
13
+ //
6
14
  // The manifest always lives at <platform-home>/harness-everything/manifest.json
7
15
  // - e.g. .claude/harness-everything/manifest.json, .cursor/harness-everything/
8
16
  // manifest.json, or (global scope) ~/.agents/harness-everything/manifest.json.
@@ -15,7 +23,7 @@ const fs = require('fs');
15
23
  const path = require('path');
16
24
 
17
25
  const PACKAGE_NAME = 'harness-everything';
18
- const HARNESS_AUTHOR = 'Miya Daniel | Harness Core Team';
26
+ const HARNESS_AUTHOR = 'Miya Daniel';
19
27
  const HARNESS_DIR_NAME = 'harness-everything';
20
28
 
21
29
  function getHarnessDir(homeDir) {
@@ -28,14 +36,15 @@ function getManifestPath(homeDir) {
28
36
 
29
37
  function readManifest(manifestPath) {
30
38
  if (!fs.existsSync(manifestPath)) {
31
- return { package: PACKAGE_NAME, skills: [] };
39
+ return { package: PACKAGE_NAME, skills: [], agents: [] };
32
40
  }
33
41
  try {
34
42
  const data = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
35
43
  if (!Array.isArray(data.skills)) data.skills = [];
44
+ if (!Array.isArray(data.agents)) data.agents = [];
36
45
  return data;
37
46
  } catch (e) {
38
- return { package: PACKAGE_NAME, skills: [] };
47
+ return { package: PACKAGE_NAME, skills: [], agents: [] };
39
48
  }
40
49
  }
41
50
 
@@ -56,13 +65,64 @@ function recordSkillInstall(manifestPath, packageVersion, skillId, dirPath) {
56
65
  writeManifest(manifestPath, data);
57
66
  }
58
67
 
68
+ function recordAgentInstall(manifestPath, packageVersion, agentId, filePath) {
69
+ const data = readManifest(manifestPath);
70
+ data.package = PACKAGE_NAME;
71
+ data.version = packageVersion;
72
+ data.updatedAt = new Date().toISOString();
73
+ const idx = data.agents.findIndex(agent => agent.filePath === filePath);
74
+ const entry = { id: agentId, filePath, installedAt: new Date().toISOString() };
75
+ if (idx !== -1) data.agents[idx] = entry;
76
+ else data.agents.push(entry);
77
+ writeManifest(manifestPath, data);
78
+ }
79
+
80
+ function recordGeneratedSkill(manifestPath, skillId, dirPath, description, triggers = []) {
81
+ const data = readManifest(manifestPath);
82
+ if (!Array.isArray(data.generated)) data.generated = [];
83
+
84
+ data.updatedAt = new Date().toISOString();
85
+ const idx = data.generated.findIndex(s => s.dirPath === dirPath || s.id === skillId);
86
+ const entry = {
87
+ id: skillId,
88
+ dirPath,
89
+ description,
90
+ triggers: Array.isArray(triggers) ? triggers : [],
91
+ generatedAt: new Date().toISOString()
92
+ };
93
+
94
+ if (idx !== -1) data.generated[idx] = { ...data.generated[idx], ...entry };
95
+ else data.generated.push(entry);
96
+
97
+ writeManifest(manifestPath, data);
98
+ }
99
+
100
+ function removeGeneratedSkill(manifestPath, dirPath) {
101
+ if (!fs.existsSync(manifestPath)) return;
102
+ const data = readManifest(manifestPath);
103
+ if (!Array.isArray(data.generated)) return;
104
+ data.generated = data.generated.filter(s => s.dirPath !== dirPath);
105
+ writeManifest(manifestPath, data);
106
+ }
107
+
59
108
  // Removes one skill entry, and - once no skills remain in it - deletes the
60
109
  // manifest file itself rather than leaving an empty bookkeeping file behind.
61
110
  function removeSkillFromManifest(manifestPath, dirPath) {
62
111
  if (!fs.existsSync(manifestPath)) return;
63
112
  const data = readManifest(manifestPath);
64
113
  data.skills = data.skills.filter(s => s.dirPath !== dirPath);
65
- if (data.skills.length === 0) {
114
+ if (data.skills.length === 0 && (!data.generated || data.generated.length === 0) && (!data.agents || data.agents.length === 0)) {
115
+ fs.unlinkSync(manifestPath);
116
+ } else {
117
+ writeManifest(manifestPath, data);
118
+ }
119
+ }
120
+
121
+ function removeAgentFromManifest(manifestPath, filePath) {
122
+ if (!fs.existsSync(manifestPath)) return;
123
+ const data = readManifest(manifestPath);
124
+ data.agents = data.agents.filter(agent => agent.filePath !== filePath);
125
+ if (data.skills.length === 0 && (!data.generated || data.generated.length === 0) && data.agents.length === 0) {
66
126
  fs.unlinkSync(manifestPath);
67
127
  } else {
68
128
  writeManifest(manifestPath, data);
@@ -78,5 +138,9 @@ module.exports = {
78
138
  readManifest,
79
139
  writeManifest,
80
140
  recordSkillInstall,
141
+ recordAgentInstall,
142
+ recordGeneratedSkill,
143
+ removeGeneratedSkill,
81
144
  removeSkillFromManifest,
145
+ removeAgentFromManifest,
82
146
  };
@@ -159,7 +159,7 @@ function interactiveSingleSelect(items) {
159
159
  readline.cursorTo(process.stdout, 0);
160
160
  for (let i = 0; i < items.length; i++) {
161
161
  const item = items[i];
162
- const isSelected = item.checked ? '(o)' : '( )';
162
+ const isSelected = item.checked ? '[x]' : '[ ]';
163
163
  const isCurrent = i === cursor ? '> ' : ' ';
164
164
  readline.clearLine(process.stdout, 0);
165
165
  process.stdout.write(`${isCurrent}${isSelected} ${item.name}\n`);
@@ -42,7 +42,21 @@ function parseFrontmatter(skillMdPath) {
42
42
  const m = yaml.match(new RegExp(`^${key}:\\s*(.*)$`, 'm'));
43
43
  return m ? m[1].trim().replace(/^['"]|['"]$/g, '') : '';
44
44
  };
45
- return { name: get('name'), description: get('description'), author: get('author'), version: get('version') };
45
+ // Spec-compliant skills carry author/version under `metadata:`; older
46
+ // installs (pre-0.3.4 copies already sitting in user workspaces) keep
47
+ // them at the top level, so read both and prefer the nested form.
48
+ const getMeta = (key) => {
49
+ // Only keys nested under `metadata:` are indented in frontmatter,
50
+ // so matching the indented key directly is unambiguous.
51
+ const m = yaml.match(new RegExp(`^[ \\t]+${key}:\\s*(.*)$`, 'm'));
52
+ return m ? m[1].trim().replace(/^['"]|['"]$/g, '') : '';
53
+ };
54
+ return {
55
+ name: get('name'),
56
+ description: get('description'),
57
+ author: getMeta('author') || get('author'),
58
+ version: getMeta('version') || get('version'),
59
+ };
46
60
  } catch (e) {
47
61
  return null;
48
62
  }
@@ -70,6 +84,15 @@ function isHarnessSkillDir(dirPath) {
70
84
  function installSkillsToTargets({ chosenSkills, targetDirs, harnessSourceDir, packageVersion }) {
71
85
  for (const target of targetDirs) {
72
86
  fs.mkdirSync(target.path, { recursive: true });
87
+
88
+ // Copy references directory
89
+ const refSrc = path.join(harnessSourceDir, 'references');
90
+ if (fs.existsSync(refSrc)) {
91
+ const refDest = path.join(path.dirname(target.manifestPath), 'references');
92
+ if (fs.existsSync(refDest)) fs.rmSync(refDest, { recursive: true, force: true });
93
+ copyDir(refSrc, refDest);
94
+ }
95
+
73
96
  for (const skillName of chosenSkills) {
74
97
  const src = path.join(harnessSourceDir, skillName);
75
98
  const dest = path.join(target.path, skillName);
@@ -83,6 +106,39 @@ function installSkillsToTargets({ chosenSkills, targetDirs, harnessSourceDir, pa
83
106
  }
84
107
  }
85
108
 
109
+ function installAgentsToTarget({ target, harnessSourceDir, packageVersion }) {
110
+ const sourceDir = path.join(harnessSourceDir, 'fable-mode', 'agents');
111
+ if (!fs.existsSync(sourceDir) || !target || !target.path || !target.manifestPath) return;
112
+
113
+ fs.mkdirSync(target.path, { recursive: true });
114
+ const trackedPaths = new Set(
115
+ (manifest.readManifest(target.manifestPath).agents || []).map(agent => agent.filePath)
116
+ );
117
+ for (const entry of fs.readdirSync(sourceDir, { withFileTypes: true })) {
118
+ if (!entry.isFile() || !entry.name.endsWith('.md')) continue;
119
+ const sourcePath = path.join(sourceDir, entry.name);
120
+ const destPath = path.join(target.path, entry.name);
121
+ if (fs.existsSync(destPath)) {
122
+ const source = fs.readFileSync(sourcePath, 'utf8');
123
+ const existing = fs.readFileSync(destPath, 'utf8');
124
+ if (source !== existing) {
125
+ console.warn(` ⚠️ Preserved existing agent without overwrite: ${destPath}`);
126
+ continue;
127
+ }
128
+ if (!trackedPaths.has(destPath)) {
129
+ console.warn(` ⚠️ Preserved pre-existing identical agent without claiming ownership: ${destPath}`);
130
+ continue;
131
+ }
132
+ } else {
133
+ fs.copyFileSync(sourcePath, destPath);
134
+ console.log(` ✅ Installed agent: ${target.label}${entry.name}`);
135
+ }
136
+ const agentInfo = parseFrontmatter(sourcePath);
137
+ const agentName = (agentInfo && agentInfo.name) || entry.name.replace(/\.md$/i, '');
138
+ manifest.recordAgentInstall(target.manifestPath, packageVersion, agentName, destPath);
139
+ }
140
+ }
141
+
86
142
  function manifestTrackedSkills(manifestPath, scopeLabel) {
87
143
  const data = manifest.readManifest(manifestPath);
88
144
  const results = [];
@@ -154,6 +210,24 @@ function getInstalledSkills(workspaceRoot, userHome) {
154
210
  return results;
155
211
  }
156
212
 
213
+ function getInstalledAgents(workspaceRoot, userHome) {
214
+ const homes = [
215
+ { home: path.join(workspaceRoot, '.claude'), scope: 'local (Claude)' },
216
+ { home: path.join(userHome, '.claude'), scope: 'global (Claude)' },
217
+ ];
218
+ const results = [];
219
+ for (const { home, scope } of homes) {
220
+ const manifestPath = manifest.getManifestPath(home);
221
+ const data = manifest.readManifest(manifestPath);
222
+ for (const entry of data.agents || []) {
223
+ if (entry.filePath && fs.existsSync(entry.filePath)) {
224
+ results.push({ ...entry, scope, manifestPath });
225
+ }
226
+ }
227
+ }
228
+ return results;
229
+ }
230
+
157
231
  function removeSkill(entry) {
158
232
  if (fs.existsSync(entry.dirPath)) {
159
233
  fs.rmSync(entry.dirPath, { recursive: true, force: true });
@@ -163,12 +237,24 @@ function removeSkill(entry) {
163
237
  }
164
238
  }
165
239
 
240
+ function removeAgent(entry) {
241
+ if (entry.filePath && fs.existsSync(entry.filePath)) {
242
+ fs.unlinkSync(entry.filePath);
243
+ }
244
+ if (entry.manifestPath) {
245
+ manifest.removeAgentFromManifest(entry.manifestPath, entry.filePath);
246
+ }
247
+ }
248
+
166
249
  module.exports = {
167
250
  copyDir,
168
251
  getAvailableSkills,
169
252
  getSkillInfo,
170
253
  isHarnessSkillDir,
171
254
  installSkillsToTargets,
255
+ installAgentsToTarget,
172
256
  getInstalledSkills,
257
+ getInstalledAgents,
173
258
  removeSkill,
259
+ removeAgent,
174
260
  };