@soleur/opencode 0.0.0-stage → 3.354.2

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 (832) hide show
  1. package/.claude-plugin/agents.manifest.json +476 -0
  2. package/.claude-plugin/plugin.json +42 -0
  3. package/README.md +44 -2
  4. package/agents/community/.gitkeep +0 -0
  5. package/agents/engineering/cto.md +87 -0
  6. package/agents/engineering/design/ddd-architect.md +95 -0
  7. package/agents/engineering/discovery/agent-finder.md +214 -0
  8. package/agents/engineering/discovery/functional-discovery.md +182 -0
  9. package/agents/engineering/infra/infra-security.md +151 -0
  10. package/agents/engineering/infra/platform-strategist.md +109 -0
  11. package/agents/engineering/infra/terraform-architect.md +171 -0
  12. package/agents/engineering/prompt-engineer.md +37 -0
  13. package/agents/engineering/research/best-practices-researcher.md +115 -0
  14. package/agents/engineering/research/framework-docs-researcher.md +93 -0
  15. package/agents/engineering/research/git-history-analyzer.md +53 -0
  16. package/agents/engineering/research/learnings-researcher.md +285 -0
  17. package/agents/engineering/research/repo-research-analyst.md +118 -0
  18. package/agents/engineering/review/agent-native-reviewer.md +279 -0
  19. package/agents/engineering/review/architecture-strategist.md +61 -0
  20. package/agents/engineering/review/code-quality-analyst.md +92 -0
  21. package/agents/engineering/review/code-simplicity-reviewer.md +109 -0
  22. package/agents/engineering/review/data-integrity-guardian.md +82 -0
  23. package/agents/engineering/review/data-migration-expert.md +98 -0
  24. package/agents/engineering/review/deployment-verification-agent.md +183 -0
  25. package/agents/engineering/review/dhh-rails-reviewer.md +46 -0
  26. package/agents/engineering/review/kieran-rails-reviewer.md +87 -0
  27. package/agents/engineering/review/legacy-code-expert.md +55 -0
  28. package/agents/engineering/review/observability-coverage-reviewer.md +147 -0
  29. package/agents/engineering/review/pattern-recognition-specialist.md +59 -0
  30. package/agents/engineering/review/performance-oracle.md +130 -0
  31. package/agents/engineering/review/security-sentinel.md +167 -0
  32. package/agents/engineering/review/semgrep-sast.md +36 -0
  33. package/agents/engineering/review/test-design-reviewer.md +150 -0
  34. package/agents/engineering/review/user-impact-reviewer.md +70 -0
  35. package/agents/engineering/workflow/pr-comment-resolver.md +69 -0
  36. package/agents/finance/budget-analyst.md +29 -0
  37. package/agents/finance/cfo.md +44 -0
  38. package/agents/finance/financial-reporter.md +30 -0
  39. package/agents/finance/revenue-analyst.md +30 -0
  40. package/agents/legal/clo.md +115 -0
  41. package/agents/legal/legal-compliance-auditor.md +110 -0
  42. package/agents/legal/legal-document-generator.md +134 -0
  43. package/agents/marketing/analytics-analyst.md +25 -0
  44. package/agents/marketing/brand-architect.md +181 -0
  45. package/agents/marketing/cmo.md +76 -0
  46. package/agents/marketing/conversion-optimizer.md +19 -0
  47. package/agents/marketing/copywriter.md +20 -0
  48. package/agents/marketing/fact-checker.md +70 -0
  49. package/agents/marketing/growth-strategist.md +145 -0
  50. package/agents/marketing/paid-media-strategist.md +28 -0
  51. package/agents/marketing/pricing-strategist.md +17 -0
  52. package/agents/marketing/programmatic-seo-specialist.md +25 -0
  53. package/agents/marketing/retention-strategist.md +23 -0
  54. package/agents/marketing/seo-aeo-analyst.md +164 -0
  55. package/agents/operations/coo.md +50 -0
  56. package/agents/operations/ops-advisor.md +78 -0
  57. package/agents/operations/ops-provisioner.md +101 -0
  58. package/agents/operations/ops-research.md +52 -0
  59. package/agents/operations/service-automator.md +278 -0
  60. package/agents/product/business-validator.md +206 -0
  61. package/agents/product/competitive-intelligence.md +89 -0
  62. package/agents/product/cpo.md +63 -0
  63. package/agents/product/design/ux-design-lead.md +209 -0
  64. package/agents/product/spec-flow-analyzer.md +122 -0
  65. package/agents/sales/cro.md +44 -0
  66. package/agents/sales/deal-architect.md +29 -0
  67. package/agents/sales/outbound-strategist.md +29 -0
  68. package/agents/sales/pipeline-analyst.md +29 -0
  69. package/agents/support/cco.md +48 -0
  70. package/agents/support/community-manager.md +570 -0
  71. package/agents/support/ticket-triage.md +70 -0
  72. package/bin/soleur-opencode.js +29 -0
  73. package/commands/go.md +660 -0
  74. package/commands/help.md +273 -0
  75. package/commands/sync.md +977 -0
  76. package/commands/version.md +103 -0
  77. package/hooks/antigravity-hooks.json +84 -0
  78. package/hooks/antigravity-session-start.sh +15 -0
  79. package/hooks/bare-root-cwd-guard.sh +131 -0
  80. package/hooks/browser-snapshot-credential-guard.sh +200 -0
  81. package/hooks/codex-session-start.sh +9 -0
  82. package/hooks/compaction-state.sh +525 -0
  83. package/hooks/destructive-command-guard.sh +1387 -0
  84. package/hooks/devin-session-start.sh +90 -0
  85. package/hooks/ext-filter-detect.sh +171 -0
  86. package/hooks/hooks.json +133 -0
  87. package/hooks/lib/hook-tool-kind.sh +24 -0
  88. package/hooks/lib/log-rotation.sh +176 -0
  89. package/hooks/lib/shell-argv.pl +576 -0
  90. package/hooks/memory-backstop.sh +1114 -0
  91. package/hooks/operator-stage-approval.sh +391 -0
  92. package/hooks/stop-hook.sh +367 -0
  93. package/hooks/unkept-promise-hook.sh +383 -0
  94. package/hooks/version-banner.sh +127 -0
  95. package/hooks/welcome-hook.sh +50 -0
  96. package/install.js +29 -0
  97. package/lib/agent-registry.ts +154 -0
  98. package/lib/c4-canonical-cli.mjs +34 -0
  99. package/lib/c4-canonical.mjs +46 -0
  100. package/lib/c4-from-components.ts +554 -0
  101. package/lib/go-routing.ts +81 -0
  102. package/lib/grok-inspect-contract.ts +311 -0
  103. package/lib/harness-model-map.ts +101 -0
  104. package/lib/harness-parity.ts +726 -0
  105. package/lib/harness-tool-map.ts +180 -0
  106. package/lib/harness.ts +716 -0
  107. package/lib/heartbeat-live-reconcile.ts +1153 -0
  108. package/lib/heartbeat-manifest.ts +361 -0
  109. package/lib/kb-coverage.ts +252 -0
  110. package/lib/pr-merge-poll.ts +103 -0
  111. package/lib/workflow-fidelity.ts +388 -0
  112. package/opencode/INSTRUCTIONS.md +171 -0
  113. package/opencode/agents/engineering/cto.md +10 -0
  114. package/opencode/agents/engineering/design/ddd-architect.md +10 -0
  115. package/opencode/agents/engineering/discovery/agent-finder.md +10 -0
  116. package/opencode/agents/engineering/discovery/functional-discovery.md +10 -0
  117. package/opencode/agents/engineering/infra/infra-security.md +10 -0
  118. package/opencode/agents/engineering/infra/platform-strategist.md +10 -0
  119. package/opencode/agents/engineering/infra/terraform-architect.md +10 -0
  120. package/opencode/agents/engineering/prompt-engineer.md +10 -0
  121. package/opencode/agents/engineering/research/best-practices-researcher.md +10 -0
  122. package/opencode/agents/engineering/research/framework-docs-researcher.md +10 -0
  123. package/opencode/agents/engineering/research/git-history-analyzer.md +10 -0
  124. package/opencode/agents/engineering/research/learnings-researcher.md +10 -0
  125. package/opencode/agents/engineering/research/repo-research-analyst.md +10 -0
  126. package/opencode/agents/engineering/review/agent-native-reviewer.md +10 -0
  127. package/opencode/agents/engineering/review/architecture-strategist.md +10 -0
  128. package/opencode/agents/engineering/review/code-quality-analyst.md +10 -0
  129. package/opencode/agents/engineering/review/code-simplicity-reviewer.md +10 -0
  130. package/opencode/agents/engineering/review/data-integrity-guardian.md +10 -0
  131. package/opencode/agents/engineering/review/data-migration-expert.md +10 -0
  132. package/opencode/agents/engineering/review/deployment-verification-agent.md +10 -0
  133. package/opencode/agents/engineering/review/dhh-rails-reviewer.md +10 -0
  134. package/opencode/agents/engineering/review/kieran-rails-reviewer.md +10 -0
  135. package/opencode/agents/engineering/review/legacy-code-expert.md +10 -0
  136. package/opencode/agents/engineering/review/observability-coverage-reviewer.md +10 -0
  137. package/opencode/agents/engineering/review/pattern-recognition-specialist.md +10 -0
  138. package/opencode/agents/engineering/review/performance-oracle.md +10 -0
  139. package/opencode/agents/engineering/review/security-sentinel.md +10 -0
  140. package/opencode/agents/engineering/review/semgrep-sast.md +10 -0
  141. package/opencode/agents/engineering/review/test-design-reviewer.md +10 -0
  142. package/opencode/agents/engineering/review/user-impact-reviewer.md +10 -0
  143. package/opencode/agents/engineering/workflow/pr-comment-resolver.md +10 -0
  144. package/opencode/agents/finance/budget-analyst.md +10 -0
  145. package/opencode/agents/finance/cfo.md +10 -0
  146. package/opencode/agents/finance/financial-reporter.md +10 -0
  147. package/opencode/agents/finance/revenue-analyst.md +10 -0
  148. package/opencode/agents/legal/clo.md +10 -0
  149. package/opencode/agents/legal/legal-compliance-auditor.md +10 -0
  150. package/opencode/agents/legal/legal-document-generator.md +10 -0
  151. package/opencode/agents/marketing/analytics-analyst.md +10 -0
  152. package/opencode/agents/marketing/brand-architect.md +10 -0
  153. package/opencode/agents/marketing/cmo.md +10 -0
  154. package/opencode/agents/marketing/conversion-optimizer.md +10 -0
  155. package/opencode/agents/marketing/copywriter.md +10 -0
  156. package/opencode/agents/marketing/fact-checker.md +10 -0
  157. package/opencode/agents/marketing/growth-strategist.md +10 -0
  158. package/opencode/agents/marketing/paid-media-strategist.md +10 -0
  159. package/opencode/agents/marketing/pricing-strategist.md +10 -0
  160. package/opencode/agents/marketing/programmatic-seo-specialist.md +10 -0
  161. package/opencode/agents/marketing/retention-strategist.md +10 -0
  162. package/opencode/agents/marketing/seo-aeo-analyst.md +10 -0
  163. package/opencode/agents/operations/coo.md +10 -0
  164. package/opencode/agents/operations/ops-advisor.md +10 -0
  165. package/opencode/agents/operations/ops-provisioner.md +10 -0
  166. package/opencode/agents/operations/ops-research.md +10 -0
  167. package/opencode/agents/operations/service-automator.md +10 -0
  168. package/opencode/agents/product/business-validator.md +10 -0
  169. package/opencode/agents/product/competitive-intelligence.md +10 -0
  170. package/opencode/agents/product/cpo.md +10 -0
  171. package/opencode/agents/product/design/ux-design-lead.md +10 -0
  172. package/opencode/agents/product/spec-flow-analyzer.md +10 -0
  173. package/opencode/agents/sales/cro.md +10 -0
  174. package/opencode/agents/sales/deal-architect.md +10 -0
  175. package/opencode/agents/sales/outbound-strategist.md +10 -0
  176. package/opencode/agents/sales/pipeline-analyst.md +10 -0
  177. package/opencode/agents/support/cco.md +10 -0
  178. package/opencode/agents/support/community-manager.md +10 -0
  179. package/opencode/agents/support/ticket-triage.md +10 -0
  180. package/opencode/commands/go.md +10 -0
  181. package/opencode/commands/help.md +10 -0
  182. package/opencode/commands/sync.md +10 -0
  183. package/opencode/commands/version.md +11 -0
  184. package/opencode/opencode.json +8 -0
  185. package/opencode/plugin.ts +818 -0
  186. package/package.json +36 -4
  187. package/scripts/admin-merge-ready.sh +545 -0
  188. package/scripts/admin-merge-ready.test.sh +753 -0
  189. package/scripts/affected-tests.sh +908 -0
  190. package/scripts/affected-tests.test.sh +1797 -0
  191. package/scripts/alpha-metrics.sh +78 -0
  192. package/scripts/alpha-metrics.test.sh +115 -0
  193. package/scripts/ancestor-signal-helpers.baseline.txt +16 -0
  194. package/scripts/audit-flag-flip.sh +107 -0
  195. package/scripts/check-red-on-main.sh +316 -0
  196. package/scripts/ci-head-verdict.sh +411 -0
  197. package/scripts/cloud-detect.sh +193 -0
  198. package/scripts/delegation-verify.sh +657 -0
  199. package/scripts/delegation-verify.test.sh +1424 -0
  200. package/scripts/deploy-arm.sh +475 -0
  201. package/scripts/domain-model-drift.sh +419 -0
  202. package/scripts/emit-decision.sh +144 -0
  203. package/scripts/emit-decision.test.sh +144 -0
  204. package/scripts/ext-filter-divergence-corpus.txt +15 -0
  205. package/scripts/ext-filter-divergence.sh +189 -0
  206. package/scripts/generate-c4-from-components.ts +442 -0
  207. package/scripts/grok-fidelity-gate.sh +68 -0
  208. package/scripts/grok-pre-push-gate.sh +232 -0
  209. package/scripts/harness-discovery-smoke.ts +906 -0
  210. package/scripts/harness-parity-census.ts +92 -0
  211. package/scripts/inngest-luks-alert-armed-probe.ts +29 -0
  212. package/scripts/install-opencode-adapter.ts +509 -0
  213. package/scripts/lib/affected-tests/common.sh +365 -0
  214. package/scripts/lib/affected-tests/go.sh +157 -0
  215. package/scripts/lib/affected-tests/js.sh +188 -0
  216. package/scripts/lib/affected-tests/nx-turbo.sh +98 -0
  217. package/scripts/lib/affected-tests/python.sh +185 -0
  218. package/scripts/lib/context-sanitize.sh +49 -0
  219. package/scripts/lib/domain-model-lib.sh +180 -0
  220. package/scripts/lib/ext-filter-grammar.tsv +34 -0
  221. package/scripts/lib/operator-script.sh +1236 -0
  222. package/scripts/lib/proc.sh +580 -0
  223. package/scripts/lib/session-state.sh +748 -0
  224. package/scripts/lib/tmp-classify.sh +843 -0
  225. package/scripts/lib/wrapper-boundary.sh +47 -0
  226. package/scripts/lint-ratchet.py +1547 -0
  227. package/scripts/monitor-pr-checks.sh +441 -0
  228. package/scripts/pipeline-tally.sh +756 -0
  229. package/scripts/pipeline-tally.test.sh +740 -0
  230. package/scripts/plugin-version.sh +528 -0
  231. package/scripts/precommit-guard.sh +115 -0
  232. package/scripts/precommit-guard.test.sh +254 -0
  233. package/scripts/reconcile-live-heartbeats.ts +705 -0
  234. package/scripts/render-c4-model.sh +217 -0
  235. package/scripts/resolve-git-root.sh +55 -0
  236. package/scripts/resolve-regenerable-conflicts.sh +363 -0
  237. package/scripts/resolve-regenerable-conflicts.test.sh +780 -0
  238. package/scripts/ruff-requirements.txt +22 -0
  239. package/scripts/run-in-pid-namespace.sh +98 -0
  240. package/scripts/run-in-pid-namespace.test.sh +290 -0
  241. package/scripts/scan-ancestor-signal-helpers.py +556 -0
  242. package/scripts/scan-ancestor-signal-helpers.test.sh +670 -0
  243. package/scripts/setup-ralph-loop.sh +238 -0
  244. package/scripts/sync-cursor-name-map.ts +316 -0
  245. package/scripts/sync-grok-agent-compat.ts +188 -0
  246. package/scripts/sync-npm-package.ts +165 -0
  247. package/scripts/sync-opencode-adapter.ts +498 -0
  248. package/scripts/sync-pr-behind.sh +647 -0
  249. package/scripts/sync-pr-behind.test.sh +252 -0
  250. package/scripts/taste-profile-update.sh +180 -0
  251. package/scripts/taste-profile-update.test.sh +167 -0
  252. package/scripts/write-budget-marker.sh +23 -0
  253. package/scripts/write-kb-coverage.ts +113 -0
  254. package/skills/admin-ip-refresh/SKILL.md +81 -0
  255. package/skills/admin-ip-refresh/references/admin-ip-refresh-procedure.md +201 -0
  256. package/skills/agent-browser/SKILL.md +698 -0
  257. package/skills/agent-browser/scripts/playwright-mcp-profile-slot.sh +304 -0
  258. package/skills/agent-browser/scripts/playwright-mcp-redact-proxy.py +964 -0
  259. package/skills/agent-browser/scripts/redact-a11y-snapshot.py +443 -0
  260. package/skills/agent-browser/test/fixtures/capture-playwright-mcp-fixtures.py +217 -0
  261. package/skills/agent-browser/test/fixtures/fake-passthrough-proxy.py +24 -0
  262. package/skills/agent-browser/test/fixtures/fake-playwright-mcp.py +131 -0
  263. package/skills/agent-browser/test/fixtures/make-proxy-mutant.py +48 -0
  264. package/skills/agent-browser/test/fixtures/odd-shapes/dialog-link-injection.json +10 -0
  265. package/skills/agent-browser/test/fixtures/odd-shapes/empty-content.json +5 -0
  266. package/skills/agent-browser/test/fixtures/odd-shapes/error-and-result.json +4 -0
  267. package/skills/agent-browser/test/fixtures/odd-shapes/error-code-bool.json +6 -0
  268. package/skills/agent-browser/test/fixtures/odd-shapes/error-code-string.json +6 -0
  269. package/skills/agent-browser/test/fixtures/odd-shapes/error-message-tree.json +6 -0
  270. package/skills/agent-browser/test/fixtures/odd-shapes/error-no-data.json +6 -0
  271. package/skills/agent-browser/test/fixtures/odd-shapes/error-string.json +4 -0
  272. package/skills/agent-browser/test/fixtures/odd-shapes/error-with-data.json +9 -0
  273. package/skills/agent-browser/test/fixtures/odd-shapes/evaluate-escaped-object.json +10 -0
  274. package/skills/agent-browser/test/fixtures/odd-shapes/invalid-utf8.json +4 -0
  275. package/skills/agent-browser/test/fixtures/odd-shapes/link-result.json +10 -0
  276. package/skills/agent-browser/test/fixtures/odd-shapes/list-two-results.json +6 -0
  277. package/skills/agent-browser/test/fixtures/odd-shapes/meta-in-result.json +13 -0
  278. package/skills/agent-browser/test/fixtures/odd-shapes/no-content.json +5 -0
  279. package/skills/agent-browser/test/fixtures/odd-shapes/quoted-key.json +10 -0
  280. package/skills/agent-browser/test/fixtures/odd-shapes/resource-block.json +18 -0
  281. package/skills/agent-browser/test/fixtures/odd-shapes/result-and-method.json +11 -0
  282. package/skills/agent-browser/test/fixtures/odd-shapes/result-string.json +3 -0
  283. package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped-one-row.json +10 -0
  284. package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped.json +10 -0
  285. package/skills/agent-browser/test/fixtures/odd-shapes/structured-content.json +13 -0
  286. package/skills/agent-browser/test/fixtures/odd-shapes/tools-list-no-tools.json +5 -0
  287. package/skills/agent-browser/test/fixtures/odd-shapes/tree-no-credential.json +10 -0
  288. package/skills/agent-browser/test/fixtures/odd-shapes/two-text-blocks.json +14 -0
  289. package/skills/agent-browser/test/fixtures/odd-shapes/unparsable-line.json +3 -0
  290. package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-brace.json +10 -0
  291. package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-link-substring.json +10 -0
  292. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/close.json +12 -0
  293. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/evaluate.json +12 -0
  294. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/find.json +12 -0
  295. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/framing.json +6 -0
  296. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/initialize.json +14 -0
  297. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate-link.json +12 -0
  298. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate.json +12 -0
  299. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/roots-list-request.json +5 -0
  300. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/screenshot.json +17 -0
  301. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-filename.json +12 -0
  302. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-json.json +12 -0
  303. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-raw.json +12 -0
  304. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot.json +12 -0
  305. package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/tools-list.json +827 -0
  306. package/skills/agent-browser/test/fixtures/proxy-session-driver.py +138 -0
  307. package/skills/agent-browser/test/fixtures/session-facts.py +102 -0
  308. package/skills/agent-browser/test/playwright-mcp-lifetime.test.sh +1620 -0
  309. package/skills/agent-browser/test/playwright-mcp-redact-proxy.test.sh +1599 -0
  310. package/skills/agent-browser/test/redact-a11y-snapshot.test.sh +527 -0
  311. package/skills/agent-native-architecture/SKILL.md +479 -0
  312. package/skills/agent-native-architecture/references/action-parity-discipline.md +430 -0
  313. package/skills/agent-native-architecture/references/agent-execution-patterns.md +483 -0
  314. package/skills/agent-native-architecture/references/agent-native-testing.md +605 -0
  315. package/skills/agent-native-architecture/references/architecture-patterns.md +493 -0
  316. package/skills/agent-native-architecture/references/dynamic-context-injection.md +358 -0
  317. package/skills/agent-native-architecture/references/files-universal-interface.md +314 -0
  318. package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +381 -0
  319. package/skills/agent-native-architecture/references/mcp-tool-design.md +524 -0
  320. package/skills/agent-native-architecture/references/mobile-patterns.md +897 -0
  321. package/skills/agent-native-architecture/references/product-implications.md +478 -0
  322. package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +342 -0
  323. package/skills/agent-native-architecture/references/self-modification.md +294 -0
  324. package/skills/agent-native-architecture/references/shared-workspace-architecture.md +700 -0
  325. package/skills/agent-native-architecture/references/system-prompt-design.md +263 -0
  326. package/skills/agent-native-audit/SKILL.md +300 -0
  327. package/skills/agent-native-audit/workflows/agent-native-audit.workflow.js +423 -0
  328. package/skills/andrew-kane-gem-writer/SKILL.md +189 -0
  329. package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
  330. package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
  331. package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
  332. package/skills/andrew-kane-gem-writer/references/resources.md +126 -0
  333. package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
  334. package/skills/architecture/SKILL.md +436 -0
  335. package/skills/architecture/references/adr-template.md +154 -0
  336. package/skills/architecture/references/likec4-reference.md +136 -0
  337. package/skills/architecture/references/nfr-reference.md +126 -0
  338. package/skills/archive-kb/SKILL.md +86 -0
  339. package/skills/archive-kb/scripts/archive-kb.sh +300 -0
  340. package/skills/archive-kb/test/archive-kb-partial-run.test.sh +276 -0
  341. package/skills/atdd-developer/SKILL.md +65 -0
  342. package/skills/brainstorm/SKILL.md +701 -0
  343. package/skills/brainstorm/references/brainstorm-brand-workshop.md +153 -0
  344. package/skills/brainstorm/references/brainstorm-domain-config.md +63 -0
  345. package/skills/brainstorm/references/brainstorm-validation-workshop.md +65 -0
  346. package/skills/brainstorm/references/ui-surface-terms.md +42 -0
  347. package/skills/brainstorm-techniques/SKILL.md +231 -0
  348. package/skills/brainstorm-techniques/references/decision-principles.md +150 -0
  349. package/skills/brainstorm-techniques/references/phase-boundaries.md +103 -0
  350. package/skills/brainstorm-techniques/references/standing-delegation.md +407 -0
  351. package/skills/brainstorm-techniques/references/technical-ruling-delegation.md +174 -0
  352. package/skills/campaign-calendar/SKILL.md +145 -0
  353. package/skills/cf-token-scope/SKILL.md +164 -0
  354. package/skills/cf-token-scope/references/widen-playbook.md +114 -0
  355. package/skills/cf-token-scope/scripts/cf-token-scope.sh +253 -0
  356. package/skills/changelog/SKILL.md +142 -0
  357. package/skills/code-to-prd/SKILL.md +66 -0
  358. package/skills/code-to-prd/references/banner-template.md +12 -0
  359. package/skills/code-to-prd/references/prd-template.md +41 -0
  360. package/skills/code-to-prd/scripts/code-to-prd.sh +634 -0
  361. package/skills/code-to-prd/test/code-to-prd.test.sh +447 -0
  362. package/skills/code-to-prd/test/fixture/.env.example +7 -0
  363. package/skills/code-to-prd/test/fixture/app/about/page.tsx +11 -0
  364. package/skills/code-to-prd/test/fixture/app/api/health/route.ts +10 -0
  365. package/skills/code-to-prd/test/fixture/app/page.tsx +14 -0
  366. package/skills/code-to-prd/test/fixture/next.config.mjs +3 -0
  367. package/skills/code-to-prd/test/fixture/package.json +6 -0
  368. package/skills/cohort-status/SKILL.md +62 -0
  369. package/skills/community/SKILL.md +210 -0
  370. package/skills/community/scripts/bsky-community.sh +644 -0
  371. package/skills/community/scripts/bsky-setup.sh +631 -0
  372. package/skills/community/scripts/community-router.sh +93 -0
  373. package/skills/community/scripts/discord-community.sh +487 -0
  374. package/skills/community/scripts/discord-setup.sh +784 -0
  375. package/skills/community/scripts/github-community.sh +706 -0
  376. package/skills/community/scripts/hn-community.sh +233 -0
  377. package/skills/community/scripts/lib/hmac-sha1-b64.sh +126 -0
  378. package/skills/community/scripts/linkedin-community.sh +750 -0
  379. package/skills/community/scripts/linkedin-setup.sh +758 -0
  380. package/skills/community/scripts/x-community.sh +890 -0
  381. package/skills/community/scripts/x-setup.sh +713 -0
  382. package/skills/community/test/community-argv.test.sh +2922 -0
  383. package/skills/community/test/github-community.test.sh +981 -0
  384. package/skills/competitive-analysis/SKILL.md +69 -0
  385. package/skills/competitive-analysis/references/peer-plugin-audit.md +218 -0
  386. package/skills/compound/SKILL.md +673 -0
  387. package/skills/compound/scripts/token-efficiency-report.sh +334 -0
  388. package/skills/compound/test/phase-16.test.sh +379 -0
  389. package/skills/compound-capture/SKILL.md +791 -0
  390. package/skills/compound-capture/assets/critical-pattern-template.md +37 -0
  391. package/skills/compound-capture/assets/resolution-template.md +116 -0
  392. package/skills/compound-capture/references/yaml-schema.md +67 -0
  393. package/skills/compound-capture/schema.yaml +181 -0
  394. package/skills/constraint-scaffold/SKILL.md +175 -0
  395. package/skills/constraint-scaffold/references/boundary-readme.template +35 -0
  396. package/skills/constraint-scaffold/references/constraint-gates-workflow.template +69 -0
  397. package/skills/constraint-scaffold/references/depcruise-config.template +230 -0
  398. package/skills/constraint-scaffold/references/fix-constraints-stage-a.template +240 -0
  399. package/skills/constraint-scaffold/references/fix-constraints-stage-b.template +313 -0
  400. package/skills/constraint-scaffold/references/shared-runner.template +135 -0
  401. package/skills/constraint-scaffold/scripts/constraint-scaffold.sh +589 -0
  402. package/skills/constraint-scaffold/test/bite-proof.test.sh +1338 -0
  403. package/skills/constraint-scaffold/test/boundary.test.sh +734 -0
  404. package/skills/constraint-scaffold/test/emit-fix-constraints.test.sh +193 -0
  405. package/skills/constraint-scaffold/test/generator.test.sh +93 -0
  406. package/skills/constraint-scaffold/test/parity.test.sh +285 -0
  407. package/skills/content-writer/SKILL.md +242 -0
  408. package/skills/content-writer/scripts/blog-jargon-scan.sh +42 -0
  409. package/skills/cron-delete/SKILL.md +56 -0
  410. package/skills/cron-list/SKILL.md +54 -0
  411. package/skills/deepen-plan/SKILL.md +937 -0
  412. package/skills/deepen-plan/workflows/deepen-plan.workflow.js +488 -0
  413. package/skills/deploy/SKILL.md +115 -0
  414. package/skills/deploy/references/hetzner-setup.md +67 -0
  415. package/skills/deploy/scripts/deploy.sh +37 -0
  416. package/skills/deploy-docs/SKILL.md +95 -0
  417. package/skills/dhh-rails-style/SKILL.md +203 -0
  418. package/skills/dhh-rails-style/references/architecture.md +717 -0
  419. package/skills/dhh-rails-style/references/controllers.md +323 -0
  420. package/skills/dhh-rails-style/references/frontend.md +556 -0
  421. package/skills/dhh-rails-style/references/gems.md +316 -0
  422. package/skills/dhh-rails-style/references/models.md +388 -0
  423. package/skills/dhh-rails-style/references/testing.md +354 -0
  424. package/skills/discord-content/SKILL.md +126 -0
  425. package/skills/docs-site/SKILL.md +214 -0
  426. package/skills/drain-labeled-backlog/SKILL.md +203 -0
  427. package/skills/drain-labeled-backlog/scripts/group-by-area.sh +208 -0
  428. package/skills/drain-labeled-backlog/workflows/drain-labeled-backlog.workflow.js +433 -0
  429. package/skills/drain-prs/SKILL.md +143 -0
  430. package/skills/drain-prs/scripts/triage-prs.sh +192 -0
  431. package/skills/drain-prs/test/argv-ceiling.test.sh +183 -0
  432. package/skills/dspy-ruby/SKILL.md +634 -0
  433. package/skills/dspy-ruby/assets/config-template.rb +359 -0
  434. package/skills/dspy-ruby/assets/module-template.rb +326 -0
  435. package/skills/dspy-ruby/assets/signature-template.rb +143 -0
  436. package/skills/dspy-ruby/references/core-concepts.md +268 -0
  437. package/skills/dspy-ruby/references/optimization.md +623 -0
  438. package/skills/dspy-ruby/references/providers.md +335 -0
  439. package/skills/eval-harness/README.md +194 -0
  440. package/skills/eval-harness/SKILL.md +157 -0
  441. package/skills/eval-harness/enums/go-routes.json +13 -0
  442. package/skills/eval-harness/enums/incident-threshold.json +5 -0
  443. package/skills/eval-harness/enums/lane.json +5 -0
  444. package/skills/eval-harness/enums/tool-selection.json +20 -0
  445. package/skills/eval-harness/enums/triage-levels.json +5 -0
  446. package/skills/eval-harness/gated-skills.json +34 -0
  447. package/skills/eval-harness/models.generated.json +5 -0
  448. package/skills/eval-harness/promptfooconfig-go-routing.yaml +35 -0
  449. package/skills/eval-harness/promptfooconfig-incident-threshold.yaml +32 -0
  450. package/skills/eval-harness/promptfooconfig-lane-inference.yaml +33 -0
  451. package/skills/eval-harness/promptfooconfig-ticket-triage.yaml +34 -0
  452. package/skills/eval-harness/promptfooconfig-tool-selection.yaml +33 -0
  453. package/skills/eval-harness/prompts/go-baseline.txt +6 -0
  454. package/skills/eval-harness/prompts/go-skill.txt +21 -0
  455. package/skills/eval-harness/prompts/incident-threshold-baseline.txt +6 -0
  456. package/skills/eval-harness/prompts/incident-threshold-skill.txt +12 -0
  457. package/skills/eval-harness/prompts/lane-inference-baseline.txt +6 -0
  458. package/skills/eval-harness/prompts/lane-inference-skill.txt +15 -0
  459. package/skills/eval-harness/prompts/tool-selection-baseline.txt +19 -0
  460. package/skills/eval-harness/prompts/tool-selection-skill.txt +22 -0
  461. package/skills/eval-harness/prompts/triage-baseline.txt +7 -0
  462. package/skills/eval-harness/prompts/triage-skill.txt +10 -0
  463. package/skills/eval-harness/scripts/eval-gate.cjs +318 -0
  464. package/skills/eval-harness/scripts/extract-block.cjs +87 -0
  465. package/skills/eval-harness/scripts/gate-classification.cjs +28 -0
  466. package/skills/eval-harness/scripts/gen-models.sh +41 -0
  467. package/skills/eval-harness/scripts/gen-skill-prompt.cjs +177 -0
  468. package/skills/eval-harness/scripts/measure-classification.cjs +30 -0
  469. package/skills/eval-harness/scripts/parse-label.cjs +93 -0
  470. package/skills/eval-harness/scripts/verdict.cjs +132 -0
  471. package/skills/eval-harness/tasks/go-routing.jsonl +8 -0
  472. package/skills/eval-harness/tasks/incident-threshold.jsonl +7 -0
  473. package/skills/eval-harness/tasks/lane-inference.jsonl +7 -0
  474. package/skills/eval-harness/tasks/ticket-triage.jsonl +6 -0
  475. package/skills/eval-harness/tasks/tool-selection.jsonl +15 -0
  476. package/skills/eval-harness/test/eval-gate.test.sh +132 -0
  477. package/skills/eval-harness/test/extract-block.test.sh +87 -0
  478. package/skills/eval-harness/test/gate-classification.test.sh +77 -0
  479. package/skills/eval-harness/test/gen-models.test.sh +75 -0
  480. package/skills/eval-harness/test/measure-classification.test.sh +74 -0
  481. package/skills/eval-harness/test/parse-label.test.sh +129 -0
  482. package/skills/eval-harness/test/registry-completeness.test.sh +109 -0
  483. package/skills/eval-harness/test/verdict.test.sh +123 -0
  484. package/skills/every-style-editor/SKILL.md +142 -0
  485. package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
  486. package/skills/feature-tweet/SKILL.md +199 -0
  487. package/skills/feature-video/SKILL.md +412 -0
  488. package/skills/feature-video/scripts/check_deps.sh +281 -0
  489. package/skills/file-todos/SKILL.md +267 -0
  490. package/skills/file-todos/assets/todo-template.md +166 -0
  491. package/skills/fix-issue/SKILL.md +278 -0
  492. package/skills/fix-issue/references/agent-authored-exclusion.md +120 -0
  493. package/skills/fix-issue/references/exclude-label-jq-snippet.md +97 -0
  494. package/skills/flag-bootstrap/SETUP.md +142 -0
  495. package/skills/flag-create/SKILL.md +145 -0
  496. package/skills/flag-create/scripts/create.sh +273 -0
  497. package/skills/flag-delete/SKILL.md +167 -0
  498. package/skills/flag-delete/scripts/delete.sh +288 -0
  499. package/skills/flag-list/SKILL.md +99 -0
  500. package/skills/flag-list/scripts/list.sh +275 -0
  501. package/skills/flag-set-role/SKILL.md +229 -0
  502. package/skills/flag-set-role/scripts/flip.sh +774 -0
  503. package/skills/frontend-anti-slop/SKILL.md +106 -0
  504. package/skills/frontend-anti-slop/references/anti-patterns.md +199 -0
  505. package/skills/frontend-anti-slop/references/slop-rules.md +65 -0
  506. package/skills/frontend-anti-slop/scripts/tier1-scan.ts +525 -0
  507. package/skills/frontend-design/SKILL.md +77 -0
  508. package/skills/gdpr-gate/NOTICE +136 -0
  509. package/skills/gdpr-gate/SKILL.md +341 -0
  510. package/skills/gdpr-gate/references/fields.md +160 -0
  511. package/skills/gdpr-gate/references/layers/api-layer.md +355 -0
  512. package/skills/gdpr-gate/references/layers/auth-sessions.md +290 -0
  513. package/skills/gdpr-gate/references/layers/data-in-transit.md +331 -0
  514. package/skills/gdpr-gate/references/layers/data-lifecycle.md +341 -0
  515. package/skills/gdpr-gate/references/layers/frontend.md +249 -0
  516. package/skills/gdpr-gate/references/layers/testing-seeding.md +256 -0
  517. package/skills/gdpr-gate/references/leakage-vectors.md +248 -0
  518. package/skills/gdpr-gate/references/legacy/legal-consent-v1-prose.md +48 -0
  519. package/skills/gdpr-gate/references/legal-consent.md +140 -0
  520. package/skills/gdpr-gate/references/non-negotiables.md +60 -0
  521. package/skills/gdpr-gate/scripts/gdpr-gate.sh +271 -0
  522. package/skills/gdpr-gate/scripts/notice-frontmatter.sh +337 -0
  523. package/skills/gdpr-gate/scripts/path-denylist.txt +39 -0
  524. package/skills/gdpr-gate/scripts/repo-scan.sh +158 -0
  525. package/skills/gdpr-gate/scripts/vendor-drift-classify.sh +120 -0
  526. package/skills/gdpr-gate/scripts/vendor-pin-integrity.sh +237 -0
  527. package/skills/gemini-imagegen/SKILL.md +283 -0
  528. package/skills/gemini-imagegen/requirements.txt +5 -0
  529. package/skills/gemini-imagegen/scripts/_error_handling.py +146 -0
  530. package/skills/gemini-imagegen/scripts/compose_images.py +150 -0
  531. package/skills/gemini-imagegen/scripts/edit_image.py +137 -0
  532. package/skills/gemini-imagegen/scripts/gemini_images.py +256 -0
  533. package/skills/gemini-imagegen/scripts/generate_image.py +147 -0
  534. package/skills/gemini-imagegen/scripts/multi_turn_chat.py +223 -0
  535. package/skills/gemini-imagegen/scripts/test_error_handling.py +179 -0
  536. package/skills/git-worktree/SKILL.md +534 -0
  537. package/skills/git-worktree/scripts/git-repo-readiness-diag.sh +98 -0
  538. package/skills/git-worktree/scripts/worktree-manager.sh +4773 -0
  539. package/skills/git-worktree/test/create-from-origin-main.test.sh +116 -0
  540. package/skills/git-worktree/test/lease-protects-active.test.sh +1056 -0
  541. package/skills/git-worktree/test/no-repo-fail-loud.test.sh +88 -0
  542. package/skills/git-worktree/test/orphan-reaper-honest-count.test.sh +379 -0
  543. package/skills/git-worktree/test/reap-archive-persistence.test.sh +725 -0
  544. package/skills/git-worktree/test/stale-lock-sweep.test.sh +176 -0
  545. package/skills/go/SKILL.md +54 -0
  546. package/skills/growth/SKILL.md +164 -0
  547. package/skills/harvest-debt/SKILL.md +78 -0
  548. package/skills/harvest-debt/scripts/harvest-debt.sh +114 -0
  549. package/skills/heal-skill/SKILL.md +173 -0
  550. package/skills/help/SKILL.md +46 -0
  551. package/skills/incident/NOTICE +39 -0
  552. package/skills/incident/SKILL.md +395 -0
  553. package/skills/incident/scripts/dry-run.sh +448 -0
  554. package/skills/incident/scripts/redact-engine.py +412 -0
  555. package/skills/incident/scripts/redact-sentinel.sh +44 -0
  556. package/skills/incident/templates/pir.md +139 -0
  557. package/skills/incident/test/fixtures/dry-run-incident.json +26 -0
  558. package/skills/incident/test/fixtures/dry-run-secret-leak.json +26 -0
  559. package/skills/incident/test/fixtures/legacy-bash-scanner.sh +82 -0
  560. package/skills/incident/test/fixtures/positive-corpus.md +87 -0
  561. package/skills/incident/test/redact-sentinel.test.sh +1420 -0
  562. package/skills/invoice/SKILL.md +206 -0
  563. package/skills/kb-glossary/SKILL.md +71 -0
  564. package/skills/kb-glossary/references/glossary-format.md +111 -0
  565. package/skills/kb-glossary/references/rejected-request-register.md +115 -0
  566. package/skills/kb-search/SKILL.md +276 -0
  567. package/skills/kb-search/scripts/kb-search-cache.sh +123 -0
  568. package/skills/legal-audit/SKILL.md +161 -0
  569. package/skills/legal-generate/NOTICE +242 -0
  570. package/skills/legal-generate/SKILL.md +244 -0
  571. package/skills/legal-generate/references/templates/advisor-agreement/template.md +12 -0
  572. package/skills/legal-generate/references/templates/business-associate-agreement/template.md +112 -0
  573. package/skills/legal-generate/references/templates/cookie-notice/template.md +82 -0
  574. package/skills/legal-generate/references/templates/dpa-global/template.md +439 -0
  575. package/skills/legal-generate/references/templates/dpa-us/template.md +222 -0
  576. package/skills/legal-generate/references/templates/employee-offer-letter/template.md +75 -0
  577. package/skills/legal-generate/references/templates/master-services-agreement/template.md +252 -0
  578. package/skills/legal-generate/references/templates/mutual-nda/template.md +66 -0
  579. package/skills/legal-generate/references/templates/one-way-nda/template.md +38 -0
  580. package/skills/legal-generate/references/templates/privacy-policy-gdpr/template.md +427 -0
  581. package/skills/legal-generate/references/templates/privacy-policy-us/template.md +313 -0
  582. package/skills/legal-generate/references/templates/terms-of-use/template.md +75 -0
  583. package/skills/legal-generate/scripts/strip-vendor-credit.sh +96 -0
  584. package/skills/linear-fetch/SKILL.md +247 -0
  585. package/skills/linear-fetch/scripts/assert-no-linear-telemetry.sh +66 -0
  586. package/skills/linear-fetch/scripts/redact-linear-urls.sh +51 -0
  587. package/skills/linear-fetch/scripts/render-caller-template.sh +36 -0
  588. package/skills/linear-fetch/test/assert-no-linear-telemetry.test.sh +113 -0
  589. package/skills/linear-fetch/test/parity.test.sh +112 -0
  590. package/skills/linear-fetch/test/persist-safe-integration.test.sh +191 -0
  591. package/skills/linear-fetch/test/redact-linear-urls.test.sh +226 -0
  592. package/skills/merge-pr/SKILL.md +670 -0
  593. package/skills/model-launch-review/SKILL.md +255 -0
  594. package/skills/model-launch-review/scripts/audit-models.sh +501 -0
  595. package/skills/one-shot/SKILL.md +316 -0
  596. package/skills/one-shot/references/token-discipline.md +74 -0
  597. package/skills/operator-bootstrap/SKILL.md +412 -0
  598. package/skills/operator-bootstrap/template.sh +439 -0
  599. package/skills/operator-digest/SKILL.md +287 -0
  600. package/skills/operator-digest/assets/operator-digest.workflow.yml +175 -0
  601. package/skills/operator-digest/scripts/digest-scrub.sh +119 -0
  602. package/skills/operator-digest/scripts/provision-operator-digest-repo.sh +147 -0
  603. package/skills/operator-rephrase/SKILL.md +98 -0
  604. package/skills/pencil-setup/SKILL.md +201 -0
  605. package/skills/pencil-setup/scripts/check_deps.sh +556 -0
  606. package/skills/pencil-setup/scripts/copy_adapter.sh +80 -0
  607. package/skills/pencil-setup/scripts/package-lock.json +1172 -0
  608. package/skills/pencil-setup/scripts/package.json +14 -0
  609. package/skills/pencil-setup/scripts/pencil-error-enrichment.mjs +21 -0
  610. package/skills/pencil-setup/scripts/pencil-mcp-adapter.mjs +733 -0
  611. package/skills/pencil-setup/scripts/pencil-response-classify.mjs +38 -0
  612. package/skills/pencil-setup/scripts/pencil-save-gate.mjs +26 -0
  613. package/skills/pencil-setup/scripts/sanitize-filename.mjs +25 -0
  614. package/skills/plan/SKILL.md +1140 -0
  615. package/skills/plan/references/differential-migration-testing.md +185 -0
  616. package/skills/plan/references/plan-community-discovery.md +42 -0
  617. package/skills/plan/references/plan-founder-check.md +137 -0
  618. package/skills/plan/references/plan-functional-overlap.md +25 -0
  619. package/skills/plan/references/plan-host-fanout.md +51 -0
  620. package/skills/plan/references/plan-issue-templates.md +779 -0
  621. package/skills/plan/references/plan-network-outage-checklist.md +131 -0
  622. package/skills/plan/references/plan-scope-check.md +126 -0
  623. package/skills/plan/references/plan-sharp-edges.md +331 -0
  624. package/skills/plan/references/plan-signoff-lifecycle.md +12 -0
  625. package/skills/plan/references/webapp-cwv-observability.md +143 -0
  626. package/skills/plan-review/SKILL.md +91 -0
  627. package/skills/plan-review/lib/named-panel.mjs +58 -0
  628. package/skills/plan-review/workflows/plan-review.workflow.js +477 -0
  629. package/skills/postmerge/SKILL.md +642 -0
  630. package/skills/postmerge/references/deploy-status-debugging.md +141 -0
  631. package/skills/postmerge/references/graceful-degradation.md +20 -0
  632. package/skills/postmerge/references/sentry-error-count-delta.md +137 -0
  633. package/skills/preflight/SKILL.md +1553 -0
  634. package/skills/preflight/references/check-13-founder-check.md +286 -0
  635. package/skills/preflight/scripts/founder-check.py +1640 -0
  636. package/skills/preflight/scripts/parse-form-a.awk +107 -0
  637. package/skills/preflight/scripts/probe-verb-gate.sh +108 -0
  638. package/skills/product-roadmap/SKILL.md +357 -0
  639. package/skills/product-roadmap/scripts/roadmap-reconcile.sh +327 -0
  640. package/skills/provision-cloudflare/SKILL.md +67 -0
  641. package/skills/provision-cloudflare/scripts/provision-cloudflare.sh +271 -0
  642. package/skills/provision-doppler/SKILL.md +58 -0
  643. package/skills/provision-doppler/scripts/provision-doppler.sh +358 -0
  644. package/skills/provision-github/SKILL.md +59 -0
  645. package/skills/provision-github/scripts/provision-github.sh +300 -0
  646. package/skills/provision-hetzner/SKILL.md +76 -0
  647. package/skills/provision-hetzner/scripts/provision-hetzner.sh +262 -0
  648. package/skills/provision-hetzner/test/fixture/knowledge-base/legal/tenant-dpa-register.md +26 -0
  649. package/skills/provision-hetzner/test/fixture/provision-hetzner-dry-run.golden +34 -0
  650. package/skills/provision-hetzner/test/provision-hetzner-characterization.test.sh +227 -0
  651. package/skills/qa/SKILL.md +263 -0
  652. package/skills/qa/references/browser-preflight.md +22 -0
  653. package/skills/questionnaire-generate/SKILL.md +328 -0
  654. package/skills/questionnaire-generate/references/questionnaire.template +60 -0
  655. package/skills/rclone/SKILL.md +162 -0
  656. package/skills/rclone/scripts/check_setup.sh +63 -0
  657. package/skills/release-announce/SKILL.md +65 -0
  658. package/skills/release-docs/SKILL.md +92 -0
  659. package/skills/reproduce-bug/SKILL.md +358 -0
  660. package/skills/resolve-debt/SKILL.md +85 -0
  661. package/skills/resolve-debt/scripts/resolve-debt.py +584 -0
  662. package/skills/resolve-parallel/SKILL.md +45 -0
  663. package/skills/resolve-parallel/workflows/resolve-parallel.workflow.js +415 -0
  664. package/skills/resolve-pr-parallel/SKILL.md +68 -0
  665. package/skills/resolve-pr-parallel/workflows/resolve-pr-parallel.workflow.js +419 -0
  666. package/skills/resolve-todo-parallel/SKILL.md +57 -0
  667. package/skills/resolve-todo-parallel/workflows/resolve-todo-parallel.workflow.js +398 -0
  668. package/skills/review/SKILL.md +1620 -0
  669. package/skills/review/references/anti-slop-scanner-hook.md +40 -0
  670. package/skills/review/references/defect-classes-migrations.md +9 -0
  671. package/skills/review/references/generated-input-oracle-surfaces.md +15 -0
  672. package/skills/review/references/review-e2e-testing.md +116 -0
  673. package/skills/review/references/review-evidence-comment.md +36 -0
  674. package/skills/review/references/review-todo-structure.md +165 -0
  675. package/skills/review/references/risk-tier-and-fix-rounds.md +97 -0
  676. package/skills/review/references/semgrep-custom-rules.yaml +174 -0
  677. package/skills/review/references/ultrathink-phases.md +98 -0
  678. package/skills/review/references/wfs.md +6 -0
  679. package/skills/review/scripts/emit-review-trailer.sh +499 -0
  680. package/skills/review/scripts/ensure-semgrep.sh +99 -0
  681. package/skills/review/scripts/fix-round-seats.sh +197 -0
  682. package/skills/review/test/emit-review-trailer.test.sh +387 -0
  683. package/skills/review/test/ensure-semgrep.test.sh +111 -0
  684. package/skills/review/test/fix-round-seats.test.sh +237 -0
  685. package/skills/review/workflows/README.md +147 -0
  686. package/skills/review/workflows/review.workflow.js +667 -0
  687. package/skills/schedule/SKILL.md +796 -0
  688. package/skills/seo-aeo/SKILL.md +139 -0
  689. package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
  690. package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
  691. package/skills/ship/SKILL.md +3023 -0
  692. package/skills/ship/references/adr-ordinal-collision.md +47 -0
  693. package/skills/ship/references/affected-gate-contract.md +115 -0
  694. package/skills/ship/references/ci-run-diagnosis.md +29 -0
  695. package/skills/ship/references/ci-workflow-authoring.md +68 -0
  696. package/skills/ship/references/cleanup-merged-archival.md +39 -0
  697. package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
  698. package/skills/ship/references/cto-ruling-armed-push.md +5 -0
  699. package/skills/ship/references/decision-challenges-render.md +71 -0
  700. package/skills/ship/references/delegated-act-authoring-form.md +7 -0
  701. package/skills/ship/references/detached-battery-verdict.md +13 -0
  702. package/skills/ship/references/epic-close-sweep.md +62 -0
  703. package/skills/ship/references/feature-tweet-draft.md +42 -0
  704. package/skills/ship/references/followthrough-issue-body-template.md +47 -0
  705. package/skills/ship/references/followthrough-stub-template.sh +92 -0
  706. package/skills/ship/references/merge-queue-dequeue.md +39 -0
  707. package/skills/ship/references/operator-holds.md +179 -0
  708. package/skills/ship/references/pipeline-tally-render.md +43 -0
  709. package/skills/ship/references/pr-overlap.md +153 -0
  710. package/skills/ship/references/queue-mode.md +7 -0
  711. package/skills/ship/references/ready-run-wait.md +36 -0
  712. package/skills/ship/references/red-on-main-quarantine.md +110 -0
  713. package/skills/ship/references/register-update-pr-pattern.md +88 -0
  714. package/skills/ship/references/settle-then-admin-merge.md +130 -0
  715. package/skills/ship/references/supabase-column-probe.md +13 -0
  716. package/skills/ship/scripts/auto-close-scan.sh +76 -0
  717. package/skills/ship/scripts/battery-owed.sh +403 -0
  718. package/skills/ship/scripts/hold-gate-eval.sh +410 -0
  719. package/skills/ship/scripts/net-issue-flow.sh +665 -0
  720. package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
  721. package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
  722. package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
  723. package/skills/skill-creator/SKILL.md +299 -0
  724. package/skills/skill-creator/references/api-security.md +248 -0
  725. package/skills/skill-creator/references/authoring-levers.md +110 -0
  726. package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
  727. package/skills/skill-creator/references/best-practices.md +431 -0
  728. package/skills/skill-creator/references/common-patterns.md +639 -0
  729. package/skills/skill-creator/references/core-principles.md +193 -0
  730. package/skills/skill-creator/references/executable-code.md +188 -0
  731. package/skills/skill-creator/references/iteration-and-testing.md +509 -0
  732. package/skills/skill-creator/references/official-spec.md +193 -0
  733. package/skills/skill-creator/references/recommended-structure.md +180 -0
  734. package/skills/skill-creator/references/skill-structure.md +396 -0
  735. package/skills/skill-creator/references/using-scripts.md +122 -0
  736. package/skills/skill-creator/references/using-templates.md +120 -0
  737. package/skills/skill-creator/references/workflows-and-validation.md +541 -0
  738. package/skills/skill-creator/scripts/init_skill.py +322 -0
  739. package/skills/skill-creator/scripts/package_skill.py +110 -0
  740. package/skills/skill-creator/scripts/quick_validate.py +64 -0
  741. package/skills/skill-creator/templates/router-skill.md +73 -0
  742. package/skills/skill-creator/templates/simple-skill.md +34 -0
  743. package/skills/skill-creator/workflows/add-reference.md +96 -0
  744. package/skills/skill-creator/workflows/add-script.md +104 -0
  745. package/skills/skill-creator/workflows/add-template.md +83 -0
  746. package/skills/skill-creator/workflows/add-workflow.md +128 -0
  747. package/skills/skill-creator/workflows/audit-skill.md +159 -0
  748. package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
  749. package/skills/skill-creator/workflows/create-new-skill.md +207 -0
  750. package/skills/skill-creator/workflows/get-guidance.md +134 -0
  751. package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
  752. package/skills/skill-creator/workflows/verify-skill.md +226 -0
  753. package/skills/skill-security-scan/SKILL.md +145 -0
  754. package/skills/skill-security-scan/references/disclaimer.md +21 -0
  755. package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
  756. package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
  757. package/skills/skill-security-scan/references/override-mechanism.md +171 -0
  758. package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
  759. package/skills/skill-security-scan/references/regex-patterns.md +136 -0
  760. package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
  761. package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
  762. package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
  763. package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
  764. package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
  765. package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
  766. package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
  767. package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
  768. package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
  769. package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
  770. package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
  771. package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
  772. package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
  773. package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
  774. package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
  775. package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
  776. package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
  777. package/skills/skill-security-scan/scripts/lib.sh +197 -0
  778. package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
  779. package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
  780. package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
  781. package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
  782. package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
  783. package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
  784. package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
  785. package/skills/social-distribute/SKILL.md +485 -0
  786. package/skills/spec-templates/SKILL.md +274 -0
  787. package/skills/sync/SKILL.md +49 -0
  788. package/skills/test-browser/SKILL.md +464 -0
  789. package/skills/test-browser/references/feature-map.md +161 -0
  790. package/skills/test-fix-loop/SKILL.md +159 -0
  791. package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
  792. package/skills/triage/SKILL.md +402 -0
  793. package/skills/trigger-cron/SKILL.md +136 -0
  794. package/skills/trigger-cron/scripts/trigger.sh +198 -0
  795. package/skills/user-set-role/SKILL.md +147 -0
  796. package/skills/user-set-role/scripts/set-role.sh +218 -0
  797. package/skills/user-story-writer/SKILL.md +77 -0
  798. package/skills/ux-audit/SKILL.md +251 -0
  799. package/skills/ux-audit/references/finding.schema.json +62 -0
  800. package/skills/ux-audit/references/route-list.yaml +95 -0
  801. package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
  802. package/skills/ux-audit/scripts/bot-signin.ts +135 -0
  803. package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
  804. package/skills/verification-scaffold/SKILL.md +73 -0
  805. package/skills/verification-scaffold/references/gitleaks.toml.template +13 -0
  806. package/skills/verification-scaffold/references/guardrail-audit.md +156 -0
  807. package/skills/verification-scaffold/references/guards/block-stash-hook.sh.template +72 -0
  808. package/skills/verification-scaffold/references/guards/commit-on-main-hook.sh.template +82 -0
  809. package/skills/verification-scaffold/references/guards/orphan-test-check.sh.template +102 -0
  810. package/skills/verification-scaffold/references/guards/precommit-guard.sh.template +115 -0
  811. package/skills/verification-scaffold/references/guards/secret-scan-hook.sh.template +176 -0
  812. package/skills/verification-scaffold/references/guards/verification-gates.yml.template +49 -0
  813. package/skills/verification-scaffold/references/guards/wrapper-boundary.sh.template +47 -0
  814. package/skills/verification-scaffold/references/guards.tsv +21 -0
  815. package/skills/verification-scaffold/references/verification-readme.template +55 -0
  816. package/skills/verification-scaffold/scripts/verification-scaffold.sh +785 -0
  817. package/skills/verification-scaffold/test/bite-proof.test.sh +159 -0
  818. package/skills/verification-scaffold/test/generator.test.sh +319 -0
  819. package/skills/verification-scaffold/test/manifest.test.sh +144 -0
  820. package/skills/work/SKILL.md +1480 -0
  821. package/skills/work/references/end-of-work-resume.md +7 -0
  822. package/skills/work/references/hook-test-main-cwd.md +24 -0
  823. package/skills/work/references/key-principles.md +83 -0
  824. package/skills/work/references/property-testing.md +122 -0
  825. package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
  826. package/skills/work/references/work-agent-teams.md +97 -0
  827. package/skills/work/references/work-lifecycle-parallel.md +147 -0
  828. package/skills/work/references/work-lockfile-bumps.md +97 -0
  829. package/skills/work/references/work-scratch-sandboxes.md +212 -0
  830. package/skills/work/references/work-subagent-fanout.md +61 -0
  831. package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
  832. package/skills/xcode-test/SKILL.md +360 -0
