harness-everything 0.2.1 → 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 (494) 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 +63 -63
  174. package/docs/workflows/eval-harness.md +64 -57
  175. package/docs/workflows/fable-discipline.md +59 -59
  176. package/docs/workflows/fable-mode.md +12 -15
  177. package/docs/workflows/find-skills.md +36 -0
  178. package/docs/workflows/git-commit.md +71 -62
  179. package/docs/workflows/grill-me.md +62 -62
  180. package/docs/workflows/grill-with-docs.md +69 -62
  181. package/docs/workflows/harness-everything.md +95 -92
  182. package/docs/workflows/improve-codebase-architecture.md +68 -60
  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 +64 -59
  186. package/docs/workflows/rewrite-commits.md +60 -60
  187. package/docs/workflows/security-review.md +77 -58
  188. package/docs/workflows/self-evolve.md +42 -59
  189. package/docs/workflows/skill-creator.md +80 -75
  190. package/docs/workflows/skill-style.md +64 -64
  191. package/docs/workflows/tdd.md +7 -4
  192. package/docs/workflows/to-spec.md +83 -0
  193. package/docs/workflows/to-tickets.md +80 -0
  194. package/docs/workflows/todo-driven-workflow.md +28 -30
  195. package/docs/workflows/using-git-worktrees.md +67 -63
  196. package/docs/workflows/verification-loop.md +71 -69
  197. package/docs/workflows/verify-before-claim.md +64 -60
  198. package/docs/workflows/zoom-out.md +74 -62
  199. package/environment-detection/SKILL.md +41 -77
  200. package/environment-detection/references/shell-syntax-rules.md +76 -0
  201. package/environment-detection/scripts/preflight.js +103 -93
  202. package/eval-framework/fixtures/bad-frontmatter-colon/SKILL.md +14 -0
  203. package/eval-framework/fixtures/duplicate-desc-skill-a/SKILL.md +14 -0
  204. package/eval-framework/fixtures/duplicate-desc-skill-b/SKILL.md +14 -0
  205. package/eval-framework/fixtures/missing-delimiter/SKILL.md +13 -0
  206. package/eval-framework/fixtures/over-budget-skill/SKILL.md +36 -0
  207. package/eval-harness/SKILL.md +42 -59
  208. package/eval-harness/references/scoring-rubric.md +68 -0
  209. package/eval-harness/scripts/evaluate.js +77 -61
  210. package/evals/environment-detection/eval.yaml +26 -0
  211. package/evals/environment-detection/tasks/negative-trigger.yaml +16 -0
  212. package/evals/environment-detection/tasks/positive-trigger.yaml +15 -0
  213. package/evals/eval-harness/eval.yaml +26 -0
  214. package/evals/eval-harness/tasks/negative-trigger.yaml +16 -0
  215. package/evals/eval-harness/tasks/positive-trigger.yaml +15 -0
  216. package/evals/fable-discipline/eval.yaml +26 -0
  217. package/evals/fable-discipline/tasks/negative-trigger.yaml +16 -0
  218. package/evals/fable-discipline/tasks/positive-trigger.yaml +15 -0
  219. package/evals/fable-mode/eval.yaml +26 -0
  220. package/evals/fable-mode/tasks/negative-tier2-no-model.yaml +18 -0
  221. package/evals/fable-mode/tasks/negative-trigger.yaml +16 -0
  222. package/evals/fable-mode/tasks/positive-haiku-mode.yaml +16 -0
  223. package/evals/fable-mode/tasks/positive-opus-mode.yaml +16 -0
  224. package/evals/fable-mode/tasks/positive-sonnet-mode.yaml +16 -0
  225. package/evals/fable-mode/tasks/positive-trigger.yaml +15 -0
  226. package/evals/find-skills/eval.yaml +26 -0
  227. package/evals/find-skills/tasks/negative-trigger.yaml +16 -0
  228. package/evals/find-skills/tasks/positive-trigger.yaml +15 -0
  229. package/evals/git-commit/eval.yaml +26 -0
  230. package/evals/git-commit/tasks/negative-trigger.yaml +16 -0
  231. package/evals/git-commit/tasks/positive-trigger.yaml +15 -0
  232. package/evals/grill-me/eval.yaml +26 -0
  233. package/evals/grill-me/tasks/negative-trigger.yaml +16 -0
  234. package/evals/grill-me/tasks/positive-trigger.yaml +15 -0
  235. package/evals/grill-with-docs/eval.yaml +26 -0
  236. package/evals/grill-with-docs/tasks/negative-trigger.yaml +16 -0
  237. package/evals/grill-with-docs/tasks/positive-trigger.yaml +15 -0
  238. package/evals/harness-everything/eval.yaml +26 -0
  239. package/evals/harness-everything/tasks/negative-non-software.yaml +16 -0
  240. package/evals/harness-everything/tasks/negative-skill-indicated.yaml +15 -0
  241. package/evals/harness-everything/tasks/positive-tier1.yaml +16 -0
  242. package/evals/harness-everything/tasks/positive-tier2.yaml +16 -0
  243. package/evals/harness-everything/tasks/positive-tier3.yaml +16 -0
  244. package/evals/improve-codebase-architecture/eval.yaml +26 -0
  245. package/evals/improve-codebase-architecture/tasks/negative-trigger.yaml +16 -0
  246. package/evals/improve-codebase-architecture/tasks/positive-trigger.yaml +15 -0
  247. package/evals/install-cognitive-os/eval.yaml +26 -0
  248. package/evals/install-cognitive-os/tasks/negative-trigger.yaml +16 -0
  249. package/evals/install-cognitive-os/tasks/positive-trigger.yaml +15 -0
  250. package/evals/multi-agent-workspace/eval.yaml +26 -0
  251. package/evals/multi-agent-workspace/tasks/negative-trigger.yaml +15 -0
  252. package/evals/multi-agent-workspace/tasks/positive-trigger.yaml +15 -0
  253. package/evals/repo-docs/eval.yaml +26 -0
  254. package/evals/repo-docs/tasks/negative-trigger.yaml +16 -0
  255. package/evals/repo-docs/tasks/positive-trigger.yaml +15 -0
  256. package/evals/rewrite-commits/eval.yaml +26 -0
  257. package/evals/rewrite-commits/tasks/negative-trigger.yaml +16 -0
  258. package/evals/rewrite-commits/tasks/positive-trigger.yaml +15 -0
  259. package/evals/security-review/eval.yaml +26 -0
  260. package/evals/security-review/tasks/negative-trigger.yaml +16 -0
  261. package/evals/security-review/tasks/positive-trigger.yaml +15 -0
  262. package/evals/self-evolve/eval.yaml +26 -0
  263. package/evals/self-evolve/tasks/negative-trigger.yaml +16 -0
  264. package/evals/self-evolve/tasks/positive-trigger.yaml +15 -0
  265. package/evals/skill-creator/eval.yaml +26 -0
  266. package/evals/skill-creator/tasks/negative-trigger.yaml +16 -0
  267. package/evals/skill-creator/tasks/positive-trigger.yaml +15 -0
  268. package/evals/skill-style/eval.yaml +26 -0
  269. package/evals/skill-style/tasks/negative-trigger.yaml +16 -0
  270. package/evals/skill-style/tasks/positive-trigger.yaml +15 -0
  271. package/evals/tdd/eval.yaml +26 -0
  272. package/evals/tdd/tasks/negative-trivia.yaml +16 -0
  273. package/evals/tdd/tasks/positive-bugfix.yaml +15 -0
  274. package/evals/tdd/tasks/positive-feature.yaml +16 -0
  275. package/evals/tdd/tasks/positive-refactor.yaml +15 -0
  276. package/evals/to-spec/eval.yaml +26 -0
  277. package/evals/to-spec/tasks/negative-trigger.yaml +16 -0
  278. package/evals/to-spec/tasks/positive-trigger.yaml +15 -0
  279. package/evals/to-tickets/eval.yaml +26 -0
  280. package/evals/to-tickets/tasks/negative-trigger.yaml +15 -0
  281. package/evals/to-tickets/tasks/positive-trigger.yaml +15 -0
  282. package/evals/todo-driven-workflow/eval.yaml +26 -0
  283. package/evals/todo-driven-workflow/tasks/negative-single-edit.yaml +16 -0
  284. package/evals/todo-driven-workflow/tasks/positive-multi-step.yaml +15 -0
  285. package/evals/todo-driven-workflow/tasks/positive-refactor-flow.yaml +15 -0
  286. package/evals/using-git-worktrees/eval.yaml +26 -0
  287. package/evals/using-git-worktrees/tasks/negative-trigger.yaml +15 -0
  288. package/evals/using-git-worktrees/tasks/positive-trigger.yaml +15 -0
  289. package/evals/verification-loop/eval.yaml +26 -0
  290. package/evals/verification-loop/tasks/negative-discussion.yaml +16 -0
  291. package/evals/verification-loop/tasks/positive-pre-ship.yaml +15 -0
  292. package/evals/verify-before-claim/eval.yaml +26 -0
  293. package/evals/verify-before-claim/tasks/negative-trigger.yaml +16 -0
  294. package/evals/verify-before-claim/tasks/positive-trigger.yaml +15 -0
  295. package/evals/zoom-out/eval.yaml +26 -0
  296. package/evals/zoom-out/tasks/negative-trivial-edit.yaml +16 -0
  297. package/evals/zoom-out/tasks/positive-repeated-failure.yaml +15 -0
  298. package/fable-discipline/SKILL.md +41 -38
  299. package/fable-discipline/references/discipline-rules.md +22 -0
  300. package/fable-mode/CONTRACT-FORMAT.md +51 -51
  301. package/fable-mode/SKILL.md +39 -51
  302. package/fable-mode/agents/fable-orchestrator.md +99 -92
  303. package/fable-mode/agents/fable-verifier.md +32 -32
  304. package/fable-mode/agents/fable-worker-haiku.md +52 -48
  305. package/fable-mode/agents/fable-worker-sonnet.md +53 -49
  306. package/fable-mode/execution-guardrails/SKILL.md +43 -87
  307. package/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
  308. package/fable-mode/fable-haiku/SKILL.md +36 -48
  309. package/fable-mode/fable-haiku/references/routing-notes.md +26 -0
  310. package/fable-mode/fable-opus/SKILL.md +36 -0
  311. package/fable-mode/fable-sonnet/SKILL.md +36 -0
  312. package/fable-mode/model-matrix.json +32 -0
  313. package/fable-mode/references/execution-phases.md +37 -0
  314. package/fable-mode/references/model-matrix.md +39 -0
  315. package/fable-mode/scripts/model-selector.js +129 -0
  316. package/find-skills/SKILL.md +48 -0
  317. package/find-skills/references/discovery-flow.md +102 -0
  318. package/find-skills/scripts/use-skill.js +106 -0
  319. package/git-commit/SKILL.md +45 -55
  320. package/git-commit/guides/ANGULAR_STYLE.md +60 -60
  321. package/git-commit/guides/COMMIT_GENERATION.md +23 -23
  322. package/git-commit/guides/LANGUAGE_DETECTION.md +16 -16
  323. package/git-commit/guides/MAIN_REPO.md +14 -14
  324. package/git-commit/guides/SUBMODULES.md +27 -27
  325. package/git-commit/references/commit-flow.md +30 -0
  326. package/grill-me/SKILL.md +43 -36
  327. package/grill-me/references/grilling-playbook.md +38 -0
  328. package/grill-with-docs/ADR-FORMAT.md +47 -47
  329. package/grill-with-docs/CONTEXT-FORMAT.md +63 -63
  330. package/grill-with-docs/SKILL.md +41 -99
  331. package/grill-with-docs/references/session-playbook.md +97 -0
  332. package/harness-everything/SKILL.md +42 -141
  333. package/harness-everything/references/skill-registry.md +39 -0
  334. package/harness-everything/references/triage-and-tiers.md +116 -0
  335. package/harness-everything/scripts/bootstrap.js +203 -140
  336. package/harness-everything/scripts/routing-keywords.json +320 -0
  337. package/harness-everything/scripts/self-heal.js +241 -189
  338. package/harness-everything/scripts/tier-router.js +334 -219
  339. package/harness-everything/scripts/verify-gate.js +87 -18
  340. package/hooks/hooks.json +155 -155
  341. package/hooks/scripts/boundary-guard.js +55 -55
  342. package/hooks/scripts/contract-test.js +79 -79
  343. package/hooks/scripts/depth-guard.js +65 -65
  344. package/hooks/scripts/lib/harness-state.js +139 -228
  345. package/hooks/scripts/lib/platforms/claude.js +185 -42
  346. package/hooks/scripts/lib/platforms/codex.js +114 -46
  347. package/hooks/scripts/lib/platforms/continue.js +91 -41
  348. package/hooks/scripts/lib/platforms/copilot.js +109 -41
  349. package/hooks/scripts/lib/platforms/cursor.js +89 -41
  350. package/hooks/scripts/lib/platforms/hermes.js +57 -32
  351. package/hooks/scripts/lib/platforms/index.js +17 -17
  352. package/hooks/scripts/lib/platforms/worktrees.js +20 -20
  353. package/hooks/scripts/reset-circuit-breaker.js +30 -30
  354. package/hooks/scripts/rule-of-3-tracker.js +124 -91
  355. package/hooks/scripts/rule-of-3.js +14 -3
  356. package/hooks/scripts/state-persist.js +99 -99
  357. package/hooks/scripts/stop-gate.js +80 -80
  358. package/hooks/scripts/subagent-scope-guard.js +88 -88
  359. package/improve-codebase-architecture/SKILL.md +40 -44
  360. package/improve-codebase-architecture/guides/DEEPENING.md +37 -37
  361. package/improve-codebase-architecture/guides/HTML-REPORT.md +123 -123
  362. package/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -44
  363. package/improve-codebase-architecture/guides/LANGUAGE.md +53 -53
  364. package/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
  365. package/install-cognitive-os/SKILL.md +38 -95
  366. package/install-cognitive-os/references/cognitive-loop.md +27 -0
  367. package/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
  368. package/multi-agent-workspace/SKILL.md +37 -0
  369. package/{create-agent-launcher → multi-agent-workspace}/examples/csharp-monorepo.md +123 -123
  370. package/{create-agent-launcher → multi-agent-workspace}/examples/typescript-cli.md +126 -126
  371. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-claude.md +77 -77
  372. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-codex.md +146 -146
  373. package/multi-agent-workspace/guidelines/platform-continue.md +38 -0
  374. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-copilot.md +74 -74
  375. package/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
  376. package/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
  377. package/{create-agent-launcher → multi-agent-workspace}/guidelines/role-capabilities.md +108 -108
  378. package/multi-agent-workspace/references/agency-agents.md +31 -0
  379. package/multi-agent-workspace/references/architecture-guide.md +32 -0
  380. package/multi-agent-workspace/references/orchestration.md +48 -0
  381. package/multi-agent-workspace/scripts/agency-catalog.js +190 -0
  382. package/multi-agent-workspace/scripts/index_memory.js +51 -0
  383. package/multi-agent-workspace/scripts/scaffold.js +253 -0
  384. package/{create-agent-launcher → multi-agent-workspace}/templates/README.md +17 -17
  385. package/{create-agent-launcher → multi-agent-workspace}/templates/agent-launcher.md +67 -67
  386. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-csharp.md +55 -55
  387. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-polyglot.md +61 -61
  388. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-ts.md +56 -56
  389. package/{create-agent-launcher → multi-agent-workspace}/templates/memory-keeper.md +36 -36
  390. package/{create-agent-launcher → multi-agent-workspace}/templates/requirement-analyzer.md +65 -65
  391. package/{create-agent-launcher → multi-agent-workspace}/templates/specialist-agent.md +34 -34
  392. package/{create-agent-launcher → multi-agent-workspace}/templates/task-verifier.md +55 -55
  393. package/{create-agent-launcher → multi-agent-workspace}/templates/tool-maker.md +32 -32
  394. package/multi-agent-workspace/workflows/01-init.md +22 -0
  395. package/multi-agent-workspace/workflows/02-analysis.md +23 -0
  396. package/multi-agent-workspace/workflows/03-generation.md +27 -0
  397. package/multi-agent-workspace/workflows/04-launcher.md +16 -0
  398. package/opencode-plugin/README.md +94 -0
  399. package/opencode-plugin/hooks/circuit-breaker.js +121 -0
  400. package/opencode-plugin/hooks/compliance.js +128 -0
  401. package/opencode-plugin/hooks/post-edit.js +62 -0
  402. package/opencode-plugin/hooks/pre-complete.js +65 -0
  403. package/opencode-plugin/hooks/verify.js +140 -0
  404. package/opencode-plugin/plugin.json +17 -0
  405. package/opencode-plugin/test-hook-firing.js +198 -0
  406. package/package.json +50 -22
  407. package/references/definition-of-done.md +67 -0
  408. package/references/performance-checklist.md +153 -0
  409. package/references/platform-advisory-template.md +58 -0
  410. package/references/security-checklist.md +205 -0
  411. package/repo-docs/SKILL.md +46 -45
  412. package/repo-docs/references/process-guide.md +60 -0
  413. package/repo-docs/templates/agents-template.md +264 -264
  414. package/repo-docs/templates/knowledge-agents-template.md +50 -50
  415. package/repo-docs/templates/knowledge-readme-template.md +83 -83
  416. package/repo-docs/templates/manual-recon.md +117 -117
  417. package/repo-docs/templates/multi-skills-readme-template.md +72 -72
  418. package/repo-docs/templates/product-agents-template.md +78 -78
  419. package/repo-docs/templates/product-readme-template.md +95 -95
  420. package/repo-docs/templates/readme-template.md +136 -136
  421. package/repo-docs/templates/single-skill-readme-template.md +70 -70
  422. package/repo-docs/templates/skills-agents-template.md +60 -60
  423. package/rewrite-commits/SKILL.md +37 -32
  424. package/rewrite-commits/references/workflow.md +18 -0
  425. package/scripts/installer.js +546 -649
  426. package/scripts/lib/advisory-text.js +167 -163
  427. package/scripts/lib/claude-hooks.js +84 -71
  428. package/scripts/lib/gitignore.js +199 -80
  429. package/scripts/lib/manifest.js +146 -82
  430. package/scripts/lib/prompts.js +241 -241
  431. package/scripts/lib/skills.js +260 -172
  432. package/scripts/lib/workspace.js +28 -28
  433. package/scripts/verify-install.js +147 -0
  434. package/security-review/SKILL.md +50 -511
  435. package/security-review/guides/OWASP-PATTERNS.md +31 -0
  436. package/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
  437. package/security-review/references/security-checklist.md +478 -0
  438. package/security-review/scripts/audit-secrets.js +84 -0
  439. package/self-evolve/SKILL.md +47 -54
  440. package/self-evolve/references/memory-resolution.md +58 -0
  441. package/self-evolve/scripts/persist-memory.js +139 -40
  442. package/self-evolve/scripts/register-dynamic-skill.js +251 -0
  443. package/self-evolve/scripts/self-regression.js +110 -113
  444. package/skill-creator/SKILL.md +49 -91
  445. package/skill-creator/references/authoring-workflow.md +14 -0
  446. package/skill-creator/references/dynamic-generation-contract.md +21 -0
  447. package/skill-creator/references/quality-checklist.md +15 -0
  448. package/skill-creator/references/quality-principles.md +81 -81
  449. package/skill-creator/references/testing-workflow.md +20 -25
  450. package/skill-style/SKILL.md +42 -48
  451. package/skill-style/references/style-guide.md +36 -0
  452. package/tdd/SKILL.md +44 -53
  453. package/tdd/guides/deep-modules.md +33 -33
  454. package/tdd/guides/interface-design.md +31 -31
  455. package/tdd/guides/mocking.md +59 -59
  456. package/tdd/guides/refactoring.md +10 -10
  457. package/tdd/guides/tests.md +61 -61
  458. package/tdd/references/core-discipline.md +49 -0
  459. package/to-spec/SKILL.md +42 -0
  460. package/to-spec/references/process.md +77 -0
  461. package/to-spec/scripts/check-project-docs.js +259 -0
  462. package/to-spec/templates/cli-reference.md +31 -0
  463. package/to-spec/templates/dev-doc.md +27 -0
  464. package/to-spec/templates/feature-spec.md +59 -0
  465. package/to-spec/templates/schema-doc.md +31 -0
  466. package/to-tickets/SKILL.md +42 -0
  467. package/to-tickets/references/publishing-and-templates.md +97 -0
  468. package/todo-driven-workflow/SKILL.md +40 -54
  469. package/todo-driven-workflow/references/execution-guide.md +27 -0
  470. package/using-git-worktrees/SKILL.md +49 -161
  471. package/using-git-worktrees/references/workflow-details.md +108 -0
  472. package/verification-loop/SKILL.md +46 -138
  473. package/verification-loop/references/verification-phases.md +116 -0
  474. package/verification-loop/templates/verification-report.template.md +15 -0
  475. package/verify-before-claim/SKILL.md +43 -86
  476. package/verify-before-claim/references/verification-guide.md +73 -0
  477. package/zoom-out/SKILL.md +42 -90
  478. package/zoom-out/references/circuit-breaker.md +66 -0
  479. package/zoom-out/templates/zoom-out-report.template.md +20 -0
  480. package/build-multi-agent-system/AGENTS.md +0 -50
  481. package/build-multi-agent-system/README.md +0 -63
  482. package/build-multi-agent-system/SKILL.md +0 -68
  483. package/create-agent-launcher/SKILL.md +0 -48
  484. package/create-agent-launcher/guidelines/platform-gemini.md +0 -101
  485. package/create-agent-launcher/workflows/01-init.md +0 -22
  486. package/create-agent-launcher/workflows/02-analysis.md +0 -26
  487. package/create-agent-launcher/workflows/03-generation.md +0 -29
  488. package/create-agent-launcher/workflows/04-launcher.md +0 -20
  489. package/docs/workflows/build-multi-agent-system.md +0 -62
  490. package/docs/workflows/create-agent-launcher.md +0 -62
  491. package/eval-framework/behavioral-test.js +0 -105
  492. package/eval-framework/mechanism-test.js +0 -251
  493. package/harness-everything/scripts/todo-cli.js +0 -157
  494. package/skill-style/STYLE.md +0 -37
