@toolu/opencode 6.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. package/generated/GENERATED-NOTES.md +16 -0
  2. package/generated/agents/toolu--architect.md +52 -0
  3. package/generated/agents/toolu--deep-explore.md +65 -0
  4. package/generated/agents/toolu--implementer.md +50 -0
  5. package/generated/agents/toolu--quick-task.md +54 -0
  6. package/generated/agents/toolu--research-agent.md +101 -0
  7. package/generated/commands/toolu--commit.md +8 -0
  8. package/generated/commands/toolu--review-and-commit.md +8 -0
  9. package/generated/opencode.toolu.json +116 -0
  10. package/generated/skills/toolu--brainstorm/SKILL.md +57 -0
  11. package/generated/skills/toolu--brainstorm/references/design-questions.md +36 -0
  12. package/generated/skills/toolu--commit--skill/SKILL.md +11 -0
  13. package/generated/skills/toolu--debug/SKILL.md +54 -0
  14. package/generated/skills/toolu--deep-research/SKILL.md +51 -0
  15. package/generated/skills/toolu--execution/SKILL.md +77 -0
  16. package/generated/skills/toolu--orchestrator/SKILL.md +145 -0
  17. package/generated/skills/toolu--orchestrator/references/delegation-cost.md +104 -0
  18. package/generated/skills/toolu--orchestrator/references/model-routing.md +112 -0
  19. package/generated/skills/toolu--plan/SKILL.md +56 -0
  20. package/generated/skills/toolu--plan/references/ledger.md +18 -0
  21. package/generated/skills/toolu--plan-review/SKILL.md +48 -0
  22. package/generated/skills/toolu--review-and-commit--skill/SKILL.md +10 -0
  23. package/generated/skills/toolu--setup/SKILL.md +24 -0
  24. package/generated/skills/toolu--setup/scripts/setup.sh +206 -0
  25. package/generated/skills/toolu--spec/SKILL.md +67 -0
  26. package/generated/skills/toolu--spec-review/SKILL.md +50 -0
  27. package/generated/skills/toolu--test/SKILL.md +49 -0
  28. package/package.json +51 -0
  29. package/plugins/agent-browser/.claude-plugin/plugin.json +18 -0
  30. package/plugins/agent-browser/.codex-plugin/plugin.json +7 -0
  31. package/plugins/agent-browser/README.md +18 -0
  32. package/plugins/agent-browser/hooks/hooks.json +15 -0
  33. package/plugins/agent-browser/hooks/session-start.sh +42 -0
  34. package/plugins/agent-browser/skills/agent-browser/SKILL.md +77 -0
  35. package/plugins/agent-browser/skills/agent-browser/scripts/agent-browser.sh +80 -0
  36. package/plugins/ast-grep/.claude-plugin/plugin.json +18 -0
  37. package/plugins/ast-grep/.codex-plugin/plugin.json +7 -0
  38. package/plugins/ast-grep/README.md +21 -0
  39. package/plugins/ast-grep/hooks/hooks.json +15 -0
  40. package/plugins/ast-grep/hooks/post-tools.d/byte-savings.sh +67 -0
  41. package/plugins/ast-grep/hooks/pre-tools.d/search-nudge.sh +170 -0
  42. package/plugins/ast-grep/hooks/register.sh +68 -0
  43. package/plugins/ast-grep/scripts/byte-savings-report.sh +28 -0
  44. package/plugins/ast-grep/skills/ast-grep/SKILL.md +127 -0
  45. package/plugins/ast-grep/skills/ast-grep/references/ast-grep-advanced.md +44 -0
  46. package/plugins/ast-grep/skills/ast-grep/scripts/ast-grep.sh +103 -0
  47. package/plugins/context7/.claude-plugin/plugin.json +18 -0
  48. package/plugins/context7/.codex-plugin/plugin.json +7 -0
  49. package/plugins/context7/README.md +19 -0
  50. package/plugins/context7/hooks/hooks.json +15 -0
  51. package/plugins/context7/hooks/session-start.sh +42 -0
  52. package/plugins/context7/skills/context7/SKILL.md +64 -0
  53. package/plugins/context7/skills/context7/scripts/search.sh +151 -0
  54. package/plugins/exa-search/.claude-plugin/plugin.json +18 -0
  55. package/plugins/exa-search/.codex-plugin/plugin.json +7 -0
  56. package/plugins/exa-search/README.md +19 -0
  57. package/plugins/exa-search/hooks/hooks.json +15 -0
  58. package/plugins/exa-search/hooks/session-start.sh +34 -0
  59. package/plugins/exa-search/skills/exa-search/SKILL.md +91 -0
  60. package/plugins/exa-search/skills/exa-search/scripts/search.sh +221 -0
  61. package/plugins/jev/.claude-plugin/plugin.json +19 -0
  62. package/plugins/jev/.codex-plugin/plugin.json +7 -0
  63. package/plugins/jev/README.md +61 -0
  64. package/plugins/jev/hooks/hooks.json +25 -0
  65. package/plugins/jev/hooks/lib/common.sh +49 -0
  66. package/plugins/jev/hooks/session-start.sh +45 -0
  67. package/plugins/jev/hooks/user-prompt-submit.sh +41 -0
  68. package/plugins/jev/skills/jev/SKILL.md +81 -0
  69. package/plugins/jev/skills/jev/evals/README.md +98 -0
  70. package/plugins/jev/skills/jev/references/problem-solving.md +198 -0
  71. package/plugins/jev/skills/jev/scripts/jev.sh +405 -0
  72. package/plugins/jira/.claude-plugin/plugin.json +18 -0
  73. package/plugins/jira/.codex-plugin/plugin.json +7 -0
  74. package/plugins/jira/README.md +42 -0
  75. package/plugins/jira/hooks/hooks.json +15 -0
  76. package/plugins/jira/hooks/session-start.sh +34 -0
  77. package/plugins/jira/skills/jira/SKILL.md +123 -0
  78. package/plugins/jira/skills/jira/scripts/jira.sh +70 -0
  79. package/plugins/jira/skills/jira/scripts/lib/adf.sh +17 -0
  80. package/plugins/jira/skills/jira/scripts/lib/attachment.sh +94 -0
  81. package/plugins/jira/skills/jira/scripts/lib/board.sh +58 -0
  82. package/plugins/jira/skills/jira/scripts/lib/http.sh +184 -0
  83. package/plugins/jira/skills/jira/scripts/lib/issue.sh +159 -0
  84. package/plugins/jira/skills/jira/scripts/lib/paginate.sh +45 -0
  85. package/plugins/jira/skills/jira/scripts/lib/plan-parse.sh +70 -0
  86. package/plugins/jira/skills/jira/scripts/lib/plan-run.sh +115 -0
  87. package/plugins/jira/skills/jira/scripts/lib/plan-store.sh +168 -0
  88. package/plugins/jira/skills/jira/scripts/lib/plan.sh +108 -0
  89. package/plugins/jira/skills/jira/scripts/lib/project.sh +42 -0
  90. package/plugins/jira/skills/jira/scripts/lib/raw.sh +15 -0
  91. package/plugins/jira/skills/jira/scripts/lib/search.sh +41 -0
  92. package/plugins/jira/skills/jira/scripts/lib/sprint.sh +88 -0
  93. package/plugins/jira/skills/jira/scripts/lib/user.sh +45 -0
  94. package/plugins/jira/skills/jira/scripts/lib/worklog.sh +56 -0
  95. package/plugins/pr-babysit/.claude-plugin/plugin.json +25 -0
  96. package/plugins/pr-babysit/.codex-plugin/plugin.json +7 -0
  97. package/plugins/pr-babysit/README.md +38 -0
  98. package/plugins/pr-babysit/commands/babysit.md +13 -0
  99. package/plugins/pr-babysit/hooks/check-toolu.sh +20 -0
  100. package/plugins/pr-babysit/hooks/hooks.json +15 -0
  101. package/plugins/pr-babysit/scripts/babysit-tick.sh +133 -0
  102. package/plugins/pr-babysit/scripts/collect-pr.sh +224 -0
  103. package/plugins/pr-babysit/scripts/lib/common.sh +146 -0
  104. package/plugins/pr-babysit/scripts/lib/gh.sh +150 -0
  105. package/plugins/pr-babysit/scripts/lib/lock.sh +84 -0
  106. package/plugins/pr-babysit/scripts/lib/normalize.sh +98 -0
  107. package/plugins/pr-babysit/scripts/lib/state.sh +37 -0
  108. package/plugins/pr-babysit/scripts/parse-verdict.sh +171 -0
  109. package/plugins/pr-babysit/scripts/record.sh +69 -0
  110. package/plugins/pr-babysit/scripts/reduce-state.sh +245 -0
  111. package/plugins/pr-babysit/scripts/reply-thread.sh +90 -0
  112. package/plugins/pr-babysit/scripts/resolve-thread.sh +71 -0
  113. package/plugins/pr-babysit/skills/babysit/SKILL.md +31 -0
  114. package/plugins/pr-babysit/skills/babysit/references/helper.md +209 -0
  115. package/plugins/pr-babysit/workflows/babysit.md +722 -0
  116. package/plugins/python-quality/.claude-plugin/plugin.json +24 -0
  117. package/plugins/python-quality/.codex-plugin/plugin.json +6 -0
  118. package/plugins/python-quality/README.md +23 -0
  119. package/plugins/python-quality/hooks/check-toolu.sh +20 -0
  120. package/plugins/python-quality/hooks/concerns/00-preamble.sh +85 -0
  121. package/plugins/python-quality/hooks/concerns/10-size-file.sh +6 -0
  122. package/plugins/python-quality/hooks/concerns/20-tests.sh +37 -0
  123. package/plugins/python-quality/hooks/concerns/30-suppression.sh +33 -0
  124. package/plugins/python-quality/hooks/concerns/50-size-fn.sh +49 -0
  125. package/plugins/python-quality/hooks/concerns/70-no-mocks.sh +76 -0
  126. package/plugins/python-quality/hooks/concerns/90-docs.sh +52 -0
  127. package/plugins/python-quality/hooks/concerns/99-finalize.sh +36 -0
  128. package/plugins/python-quality/hooks/hooks.json +19 -0
  129. package/plugins/python-quality/hooks/register.sh +65 -0
  130. package/plugins/rust-quality/.claude-plugin/plugin.json +24 -0
  131. package/plugins/rust-quality/.codex-plugin/plugin.json +6 -0
  132. package/plugins/rust-quality/README.md +24 -0
  133. package/plugins/rust-quality/hooks/check-toolu.sh +20 -0
  134. package/plugins/rust-quality/hooks/concerns/00-preamble.sh +93 -0
  135. package/plugins/rust-quality/hooks/concerns/10-size-file.sh +10 -0
  136. package/plugins/rust-quality/hooks/concerns/20-tests.sh +84 -0
  137. package/plugins/rust-quality/hooks/concerns/30-suppression.sh +26 -0
  138. package/plugins/rust-quality/hooks/concerns/40-unsafe.sh +39 -0
  139. package/plugins/rust-quality/hooks/concerns/50-size-fn.sh +38 -0
  140. package/plugins/rust-quality/hooks/concerns/55-size-impl.sh +28 -0
  141. package/plugins/rust-quality/hooks/concerns/60-error-handling.sh +149 -0
  142. package/plugins/rust-quality/hooks/concerns/70-no-mocks.sh +139 -0
  143. package/plugins/rust-quality/hooks/concerns/90-docs.sh +32 -0
  144. package/plugins/rust-quality/hooks/concerns/99-finalize.sh +36 -0
  145. package/plugins/rust-quality/hooks/hooks.json +19 -0
  146. package/plugins/rust-quality/hooks/register.sh +65 -0
  147. package/plugins/statusline/.claude-plugin/plugin.json +19 -0
  148. package/plugins/statusline/.codex-plugin/plugin.json +7 -0
  149. package/plugins/statusline/README.md +108 -0
  150. package/plugins/statusline/commands/setup.md +30 -0
  151. package/plugins/statusline/hooks/hooks.json +15 -0
  152. package/plugins/statusline/hooks/session-start.sh +45 -0
  153. package/plugins/statusline/scripts/collect-status.sh +147 -0
  154. package/plugins/statusline/scripts/setup.sh +93 -0
  155. package/plugins/statusline/scripts/status.sh +55 -0
  156. package/plugins/statusline/skills/status/SKILL.md +13 -0
  157. package/plugins/statusline/statusline.sh +177 -0
  158. package/plugins/toolu/.claude-plugin/plugin.json +19 -0
  159. package/plugins/toolu/.codex-plugin/plugin.json +7 -0
  160. package/plugins/toolu/README.md +35 -0
  161. package/plugins/toolu/agents/.gitkeep +0 -0
  162. package/plugins/toolu/agents/architect.md +52 -0
  163. package/plugins/toolu/agents/deep-explore.md +65 -0
  164. package/plugins/toolu/agents/implementer.md +50 -0
  165. package/plugins/toolu/agents/quick-task.md +54 -0
  166. package/plugins/toolu/agents/research-agent.md +107 -0
  167. package/plugins/toolu/assets/agents/architect.toml +9 -0
  168. package/plugins/toolu/assets/agents/deep-explore.toml +9 -0
  169. package/plugins/toolu/assets/agents/implementer.toml +9 -0
  170. package/plugins/toolu/assets/agents/quick-task.toml +9 -0
  171. package/plugins/toolu/assets/agents/research-agent.toml +9 -0
  172. package/plugins/toolu/commands/.gitkeep +0 -0
  173. package/plugins/toolu/commands/commit.md +5 -0
  174. package/plugins/toolu/commands/review-and-commit.md +5 -0
  175. package/plugins/toolu/hooks/docs/gates.md +157 -0
  176. package/plugins/toolu/hooks/docs/model-routing.md +14 -0
  177. package/plugins/toolu/hooks/docs/post-compaction.md +3 -0
  178. package/plugins/toolu/hooks/docs/push-review.md +123 -0
  179. package/plugins/toolu/hooks/docs/session-start-python.md +3 -0
  180. package/plugins/toolu/hooks/docs/session-start-rust.md +4 -0
  181. package/plugins/toolu/hooks/docs/session-start-ts.md +3 -0
  182. package/plugins/toolu/hooks/docs/session-start.md +16 -0
  183. package/plugins/toolu/hooks/hooks.json +76 -0
  184. package/plugins/toolu/hooks/lib/config.sh +355 -0
  185. package/plugins/toolu/hooks/lib/detect.sh +929 -0
  186. package/plugins/toolu/hooks/lib/diff-sha.sh +32 -0
  187. package/plugins/toolu/hooks/lib/dispatch.sh +365 -0
  188. package/plugins/toolu/hooks/lib/docs-sync-config.sh +81 -0
  189. package/plugins/toolu/hooks/lib/edit-records.sh +157 -0
  190. package/plugins/toolu/hooks/lib/gate-file.sh +201 -0
  191. package/plugins/toolu/hooks/lib/gate-mode.sh +244 -0
  192. package/plugins/toolu/hooks/lib/host.sh +205 -0
  193. package/plugins/toolu/hooks/lib/permissions.sh +125 -0
  194. package/plugins/toolu/hooks/lib/plan-ledger-parse.sh +219 -0
  195. package/plugins/toolu/hooks/lib/plan-ledger-preflight.sh +137 -0
  196. package/plugins/toolu/hooks/lib/plan-ledger.sh +749 -0
  197. package/plugins/toolu/hooks/lib/push-waiver.sh +116 -0
  198. package/plugins/toolu/hooks/lib/quality-config.sh +184 -0
  199. package/plugins/toolu/hooks/lib/registry.sh +72 -0
  200. package/plugins/toolu/hooks/lib/state-sweeper.sh +194 -0
  201. package/plugins/toolu/hooks/lib/telemetry.sh +94 -0
  202. package/plugins/toolu/hooks/lib/verdict.sh +477 -0
  203. package/plugins/toolu/hooks/post-tools/mod.sh +42 -0
  204. package/plugins/toolu/hooks/post-tools/modules/gate-status.sh +140 -0
  205. package/plugins/toolu/hooks/post-tools/modules/push-waiver.sh +97 -0
  206. package/plugins/toolu/hooks/pre-compact.sh +18 -0
  207. package/plugins/toolu/hooks/pre-tools/agent-tier.sh +111 -0
  208. package/plugins/toolu/hooks/pre-tools/mod.sh +37 -0
  209. package/plugins/toolu/hooks/pre-tools/modules/bash-commands.sh +187 -0
  210. package/plugins/toolu/hooks/pre-tools/modules/code-edit-rules.sh +78 -0
  211. package/plugins/toolu/hooks/pre-tools/modules/commit-gate.sh +70 -0
  212. package/plugins/toolu/hooks/pre-tools/modules/docs-sync.sh +137 -0
  213. package/plugins/toolu/hooks/pre-tools/modules/mcp-blocker.sh +151 -0
  214. package/plugins/toolu/hooks/pre-tools/modules/plan-ledger.sh +201 -0
  215. package/plugins/toolu/hooks/pre-tools/modules/protected-files.sh +177 -0
  216. package/plugins/toolu/hooks/pre-tools/modules/push-review.sh +273 -0
  217. package/plugins/toolu/hooks/pre-tools/modules/quality-gate.sh +87 -0
  218. package/plugins/toolu/hooks/session-start.sh +379 -0
  219. package/plugins/toolu/hooks/user-prompt-submit.sh +197 -0
  220. package/plugins/toolu/scripts/context-budget.sh +111 -0
  221. package/plugins/toolu/scripts/debug-log.sh +98 -0
  222. package/plugins/toolu/scripts/debug-stack.sh +108 -0
  223. package/plugins/toolu/scripts/debug-testfail.sh +97 -0
  224. package/plugins/toolu/settings/.gitkeep +0 -0
  225. package/plugins/toolu/settings/README.md +127 -0
  226. package/plugins/toolu/settings/bash-allowlist.txt +12 -0
  227. package/plugins/toolu/settings/bash-denylist.txt +25 -0
  228. package/plugins/toolu/settings/code-edit-rules.json +67 -0
  229. package/plugins/toolu/settings/commit-prefixes.txt +12 -0
  230. package/plugins/toolu/settings/mcp-blocklist.txt +8 -0
  231. package/plugins/toolu/settings/permissions.fragment.json +36 -0
  232. package/plugins/toolu/settings/protected-files.txt +30 -0
  233. package/plugins/toolu/settings/rust-unsafe-exemptions.txt +5 -0
  234. package/plugins/toolu/settings/toolu.config.example.json +130 -0
  235. package/plugins/toolu/skills/.gitkeep +0 -0
  236. package/plugins/toolu/skills/brainstorm/SKILL.md +57 -0
  237. package/plugins/toolu/skills/brainstorm/references/design-questions.md +36 -0
  238. package/plugins/toolu/skills/commit/SKILL.md +11 -0
  239. package/plugins/toolu/skills/debug/SKILL.md +54 -0
  240. package/plugins/toolu/skills/debug/evals/README.md +17 -0
  241. package/plugins/toolu/skills/debug/evals/cases.json +24 -0
  242. package/plugins/toolu/skills/debug/evals/results.json +34 -0
  243. package/plugins/toolu/skills/deep-research/SKILL.md +51 -0
  244. package/plugins/toolu/skills/execution/SKILL.md +77 -0
  245. package/plugins/toolu/skills/orchestrator/SKILL.md +145 -0
  246. package/plugins/toolu/skills/orchestrator/references/delegation-cost.md +104 -0
  247. package/plugins/toolu/skills/orchestrator/references/model-routing.md +112 -0
  248. package/plugins/toolu/skills/plan/SKILL.md +56 -0
  249. package/plugins/toolu/skills/plan/references/ledger.md +18 -0
  250. package/plugins/toolu/skills/plan-review/SKILL.md +48 -0
  251. package/plugins/toolu/skills/review-and-commit/SKILL.md +10 -0
  252. package/plugins/toolu/skills/setup/SKILL.md +24 -0
  253. package/plugins/toolu/skills/setup/scripts/setup.sh +206 -0
  254. package/plugins/toolu/skills/spec/SKILL.md +67 -0
  255. package/plugins/toolu/skills/spec-review/SKILL.md +50 -0
  256. package/plugins/toolu/skills/test/SKILL.md +49 -0
  257. package/plugins/toolu/workflows/commit.md +21 -0
  258. package/plugins/toolu/workflows/host-mapping.md +22 -0
  259. package/plugins/toolu/workflows/review-and-commit.md +54 -0
  260. package/plugins/toolu/workflows/semantic-judgments.md +35 -0
  261. package/plugins/toolu-review/.claude-plugin/plugin.json +18 -0
  262. package/plugins/toolu-review/.codex-plugin/plugin.json +7 -0
  263. package/plugins/toolu-review/README.md +17 -0
  264. package/plugins/toolu-review/hooks/hooks.json +15 -0
  265. package/plugins/toolu-review/hooks/session-start.sh +34 -0
  266. package/plugins/toolu-review/skills/review/SKILL.md +90 -0
  267. package/plugins/toolu-review/skills/review/scripts/write-state.sh +189 -0
  268. package/plugins/ts-quality/.claude-plugin/plugin.json +24 -0
  269. package/plugins/ts-quality/.codex-plugin/plugin.json +6 -0
  270. package/plugins/ts-quality/README.md +24 -0
  271. package/plugins/ts-quality/hooks/check-toolu.sh +20 -0
  272. package/plugins/ts-quality/hooks/concerns/00-preamble.sh +123 -0
  273. package/plugins/ts-quality/hooks/concerns/10-imports.sh +33 -0
  274. package/plugins/ts-quality/hooks/concerns/15-type-as.sh +9 -0
  275. package/plugins/ts-quality/hooks/concerns/20-tests.sh +26 -0
  276. package/plugins/ts-quality/hooks/concerns/25-size-file.sh +40 -0
  277. package/plugins/ts-quality/hooks/concerns/30-size-fn.sh +53 -0
  278. package/plugins/ts-quality/hooks/concerns/35-react-hooks.sh +7 -0
  279. package/plugins/ts-quality/hooks/concerns/40-factory.sh +5 -0
  280. package/plugins/ts-quality/hooks/concerns/45-typeguard.sh +6 -0
  281. package/plugins/ts-quality/hooks/concerns/50-type-dup.sh +16 -0
  282. package/plugins/ts-quality/hooks/concerns/55-naming.sh +11 -0
  283. package/plugins/ts-quality/hooks/concerns/60-console.sh +6 -0
  284. package/plugins/ts-quality/hooks/concerns/65-suppression.sh +12 -0
  285. package/plugins/ts-quality/hooks/concerns/70-ui-confirm.sh +8 -0
  286. package/plugins/ts-quality/hooks/concerns/72-ui-radix.sh +12 -0
  287. package/plugins/ts-quality/hooks/concerns/74-react-props.sh +6 -0
  288. package/plugins/ts-quality/hooks/concerns/76-toast.sh +10 -0
  289. package/plugins/ts-quality/hooks/concerns/78-error-ast.sh +242 -0
  290. package/plugins/ts-quality/hooks/concerns/80-throw-literal.sh +23 -0
  291. package/plugins/ts-quality/hooks/concerns/85-no-mocks.sh +109 -0
  292. package/plugins/ts-quality/hooks/concerns/90-duplication.sh +30 -0
  293. package/plugins/ts-quality/hooks/concerns/92-docs.sh +36 -0
  294. package/plugins/ts-quality/hooks/concerns/94-handler.sh +15 -0
  295. package/plugins/ts-quality/hooks/concerns/99-finalize.sh +46 -0
  296. package/plugins/ts-quality/hooks/hooks.json +19 -0
  297. package/plugins/ts-quality/hooks/register.sh +65 -0
  298. package/src/adapter/__tests__/evaluate.test.ts +82 -0
  299. package/src/adapter/__tests__/permission-map.test.ts +91 -0
  300. package/src/adapter/evaluate.ts +54 -0
  301. package/src/adapter/permission-map.ts +177 -0
  302. package/src/bootstrap/__tests__/bootstrap.test.ts +148 -0
  303. package/src/bootstrap/entrypoint.ts +18 -0
  304. package/src/bootstrap/index.ts +5 -0
  305. package/src/bootstrap/readiness.ts +59 -0
  306. package/src/bootstrap/result.ts +21 -0
  307. package/src/bootstrap/runtime.ts +99 -0
  308. package/src/bootstrap/test-helpers.ts +25 -0
  309. package/src/host/__tests__/host.test.ts +37 -0
  310. package/src/host/detect.ts +46 -0
  311. package/src/host/index.ts +10 -0
  312. package/src/host/roots.ts +59 -0
  313. package/src/host/types.ts +14 -0
  314. package/src/inventory/__tests__/inventory.test.ts +69 -0
  315. package/src/inventory/index.ts +9 -0
  316. package/src/inventory/manifest.ts +46 -0
  317. package/src/inventory/scan.ts +66 -0
  318. package/src/inventory/selection.ts +92 -0
  319. package/src/inventory/types.ts +22 -0
  320. package/src/lifecycle/__tests__/lifecycle.test.ts +7 -0
  321. package/src/lifecycle/index.ts +2 -0
  322. package/src/lifecycle/table.ts +42 -0
  323. package/src/plugin/__tests__/plugin-stub.test.ts +6 -0
  324. package/src/plugin/plugin-stub.ts +7 -0
  325. package/src/plugin/toolu.ts +142 -0
  326. package/src/preflight/__tests__/preflight.test.ts +20 -0
  327. package/src/preflight/check.ts +75 -0
  328. package/src/preflight/index.ts +2 -0
  329. package/src/select/__tests__/select.test.ts +52 -0
  330. package/src/select/index.ts +2 -0
  331. package/src/select/resolve.ts +87 -0