@@ -0,0 +1,499 @@
1
+ #!/usr/bin/env bash
2
+ # Emit the machine-readable "a review actually ran on this branch" signal (#6724).
3
+ #
4
+ # WHY THIS IS A SCRIPT AND NOT A PROSE INSTRUCTION
5
+ #
6
+ # The pre-existing convention was a sentence in review/SKILL.md telling the
7
+ # agent to commit review artifacts. Its measured compliance is zero on
8
+ # zero-finding branches, because the same skill explicitly says:
9
+ #
10
+ # "If there are no local changes, skip the commit (this is the expected
11
+ # case — review's primary output is GitHub issues, which are remote-only)."
12
+ #
13
+ # So the cleanest branches — the ones where review found nothing — produce no
14
+ # local evidence at all. Every downstream review-evidence gate then reads
15
+ # "review never ran" and denies the merge, with no escape hatch. That is the
16
+ # P0 this script exists to close, and it is why `--allow-empty` below is
17
+ # load-bearing rather than a convenience: without it, a zero-finding review
18
+ # makes no commit, emits no trailer, and deadlocks exactly the branches that
19
+ # had nothing wrong with them.
20
+ #
21
+ # The trailer is emitted by a script rather than described in prose because a
22
+ # described `git commit` line is advisory and a script invocation is not.
23
+ #
24
+ # WHAT THIS TRAILER DOES AND DOES NOT MEAN (ADR-127)
25
+ #
26
+ # It is a BOOLEAN: "a review ran on this branch". It is NOT an attestation that
27
+ # the merged tree is the tree that was reviewed. Reviewing early and then
28
+ # pushing further commits leaves the trailer in range and the gate passes.
29
+ #
30
+ # That is deliberate, not an oversight. The consuming gate is a three-signal
31
+ # OR in which every leg is a boolean — the legacy `review: ` subject pattern is
32
+ # checked BEFORE this trailer, and Signal 3 (a labelled GitHub issue) cannot be
33
+ # bound to a tree at all. Content-binding this one leg would therefore close
34
+ # nothing: `git commit --allow-empty -m "review: x"` still satisfies the gate.
35
+ # Making the binding real means deleting the legacy patterns (stranding every
36
+ # branch reviewed before this shipped) and re-architecting Signal 3 — a much
37
+ # larger change, landing a re-review treadmill on a gate already denying most
38
+ # open PRs. Gates that block constantly get bypassed; that is how #6724 was
39
+ # created.
40
+ #
41
+ # Threat model: agent forgetfulness on a trusted single-operator repo. These
42
+ # hooks live in the operator's own checkout and are editable by the same agent
43
+ # they constrain, so there is no enforcement boundary to build on. A boolean is
44
+ # the honest instrument for that.
45
+ #
46
+ # `Reviewed-Commit:` below records the reviewed sha WITHOUT any consumer reading
47
+ # it, so the forensic data exists if the threat model ever changes (external
48
+ # contributors merging without operator review) and enforcement becomes
49
+ # warranted. Adding the field later would be the expensive part; enforcing a
50
+ # field already present is cheap.
51
+ #
52
+ # WHAT `Reviewed-Coverage:` ADDS, AND WHY IT IS NOT A CONTRADICTION OF ADR-127
53
+ #
54
+ # ADR-127 settled ONE axis: the trailer does not attest that the merged tree is
55
+ # the reviewed tree, and content-binding was rejected. `Reviewed-Coverage:`
56
+ # records a DIFFERENT axis — HOW MUCH review ran — and leaves that decision
57
+ # untouched.
58
+ #
59
+ # The gap it closes is measured, not hypothetical. review/SKILL.md's Rate Limit
60
+ # Fallback gate reads "if ANY agent returned substantive output: proceed
61
+ # normally with available results", which is the right call and is silent about
62
+ # WHICH agents did not. So a 10-agent review where every agent concurred and a
63
+ # review where 7 of 10 died on `529 Overloaded` — losing security-sentinel,
64
+ # test-design-reviewer and architecture-strategist — emit a BYTE-IDENTICAL
65
+ # trailer. Downstream, `/ship` reads that boolean and merges. Observed
66
+ # 2026-07-29 on PR #7066: 7 of 9 agents terminated early on 529s, and nothing
67
+ # in the repo would have recorded it.
68
+ #
69
+ # The worse shape is a review that could not spawn agents AT ALL — a harness
70
+ # constraint, a headless run with no agent surface. The Rate Limit Fallback gate
71
+ # cannot see that state, because it is defined over agents that COMPLETED and
72
+ # nothing ever completes. The reviewer then either does an inline pass (correct)
73
+ # or skips review (silent), and both emit the full-strength trailer.
74
+ #
75
+ # This field is emitted with NO consumer, by exactly the argument ADR-127 used
76
+ # for `Reviewed-Commit:`: adding a field once the key is in main's permanent
77
+ # history and read by three consumers is the expensive part. Recording it now is
78
+ # cheap; a future gate that wants to weight a merge by review strength — or an
79
+ # operator asking "was this PR actually reviewed, or reviewed-shaped?" — needs
80
+ # the data to already be there.
81
+ #
82
+ # It is NOT a quality score. Ten agents returning nothing useful outranks two
83
+ # that found a P1 on every axis this field measures. It answers one narrow
84
+ # question: how many of the intended reviewers actually ran.
85
+ #
86
+ # Usage:
87
+ # emit-review-trailer.sh [--findings <n>] [--summary <text>]
88
+ # [--agents-ran <n>] [--agents-expected <n>]
89
+ # [--agents-missing <comma-separated-names>]
90
+ # [--mode full|degraded|inline-fallback|sequential-fallback]
91
+ # [--risk-tier 'none|single-user incident|aggregate pattern']
92
+ #
93
+ # `Reviewed-Risk-Tier:` (ADR-267) records the risk tier the review panel was
94
+ # scaled to — the resolved 3-value enum only; `undeclared` is a classifier
95
+ # parse state and is rejected like any other invalid value. No consumer reads
96
+ # it (the ADR-127 argument: recording a field whose key is already in main's
97
+ # history is cheap; adding it later is the expensive part).
98
+ #
99
+ # Exit codes:
100
+ # 0 trailer committed and verified parseable
101
+ # 0 skipped (on main/master, or evidence already present for this branch)
102
+ # 1 commit succeeded but the trailer does not parse — see VERIFY below
103
+ # 2 usage / environment error
104
+ set -euo pipefail
105
+
106
+ # (#7797) Refuse to run under shell tracing while a live credential is set: `set -x`
107
+ # echoes commands AFTER expansion, so a bound credential reaches the transcript
108
+ # before it reaches any command. `case "$-" in *x*)` tests whether tracing is ON
109
+ # rather than enumerating the ways to turn it on, two of which carry no `-x`
110
+ # token at all.
111
+ case "$-" in
112
+ *x*)
113
+ if [ -n "${COVERAGE_KEY:+x}${RISK_TIER_KEY:+x}${TRAILER_KEY:+x}${FIX_ROUND_KEY:+x}${FIX_RANGE_KEY:+x}" ]; then
114
+ printf '[FATAL] refusing to trace with a live credential set (see #7797)\n' >&2
115
+ exit 78
116
+ fi
117
+ ;;
118
+ esac
119
+
120
+ usage() {
121
+ cat <<'EOF'
122
+ Usage: emit-review-trailer.sh [--findings <n>] [--summary <text>]
123
+ [--agents-ran <n>] [--agents-expected <n>]
124
+ [--agents-missing <comma-separated-names>]
125
+ [--mode full|degraded|inline-fallback|sequential-fallback]
126
+ [--risk-tier 'none|single-user incident|aggregate pattern']
127
+ [--fix-round --since <sha>]
128
+
129
+ Pass --agents-ran AND --agents-expected or the trailer records
130
+ `Reviewed-Coverage: unknown`, and nothing downstream can distinguish a
131
+ full review from one where the agents that mattered never ran.
132
+
133
+ Commits an empty commit carrying the Reviewed-By-Soleur: trailer, the
134
+ machine-readable proof that soleur:review ran on this branch (#6724).
135
+
136
+ --fix-round (ADR-267): emits a targeted-round attestation with DIFFERENT keys
137
+ — `Reviewed-Fix-Round:`/`Reviewed-Fix-Range:` — and NEVER `Reviewed-Coverage:`.
138
+ A fix round covers only the fix-commit range; writing `full` there would be a
139
+ coverage overclaim on the merge gate, and the main trailer's idempotence guard
140
+ would swallow it anyway. Requires --since <sha> (the panel snapshot).
141
+
142
+ Exit codes:
143
+ 0 trailer committed and verified parseable
144
+ 0 skipped (on main/master, or evidence already present for this branch)
145
+ 1 commit succeeded but the trailer does not parse
146
+ 2 usage / environment error
147
+ EOF
148
+ }
149
+
150
+ TRAILER_KEY="Reviewed-By-Soleur"
151
+ COVERAGE_KEY="Reviewed-Coverage"
152
+ RISK_TIER_KEY="Reviewed-Risk-Tier"
153
+ FIX_ROUND_KEY="Reviewed-Fix-Round"
154
+ FIX_RANGE_KEY="Reviewed-Fix-Range"
155
+ FINDINGS=""
156
+ SUMMARY=""
157
+ AGENTS_RAN=""
158
+ AGENTS_EXPECTED=""
159
+ AGENTS_MISSING=""
160
+ MODE=""
161
+ RISK_TIER=""
162
+ FIX_ROUND=0
163
+ FIX_SINCE=""
164
+
165
+ while [[ $# -gt 0 ]]; do
166
+ case "$1" in
167
+ --findings) FINDINGS="${2:?--findings needs a value}"; shift 2 ;;
168
+ --summary) SUMMARY="${2:?--summary needs a value}"; shift 2 ;;
169
+ --agents-ran) AGENTS_RAN="${2:?--agents-ran needs a value}"; shift 2 ;;
170
+ --agents-expected) AGENTS_EXPECTED="${2:?--agents-expected needs a value}"; shift 2 ;;
171
+ --agents-missing) AGENTS_MISSING="${2:?--agents-missing needs a value}"; shift 2 ;;
172
+ --mode) MODE="${2:?--mode needs a value}"; shift 2 ;;
173
+ --risk-tier) RISK_TIER="${2:?--risk-tier needs a value}"; shift 2 ;;
174
+ --fix-round) FIX_ROUND=1; shift ;;
175
+ --since) FIX_SINCE="${2:?--since needs a value}"; shift 2 ;;
176
+ -h|--help) usage; exit 0 ;;
177
+ *) echo "emit-review-trailer: unknown argument '$1'" >&2; exit 2 ;;
178
+ esac
179
+ done
180
+
181
+ # Validate the coverage inputs BEFORE committing anything. A malformed count
182
+ # would land in main's permanent history as an unparseable coverage claim, which
183
+ # is the same "looks like evidence to a human, invisible to a consumer" defect
184
+ # the VERIFY block at the bottom exists to prevent — just on a different field.
185
+ for _pair in "AGENTS_RAN:$AGENTS_RAN" "AGENTS_EXPECTED:$AGENTS_EXPECTED"; do
186
+ _name="${_pair%%:*}"; _val="${_pair#*:}"
187
+ if [[ -n "$_val" && ! "$_val" =~ ^[0-9]+$ ]]; then
188
+ echo "emit-review-trailer: --${_name,,} must be a non-negative integer (got '${_val}')" >&2
189
+ exit 2
190
+ fi
191
+ done
192
+ # `sequential-fallback` is distinct from `inline-fallback`: the former means the
193
+ # plugin subagent surface was unavailable (a Devin Cloud session) so the review
194
+ # roles ran sequentially inline, the latter that there was no agent surface at
195
+ # all. Both are degraded coverage, but a consumer weighting review strength can
196
+ # legitimately score them differently.
197
+ if [[ -n "$MODE" && ! "$MODE" =~ ^(full|degraded|inline-fallback|sequential-fallback)$ ]]; then
198
+ echo "emit-review-trailer: --mode must be one of full|degraded|inline-fallback|sequential-fallback (got '${MODE}')" >&2
199
+ exit 2
200
+ fi
201
+ # Only the resolved 3-value enum reaches main's history — `undeclared` is a
202
+ # classifier parse state, rejected here like any other invalid token (ADR-267).
203
+ if [[ -n "$RISK_TIER" && ! "$RISK_TIER" =~ ^(none|single-user incident|aggregate pattern)$ ]]; then
204
+ echo "emit-review-trailer: --risk-tier must be one of 'none'|'single-user incident'|'aggregate pattern' (got '${RISK_TIER}')" >&2
205
+ exit 2
206
+ fi
207
+ # `ran > expected` is a contradiction, and silently accepting it would let the
208
+ # field overclaim in exactly the direction that matters.
209
+ if [[ -n "$AGENTS_RAN" && -n "$AGENTS_EXPECTED" && "$AGENTS_RAN" -gt "$AGENTS_EXPECTED" ]]; then
210
+ echo "emit-review-trailer: --agents-ran ($AGENTS_RAN) exceeds --agents-expected ($AGENTS_EXPECTED)" >&2
211
+ exit 2
212
+ fi
213
+
214
+ # DERIVE the mode rather than trusting the caller's label where the counts
215
+ # already answer it. A caller that passes `--mode full` alongside `--agents-ran 2
216
+ # --agents-expected 10` is either confused or overclaiming; the counts win.
217
+ #
218
+ # Exception: `sequential-fallback` is NOT a count axis — it attests that the
219
+ # plugin subagent surface was unavailable and the roles ran inline. A cloud
220
+ # review that ran all N roles sequentially passes N/N, which counts alone would
221
+ # "upgrade" to `full` — silently defeating the /ship gate that keys on the
222
+ # sequential-fallback prefix. An explicit `--mode sequential-fallback` survives
223
+ # derivation; the counts still annotate the coverage string.
224
+ if [[ -n "$AGENTS_RAN" && -n "$AGENTS_EXPECTED" && "$MODE" != "sequential-fallback" ]]; then
225
+ if [[ "$AGENTS_RAN" -eq 0 ]]; then
226
+ MODE="inline-fallback"
227
+ elif [[ "$AGENTS_RAN" -lt "$AGENTS_EXPECTED" ]]; then
228
+ MODE="degraded"
229
+ else
230
+ MODE="full"
231
+ fi
232
+ fi
233
+
234
+ # UNKNOWN is the honest default, and it is deliberately not "full". A caller that
235
+ # does not pass the flags has told us nothing about coverage, and defaulting an
236
+ # absent measurement to the strongest value is how a field like this becomes
237
+ # decorative — every legacy call site would silently read as a 10-agent review.
238
+ COVERAGE_VALUE="unknown"
239
+ if [[ -n "$AGENTS_RAN" && -n "$AGENTS_EXPECTED" ]]; then
240
+ COVERAGE_VALUE="${MODE} ${AGENTS_RAN}/${AGENTS_EXPECTED} agents"
241
+ if [[ -n "$AGENTS_MISSING" ]]; then
242
+ # Commas separate names; keep them, they cannot break trailer parsing (only a
243
+ # newline or a non-`Key: value` line can).
244
+ COVERAGE_VALUE="${COVERAGE_VALUE} (missing: ${AGENTS_MISSING})"
245
+ fi
246
+ elif [[ -n "$MODE" ]]; then
247
+ COVERAGE_VALUE="$MODE"
248
+ fi
249
+ # Newlines would split the final paragraph and void every trailer below this one.
250
+ COVERAGE_VALUE="${COVERAGE_VALUE//$'\n'/ }"
251
+
252
+ # --fix-round/--since pairing: the flag means nothing without an explicit
253
+ # panel-snapshot sha (the merge-base fallback would scope the "targeted" round
254
+ # to the whole branch — the overclaim this key set exists to prevent), and
255
+ # --since outside --fix-round is a stranded operand.
256
+ if [[ "$FIX_ROUND" -eq 1 && -z "$FIX_SINCE" ]]; then
257
+ echo "emit-review-trailer: --fix-round requires --since <sha>" >&2
258
+ exit 2
259
+ fi
260
+ if [[ "$FIX_ROUND" -eq 0 && -n "$FIX_SINCE" ]]; then
261
+ echo "emit-review-trailer: --since requires --fix-round" >&2
262
+ exit 2
263
+ fi
264
+
265
+ if ! git rev-parse --git-dir >/dev/null 2>&1; then
266
+ echo "emit-review-trailer: not a git repository" >&2
267
+ exit 2
268
+ fi
269
+
270
+ if [[ "$FIX_ROUND" -eq 1 ]] && ! git rev-parse --verify --quiet "${FIX_SINCE}^{commit}" >/dev/null 2>&1; then
271
+ echo "emit-review-trailer: --since '${FIX_SINCE}' does not resolve to a commit" >&2
272
+ exit 2
273
+ fi
274
+ # Canonicalize to the full sha — rev expressions like HEAD~2 would otherwise
275
+ # land in permanent history and alias the idempotence key. Then prove the base
276
+ # is an ANCESTOR of HEAD: a stale sha still resolves post-rebase but computes a
277
+ # range over unrelated history.
278
+ if [[ "$FIX_ROUND" -eq 1 ]]; then
279
+ FIX_SINCE="$(git rev-parse "$FIX_SINCE")"
280
+ git merge-base --is-ancestor "$FIX_SINCE" HEAD 2>/dev/null || {
281
+ echo "emit-review-trailer: --since ${FIX_SINCE} is not an ancestor of HEAD" >&2
282
+ echo " (a rebase may have invalidated the panel snapshot — recover the base per references/risk-tier-and-fix-rounds.md)" >&2
283
+ exit 2
284
+ }
285
+ fi
286
+
287
+ BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
288
+ if [[ -z "$BRANCH" ]]; then
289
+ echo "emit-review-trailer: could not resolve branch" >&2
290
+ exit 2
291
+ fi
292
+
293
+ # Never emit on main/master or in detached HEAD: nothing to mark there. The gate
294
+ # reads the merged PR's own head (#8778), so the trailer must land on the PR's
295
+ # branch — run this from that checkout, then push.
296
+ if [[ "$BRANCH" == "main" || "$BRANCH" == "master" || "$BRANCH" == "HEAD" ]]; then
297
+ echo "emit-review-trailer: on '$BRANCH' — nothing to mark, skipping."
298
+ exit 0
299
+ fi
300
+
301
+ # Resolve the branch's base ref explicitly. `origin/main..HEAD` is the right
302
+ # scope in the real repo, but silently degrades to an ERROR — and therefore to
303
+ # an empty result — anywhere that ref is absent (throwaway fixtures, clones
304
+ # with a different default branch, detached CI checkouts). An empty result
305
+ # reads identically to "no trailer yet", so the idempotence check below would
306
+ # fail open and stack a duplicate empty commit on every invocation. Falling
307
+ # back to the whole of HEAD is the conservative direction: it can only ever
308
+ # suppress an extra commit, never emit a spurious one.
309
+ BASE_REF=""
310
+ for cand in origin/main origin/master main master; do
311
+ if git rev-parse --verify --quiet "$cand" >/dev/null 2>&1; then BASE_REF="$cand"; break; fi
312
+ done
313
+ if [[ -n "$BASE_REF" ]] && [[ "$(git rev-parse "$BASE_REF")" != "$(git rev-parse HEAD)" ]]; then
314
+ SCOPE="${BASE_REF}..HEAD"
315
+ else
316
+ SCOPE="HEAD"
317
+ fi
318
+
319
+ # Idempotence: if this branch already carries the trailer, a second review pass
320
+ # should not stack duplicate empty commits. Scoped to commits unique to the
321
+ # branch, for the same reason the gate is (see below).
322
+ # Fix-round idempotence is keyed on the full reviewed RANGE, not the branch
323
+ # trailer: the main-panel trailer is expected to exist already, so the
324
+ # branch-level skip would make every fix-round emission unreachable — and a
325
+ # left-edge-only match would swallow a SECOND round covering further commits.
326
+ # The right edge is the newest commit WITHOUT a review-attestation trailer —
327
+ # matched on trailers, not subjects, because `review: <summary> (P<N>)` is also
328
+ # this repo's prescribed FIX-commit subject (SKILL.md) and a subject filter
329
+ # would over-exclude real fixes, collapsing the recorded range and re-swallowing
330
+ # the second-round attestation this keying exists to preserve.
331
+ if [[ "$FIX_ROUND" -eq 1 ]]; then
332
+ # The walk is scoped to the round's range (an unbounded HEAD walk into an
333
+ # early-exiting consumer is a SIGPIPE-under-pipefail trap on big histories),
334
+ # and the awk consumes ALL input (no early `exit`) for the same reason.
335
+ # $1 must be a full sha — a trailer VALUE on a continuation line must not be
336
+ # mistaken for a commit.
337
+ EFFECTIVE_HEAD=$(git log --format='%H %(trailers:key='"$TRAILER_KEY"',valueonly)%(trailers:key='"$FIX_ROUND_KEY"',valueonly)' "${FIX_SINCE}..HEAD" \
338
+ | awk 'NF == 1 && $1 ~ /^[0-9a-f]{40}$/ && !found { found = $1 } END { print found }')
339
+ # All-attestation range (repeat call with no new fix commits) → the effective
340
+ # range is empty: record since..since. Falling back to HEAD would point at
341
+ # the prior ATTESTATION commit, rotating the range on every call and never
342
+ # deduping.
343
+ [[ -n "$EFFECTIVE_HEAD" ]] || EFFECTIVE_HEAD="$FIX_SINCE"
344
+ RANGE="${FIX_SINCE}..${EFFECTIVE_HEAD}"
345
+ if grep -qF "$RANGE" \
346
+ < <(git log "$SCOPE" --format='%(trailers:key='"$FIX_RANGE_KEY"',valueonly)' 2>/dev/null); then
347
+ echo "emit-review-trailer: a fix-round attestation over ${RANGE} already exists — skipping."
348
+ exit 0
349
+ fi
350
+ elif grep -q '[^[:space:]]' \
351
+ < <(git log "$SCOPE" --format='%(trailers:key='"$TRAILER_KEY"',valueonly)' 2>/dev/null); then
352
+ # Skipping is right for a REPEATED pass and wrong when the recorded reality CHANGED — e.g. a
353
+ # degraded 0/N review whose agents later ran to N/N (#7220, 2026-08-04). The stale trailer then
354
+ # misdescribes coverage to every downstream consumer, in the direction that looks safe. To
355
+ # supersede, commit a trailer by hand whose final paragraph is trailers ONLY, and say in the body
356
+ # which commit it supersedes and why.
357
+ echo "emit-review-trailer: branch already carries a $TRAILER_KEY trailer (scope: $SCOPE) — skipping."
358
+ echo "emit-review-trailer: if coverage CHANGED since that trailer, supersede it by hand — see the comment at this line." >&2
359
+ exit 0
360
+ fi
361
+
362
+ if [[ -z "$SUMMARY" ]]; then
363
+ if [[ "$FIX_ROUND" -eq 1 ]]; then
364
+ SUMMARY="targeted fix-commit round"
365
+ elif [[ "$FINDINGS" == "0" ]]; then
366
+ SUMMARY="no findings"
367
+ elif [[ -n "$FINDINGS" ]]; then
368
+ SUMMARY="$FINDINGS finding(s) triaged"
369
+ else
370
+ SUMMARY="review complete"
371
+ fi
372
+ fi
373
+
374
+ # The subject deliberately matches the legacy Signal 2 regex (`review: `) so
375
+ # this commit is recognised by gates that predate the trailer and have not been
376
+ # updated yet. The trailer is the durable signal; the subject is the fallback.
377
+ #
378
+ # The final paragraph is trailers ONLY. Git parses just the last contiguous
379
+ # block of `Token: value` lines, so a stray `Refs #6724.` there would silently
380
+ # void every trailer below it — including this one. Issue references therefore
381
+ # stay in the body prose above.
382
+ #
383
+ # `Reviewed-Commit:` records the sha under review. NO consumer reads it — see
384
+ # the ADR-127 note in the header. It is recorded now because adding a field
385
+ # later, once the key is in main's permanent history and read by three
386
+ # consumers, is the expensive part; enforcing a field already present is cheap.
387
+ REVIEWED_SHA=$(git rev-parse HEAD)
388
+ # The tier line is absent entirely when the flag is absent — a fabricated
389
+ # `unknown` literal would be a claim the caller never measured. RISK_TIER is
390
+ # enum-validated above, so it can never carry the newline that would split the
391
+ # trailers paragraph.
392
+ RISK_TIER_LINE=""
393
+ if [[ -n "$RISK_TIER" ]]; then
394
+ RISK_TIER_LINE="${RISK_TIER_KEY}: ${RISK_TIER}"$'\n'
395
+ fi
396
+ if [[ "$FIX_ROUND" -eq 1 ]]; then
397
+ # Distinct keys, never Reviewed-Coverage — a targeted round covers only the
398
+ # fix-commit range, and ship's gate reads Reviewed-Coverage for the BRANCH.
399
+ # The coverage-shaped value is kept on the round's own key so the seat counts
400
+ # still record.
401
+ # The fix-round subject deliberately does NOT match the legacy Signal-2
402
+ # `review(\(scope\))?: ` regex — a targeted round is not branch-level review
403
+ # evidence, and matching that leg would let a standalone round pass the
404
+ # merge gate's "did review run" signal exactly like the coverage overclaim
405
+ # the distinct trailer keys exist to prevent.
406
+ COMMIT_MSG=$(printf '%s\n\n%s\n\n%s: %s\n%s: %s\n%s: %s..%s\n%s' \
407
+ "review-fix-round: ${SUMMARY}" \
408
+ "Records that a targeted fix-commit review round ran on this branch (ADR-267). It re-reviews only the named fix range with seats mapped to the areas the fix touched; it carries no branch-level coverage claim — the main panel's Reviewed-Coverage remains the branch signal." \
409
+ "$FIX_ROUND_KEY" "$COVERAGE_VALUE" \
410
+ "Reviewed-Commit" "$REVIEWED_SHA" \
411
+ "$FIX_RANGE_KEY" "$FIX_SINCE" "$EFFECTIVE_HEAD" \
412
+ "$RISK_TIER_LINE")
413
+ else
414
+ COMMIT_MSG=$(printf '%s\n\n%s\n\n%s: soleur:review\n%s: %s\n%s%s: %s\n' \
415
+ "review: ${SUMMARY}" \
416
+ "Records that soleur:review ran on this branch (see issue 6724). Empty by design: a review that finds nothing still needs to prove it ran. This is a boolean, not an attestation that the merged tree is the reviewed tree — see ADR-127. Reviewed-Coverage records HOW MUCH review ran (a separate axis from ADR-127's tree-binding decision); 'unknown' means the caller did not measure, never that coverage was full. Reviewed-Risk-Tier records the resolved risk tier the panel was scaled to (ADR-267); absent when the caller did not resolve one." \
417
+ "$TRAILER_KEY" \
418
+ "Reviewed-Commit" "$REVIEWED_SHA" \
419
+ "$RISK_TIER_LINE" \
420
+ "$COVERAGE_KEY" "$COVERAGE_VALUE")
421
+ fi
422
+
423
+ # `--allow-empty` does NOT mean "empty" — it commits the INDEX, so anything
424
+ # staged is silently absorbed into a commit whose subject reads
425
+ # "review: no findings". That is reachable: review's step 2 stages artifacts and
426
+ # its commit is conditional, while step 3 runs unconditionally right after.
427
+ # Refuse rather than absorb; the caller can commit or unstage and re-run.
428
+ if ! git diff --cached --quiet 2>/dev/null; then
429
+ echo "emit-review-trailer: refusing to run with staged changes." >&2
430
+ echo " --allow-empty commits the index, so these would be silently absorbed" >&2
431
+ echo " into a commit subject 'review: ${SUMMARY}':" >&2
432
+ git diff --cached --name-only 2>/dev/null | sed 's/^/ /' >&2
433
+ echo " Commit or unstage them first, then re-run." >&2
434
+ exit 2
435
+ fi
436
+
437
+ if ! git commit --allow-empty -q -m "$COMMIT_MSG"; then
438
+ echo "emit-review-trailer: git commit failed" >&2
439
+ exit 2
440
+ fi
441
+
442
+ # VERIFY: a trailer that does not parse is worse than no trailer — it looks
443
+ # like evidence to a human reading the log and is invisible to the gate that
444
+ # actually consumes it. This repo has shipped that exact defect before, so the
445
+ # script refuses to report success on an unparseable trailer.
446
+ if [[ "$FIX_ROUND" -eq 1 ]]; then
447
+ # The fix-round block must parse as trailers; the range key is the round's
448
+ # load-bearing field, so it is the verified one.
449
+ PARSED=$(git log -1 --format='%(trailers:key='"$FIX_RANGE_KEY"',valueonly)' | tr -d '[:space:]')
450
+ if [[ -z "$PARSED" ]]; then
451
+ echo "emit-review-trailer: FAILED — commit landed but '$FIX_RANGE_KEY' does not parse." >&2
452
+ exit 1
453
+ fi
454
+ echo "emit-review-trailer: emitted $FIX_ROUND_KEY on '$BRANCH' ($(git rev-parse --short HEAD)) over ${FIX_SINCE}.."
455
+ exit 0
456
+ fi
457
+ PARSED=$(git log -1 --format='%(trailers:key='"$TRAILER_KEY"',valueonly)' | tr -d '[:space:]')
458
+ if [[ -z "$PARSED" ]]; then
459
+ echo "emit-review-trailer: FAILED — commit landed but '$TRAILER_KEY' does not parse." >&2
460
+ echo " The final paragraph of the commit message must contain ONLY 'Token: value' lines." >&2
461
+ echo " Inspect with: git interpret-trailers --parse < <(git log -1 --format=%B)" >&2
462
+ exit 1
463
+ fi
464
+
465
+ # Verify the coverage key SEPARATELY. `Reviewed-By-Soleur` parsing does not imply
466
+ # its siblings parse: git needs the whole final paragraph to be `Key: value`
467
+ # lines, but a value containing a newline splits the block and voids only the
468
+ # keys BELOW the split — which is exactly where this one sits. Checking the first
469
+ # key alone would report success while the field this change exists to add is
470
+ # silently absent.
471
+ PARSED_COVERAGE=$(git log -1 --format='%(trailers:key='"$COVERAGE_KEY"',valueonly)' | tr -d '[:space:]')
472
+ if [[ -z "$PARSED_COVERAGE" ]]; then
473
+ echo "emit-review-trailer: FAILED — commit landed but '$COVERAGE_KEY' does not parse." >&2
474
+ echo " It is the LAST trailer, so it is the first casualty of a split final paragraph." >&2
475
+ echo " Inspect with: git interpret-trailers --parse < <(git log -1 --format=%B)" >&2
476
+ exit 1
477
+ fi
478
+
479
+ echo "emit-review-trailer: emitted $TRAILER_KEY on '$BRANCH' ($(git rev-parse --short HEAD))"
480
+ echo "emit-review-trailer: $COVERAGE_KEY: $COVERAGE_VALUE"
481
+ if [[ "$COVERAGE_VALUE" == "unknown" ]]; then
482
+ echo "emit-review-trailer: NOTE — coverage is 'unknown' because no --agents-ran/--agents-expected was passed." >&2
483
+ echo " This is recorded honestly, but it means nothing downstream can tell a full review from a degraded one." >&2
484
+ fi
485
+
486
+ # Lifecycle successor, printed at the one moment it is actionable.
487
+ #
488
+ # Emitting this trailer means review is DONE, and review is not a stopping point
489
+ # (rf-never-skip-qa-review-before-merging). Twice in one session (2026-09-03) the
490
+ # lead pushed `review:` fixes, reported status, and ended the turn — the operator
491
+ # had to ask "why did you stop?" both times. The rule was present and had already
492
+ # been routed into review/SKILL.md as prose after the first occurrence; prose was
493
+ # not the gap, and a second paragraph would not have closed it.
494
+ #
495
+ # So the reminder is emitted by the tool at the checkpoint instead of relied upon
496
+ # as recall. This is stdout, not an error: it cannot fail a pipeline, and it costs
497
+ # two lines at exactly the point where the next action is unambiguous.
498
+ echo "emit-review-trailer: NEXT → /soleur:compound, then /soleur:ship (carry the PR to MERGED)."
499
+ echo "emit-review-trailer: review is not a turn boundary — 'CI is running' is not a handoff."
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env bash
2
+ # Ensure the semgrep CLI is on PATH AND RUNS. If missing or dead (resolves but
3
+ # crashes on invocation — the mise/python-latest shebang class, #9964),
4
+ # attempt an auto-install from the first available package manager. On success
5
+ # prints the path to the installed semgrep and exits 0. On failure prints a
6
+ # diagnostic to stderr and exits non-zero so callers can abort the review gate.
7
+ #
8
+ # Supported install paths (in order):
9
+ # 1. brew install semgrep (macOS / Linuxbrew)
10
+ # 2. pipx install semgrep (python user-env isolation)
11
+ # 3. python3 -m pip install --user semgrep (pip user install)
12
+ #
13
+ # Exit codes:
14
+ # 0 - semgrep resolves on PATH AND `semgrep --version` executes
15
+ # 1 - install attempted but semgrep still does not run (incl. a fresh
16
+ # install shadowed by a broken earlier PATH entry)
17
+ # 2 - no install path available (no brew, pipx, or python3 with pip) —
18
+ # includes the dead-shim case: resolution is not enough to count as
19
+ # present, so "no installer" is the honest code
20
+
21
+ set -euo pipefail
22
+
23
+ # semgrep_works: the single success gate — resolution AND execution. A
24
+ # `command -v` hit is necessary but not sufficient: a resolvable-but-dead
25
+ # shim must fall through to the install path exactly like an absent binary
26
+ # (#9964). Bounded when `timeout`/`gtimeout` exists — a mandatory gate that
27
+ # can hang is the same worst-shape failure as a vacuous pass.
28
+ semgrep_works() {
29
+ SEMGREP_VERSION_ERR=""
30
+ command -v semgrep >/dev/null 2>&1 || return 1
31
+ local -a t=()
32
+ local err
33
+ if command -v timeout >/dev/null 2>&1; then t=(timeout -k 1 30); elif command -v gtimeout >/dev/null 2>&1; then t=(gtimeout -k 1 30); fi
34
+ err="$("${t[@]}" semgrep --version 2>&1)" && return 0
35
+ SEMGREP_VERSION_ERR="$err"
36
+ return 1
37
+ }
38
+
39
+ dead_shim_diag() {
40
+ local resolved
41
+ resolved="$(command -v semgrep 2>/dev/null || echo "<unresolvable>")"
42
+ echo "ERROR: semgrep resolves at $resolved but does not run (${SEMGREP_VERSION_ERR:-unknown error}) — a resolvable-but-dead shim (#9964)." >&2
43
+ }
44
+
45
+ if semgrep_works; then
46
+ command -v semgrep
47
+ exit 0
48
+ fi
49
+
50
+ if command -v semgrep >/dev/null 2>&1; then
51
+ echo "semgrep resolves but does not run — treating as absent, attempting install" >&2
52
+ else
53
+ echo "semgrep not found on PATH — attempting auto-install" >&2
54
+ fi
55
+
56
+ attempted=0
57
+ if command -v brew >/dev/null 2>&1; then
58
+ echo "installing via brew..." >&2
59
+ attempted=1
60
+ if brew install semgrep >&2; then
61
+ if semgrep_works; then command -v semgrep; exit 0; fi
62
+ fi
63
+ echo "brew install semgrep failed (or installed but still not runnable — a broken shim may be shadowing it)" >&2
64
+ fi
65
+
66
+ if command -v pipx >/dev/null 2>&1; then
67
+ echo "installing via pipx..." >&2
68
+ attempted=1
69
+ if pipx install semgrep >&2; then
70
+ # pipx adds ~/.local/bin to PATH lazily; ensure binary is reachable.
71
+ export PATH="$HOME/.local/bin:$PATH"
72
+ if semgrep_works; then command -v semgrep; exit 0; fi
73
+ fi
74
+ echo "pipx install semgrep failed (or installed but still not runnable)" >&2
75
+ fi
76
+
77
+ if command -v python3 >/dev/null 2>&1; then
78
+ echo "installing via python3 -m pip --user..." >&2
79
+ attempted=1
80
+ if python3 -m pip install --user semgrep >&2; then
81
+ export PATH="$HOME/.local/bin:$PATH"
82
+ if semgrep_works; then command -v semgrep; exit 0; fi
83
+ fi
84
+ echo "pip --user install semgrep failed (or installed but still not runnable)" >&2
85
+ fi
86
+
87
+ if (( attempted )); then
88
+ dead_shim_diag
89
+ echo "install path(s) ran but semgrep still does not run — remove the dead shim or fix PATH ordering" >&2
90
+ exit 1
91
+ fi
92
+
93
+ if command -v semgrep >/dev/null 2>&1; then
94
+ dead_shim_diag
95
+ echo "no install path available (brew, pipx, or python3-pip required) — remove the dead shim or install a package manager" >&2
96
+ else
97
+ echo "ERROR: no install path available (brew, pipx, or python3-pip required)" >&2
98
+ fi
99
+ exit 2