@@ -1,172 +1,260 @@
1
- // Skill discovery, copy, and manifest-aware install/uninstall bookkeeping.
2
- const fs = require('fs');
3
- const path = require('path');
4
- const manifest = require('./manifest');
5
-
6
- function copyDir(src, dest) {
7
- fs.mkdirSync(dest, { recursive: true });
8
- const entries = fs.readdirSync(src, { withFileTypes: true });
9
- for (const entry of entries) {
10
- const srcPath = path.join(src, entry.name);
11
- const destPath = path.join(dest, entry.name);
12
- if (entry.isDirectory()) {
13
- copyDir(srcPath, destPath);
14
- } else {
15
- fs.copyFileSync(srcPath, destPath);
16
- }
17
- }
18
- }
19
-
20
- function getAvailableSkills(harnessSourceDir) {
21
- const dirs = fs.readdirSync(harnessSourceDir, { withFileTypes: true });
22
- const skills = [];
23
- for (const dir of dirs) {
24
- if (dir.isDirectory() && !dir.name.startsWith('.') && !['bin', 'docs', 'hooks', 'scripts', 'node_modules'].includes(dir.name)) {
25
- const skillPath = path.join(harnessSourceDir, dir.name, 'SKILL.md');
26
- if (fs.existsSync(skillPath)) {
27
- skills.push(dir.name);
28
- }
29
- }
30
- }
31
- return skills.sort();
32
- }
33
-
34
- function parseFrontmatter(skillMdPath) {
35
- if (!fs.existsSync(skillMdPath)) return null;
36
- try {
37
- const content = fs.readFileSync(skillMdPath, 'utf8');
38
- const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
39
- if (!match) return null;
40
- const yaml = match[1];
41
- const get = (key) => {
42
- const m = yaml.match(new RegExp(`^${key}:\\s*(.*)$`, 'm'));
43
- return m ? m[1].trim().replace(/^['"]|['"]$/g, '') : '';
44
- };
45
- return { name: get('name'), description: get('description'), author: get('author'), version: get('version') };
46
- } catch (e) {
47
- return null;
48
- }
49
- }
50
-
51
- function getSkillInfo(harnessSourceDir, skillDirName) {
52
- const fm = parseFrontmatter(path.join(harnessSourceDir, skillDirName, 'SKILL.md'));
53
- if (!fm) return null;
54
- return { id: skillDirName, name: fm.name || skillDirName, description: fm.description || '' };
55
- }
56
-
57
- // The one signal that lets uninstall tell "a skill this package shipped"
58
- // apart from anything else living in the same shared skills folder (Cursor/
59
- // Copilot/Codex/Continue skills keep their platform-native location, so it's
60
- // still a shared folder) - including a user's own manually-installed skills
61
- // and self-evolve's locally-generated `skills/generated/*` skills, neither
62
- // of which carry this author string.
63
- function isHarnessSkillDir(dirPath) {
64
- const fm = parseFrontmatter(path.join(dirPath, 'SKILL.md'));
65
- return !!fm && fm.author === manifest.HARNESS_AUTHOR;
66
- }
67
-
68
- // targetDirs entries: { path, label, manifestPath } - manifestPath is that
69
- // target's own <platform-home>/harness-everything/manifest.json.
70
- function installSkillsToTargets({ chosenSkills, targetDirs, harnessSourceDir, packageVersion }) {
71
- for (const target of targetDirs) {
72
- fs.mkdirSync(target.path, { recursive: true });
73
- for (const skillName of chosenSkills) {
74
- const src = path.join(harnessSourceDir, skillName);
75
- const dest = path.join(target.path, skillName);
76
- if (fs.existsSync(dest)) {
77
- fs.rmSync(dest, { recursive: true, force: true });
78
- }
79
- copyDir(src, dest);
80
- manifest.recordSkillInstall(target.manifestPath, packageVersion, skillName, dest);
81
- console.log(` ✅ Installed skill: ${target.label}${skillName}/`);
82
- }
83
- }
84
- }
85
-
86
- function manifestTrackedSkills(manifestPath, scopeLabel) {
87
- const data = manifest.readManifest(manifestPath);
88
- const results = [];
89
- for (const entry of data.skills || []) {
90
- if (fs.existsSync(entry.dirPath) && isHarnessSkillDir(entry.dirPath)) {
91
- results.push({ id: entry.id, scope: scopeLabel, dirPath: entry.dirPath, parentPath: path.dirname(entry.dirPath), manifestPath });
92
- }
93
- }
94
- return results;
95
- }
96
-
97
- // Returns every skill this package can currently account for, scoped local +
98
- // global. Never lists a directory just because it happens to live under a
99
- // known skills folder - only manifest-recorded installs (or, as a fallback
100
- // for pre-manifest / pre-reorg installs, directories that still self-identify
101
- // via the author marker) qualify. This is what keeps "uninstall skills" from
102
- // ever touching a skill this package didn't put there.
103
- function getInstalledSkills(workspaceRoot, userHome) {
104
- const results = [];
105
- const globalAgentsDir = path.join(userHome, '.agents');
106
-
107
- const manifestHomes = [
108
- { home: path.join(workspaceRoot, '.claude'), scope: 'local (Claude)' },
109
- { home: path.join(workspaceRoot, '.cursor'), scope: 'local (Cursor)' },
110
- { home: path.join(workspaceRoot, '.github'), scope: 'local (Copilot)' },
111
- { home: path.join(workspaceRoot, '.codex'), scope: 'local (Codex)' },
112
- { home: path.join(workspaceRoot, '.continue'), scope: 'local (Continue)' },
113
- { home: globalAgentsDir, scope: 'global' },
114
- ];
115
- for (const { home, scope } of manifestHomes) {
116
- results.push(...manifestTrackedSkills(manifest.getManifestPath(home), scope));
117
- }
118
-
119
- // Legacy fallback for installs that predate per-platform manifests (or the
120
- // old self-invented .harness/ local root, or - for Codex specifically - an
121
- // earlier version's mistaken `.agents/skills` target; Codex's real project
122
- // skills directory is `.codex/skills/`): scan the raw directories
123
- // directly, but only ever list an entry that still self-identifies via the
124
- // author marker - never a blind directory listing.
125
- const legacyDirs = [
126
- { path: path.join(workspaceRoot, '.harness', 'skills'), scope: 'local (legacy .harness)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.claude')) },
127
- { path: path.join(workspaceRoot, '.cursor', 'skills'), scope: 'local (Cursor)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.cursor')) },
128
- { path: path.join(workspaceRoot, '.github', 'skills'), scope: 'local (Copilot)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.github')) },
129
- { path: path.join(workspaceRoot, '.codex', 'skills'), scope: 'local (Codex)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.codex')) },
130
- { path: path.join(workspaceRoot, '.agents', 'skills'), scope: 'local (Codex, legacy .agents path)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.codex')) },
131
- { path: path.join(workspaceRoot, '.continue', 'skills'), scope: 'local (Continue)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.continue')) },
132
- { path: path.join(globalAgentsDir, 'skills'), scope: 'global', manifestPath: manifest.getManifestPath(globalAgentsDir) },
133
- ];
134
- const known = new Set(results.map(r => r.dirPath));
135
- for (const item of legacyDirs) {
136
- if (!fs.existsSync(item.path)) continue;
137
- try {
138
- const entries = fs.readdirSync(item.path, { withFileTypes: true });
139
- for (const entry of entries) {
140
- if (!entry.isDirectory()) continue;
141
- const dirPath = path.join(item.path, entry.name);
142
- if (known.has(dirPath)) continue;
143
- if (isHarnessSkillDir(dirPath)) {
144
- results.push({ id: entry.name, scope: item.scope, dirPath, parentPath: item.path, manifestPath: item.manifestPath });
145
- known.add(dirPath);
146
- }
147
- }
148
- } catch (e) {
149
- // ignore unreadable dirs
150
- }
151
- }
152
- return results;
153
- }
154
-
155
- function removeSkill(entry) {
156
- if (fs.existsSync(entry.dirPath)) {
157
- fs.rmSync(entry.dirPath, { recursive: true, force: true });
158
- }
159
- if (entry.manifestPath) {
160
- manifest.removeSkillFromManifest(entry.manifestPath, entry.dirPath);
161
- }
162
- }
163
-
164
- module.exports = {
165
- copyDir,
166
- getAvailableSkills,
167
- getSkillInfo,
168
- isHarnessSkillDir,
169
- installSkillsToTargets,
170
- getInstalledSkills,
171
- removeSkill,
172
- };
1
+ // Skill discovery, copy, and manifest-aware install/uninstall bookkeeping.
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const manifest = require('./manifest');
5
+
6
+ function copyDir(src, dest) {
7
+ fs.mkdirSync(dest, { recursive: true });
8
+ const entries = fs.readdirSync(src, { withFileTypes: true });
9
+ for (const entry of entries) {
10
+ const srcPath = path.join(src, entry.name);
11
+ const destPath = path.join(dest, entry.name);
12
+ if (entry.isDirectory()) {
13
+ copyDir(srcPath, destPath);
14
+ } else {
15
+ fs.copyFileSync(srcPath, destPath);
16
+ }
17
+ }
18
+ }
19
+
20
+ function getAvailableSkills(harnessSourceDir) {
21
+ const dirs = fs.readdirSync(harnessSourceDir, { withFileTypes: true });
22
+ const skills = [];
23
+ for (const dir of dirs) {
24
+ if (dir.isDirectory() && !dir.name.startsWith('.') && !['bin', 'docs', 'hooks', 'scripts', 'node_modules'].includes(dir.name)) {
25
+ const skillPath = path.join(harnessSourceDir, dir.name, 'SKILL.md');
26
+ if (fs.existsSync(skillPath)) {
27
+ skills.push(dir.name);
28
+ }
29
+ }
30
+ }
31
+ return skills.sort();
32
+ }
33
+
34
+ function parseFrontmatter(skillMdPath) {
35
+ if (!fs.existsSync(skillMdPath)) return null;
36
+ try {
37
+ const content = fs.readFileSync(skillMdPath, 'utf8');
38
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
39
+ if (!match) return null;
40
+ const yaml = match[1];
41
+ const get = (key) => {
42
+ const m = yaml.match(new RegExp(`^${key}:\\s*(.*)$`, 'm'));
43
+ return m ? m[1].trim().replace(/^['"]|['"]$/g, '') : '';
44
+ };
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
+ };
60
+ } catch (e) {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ function getSkillInfo(harnessSourceDir, skillDirName) {
66
+ const fm = parseFrontmatter(path.join(harnessSourceDir, skillDirName, 'SKILL.md'));
67
+ if (!fm) return null;
68
+ return { id: skillDirName, name: fm.name || skillDirName, description: fm.description || '' };
69
+ }
70
+
71
+ // The one signal that lets uninstall tell "a skill this package shipped"
72
+ // apart from anything else living in the same shared skills folder (Cursor/
73
+ // Copilot/Codex/Continue skills keep their platform-native location, so it's
74
+ // still a shared folder) - including a user's own manually-installed skills
75
+ // and self-evolve's locally-generated `skills/generated/*` skills, neither
76
+ // of which carry this author string.
77
+ function isHarnessSkillDir(dirPath) {
78
+ const fm = parseFrontmatter(path.join(dirPath, 'SKILL.md'));
79
+ return !!fm && fm.author === manifest.HARNESS_AUTHOR;
80
+ }
81
+
82
+ // targetDirs entries: { path, label, manifestPath } - manifestPath is that
83
+ // target's own <platform-home>/harness-everything/manifest.json.
84
+ function installSkillsToTargets({ chosenSkills, targetDirs, harnessSourceDir, packageVersion }) {
85
+ for (const target of targetDirs) {
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
+
96
+ for (const skillName of chosenSkills) {
97
+ const src = path.join(harnessSourceDir, skillName);
98
+ const dest = path.join(target.path, skillName);
99
+ if (fs.existsSync(dest)) {
100
+ fs.rmSync(dest, { recursive: true, force: true });
101
+ }
102
+ copyDir(src, dest);
103
+ manifest.recordSkillInstall(target.manifestPath, packageVersion, skillName, dest);
104
+ console.log(` ✅ Installed skill: ${target.label}${skillName}/`);
105
+ }
106
+ }
107
+ }
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
+
142
+ function manifestTrackedSkills(manifestPath, scopeLabel) {
143
+ const data = manifest.readManifest(manifestPath);
144
+ const results = [];
145
+ for (const entry of data.skills || []) {
146
+ if (fs.existsSync(entry.dirPath) && isHarnessSkillDir(entry.dirPath)) {
147
+ results.push({ id: entry.id, scope: scopeLabel, dirPath: entry.dirPath, parentPath: path.dirname(entry.dirPath), manifestPath });
148
+ }
149
+ }
150
+ return results;
151
+ }
152
+
153
+ // Returns every skill this package can currently account for, scoped local +
154
+ // global. Never lists a directory just because it happens to live under a
155
+ // known skills folder - only manifest-recorded installs (or, as a fallback
156
+ // for pre-manifest / pre-reorg installs, directories that still self-identify
157
+ // via the author marker) qualify. This is what keeps "uninstall skills" from
158
+ // ever touching a skill this package didn't put there.
159
+ function getInstalledSkills(workspaceRoot, userHome) {
160
+ const results = [];
161
+ const globalAgentsDir = path.join(userHome, '.agents');
162
+
163
+ const manifestHomes = [
164
+ { home: path.join(workspaceRoot, '.claude'), scope: 'local (Claude)' },
165
+ { home: path.join(workspaceRoot, '.cursor'), scope: 'local (Cursor)' },
166
+ { home: path.join(workspaceRoot, '.github'), scope: 'local (Copilot)' },
167
+ { home: path.join(workspaceRoot, '.codex'), scope: 'local (Codex)' },
168
+ { home: path.join(workspaceRoot, '.continue'), scope: 'local (Continue)' },
169
+ { home: path.join(userHome, '.claude'), scope: 'global (Claude)' },
170
+ { home: globalAgentsDir, scope: 'global' },
171
+ ];
172
+ for (const { home, scope } of manifestHomes) {
173
+ results.push(...manifestTrackedSkills(manifest.getManifestPath(home), scope));
174
+ }
175
+
176
+ // Legacy fallback for installs that predate per-platform manifests (or the
177
+ // old self-invented .harness/ local root, or - for Codex specifically - an
178
+ // earlier version's mistaken `.agents/skills` target; Codex's real project
179
+ // skills directory is `.codex/skills/`): scan the raw directories
180
+ // directly, but only ever list an entry that still self-identifies via the
181
+ // author marker - never a blind directory listing.
182
+ const legacyDirs = [
183
+ { path: path.join(workspaceRoot, '.harness', 'skills'), scope: 'local (legacy .harness)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.claude')) },
184
+ { path: path.join(workspaceRoot, '.claude', 'harness-everything', 'skills'), scope: 'local (Claude legacy erroneous path)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.claude')) },
185
+ { path: path.join(workspaceRoot, '.cursor', 'skills'), scope: 'local (Cursor)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.cursor')) },
186
+ { path: path.join(workspaceRoot, '.github', 'skills'), scope: 'local (Copilot)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.github')) },
187
+ { path: path.join(workspaceRoot, '.codex', 'skills'), scope: 'local (Codex)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.codex')) },
188
+ { path: path.join(workspaceRoot, '.agents', 'skills'), scope: 'local (Codex, legacy .agents path)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.codex')) },
189
+ { path: path.join(workspaceRoot, '.continue', 'skills'), scope: 'local (Continue)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.continue')) },
190
+ { path: path.join(globalAgentsDir, 'skills'), scope: 'global', manifestPath: manifest.getManifestPath(globalAgentsDir) },
191
+ ];
192
+ const known = new Set(results.map(r => r.dirPath));
193
+ for (const item of legacyDirs) {
194
+ if (!fs.existsSync(item.path)) continue;
195
+ try {
196
+ const entries = fs.readdirSync(item.path, { withFileTypes: true });
197
+ for (const entry of entries) {
198
+ if (!entry.isDirectory()) continue;
199
+ const dirPath = path.join(item.path, entry.name);
200
+ if (known.has(dirPath)) continue;
201
+ if (isHarnessSkillDir(dirPath)) {
202
+ results.push({ id: entry.name, scope: item.scope, dirPath, parentPath: item.path, manifestPath: item.manifestPath });
203
+ known.add(dirPath);
204
+ }
205
+ }
206
+ } catch (e) {
207
+ // ignore unreadable dirs
208
+ }
209
+ }
210
+ return results;
211
+ }
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
+
231
+ function removeSkill(entry) {
232
+ if (fs.existsSync(entry.dirPath)) {
233
+ fs.rmSync(entry.dirPath, { recursive: true, force: true });
234
+ }
235
+ if (entry.manifestPath) {
236
+ manifest.removeSkillFromManifest(entry.manifestPath, entry.dirPath);
237
+ }
238
+ }
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
+
249
+ module.exports = {
250
+ copyDir,
251
+ getAvailableSkills,
252
+ getSkillInfo,
253
+ isHarnessSkillDir,
254
+ installSkillsToTargets,
255
+ installAgentsToTarget,
256
+ getInstalledSkills,
257
+ getInstalledAgents,
258
+ removeSkill,
259
+ removeAgent,
260
+ };
@@ -1,28 +1,28 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const os = require('os');
4
-
5
- function getWorkspaceRoot() {
6
- let dir = path.resolve(process.cwd());
7
- while (dir !== path.parse(dir).root) {
8
- if (fs.existsSync(path.join(dir, '.git'))) return dir;
9
- dir = path.dirname(dir);
10
- }
11
- return process.cwd();
12
- }
13
-
14
- function getUserPromptsDir() {
15
- if (process.env.VSCODE_USER_PROMPTS_FOLDER) {
16
- return process.env.VSCODE_USER_PROMPTS_FOLDER;
17
- }
18
- const home = os.homedir();
19
- if (process.platform === 'win32') {
20
- return path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'Code', 'User', 'prompts');
21
- } else if (process.platform === 'darwin') {
22
- return path.join(home, 'Library', 'Application Support', 'Code', 'User', 'prompts');
23
- } else {
24
- return path.join(home, '.config', 'Code', 'User', 'prompts');
25
- }
26
- }
27
-
28
- module.exports = { getWorkspaceRoot, getUserPromptsDir };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ function getWorkspaceRoot() {
6
+ let dir = path.resolve(process.cwd());
7
+ while (dir !== path.parse(dir).root) {
8
+ if (fs.existsSync(path.join(dir, '.git'))) return dir;
9
+ dir = path.dirname(dir);
10
+ }
11
+ return process.cwd();
12
+ }
13
+
14
+ function getUserPromptsDir() {
15
+ if (process.env.VSCODE_USER_PROMPTS_FOLDER) {
16
+ return process.env.VSCODE_USER_PROMPTS_FOLDER;
17
+ }
18
+ const home = os.homedir();
19
+ if (process.platform === 'win32') {
20
+ return path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'Code', 'User', 'prompts');
21
+ } else if (process.platform === 'darwin') {
22
+ return path.join(home, 'Library', 'Application Support', 'Code', 'User', 'prompts');
23
+ } else {
24
+ return path.join(home, '.config', 'Code', 'User', 'prompts');
25
+ }
26
+ }
27
+
28
+ module.exports = { getWorkspaceRoot, getUserPromptsDir };
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Verify a Harness installation against this package source.
4
+ *
5
+ * The install manifest records where Harness copied each skill. This command
6
+ * checks its package version, every recorded skill, and the complete file
7
+ * tree, so an old install is reported as stale instead of looking healthy.
8
+ */
9
+
10
+ const crypto = require('crypto');
11
+ const fs = require('fs');
12
+ const os = require('os');
13
+ const path = require('path');
14
+ const { getWorkspaceRoot } = require('./lib/workspace');
15
+ const manifest = require('./lib/manifest');
16
+
17
+ const sourceRoot = path.resolve(__dirname, '..');
18
+ const packageVersion = require(path.join(sourceRoot, 'package.json')).version;
19
+ const userHome = os.homedir();
20
+
21
+ function fileTreeHash(root) {
22
+ if (!fs.existsSync(root)) return null;
23
+ const files = [];
24
+ function walk(dir) {
25
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
26
+ const full = path.join(dir, entry.name);
27
+ if (entry.isDirectory()) walk(full);
28
+ else if (entry.isFile()) files.push(path.relative(root, full).replace(/\\/g, '/') + ':' + crypto.createHash('sha256').update(fs.readFileSync(full)).digest('hex'));
29
+ }
30
+ }
31
+ walk(root);
32
+ return crypto.createHash('sha256').update(files.sort().join('\n')).digest('hex');
33
+ }
34
+
35
+ function availableSkills() {
36
+ return new Set(fs.readdirSync(sourceRoot, { withFileTypes: true })
37
+ .filter(entry => entry.isDirectory() && fs.existsSync(path.join(sourceRoot, entry.name, 'SKILL.md')))
38
+ .map(entry => entry.name));
39
+ }
40
+
41
+ function isHarnessSkill(dir) {
42
+ const skillMd = path.join(dir, 'SKILL.md');
43
+ if (!fs.existsSync(skillMd)) return false;
44
+ const raw = fs.readFileSync(skillMd, 'utf8');
45
+ return /(?:^|\n)\s*author:\s*["']?Miya Daniel["']?/m.test(raw);
46
+ }
47
+
48
+ function verifyManifest(manifestPath, expectedSkillRoot) {
49
+ const failures = [];
50
+ if (!fs.existsSync(manifestPath)) {
51
+ const known = availableSkills();
52
+ const legacy = expectedSkillRoot && fs.existsSync(expectedSkillRoot)
53
+ ? fs.readdirSync(expectedSkillRoot, { withFileTypes: true })
54
+ .filter(entry => entry.isDirectory() && known.has(entry.name) && isHarnessSkill(path.join(expectedSkillRoot, entry.name)))
55
+ .map(entry => entry.name)
56
+ : [];
57
+ if (!legacy.length) return { checked: false, failures };
58
+ failures.push(`STALE untracked installation: ${legacy.length} Harness skill copy/copies have no manifest`);
59
+ for (const id of legacy) {
60
+ if (fileTreeHash(path.join(sourceRoot, id)) !== fileTreeHash(path.join(expectedSkillRoot, id))) {
61
+ failures.push(`STALE tree: ${id} differs from source`);
62
+ }
63
+ }
64
+ return { checked: true, failures };
65
+ }
66
+ const data = manifest.readManifest(manifestPath);
67
+ if (data.package !== manifest.PACKAGE_NAME) failures.push(`manifest package is ${data.package || '(missing)'}`);
68
+ if (data.version !== packageVersion) failures.push(`STALE version: installed ${data.version || '(missing)'}, source ${packageVersion}`);
69
+ const known = availableSkills();
70
+ const recordedPaths = new Set();
71
+ for (const entry of data.skills || []) {
72
+ const dir = entry.dirPath;
73
+ recordedPaths.add(path.resolve(dir || ''));
74
+ if (!entry.id || !known.has(entry.id)) {
75
+ failures.push(`unknown or removed skill in manifest: ${entry.id || '(missing id)'}`);
76
+ continue;
77
+ }
78
+ if (!dir || !fs.existsSync(dir)) {
79
+ failures.push(`missing installed skill: ${entry.id}`);
80
+ continue;
81
+ }
82
+ const sourceHash = fileTreeHash(path.join(sourceRoot, entry.id));
83
+ const installedHash = fileTreeHash(dir);
84
+ if (sourceHash !== installedHash) failures.push(`STALE tree: ${entry.id} differs from source`);
85
+ }
86
+ if (expectedSkillRoot && fs.existsSync(expectedSkillRoot)) {
87
+ for (const entry of fs.readdirSync(expectedSkillRoot, { withFileTypes: true })) {
88
+ const dir = path.join(expectedSkillRoot, entry.name);
89
+ if (entry.isDirectory() && isHarnessSkill(dir) && !recordedPaths.has(path.resolve(dir))) {
90
+ failures.push(`untracked Harness skill copy: ${entry.name}`);
91
+ }
92
+ }
93
+ }
94
+ return { checked: true, failures };
95
+ }
96
+
97
+ function parseArgs() {
98
+ const args = process.argv.slice(2);
99
+ const value = (name) => {
100
+ const i = args.indexOf(name);
101
+ return i === -1 ? undefined : args[i + 1];
102
+ };
103
+ return {
104
+ root: value('--root') ? path.resolve(value('--root')) : getWorkspaceRoot(),
105
+ manifestPath: value('--manifest') ? path.resolve(value('--manifest')) : undefined,
106
+ global: args.includes('--global'),
107
+ };
108
+ }
109
+
110
+ function main() {
111
+ const options = parseArgs();
112
+ const targets = options.manifestPath
113
+ ? [{ manifestPath: options.manifestPath, skillRoot: path.dirname(options.manifestPath).replace(/harness-everything$/, 'skills') }]
114
+ : options.global
115
+ ? [{ manifestPath: manifest.getManifestPath(path.join(userHome, '.agents')), skillRoot: path.join(userHome, '.agents', 'skills') }]
116
+ : [
117
+ ['.claude', '.claude/skills'], ['.cursor', '.cursor/skills'], ['.github', '.github/skills'],
118
+ ['.codex', '.codex/skills'], ['.continue', '.continue/skills'],
119
+ ].map(([home, skillsPath]) => ({
120
+ manifestPath: manifest.getManifestPath(path.join(options.root, home)),
121
+ skillRoot: path.join(options.root, skillsPath),
122
+ }));
123
+ let checked = 0;
124
+ let failures = 0;
125
+ for (const target of targets) {
126
+ const result = verifyManifest(target.manifestPath, target.skillRoot);
127
+ if (!result.checked) continue;
128
+ checked++;
129
+ console.log(`Checking ${path.relative(options.root, target.manifestPath) || target.manifestPath}...`);
130
+ if (result.failures.length) {
131
+ result.failures.forEach(failure => console.error(` FAIL ${failure}`));
132
+ failures += result.failures.length;
133
+ } else console.log(' PASS version and skill tree match source.');
134
+ }
135
+ if (!checked) {
136
+ console.error('No Harness installation manifest found. Install Harness before verifying it.');
137
+ process.exit(1);
138
+ }
139
+ if (failures) {
140
+ console.error(`INSTALL VERIFICATION FAILED: ${failures} problem(s).`);
141
+ process.exit(1);
142
+ }
143
+ console.log(`INSTALL VERIFICATION PASSED: ${checked} manifest(s).`);
144
+ }
145
+
146
+ if (require.main === module) main();
147
+ module.exports = { fileTreeHash, verifyManifest };