@@ -0,0 +1,273 @@
1
+ #!/usr/bin/env bash
2
+ # Pre-tool check: gate `git push` on a recorded code review.
3
+ #
4
+ # How firmly it gates is a mode, not a constant — see lib/gate-mode.sh. At the
5
+ # shipped default (balanced) this ADVISES: the agent is told, the push is not
6
+ # stopped. `gates.pushReview.mode: ask` prompts and remembers a yes as a
7
+ # waiver for that exact diff (lib/push-waiver.sh). `block` restores the
8
+ # original hard deny.
9
+ # Project-agnostic: base branch is detected via detect_base_branch
10
+ # (or env-overridden with $PUSH_REVIEW_BASE for tests).
11
+ #
12
+ # Inputs (from parent dispatcher pre-tools/mod.sh, via `export`):
13
+ # $tool_name - name of the tool being invoked
14
+ # $input - raw JSON payload (also piped to stdin; this module reads the env var)
15
+ #
16
+ # State file: <host-state>/tmp/push-review/<branch-slug>.json
17
+ # Override via $STATE_DIR for testing.
18
+
19
+ # pipefail so a `git diff | git hash-object` failure surfaces; without it,
20
+ # an empty diff stream succeeds and yields the well-known empty-blob SHA,
21
+ # which a stale state file can cache and reuse across any future empty-diff
22
+ # state on the same branch (including post-force-reset).
23
+ set -o pipefail
24
+
25
+ : "${tool_name:=}"
26
+ : "${input:=}"
27
+
28
+ _toolu_lib="${TOOLU_LIB_DIR:-${BASH_SOURCE%/*}/../../lib}"
29
+ # shellcheck source=../../lib/detect.sh
30
+ . "$_toolu_lib/detect.sh"
31
+ # shellcheck source=../../lib/diff-sha.sh
32
+ . "$_toolu_lib/diff-sha.sh"
33
+ # shellcheck source=../../lib/telemetry.sh
34
+ . "$_toolu_lib/telemetry.sh"
35
+ # shellcheck source=../../lib/gate-mode.sh
36
+ . "$_toolu_lib/gate-mode.sh"
37
+ # shellcheck source=../../lib/push-waiver.sh
38
+ . "$_toolu_lib/push-waiver.sh"
39
+
40
+ [[ "$tool_name" != "Bash" ]] && exit 0
41
+
42
+ command -v jq >/dev/null 2>&1 || exit 0
43
+ command -v git >/dev/null 2>&1 || exit 0
44
+
45
+ command=$(echo "$input" | jq -r '.tool_input.command // ""')
46
+
47
+ # Push detection (strip_heredocs + boundary-anchored regex) is shared via
48
+ # detect.sh's is_git_push. The trailing boundary also catches statement
49
+ # terminators (`git push;`, `git push&`, `git push|tee`) — without them an agent
50
+ # could append `;` and slip the push past the gate, which is now the only
51
+ # push-time check.
52
+ is_git_push "$command" || exit 0
53
+
54
+ # Resolve the delivery mode before doing any work: `off` means this gate has
55
+ # nothing to say, and the git plumbing below is not free.
56
+ mode=$(toolu_gate_mode pushReview)
57
+ [ "$mode" = "off" ] && exit 0
58
+
59
+ # Every check below reads the repo the push TARGETS, not the hook's cwd — a
60
+ # `git -C <worktree> push` must be judged on the worktree's branch, diff and
61
+ # state file. Keying off $CLAUDE_PROJECT_DIR (a main-checkout path) split the
62
+ # state file in two: the reviewer wrote the worktree's copy while the gate read
63
+ # the main checkout's, so no amount of re-reviewing could satisfy it.
64
+ repo_root=$(push_target_root "$command")
65
+
66
+ # The checked-out branch, or — on a detached checkout such as pr-babysit's
67
+ # `git worktree add --detach` + `push origin HEAD:<branch>` — the refspec
68
+ # destination (push_target_branch in lib/detect.sh). Empty means neither
69
+ # names a branch and the detached-head deny below stands.
70
+ current_branch=$(push_target_branch "$command" "$repo_root")
71
+ slug=$(branch_slug "$current_branch")
72
+
73
+ # Resolve state dir: env override takes precedence; else target-repo default.
74
+ state_dir=${STATE_DIR:-$(toolu_project_state_dir push-review "$repo_root")}
75
+ state_file="$state_dir/${slug}.json"
76
+
77
+ # Base branch: env override > detect_base_branch, resolved in the target repo.
78
+ base_branch="${PUSH_REVIEW_BASE:-$(detect_base_branch "$repo_root")}"
79
+
80
+ # push_check telemetry: one closed set of reason codes across every decision
81
+ # exit below (base-missing, detached-head, diff-failed, no-state, stale-diff,
82
+ # schema-v1, schema, file-coverage, findings, reviewer, round-cap, empty-diff,
83
+ # pass). detached-head is unreachable-by-contract in the stream: telemetry_append
84
+ # refuses branch=="HEAD", so that deny never produces a line — the call stays for
85
+ # consistency should the contract change. ROUND is the state file's review_round
86
+ # when it's already known at the call site; the exits that precede reading the
87
+ # state file (or that fail its schema) pass "" -> JSON null.
88
+ _pr_telemetry() {
89
+ local result="$1" code="$2" round="${3:-}"
90
+ local round_json="null"
91
+ [[ "$round" =~ ^[0-9]+$ ]] && round_json="$round"
92
+ telemetry_append "$repo_root" "push_check" \
93
+ "$(jq -cn --arg result "$result" --arg code "$code" --argjson round "$round_json" \
94
+ '{result: $result, reason_code: $code, round: $round}')"
95
+ }
96
+
97
+ # _pr_decide CODE REASON [ROUND]
98
+ # Deliver one failed check in the configured mode, record it, and stop.
99
+ #
100
+ # In `ask` mode the question is also written down as a pending waiver keyed to
101
+ # the diff being asked about, so post-tools/modules/push-waiver.sh can promote
102
+ # it if the push actually happens. Checks that fail before a diff SHA exists
103
+ # (missing base, detached HEAD) have nothing to key a waiver to and simply skip
104
+ # that step — they are operational errors, not review decisions.
105
+ _pr_decide() {
106
+ local code="$1" reason="$2" round="${3:-}"
107
+ local result="$mode"
108
+ case "$mode" in
109
+ block) result=deny ;;
110
+ ask)
111
+ result=ask
112
+ reason="No clean review is recorded for this diff. Approving pushes anyway, and the approval is remembered until the diff changes.
113
+
114
+ $reason"
115
+ if [ -n "${current_diff_sha:-}" ]; then
116
+ push_waiver_pend "$repo_root" "$slug" "$current_diff_sha" "$base_branch" "$code" \
117
+ || echo "push-review: could not record the pending waiver; a yes will be asked again" >&2
118
+ fi
119
+ ;;
120
+ advise) result=advise ;;
121
+ esac
122
+ toolu_gate_emit "$mode" "$reason"
123
+ _pr_telemetry "$result" "$code" "$round"
124
+ exit 0
125
+ }
126
+
127
+ # Verify base branch exists locally.
128
+ if ! git -C "$repo_root" rev-parse --verify --quiet "$base_branch" >/dev/null; then
129
+ _pr_decide base-missing "base branch '$base_branch' not found locally; run \`git fetch origin $base_branch:$base_branch\`"
130
+ fi
131
+
132
+ # Detached HEAD with no refspec destination to judge instead.
133
+ if [[ "$current_branch" == "HEAD" || -z "$current_branch" ]]; then
134
+ _pr_decide detached-head "detached HEAD — checkout a branch, or push an explicit \`HEAD:<branch>\` refspec so the review state can be keyed to that branch"
135
+ fi
136
+
137
+ # Pushing the base branch itself (e.g. fast-forwarded main after a local merge)
138
+ # is not a feature-review scenario — `<base>...<base>` has empty diff by
139
+ # definition. Allow without state-file gate.
140
+ if [[ "$current_branch" == "$base_branch" ]]; then
141
+ exit 0
142
+ fi
143
+
144
+ # Compute branch diff SHA (content-addressed, survives amend/rebase).
145
+ # Well-known git empty-blob SHA — the value `git hash-object --stdin` produces
146
+ # for an empty stream. We refuse to cache or trust this value: a state file
147
+ # bearing it would be reusable across any future empty-diff state on the same
148
+ # branch (e.g. after a force reset wipes commits).
149
+ EMPTY_BLOB_SHA="e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
150
+
151
+ current_diff_sha=$(toolu_diff_sha "$repo_root" "$base_branch")
152
+ if [[ -z "$current_diff_sha" ]]; then
153
+ # git diff failed (disk full, etc). Allow push; underlying push will surface real failure.
154
+ echo "push-review: git diff ${base_branch}...HEAD failed; allowing push to surface real error" >&2
155
+ _pr_telemetry allow diff-failed
156
+ exit 0
157
+ fi
158
+
159
+ if [[ "$current_diff_sha" == "$EMPTY_BLOB_SHA" ]]; then
160
+ # Empty diff against base: nothing to review and nothing to push. Treat as
161
+ # a sentinel that NEVER satisfies the cache check, then deny the push so
162
+ # the user is forced to confirm intent rather than push a no-op.
163
+ current_diff_sha="empty-diff"
164
+ _pr_decide empty-diff "Refusing to push: diff against $base_branch is empty. Either no commits diverged from base, or the branch was force-reset. Verify intent before pushing."
165
+ fi
166
+
167
+ # A waiver for THIS diff means the user already answered "push anyway" for
168
+ # exactly this code. Honor it silently — asking again about an answered
169
+ # question is the nag this gate is trying not to be.
170
+ if push_waiver_matches "$repo_root" "$slug" "$current_diff_sha"; then
171
+ _pr_telemetry allow waived
172
+ exit 0
173
+ fi
174
+
175
+ # Reviewer guidance is agnostic: any one accepted reviewer satisfies the gate.
176
+ # The built-in /code-review skill is the always-available baseline.
177
+ reviewer_hint="the built-in \`/code-review xhigh --fix\` skill, recorded as \"code-review\" (or the \`toolu-review:review\` skill)"
178
+
179
+ # State file gate.
180
+ if [[ ! -f "$state_file" ]]; then
181
+ _pr_decide no-state "Code review required before push (diff SHA $current_diff_sha, base $base_branch).
182
+ Run a code reviewer on \`git diff $base_branch...HEAD\` and apply its findings — use $reviewer_hint. Then atomically write $state_file (tmp+mv) with schema { version: 2, branch, diff_sha, base_branch, reviewed_at, reviewers, findings_count, findings, review_round, reviewed_files }. \`reviewers\` must include at least one accepted reviewer (code-review, toolu-review:review, code-review:xhigh, review, or security-review), \`findings_count\` must be 0, \`review_round\` starts at 1 for a new \`diff_sha\` and bumps by 1 only when rewriting at the same \`diff_sha\`. \`reviewed_files\` must list every path from \`git diff $base_branch...HEAD --name-only\` (sorted, unique) — the actual reviewer file coverage. Retry push."
183
+ fi
184
+
185
+ # Validate state file: version, diff_sha, findings_count, reviewers.
186
+ state_version=$(jq -r '.version // ""' "$state_file" 2>/dev/null || echo "")
187
+ state_sha=$(jq -r '.diff_sha // ""' "$state_file" 2>/dev/null || echo "")
188
+ state_findings=$(jq -r '.findings_count // ""' "$state_file" 2>/dev/null || echo "")
189
+
190
+ # A schema v1 state (no reviewed_files contract) gets a dedicated one-time
191
+ # upgrade deny rather than the generic "corrupted" deny — the state is valid,
192
+ # just stale-schema, and the fix is a re-review, not a delete-and-retry.
193
+ if [[ "$state_version" == "1" ]]; then
194
+ _pr_decide schema-v1 "push-review state is schema v1; harness v2 requires reviewed_files — re-run the review to regenerate the state file"
195
+ fi
196
+
197
+ if [[ "$state_version" != "2" || -z "$state_sha" || -z "$state_findings" ]]; then
198
+ _pr_decide schema "state file corrupted at $state_file; delete and re-review"
199
+ fi
200
+
201
+ # review_round: read here (once) rather than only at the round-cap check below,
202
+ # so it's already known for the reviewer-acceptance telemetry exit too. Missing
203
+ # field defaults to round 1 for backward compat (same default the round-cap
204
+ # check uses).
205
+ state_round=$(jq -r '.review_round // 1' "$state_file" 2>/dev/null || echo "1")
206
+
207
+ # Reviewer-agnostic gate: at least ONE accepted reviewer must appear in the
208
+ # state file. The built-in /code-review skill is the always-available baseline;
209
+ # other known reviewers are accepted too. The check is "intersection non-empty",
210
+ # not equality, so running extra reviewers first is always
211
+ # fine. Requiring at least one known name still prevents an agent from writing a
212
+ # junk reviewer entry to bypass the gate.
213
+ accepted_reviewers='["code-review","toolu-review:review","code-review:xhigh","review","security-review"]'
214
+ if ! jq -e --argjson acc "$accepted_reviewers" \
215
+ '(.reviewers // []) as $r | any($acc[]; . as $x | $r | index($x) != null)' \
216
+ "$state_file" >/dev/null 2>&1; then
217
+ _pr_decide reviewer "state file lists no accepted reviewer at $state_file
218
+ \`reviewers\` must include at least one of: $accepted_reviewers
219
+ Run a reviewer — use $reviewer_hint — then rewrite the state file." "$state_round"
220
+ fi
221
+
222
+ # Max review rounds — bound the fix→re-review loop. `review_round` counts
223
+ # rewrites AT THE SAME diff_sha: a changed diff resets it to 1, so the counter
224
+ # measures "reviewers keep finding issues in code that never changed", not
225
+ # "this branch has been worked on for a while". Counting every rewrite instead
226
+ # made the cap terminal — nothing resets it after a push, so a long-lived
227
+ # branch eventually denied every push forever.
228
+ # Missing field is treated as round 1 for backward compat.
229
+ # After MAX_ROUNDS, deny with an escalation message so the babysit triggers
230
+ # its Step 6 escalation stop instead of looping indefinitely.
231
+ MAX_ROUNDS=5
232
+ if [[ "$state_round" =~ ^[0-9]+$ ]] && (( state_round > MAX_ROUNDS )); then
233
+ _pr_decide round-cap "ESCALATE: review loop hit $state_round rounds (max $MAX_ROUNDS) on an unchanged diff at $state_file. Reviewers keep finding new issues after each fix — stop auto-looping and surface the current findings to the human. Babysit: treat as Escalation stop (Step 6)." "$state_round"
234
+ fi
235
+
236
+ if [[ "$state_sha" != "$current_diff_sha" ]]; then
237
+ _pr_decide stale-diff "Code review required: diff changed since review.
238
+ Current diff SHA: $current_diff_sha
239
+ State file: $state_file (stale)
240
+ Re-run reviewers on the new diff and rewrite the state file." "$state_round"
241
+ fi
242
+
243
+ if [[ "$state_findings" != "0" ]]; then
244
+ _pr_decide findings "Code review has open findings ($state_findings).
245
+ State file: $state_file
246
+ Address every finding (any finding blocks). Re-commit. Re-run reviewers. Rewrite state file with findings_count=0." "$state_round"
247
+ fi
248
+
249
+ # Reviewer file coverage (v2): reviewed_files must equal the diff's changed
250
+ # paths (sorted, unique) — catches honestly-reported partial review scope.
251
+ # Not adversary-proof against a writer that lies about what it reviewed
252
+ # (Non-Goal 3, spec). A missing/malformed reviewed_files reads as empty here
253
+ # (jq errors are silenced), which correctly denies naming every changed path
254
+ # as missing rather than passing vacuously.
255
+ changed_sorted=$(git -C "$repo_root" diff --no-color "${base_branch}...HEAD" --name-only 2>/dev/null | sort -u)
256
+ reviewed_sorted=$(jq -r '.reviewed_files[]' "$state_file" 2>/dev/null | sort -u)
257
+
258
+ if [[ "$changed_sorted" != "$reviewed_sorted" ]]; then
259
+ missing=$(comm -23 <(printf '%s\n' "$changed_sorted") <(printf '%s\n' "$reviewed_sorted"))
260
+ extra=$(comm -13 <(printf '%s\n' "$changed_sorted") <(printf '%s\n' "$reviewed_sorted"))
261
+ reason="reviewed_files does not match the current diff at $state_file."
262
+ [ -n "$missing" ] && reason="$reason
263
+ Missing from reviewed_files (changed but not reviewed): $missing"
264
+ [ -n "$extra" ] && reason="$reason
265
+ In reviewed_files but not in the current diff: $extra"
266
+ reason="$reason
267
+ Re-review the full diff and rewrite reviewed_files to match \`git diff $base_branch...HEAD --name-only\` exactly."
268
+ _pr_decide file-coverage "$reason" "$state_round"
269
+ fi
270
+
271
+ # All gates pass: allow push.
272
+ _pr_telemetry allow pass "$state_round"
273
+ exit 0
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env bash
2
+ # Pre-tool check: quality gate enforcement.
3
+ #
4
+ # When the gate state file says "failing", this stops the two actions that
5
+ # would let a red build escape the working tree: `git commit` and `git push`.
6
+ # Nothing else. Reading, searching, editing, and running commands stay open —
7
+ # a failing gate is a reason not to SHIP, not a reason to be unable to work.
8
+ # (It used to deny every tool call except a whitelist, which meant a stale red
9
+ # gate could block `ls`.)
10
+ #
11
+ # How firmly it stops them is a mode — see lib/gate-mode.sh. Default: block.
12
+ # `MY_CLAUDE_QUALITY=off` remains an env-level kill switch for the whole gate.
13
+ #
14
+ # Project-agnostic: tooling is auto-detected; missing tooling → silent skip.
15
+ #
16
+ # Inputs (from parent dispatcher pre-tools/mod.sh, via `export`):
17
+ # $tool_name - name of the tool being invoked
18
+ # $input - raw JSON payload on stdin
19
+
20
+ : "${tool_name:=}"
21
+ : "${input:=}"
22
+
23
+ _toolu_lib="${TOOLU_LIB_DIR:-${BASH_SOURCE%/*}/../../lib}"
24
+ # shellcheck source=../../lib/detect.sh
25
+ . "$_toolu_lib/detect.sh"
26
+ # shellcheck source=../../lib/gate-mode.sh
27
+ . "$_toolu_lib/gate-mode.sh"
28
+
29
+ # Owner kill-switch.
30
+ [ "${MY_CLAUDE_QUALITY:-}" = "off" ] && exit 0
31
+
32
+ # Guard tooling.
33
+ command -v jq >/dev/null 2>&1 || exit 0
34
+ command -v git >/dev/null 2>&1 || exit 0
35
+
36
+ # Only Bash/Shell can commit or push, so every other tool is out of scope
37
+ # before any file is read.
38
+ [[ "$tool_name" != "Bash" && "$tool_name" != "Shell" ]] && exit 0
39
+
40
+ command=$(echo "$input" | jq -r '.tool_input.command // ""')
41
+ cmd_only=$(printf '%s\n' "$command" | strip_heredocs)
42
+
43
+ # Heredoc-stripped, boundary-anchored detection shared with push-review, so
44
+ # `git -C <path> commit` and `foo && git push` are seen and a commit message
45
+ # that merely mentions pushing is not.
46
+ if ! is_git_commit "$cmd_only" && ! is_git_push "$cmd_only"; then
47
+ exit 0
48
+ fi
49
+
50
+ # Only now is the config worth loading. This module runs on every Bash call and
51
+ # almost none of them are a commit or a push; resolving the mode first would
52
+ # have paid a config read + jq parse for every `ls`.
53
+ mode=$(toolu_gate_mode qualityGate)
54
+ [ "$mode" = "off" ] && exit 0
55
+
56
+ project_root="$(detect_project_root)"
57
+ [ -z "$project_root" ] && project_root="$(pwd)"
58
+
59
+ gate_file="$(toolu_project_state_root "$project_root")/quality-gate-status.json"
60
+
61
+ [[ ! -f "$gate_file" ]] && exit 0
62
+ [[ "$(jq -r '.status // ""' "$gate_file" 2>/dev/null)" != "failing" ]] && exit 0
63
+
64
+ # Skip enforcement in git linked worktrees — quality state lives on the main checkout.
65
+ git_dir="$(git -C "$project_root" rev-parse --path-format=absolute --git-dir 2>/dev/null || true)"
66
+ common_dir="$(git -C "$project_root" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)"
67
+ git_dir="${git_dir%/}"
68
+ common_dir="${common_dir%/}"
69
+ if [[ -n "$git_dir" && -n "$common_dir" && "$git_dir" != "$common_dir" ]]; then
70
+ exit 0
71
+ fi
72
+
73
+ reason=$(jq -r '.reason // "Quality gate failing"' "$gate_file" 2>/dev/null || echo "Quality gate failing")
74
+ violations=$(jq -r '.violations // ""' "$gate_file" 2>/dev/null || echo "")
75
+
76
+ # The lead sentence follows the mode: claiming something was BLOCKED while
77
+ # merely advising would be a lie in the one place the user is reading closely.
78
+ case "$mode" in
79
+ block) lead="BLOCKED: quality gate failing — fix the violations before committing or pushing." ;;
80
+ ask) lead="The quality gate is failing. Commit/push anyway?" ;;
81
+ *) lead="Heads up: the quality gate is failing (commit and push are not blocked at this setting)." ;;
82
+ esac
83
+
84
+ toolu_gate_emit "$mode" "$lead
85
+ $reason
86
+ $violations"
87
+ exit 0