@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,80 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agent-browser wrapper — bakes token-lean defaults onto the read-heavy command
5
+ # family so the agent spends context on the accessibility tree, not raw HTML or
6
+ # screenshots. Injection is fail-open via a STATIC per-subcommand allow-map: a
7
+ # default flag is added ONLY where that subcommand accepts it, so shaping can
8
+ # never turn a working call into a usage error; every other subcommand passes
9
+ # through untouched. A leading `--raw` bypasses all shaping. The binary is never
10
+ # auto-installed — a missing one prints an install guide and exits non-zero.
11
+ #
12
+ # $AGENT_BROWSER_BIN overrides the binary (absolute path or PATH name), for
13
+ # pointing at a custom build or for tests.
14
+
15
+ BIN="${AGENT_BROWSER_BIN:-agent-browser}"
16
+ DEFAULT_MAX_OUTPUT=4000
17
+
18
+ install_guide() {
19
+ echo "agent-browser not found — install: npm i -g agent-browser && agent-browser install (or: brew install agent-browser / cargo install agent-browser)" >&2
20
+ }
21
+
22
+ require_bin() {
23
+ command -v "$BIN" >/dev/null 2>&1 || { install_guide; exit 127; }
24
+ }
25
+
26
+ # Exact-token or --opt=value match against the remaining args.
27
+ has_flag() {
28
+ local needle="$1"; shift
29
+ local a
30
+ for a in "$@"; do
31
+ case "$a" in
32
+ "$needle" | "$needle="*) return 0 ;;
33
+ esac
34
+ done
35
+ return 1
36
+ }
37
+
38
+ # --raw: total bypass, no shaping.
39
+ if [ "${1:-}" = "--raw" ]; then
40
+ shift
41
+ require_bin
42
+ exec "$BIN" "$@"
43
+ fi
44
+
45
+ require_bin
46
+
47
+ # No subcommand — let agent-browser print its own help/usage.
48
+ if [ "$#" -eq 0 ]; then
49
+ exec "$BIN"
50
+ fi
51
+
52
+ cmd="$1"; shift # remaining flags/args stay in "$@"
53
+
54
+ inject=()
55
+ case "$cmd" in
56
+ snapshot)
57
+ # -i (interactive-only compact tree) unless the caller already scoped it.
58
+ if ! has_flag -i "$@" && ! has_flag -a "$@" \
59
+ && ! has_flag -s "$@" && ! has_flag -d "$@"; then
60
+ inject+=(-i)
61
+ fi
62
+ has_flag --json "$@" || inject+=(--json)
63
+ has_flag --max-output "$@" || inject+=(--max-output "$DEFAULT_MAX_OUTPUT")
64
+ has_flag --content-boundaries "$@" || inject+=(--content-boundaries)
65
+ ;;
66
+ get)
67
+ has_flag --json "$@" || inject+=(--json)
68
+ has_flag --max-output "$@" || inject+=(--max-output "$DEFAULT_MAX_OUTPUT")
69
+ has_flag --content-boundaries "$@" || inject+=(--content-boundaries)
70
+ ;;
71
+ find | diff)
72
+ has_flag --json "$@" || inject+=(--json)
73
+ has_flag --max-output "$@" || inject+=(--max-output "$DEFAULT_MAX_OUTPUT")
74
+ ;;
75
+ *)
76
+ : # unknown/binary-output subcommand — inject nothing (fail-open passthrough)
77
+ ;;
78
+ esac
79
+
80
+ exec "$BIN" "$cmd" "${inject[@]+"${inject[@]}"}" "$@"
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "ast-grep",
3
+ "version": "6.8.0",
4
+ "description": "Structural code search & rewrite (ast-grep): skill, wrapper, and a PreToolUse Grep→ast-grep nudge registered into the toolu hook engine.",
5
+ "author": {
6
+ "name": "Falconiere Barbosa",
7
+ "email": "hello@falconiere.io"
8
+ },
9
+ "homepage": "https://github.com/falconiere/toolu",
10
+ "repository": "https://github.com/falconiere/toolu.git",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "claude-code",
14
+ "ast-grep",
15
+ "structural-search",
16
+ "hooks"
17
+ ]
18
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "ast-grep",
3
+ "version": "6.8.0",
4
+ "description": "Structural code search & rewrite (ast-grep): skill, wrapper, and a PreToolUse Grep→ast-grep nudge registered into the toolu hook engine.",
5
+ "skills": "./skills/",
6
+ "hooks": "./hooks/hooks.json"
7
+ }
@@ -0,0 +1,21 @@
1
+ # ast-grep
2
+
3
+ Structural code search & rewrite (ast-grep): a skill, a wrapper, and a `PreToolUse` `Grep → ast-grep` nudge registered into the toolu hook engine.
4
+
5
+ ## Install
6
+
7
+ ```
8
+ /plugin install ast-grep@toolu
9
+ ```
10
+
11
+ Standalone, no dependencies.
12
+
13
+ ## What it provides
14
+
15
+ - **`ast-grep` skill** — an always-active protocol that mandates ast-grep (tree-sitter AST patterns) over Grep/sed for any find-or-rewrite-by-code-shape task, falling back to Grep only for exact literals.
16
+ - **`search-nudge` (`PreToolUse`)** — nudges Grep on code files, and `grep`/`rg` in Bash, toward the proper structural tool.
17
+ - **`byte-savings` (`PostToolUse`)** + `byte-savings-report.sh` — instrumentation for tokens saved by structural search.
18
+
19
+ ## The ast-grep binary
20
+
21
+ The skill drives the `ast-grep` (a.k.a. `sg`) CLI — a tree-sitter AST pattern matcher and rewriter. Install it via `brew install ast-grep`, `cargo install ast-grep`, or `npm i -g @ast-grep/cli`. The plugin's hook modules register themselves into the core toolu dispatcher at `SessionStart` and run only while this plugin is installed.
@@ -0,0 +1,15 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "startup|resume|clear|compact",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/register.sh"
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env bash
2
+ # PostToolUse instrumentation — measure how many bytes targeted/structural tools
3
+ # inject into context, so the "ast-grep returns far less than reading whole
4
+ # files" claim is MEASURED, not asserted.
5
+ #
6
+ # Honest by construction: it records the REAL byte count each tool returned. For
7
+ # a Read of a single on-disk file it also records that file's full size (the
8
+ # bytes a whole read costs), so a ranged Read shows a real saving. It does NOT
9
+ # fabricate a counterfactual for searches — it records what ast-grep/Grep
10
+ # actually returned, and the report aggregates per tool so the volume gap is
11
+ # visible. Append-only ledger; never blocks; emits nothing to context.
12
+ #
13
+ # Inputs (exported by post-tools/mod.sh): $tool_name $input $PROJECT_ROOT
14
+ : "${tool_name:=}"
15
+ : "${input:=}"
16
+
17
+ command -v jq >/dev/null 2>&1 || exit 0
18
+
19
+ # Classify the tool; ignore everything we don't measure as cheaply as possible.
20
+ kind=""
21
+ case "$tool_name" in
22
+ Read) kind="read" ;;
23
+ Grep) kind="grep" ;;
24
+ Glob) kind="glob" ;;
25
+ Bash|Shell)
26
+ cmd=$(jq -r '.tool_input.command // ""' <<<"$input" 2>/dev/null)
27
+ # Matches `ast-grep …`, `sg …`, and piped forms (`… | ast-grep …`) — the
28
+ # leading-space alternative subsumes the pipe case, so no separate pattern.
29
+ case "$cmd" in
30
+ ast-grep*|sg\ *|*\ ast-grep\ *) kind="ast-grep" ;;
31
+ *) exit 0 ;;
32
+ esac
33
+ ;;
34
+ *) exit 0 ;;
35
+ esac
36
+
37
+ # Returned bytes = byte length of the tool's textual response. tool_response may
38
+ # be a string (Read/Grep) or an object (Bash); coerce to text then measure.
39
+ resp=$(jq -r '
40
+ .tool_response
41
+ | if type == "string" then .
42
+ elif type == "object" then (.content? // .stdout? // .output? // tostring)
43
+ else tostring end' <<<"$input" 2>/dev/null)
44
+ [ -n "$resp" ] || exit 0
45
+ returned=$(printf '%s' "$resp" | wc -c | tr -d ' ')
46
+ [ -n "$returned" ] || exit 0
47
+
48
+ # Full-file bytes (single-file Read only): the cost a whole read would incur.
49
+ full=0
50
+ if [ "$kind" = "read" ]; then
51
+ fp=$(jq -r '.tool_input.file_path // ""' <<<"$input" 2>/dev/null)
52
+ if [ -n "$fp" ] && [ -f "$fp" ]; then
53
+ full=$(wc -c < "$fp" 2>/dev/null | tr -d ' ')
54
+ [ -n "$full" ] || full=0
55
+ fi
56
+ fi
57
+
58
+ # Append one compact record to the per-session ledger. Session-scoped so a
59
+ # stale id can never grow unbounded; the report aggregates a single session.
60
+ sid=$(jq -r '.session_id // "unknown"' <<<"$input" 2>/dev/null | tr -cd 'A-Za-z0-9-')
61
+ [ -n "$sid" ] || sid="unknown"
62
+ ledger_dir="${TOOLU_CONFIG_DIR:-${CODEX_HOME:-${CLAUDE_CONFIG_DIR:-$HOME/.claude}}}/toolu/byte-savings"
63
+ mkdir -p "$ledger_dir" 2>/dev/null || exit 0
64
+ printf '{"kind":"%s","returned":%s,"full":%s}\n' "$kind" "$returned" "$full" \
65
+ >> "$ledger_dir/$sid.jsonl" 2>/dev/null
66
+
67
+ exit 0
@@ -0,0 +1,170 @@
1
+ #!/bin/bash
2
+ # Pre-tool check: Enforce search hierarchy
3
+ # 1. ast-grep (structural / AST patterns) — first on code files
4
+ # 2. Grep (exact literals on non-code files, or after ast-grep returned nothing)
5
+ #
6
+ # Grep on code files is nudged toward ast-grep when patterns look structural.
7
+ # Bash grep/rg is always nudged toward proper tools.
8
+ #
9
+ # Inputs (from parent dispatcher pre-tools/mod.sh, via `export`):
10
+ # $tool_name - name of the tool being invoked
11
+ # $input - raw JSON payload on stdin
12
+
13
+ : "${tool_name:=}"
14
+ : "${input:=}"
15
+
16
+ # Core lib comes from the toolu dispatcher via TOOLU_LIB_DIR (set by
17
+ # plugins/toolu/hooks/pre-tools/mod.sh before registry dispatch). Outside
18
+ # that pipeline there is no relative path to it — fail SOFT: this module is
19
+ # an advisory extra and must never break tool calls by erroring.
20
+ [ -n "${TOOLU_LIB_DIR:-}" ] && [ -f "$TOOLU_LIB_DIR/detect.sh" ] && [ -f "$TOOLU_LIB_DIR/config.sh" ] || exit 0
21
+ # shellcheck source=../../../toolu/hooks/lib/detect.sh
22
+ . "$TOOLU_LIB_DIR/detect.sh"
23
+ # shellcheck source=../../../toolu/hooks/lib/config.sh
24
+ . "$TOOLU_LIB_DIR/config.sh"
25
+
26
+ # Decide ast-grep state lazily: config + CLI detection are only consulted when
27
+ # a structural pattern or grep/rg invocation is actually matched, so the
28
+ # common Bash/Grep tool call pays nothing.
29
+ ASTGREP_STATE=""
30
+ astgrep_state() {
31
+ if [ -z "$ASTGREP_STATE" ]; then
32
+ if ! toolu_enabled skills ast-grep; then
33
+ ASTGREP_STATE="opt-out"
34
+ elif [ "$(detect_ast_grep)" = "ast-grep" ]; then
35
+ ASTGREP_STATE="available"
36
+ else
37
+ ASTGREP_STATE="missing"
38
+ fi
39
+ fi
40
+ printf '%s' "$ASTGREP_STATE"
41
+ }
42
+
43
+ # ── Structural pattern keywords (shared) ────────────────────────────────────
44
+ STRUCT_RE='(^|\s)(fn |impl |async fn|async |class |function |struct |trait |interface |type |pub (fn|struct|enum|trait|mod|type|async)|export (function|class|interface|type|const|default)|enum |mod |const fn|#\[derive|#\[cfg|#\[test|@Component|@Injectable|@Module|=>|-> Result|-> impl|dyn |Box<|Arc<|Vec<|Option<|where |for .*in )'
45
+
46
+ # ── Non-code file globs (Grep is sole tool for these) ──────────────────────
47
+ NON_CODE_GLOB_RE='\*\.(toml|md|markdown|json|jsonc|yaml|yml|txt|env|sql|sh|bash|zsh|fish|lock|cfg|ini|conf|csv|xml|html|svg|css|graphql|gql|proto|makefile|dockerfile)'
48
+ NON_CODE_TYPE_RE='^(toml|json|yaml|md|markdown|html|css|sql|sh|bash|make|docker|config|xml|csv|graphql|proto)$'
49
+
50
+ # ── Non-code path segments (hooks, docs, config dirs) ──────────────────────
51
+ NON_CODE_PATH_RE='(\.claude/|docs/|\.github/|infra/|scripts/|\.config|Makefile|Dockerfile|Cargo\.toml|package\.json|tsconfig)'
52
+
53
+ # ── Grep tool ───────────────────────────────────────────────────────────────
54
+ if [[ "$tool_name" == "Grep" ]]; then
55
+ pattern=$(echo "$input" | jq -r '.tool_input.pattern // ""')
56
+ glob_filter=$(echo "$input" | jq -r '.tool_input.glob // ""')
57
+ type_filter=$(echo "$input" | jq -r '.tool_input.type // ""')
58
+ path_filter=$(echo "$input" | jq -r '.tool_input.path // ""')
59
+
60
+ # ── ALLOW: Non-code file types (Grep is sole tool — ast-grep can't do these)
61
+ if [[ -n "$glob_filter" ]] && echo "$glob_filter" | grep -qiE "$NON_CODE_GLOB_RE"; then
62
+ exit 0
63
+ fi
64
+ if [[ -n "$type_filter" ]] && echo "$type_filter" | grep -qiE "$NON_CODE_TYPE_RE"; then
65
+ exit 0
66
+ fi
67
+ if [[ -n "$path_filter" ]] && echo "$path_filter" | grep -qiE "$NON_CODE_PATH_RE"; then
68
+ exit 0
69
+ fi
70
+
71
+ # ── STOP: Structural code pattern → ast-grep (only when installed)
72
+ if echo "$pattern" | grep -qE "$STRUCT_RE"; then
73
+ case "$(astgrep_state)" in
74
+ available)
75
+ jq -n '{
76
+ "hookSpecificOutput": {
77
+ "hookEventName": "PreToolUse",
78
+ "additionalContext": "STOP: Structural code pattern detected. Use ast-grep: `ast-grep run --pattern \"your pattern\" --lang rust/typescript .` AST-aware matching is far more accurate. Grep is for exact literals on non-code files, or after ast-grep returned nothing."
79
+ }
80
+ }'
81
+ ;;
82
+ missing)
83
+ jq -n '{
84
+ "hookSpecificOutput": {
85
+ "hookEventName": "PreToolUse",
86
+ "additionalContext": "WARN: structural code pattern detected but ast-grep is not installed. Falling back to Grep — expect false positives. Install ast-grep (`cargo install ast-grep` or `brew install ast-grep`) for AST-aware matching."
87
+ }
88
+ }'
89
+ ;;
90
+ opt-out|*)
91
+ : # user opted out of ast-grep — no nudge, no install hint
92
+ ;;
93
+ esac
94
+ exit 0
95
+ fi
96
+
97
+ exit 0
98
+ fi
99
+
100
+ # ── Bash tool: catch grep/rg being used for code search ────────────────────
101
+ if [[ "$tool_name" == "Bash" || "$tool_name" == "Shell" ]]; then
102
+ command=$(echo "$input" | jq -r '.tool_input.command // ""')
103
+
104
+ # Strip heredoc bodies
105
+ cmd_only=$(printf '%s\n' "$command" | strip_heredocs)
106
+
107
+ # Catch grep/rg invocations
108
+ if echo "$cmd_only" | grep -qE '(^|\s|&&|\|\||;)(grep|rg|ripgrep)\s'; then
109
+ # Structural patterns → ast-grep (only when installed)
110
+ if echo "$cmd_only" | grep -qE "$STRUCT_RE"; then
111
+ case "$(astgrep_state)" in
112
+ available)
113
+ jq -n '{
114
+ "hookSpecificOutput": {
115
+ "hookEventName": "PreToolUse",
116
+ "additionalContext": "STOP: grep/rg for structural code search. Use ast-grep: `ast-grep run --pattern \"your pattern\" --lang rust/typescript .` grep/rg is for piping command output or non-code files."
117
+ }
118
+ }'
119
+ ;;
120
+ missing)
121
+ jq -n '{
122
+ "hookSpecificOutput": {
123
+ "hookEventName": "PreToolUse",
124
+ "additionalContext": "WARN: structural grep/rg detected but ast-grep is not installed. Proceeding with grep/rg — expect false positives. Install ast-grep (`cargo install ast-grep` or `brew install ast-grep`) for AST-aware matching."
125
+ }
126
+ }'
127
+ ;;
128
+ opt-out|*)
129
+ : # ast-grep opted out — no STOP/WARN
130
+ ;;
131
+ esac
132
+ exit 0
133
+ fi
134
+
135
+ # All other grep/rg → nudge toward proper tools.
136
+ # The Grep-tool-vs-bash-grep advice is independent of ast-grep, so this
137
+ # fires even when ast-grep is opted out; we just drop the ast-grep half.
138
+ case "$(astgrep_state)" in
139
+ available)
140
+ jq -n '{
141
+ "hookSpecificOutput": {
142
+ "hookEventName": "PreToolUse",
143
+ "additionalContext": "grep/rg in Bash detected. Use ast-grep for structural patterns on code files, Grep tool for exact literals on non-code files. Bash grep/rg only for piping command output."
144
+ }
145
+ }'
146
+ ;;
147
+ missing)
148
+ jq -n '{
149
+ "hookSpecificOutput": {
150
+ "hookEventName": "PreToolUse",
151
+ "additionalContext": "grep/rg in Bash detected. Use Grep tool for exact literals on non-code files. Bash grep/rg only for piping command output. (ast-grep not installed — structural matching unavailable.)"
152
+ }
153
+ }'
154
+ ;;
155
+ opt-out|*)
156
+ jq -n '{
157
+ "hookSpecificOutput": {
158
+ "hookEventName": "PreToolUse",
159
+ "additionalContext": "grep/rg in Bash detected. Use Grep tool for exact literals on non-code files. Bash grep/rg only for piping command output."
160
+ }
161
+ }'
162
+ ;;
163
+ esac
164
+ exit 0
165
+ fi
166
+
167
+ exit 0
168
+ fi
169
+
170
+ exit 0
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env bash
2
+ # SessionStart registry sync for the ast-grep plugin.
3
+ #
4
+ # Mirrors hooks/pre-tools.d/*.sh and hooks/post-tools.d/*.sh into the toolu
5
+ # runtime registry (${TOOLU_CONFIG_DIR:-${CLAUDE_CONFIG_DIR:-$HOME/.claude}}/toolu/{pre,post}-tools.d/)
6
+ # under the namespaced filename ast-grep@toolu__<name>.sh, and prunes entries
7
+ # bearing OUR prefix whose source module no longer exists. Other plugins'
8
+ # entries are never touched. The core toolu dispatcher executes the synced
9
+ # copies, gated on this plugin being installed.
10
+ #
11
+ # Silent on success (SessionStart stdout becomes context); errors are
12
+ # non-fatal — a failed sync means the registry copy is stale, not broken.
13
+
14
+ SPEC="ast-grep@toolu"
15
+ SELF_DIR="$(cd "$(dirname "$0")" && pwd)"
16
+ if [ -n "${TOOLU_CONFIG_DIR:-}" ]; then
17
+ CONFIG_ROOT="$TOOLU_CONFIG_DIR"
18
+ elif [ "${TOOLU_HOST_OVERRIDE:-}" = codex ] || { [ -z "${TOOLU_HOST_OVERRIDE:-}" ] && [ -n "${PLUGIN_ROOT:-}" ]; }; then
19
+ CONFIG_ROOT="${CODEX_HOME:-$HOME/.codex}"
20
+ else
21
+ CONFIG_ROOT="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
22
+ fi
23
+ REG_ROOT="$CONFIG_ROOT/toolu"
24
+
25
+ # Consume stdin so Claude Code's hook IPC never stalls.
26
+ cat > /dev/null 2>&1 || true
27
+
28
+ # Mirror one source dir into its matching registry dir (atomic, self-pruning).
29
+ sync_dir() {
30
+ local src_dir="$1" reg_dir="$2" src name dst tmp
31
+ [ -d "$src_dir" ] || return 0
32
+ mkdir -p "$reg_dir" 2>/dev/null || return 0
33
+
34
+ # Clear OUR orphaned atomic-write residue from prior crashed runs (a death
35
+ # between cp and mv leaves <spec>__<name>.sh.tmp.<pid>; nothing executes
36
+ # them, but nothing else cleans them either). Age-gated so a concurrent
37
+ # SessionStart's in-flight tmp (seconds old) is never clobbered.
38
+ find "$reg_dir" -maxdepth 1 -name "${SPEC}__*.sh.tmp.*" -mmin +1 -delete 2>/dev/null
39
+
40
+ # Sync: copy each source module if missing or changed (atomic tmp+mv).
41
+ for src in "$src_dir"/*.sh; do
42
+ [ -f "$src" ] || continue
43
+ name=$(basename "$src")
44
+ dst="$reg_dir/${SPEC}__${name}"
45
+ if [ ! -f "$dst" ] || ! cmp -s "$src" "$dst"; then
46
+ tmp="${dst}.tmp.$$"
47
+ if cp "$src" "$tmp" 2>/dev/null; then
48
+ mv "$tmp" "$dst" 2>/dev/null || rm -f "$tmp"
49
+ else
50
+ rm -f "$tmp" 2>/dev/null
51
+ fi
52
+ fi
53
+ done
54
+
55
+ # Prune: remove OUR entries whose source module is gone. Never glob outside
56
+ # our own spec prefix.
57
+ for dst in "$reg_dir/${SPEC}__"*.sh; do
58
+ [ -f "$dst" ] || continue
59
+ name=$(basename "$dst")
60
+ src="$src_dir/${name#"${SPEC}"__}"
61
+ [ -f "$src" ] || rm -f "$dst"
62
+ done
63
+ }
64
+
65
+ sync_dir "$SELF_DIR/pre-tools.d" "$REG_ROOT/pre-tools.d"
66
+ sync_dir "$SELF_DIR/post-tools.d" "$REG_ROOT/post-tools.d"
67
+
68
+ exit 0
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env bash
2
+ # byte-savings-report.sh <ledger.jsonl>
3
+ #
4
+ # Aggregates a per-session byte-savings ledger (written by the post-tools
5
+ # byte-savings instrumentation module) into a per-kind summary: bytes each tool
6
+ # returned into context (with a ~token estimate at 4 bytes/token) and, for
7
+ # single-file Reads, the targeting saving vs reading the whole file. Read-only.
8
+ set -u
9
+
10
+ ledger="${1:-}"
11
+ command -v jq >/dev/null 2>&1 || { echo "byte-savings-report: jq required" >&2; exit 1; }
12
+ [ -n "$ledger" ] && [ -f "$ledger" ] || {
13
+ echo "usage: byte-savings-report.sh <ledger.jsonl>" >&2; exit 1; }
14
+
15
+ jq -rs '
16
+ group_by(.kind)
17
+ | map({ kind: .[0].kind,
18
+ n: length,
19
+ returned: (map(.returned) | add),
20
+ full: (map(.full) | add) }) as $g
21
+ | ($g | map(.returned) | add) as $tot
22
+ | ( $g[]
23
+ | if .kind == "read" and .full > 0
24
+ then "\(.kind): returned=\(.returned) full=\(.full) saved=\((((.full - .returned) * 100) / .full) | floor)% (n=\(.n))"
25
+ else "\(.kind): returned=\(.returned) (n=\(.n))"
26
+ end ),
27
+ "TOTAL returned: \($tot) bytes (~\(($tot / 4) | floor) tok)"
28
+ ' "$ledger"
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: ast-grep
3
+ description: "ALWAYS ACTIVE — Structural code search and rewrite protocol. You MUST use ast-grep instead of Grep/sed for any 'find/rewrite by code shape' task (AST patterns, not text). Falls back to Grep for exact literals only."
4
+ ---
5
+
6
+ # ast-grep Structural Search & Rewrite Protocol
7
+
8
+ You have ast-grep (tree-sitter AST pattern matcher + rewriter) via the `ast-grep` / `sg` CLI.
9
+ This protocol is **MANDATORY and ALWAYS ACTIVE**.
10
+
11
+ ## Hard Constraints
12
+
13
+ - Use `ast-grep run -p '<pattern>'` BEFORE Grep when the query is about **code shape** (AST), not text.
14
+ - Use `ast-grep run -p '...' -r '...'` BEFORE sed/Edit-loops when rewriting many call sites.
15
+ - Always pass `-l <lang>` for clarity (`typescript`, `tsx`, `javascript`, `rust`, `python`, `go`, ...).
16
+ - Never edit hand-rolled regex over multi-line code — use ast-grep instead.
17
+
18
+ ## Position in the Search Stack
19
+
20
+ ```
21
+ comemory → "what was decided / where is X" (memory)
22
+ ast-grep → "find / rewrite this code shape" (AST structural) ← here
23
+ Grep → "find exact literal `FOO_BAR`" (text)
24
+ Glob → "list paths matching `**/*.test.ts`" (paths)
25
+ Read → "open known file" (verify)
26
+ ```
27
+
28
+ ## When to Use ast-grep
29
+
30
+ ✓ "Find all `useState($X)` calls without initial value"
31
+ ✓ "Find all `try` blocks without `catch`"
32
+ ✓ "Replace `console.log($X)` with `logger.info($X)` repo-wide"
33
+ ✓ "Find all functions returning `Promise<void>`"
34
+ ✓ "Find all `export default function` declarations"
35
+ ✓ "Find all `await fetch($URL)` without error handling"
36
+ ✓ Bulk safe refactor across many files (AST-aware, comment-preserving)
37
+
38
+ ## When NOT to Use ast-grep
39
+
40
+ ✗ Semantic intent ("how does auth work") → check comemory memory, then Grep on keywords + Read on hits
41
+ ✗ Exact literal in config files (`*.toml`, `*.md`, `*.json`) → Grep
42
+ ✗ Path/filename patterns → Glob
43
+ ✗ Single-file targeted edit → Read + Edit
44
+
45
+ ## CLI Reference
46
+
47
+ ### Search
48
+ ```bash
49
+ ast-grep run -p '<pattern>' -l <lang> [paths...]
50
+ ast-grep run -p '<pattern>' -l typescript apps/api/src
51
+ ```
52
+
53
+ ### Rewrite (preview)
54
+ ```bash
55
+ ast-grep run -p '<pattern>' -r '<replacement>' -l <lang> [paths...]
56
+ ```
57
+ Shows diff. Add `-U` (or `--update-all`) to apply.
58
+
59
+ ### Apply rewrite
60
+ ```bash
61
+ ast-grep run -p '<pattern>' -r '<replacement>' -l <lang> -U [paths...]
62
+ ```
63
+
64
+ ### Inspect AST (debugging patterns)
65
+ ```bash
66
+ ast-grep run -p '<pattern>' -l <lang> --debug-query=ast
67
+ ```
68
+
69
+ ### Strictness
70
+ ```bash
71
+ --strictness smart # default — ignores trivia
72
+ --strictness relaxed # ignores comments
73
+ --strictness signature # ignores text — match by shape only
74
+ ```
75
+
76
+ ## Pattern Syntax (Quick)
77
+
78
+ - `$X` — single named metavariable (any node)
79
+ - `$$$ARGS` — multi-node metavariable (zero or more)
80
+ - `$_` — anonymous wildcard
81
+ - Same metavariable name = same content (linear pattern)
82
+
83
+ Examples:
84
+ | Want | Pattern |
85
+ |------|---------|
86
+ | any `console.log` call | `console.log($$$)` |
87
+ | `useState` with no arg | `useState()` |
88
+ | same var assigned to itself | `$X = $X` |
89
+ | arrow fn with single body expr | `($$$) => $BODY` |
90
+ | catch-all `try` no catch | `try { $$$ } finally { $$$ }` |
91
+
92
+ ## Workflow — Search
93
+
94
+ 1. Draft pattern. Run with `--debug-query=ast` once to verify shape.
95
+ 2. Run real search: `ast-grep run -p '...' -l <lang> <paths>`.
96
+ 3. If too many hits → narrow with `--strictness smart` or extra context nodes.
97
+ 4. If zero hits → broaden to `$_` / `$$$`, recheck AST.
98
+
99
+ ## Workflow — Rewrite
100
+
101
+ 1. **Preview first**: never use `-U` until diff looks right.
102
+ 2. Run preview: `ast-grep run -p '...' -r '...' -l <lang> <paths>`.
103
+ 3. Read the diff. Confirm metavariables map correctly.
104
+ 4. Apply: same command with `-U`.
105
+ 5. Run your project's typecheck/lint (use the detected package manager — see `detect_node_pm` / `detect_rust` in `hooks/lib/detect.sh`) to verify zero regressions.
106
+ 6. Save the pattern if reusable — when the `comemory` plugin is installed, persist it via its wrapper: `comemory.sh save "ast-grep <name> pattern" "<pattern + what it matches>" --kind pattern --tags "ast-grep"`.
107
+
108
+ ## Self-Check Before Editing
109
+
110
+ > "Am I about to write a regex over multi-line code? → ast-grep instead."
111
+ > "Am I about to Edit-loop the same change across many files? → ast-grep rewrite instead."
112
+ > "Am I searching for code by shape (call form, signature, control flow)? → ast-grep, not Grep."
113
+
114
+ ## Config (sgconfig.yml — optional, lazy)
115
+
116
+ If a recurring rule emerges (e.g. forbid `console.log` in apps/api), promote it to `sgconfig.yml`:
117
+ ```bash
118
+ ast-grep new project # bootstrap config
119
+ ast-grep new rule # add reusable rule
120
+ ast-grep scan # run all configured rules
121
+ ```
122
+ Hold off until pattern is proven across ≥3 files.
123
+
124
+ ## Cross-Reference
125
+
126
+ - Memory: `skills/agent-memory/SKILL.md`
127
+ - Project rules: `AGENTS.md`, `CLAUDE.md`, and other host instruction files
@@ -0,0 +1,44 @@
1
+ # ast-grep Advanced Usage
2
+
3
+ ## Complex Rules (inline YAML)
4
+
5
+ For patterns beyond simple `--pattern`, use `scan` with inline YAML:
6
+
7
+ ```bash
8
+ mod.sh ast-grep scan 'id: find-async
9
+ language: rust
10
+ rule:
11
+ kind: function_item
12
+ has:
13
+ pattern: async fn \$NAME
14
+ stopBy: end'
15
+ ```
16
+
17
+ ## Critical Rules
18
+
19
+ - `stopBy: end` required in `has`/`inside` for deep matching — without it, only direct children match
20
+ - `scan` rules require `kind` field
21
+ - `--max-results` only works in `scan` — use `| head -N` for `search`
22
+ - Escape `$` as `\$` in inline-rules strings (not needed in `--pattern` with single quotes)
23
+
24
+ ## Common Patterns
25
+
26
+ ```bash
27
+ # Rust: impl blocks for a trait
28
+ mod.sh ast-grep search 'impl $TRAIT for $TYPE { $$$BODY }' --lang rust
29
+
30
+ # Rust: async functions
31
+ mod.sh ast-grep search 'async fn $NAME($$$ARGS)' --lang rust
32
+
33
+ # Rust: functions returning Result
34
+ mod.sh ast-grep search 'fn $NAME($$$ARGS) -> Result<$$$>' --lang rust
35
+
36
+ # TypeScript: console.log calls
37
+ mod.sh ast-grep search 'console.log($$$ARGS)' --lang typescript
38
+
39
+ # File paths only (no content)
40
+ mod.sh ast-grep files 'impl $TRAIT for $TYPE { $$$BODY }' --lang rust
41
+
42
+ # Debug pattern parsing
43
+ mod.sh ast-grep debug 'fn $NAME($$$ARGS)' --lang rust
44
+ ```