@soleur/opencode 0.0.0-stage → 1.0.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 (812) 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 +659 -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 +108 -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 +342 -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 +152 -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 +493 -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 +363 -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 +520 -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 +113 -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 +178 -0
  247. package/scripts/sync-opencode-adapter.ts +479 -0
  248. package/scripts/sync-pr-behind.sh +534 -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 +65 -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 +142 -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 +118 -0
  493. package/skills/fix-issue/references/exclude-label-jq-snippet.md +96 -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 +668 -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 +325 -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 +138 -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 +1621 -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-todo-structure.md +165 -0
  674. package/skills/review/references/risk-tier-and-fix-rounds.md +95 -0
  675. package/skills/review/references/semgrep-custom-rules.yaml +174 -0
  676. package/skills/review/references/ultrathink-phases.md +98 -0
  677. package/skills/review/references/wfs.md +6 -0
  678. package/skills/review/scripts/emit-review-trailer.sh +499 -0
  679. package/skills/review/scripts/ensure-semgrep.sh +99 -0
  680. package/skills/review/scripts/fix-round-seats.sh +197 -0
  681. package/skills/review/test/emit-review-trailer.test.sh +387 -0
  682. package/skills/review/test/ensure-semgrep.test.sh +111 -0
  683. package/skills/review/test/fix-round-seats.test.sh +237 -0
  684. package/skills/review/workflows/README.md +147 -0
  685. package/skills/review/workflows/review.workflow.js +667 -0
  686. package/skills/schedule/SKILL.md +796 -0
  687. package/skills/seo-aeo/SKILL.md +139 -0
  688. package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
  689. package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
  690. package/skills/ship/SKILL.md +3022 -0
  691. package/skills/ship/references/adr-ordinal-collision.md +47 -0
  692. package/skills/ship/references/affected-gate-contract.md +115 -0
  693. package/skills/ship/references/ci-run-diagnosis.md +29 -0
  694. package/skills/ship/references/ci-workflow-authoring.md +68 -0
  695. package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
  696. package/skills/ship/references/cto-ruling-armed-push.md +5 -0
  697. package/skills/ship/references/decision-challenges-render.md +71 -0
  698. package/skills/ship/references/detached-battery-verdict.md +13 -0
  699. package/skills/ship/references/feature-tweet-draft.md +42 -0
  700. package/skills/ship/references/followthrough-issue-body-template.md +47 -0
  701. package/skills/ship/references/followthrough-stub-template.sh +92 -0
  702. package/skills/ship/references/merge-queue-dequeue.md +39 -0
  703. package/skills/ship/references/operator-holds.md +149 -0
  704. package/skills/ship/references/pipeline-tally-render.md +43 -0
  705. package/skills/ship/references/pr-overlap.md +153 -0
  706. package/skills/ship/references/queue-mode.md +7 -0
  707. package/skills/ship/references/ready-run-wait.md +36 -0
  708. package/skills/ship/references/red-on-main-quarantine.md +110 -0
  709. package/skills/ship/references/register-update-pr-pattern.md +88 -0
  710. package/skills/ship/references/settle-then-admin-merge.md +130 -0
  711. package/skills/ship/references/supabase-column-probe.md +13 -0
  712. package/skills/ship/scripts/auto-close-scan.sh +76 -0
  713. package/skills/ship/scripts/battery-owed.sh +403 -0
  714. package/skills/ship/scripts/hold-gate-eval.sh +410 -0
  715. package/skills/ship/scripts/net-issue-flow.sh +665 -0
  716. package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
  717. package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
  718. package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
  719. package/skills/skill-creator/SKILL.md +299 -0
  720. package/skills/skill-creator/references/api-security.md +248 -0
  721. package/skills/skill-creator/references/authoring-levers.md +110 -0
  722. package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
  723. package/skills/skill-creator/references/best-practices.md +431 -0
  724. package/skills/skill-creator/references/common-patterns.md +639 -0
  725. package/skills/skill-creator/references/core-principles.md +193 -0
  726. package/skills/skill-creator/references/executable-code.md +188 -0
  727. package/skills/skill-creator/references/iteration-and-testing.md +509 -0
  728. package/skills/skill-creator/references/official-spec.md +193 -0
  729. package/skills/skill-creator/references/recommended-structure.md +180 -0
  730. package/skills/skill-creator/references/skill-structure.md +396 -0
  731. package/skills/skill-creator/references/using-scripts.md +122 -0
  732. package/skills/skill-creator/references/using-templates.md +120 -0
  733. package/skills/skill-creator/references/workflows-and-validation.md +541 -0
  734. package/skills/skill-creator/scripts/init_skill.py +322 -0
  735. package/skills/skill-creator/scripts/package_skill.py +110 -0
  736. package/skills/skill-creator/scripts/quick_validate.py +64 -0
  737. package/skills/skill-creator/templates/router-skill.md +73 -0
  738. package/skills/skill-creator/templates/simple-skill.md +34 -0
  739. package/skills/skill-creator/workflows/add-reference.md +96 -0
  740. package/skills/skill-creator/workflows/add-script.md +104 -0
  741. package/skills/skill-creator/workflows/add-template.md +83 -0
  742. package/skills/skill-creator/workflows/add-workflow.md +128 -0
  743. package/skills/skill-creator/workflows/audit-skill.md +159 -0
  744. package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
  745. package/skills/skill-creator/workflows/create-new-skill.md +207 -0
  746. package/skills/skill-creator/workflows/get-guidance.md +134 -0
  747. package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
  748. package/skills/skill-creator/workflows/verify-skill.md +226 -0
  749. package/skills/skill-security-scan/SKILL.md +145 -0
  750. package/skills/skill-security-scan/references/disclaimer.md +21 -0
  751. package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
  752. package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
  753. package/skills/skill-security-scan/references/override-mechanism.md +171 -0
  754. package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
  755. package/skills/skill-security-scan/references/regex-patterns.md +136 -0
  756. package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
  757. package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
  758. package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
  759. package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
  760. package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
  761. package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
  762. package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
  763. package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
  764. package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
  765. package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
  766. package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
  767. package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
  768. package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
  769. package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
  770. package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
  771. package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
  772. package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
  773. package/skills/skill-security-scan/scripts/lib.sh +197 -0
  774. package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
  775. package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
  776. package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
  777. package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
  778. package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
  779. package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
  780. package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
  781. package/skills/social-distribute/SKILL.md +485 -0
  782. package/skills/spec-templates/SKILL.md +274 -0
  783. package/skills/sync/SKILL.md +49 -0
  784. package/skills/test-browser/SKILL.md +464 -0
  785. package/skills/test-browser/references/feature-map.md +161 -0
  786. package/skills/test-fix-loop/SKILL.md +159 -0
  787. package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
  788. package/skills/triage/SKILL.md +402 -0
  789. package/skills/trigger-cron/SKILL.md +136 -0
  790. package/skills/trigger-cron/scripts/trigger.sh +198 -0
  791. package/skills/user-set-role/SKILL.md +147 -0
  792. package/skills/user-set-role/scripts/set-role.sh +218 -0
  793. package/skills/user-story-writer/SKILL.md +77 -0
  794. package/skills/ux-audit/SKILL.md +251 -0
  795. package/skills/ux-audit/references/finding.schema.json +62 -0
  796. package/skills/ux-audit/references/route-list.yaml +95 -0
  797. package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
  798. package/skills/ux-audit/scripts/bot-signin.ts +135 -0
  799. package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
  800. package/skills/work/SKILL.md +1479 -0
  801. package/skills/work/references/end-of-work-resume.md +7 -0
  802. package/skills/work/references/hook-test-main-cwd.md +24 -0
  803. package/skills/work/references/key-principles.md +83 -0
  804. package/skills/work/references/property-testing.md +122 -0
  805. package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
  806. package/skills/work/references/work-agent-teams.md +97 -0
  807. package/skills/work/references/work-lifecycle-parallel.md +147 -0
  808. package/skills/work/references/work-lockfile-bumps.md +97 -0
  809. package/skills/work/references/work-scratch-sandboxes.md +212 -0
  810. package/skills/work/references/work-subagent-fanout.md +61 -0
  811. package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
  812. package/skills/xcode-test/SKILL.md +360 -0
@@ -0,0 +1,525 @@
1
+ #!/usr/bin/env bash
2
+ # compaction-state.sh -- compaction-aware session hooks (#8323, ADR-227).
3
+ #
4
+ # Bound TWICE in hooks.json and dispatching on hook_event_name:
5
+ # PreCompact (matcher manual|auto) -> shape the summary (FR3)
6
+ # SessionStart (matcher startup|resume|clear|compact) -> reset the window, or
7
+ # emit the directive (FR1/FR2)
8
+ #
9
+ # ---------------------------------------------------------------------------
10
+ # MEASURED PAYLOAD CONTRACT -- Claude Code 2.1.273, Linux, 2026-09-18.
11
+ # Captured from a real marker hook bound in a throwaway project and driven by
12
+ # headless `claude -p --continue "/compact"`. Docs are not the source here; this
13
+ # is. NOTHING DETECTS DRIFT IN IT AUTOMATICALLY -- an earlier revision shipped a
14
+ # canary and review deleted it (ADR-227 `## Amendment`), because it watched the
15
+ # transcript while this contract lives in the stdin envelope. Re-measure these
16
+ # rows on a CLI bump; a matcher miss here is silent in both directions (a missing
17
+ # PreCompact under-counts, a missing SessionStart source over-counts).
18
+ #
19
+ # SessionStart:startup keys: cwd hook_event_name session_id source transcript_path
20
+ # ...and transcript_path names a file that DOES NOT YET EXIST.
21
+ # SessionStart:compact keys: cwd hook_event_name model prompt_id session_id
22
+ # source transcript_path -- NO `trigger`.
23
+ # PreCompact keys: custom_instructions cwd hook_event_name prompt_id
24
+ # session_id transcript_path trigger -- NO `source`.
25
+ # PostCompact keys: compact_summary cwd hook_event_name prompt_id
26
+ # session_id transcript_path trigger -- not bound here.
27
+ #
28
+ # source after a compaction is literally "compact".
29
+ # transcript_path is STABLE across a compaction (identical at all three events).
30
+ # --fork-session starts a new session_id and a new transcript file, and fired
31
+ # no SessionStart hook at all.
32
+ #
33
+ # THE TWO FINDINGS THAT DETERMINE THIS FILE'S DESIGN:
34
+ #
35
+ # 1. At SessionStart:compact the just-fired compaction's compact_boundary is
36
+ # NOT on disk. Measured twice: compaction #1 read count=0 (1 present
37
+ # afterwards), compaction #2 read count=1 (2 present). PostCompact, 100 ms
38
+ # later, reads the same lagging value. The boundary's own timestamp
39
+ # PRECEDES the hook fire, so the record exists in memory and is flushed
40
+ # after the hook returns. The transcript therefore cannot answer "how many
41
+ # compactions has this session had" at the moment this hook needs it, and
42
+ # carries no trigger for the current compaction either.
43
+ #
44
+ # 2. PreCompact firing does NOT imply a compaction occurred -- 3 fires
45
+ # produced 2 boundaries, because a /compact with nothing left to compact
46
+ # fires PreCompact and then no SessionStart:compact. So "append one line
47
+ # per PreCompact and count lines" over-counts and moves the
48
+ # recommendation one compaction early, with every fixture green.
49
+ #
50
+ # Hence PENDING-THEN-COMMIT over a per-session ledger under TMPDIR:
51
+ # PreCompact overwrites one `pending` slot with its own trigger.
52
+ # SessionStart:compact commits that slot as one ledger line, then counts.
53
+ # It fires exactly once per REAL compaction.
54
+ # SessionStart:other truncates the ledger and clears pending -- this is
55
+ # what makes TR2's session-window scoping exact rather
56
+ # than approximated, and it is why the matcher is
57
+ # startup|resume|clear|compact and not compact alone.
58
+ #
59
+ # The transcript is NOT read. An earlier revision greped it once for a
60
+ # `prior_boundaries` corroboration marker; review deleted that, because nothing
61
+ # consumed the field and -- since the ledger resets per window while the
62
+ # transcript accumulates across --resume -- the two numbers diverge arbitrarily,
63
+ # so it handed the model a contradiction with no reconciliation rule. The
64
+ # measurements in this header are what the transcript was for; they are
65
+ # recorded, not re-derived at runtime.
66
+ #
67
+ # FAIL-OPEN BY CONTRACT. Every path exits 0. `trap 'exit 0' ERR EXIT`: the EXIT
68
+ # arm is load-bearing because a `set -u` unbound-variable expansion terminates
69
+ # the shell with status 1 WITHOUT firing ERR, and any non-zero exit other than 2
70
+ # makes Claude Code silently drop the whole JSON output.
71
+ #
72
+ # Kill switch: SOLEUR_DISABLE_COMPACTION_HOOKS=1
73
+ # Threshold: SOLEUR_COMPACTION_COUNT_THRESHOLD (default 2)
74
+ # ---------------------------------------------------------------------------
75
+
76
+ set -uo pipefail
77
+ trap 'exit 0' ERR EXIT
78
+
79
+ # Canonical copy of test-helpers.sh's assert_fixture_dir -- P1a requires every
80
+ # tracked copy be byte-equal, and the P1b scanner recognises ONLY this name.
81
+ # Here it guards the ledger window: TMPDIR is caller-supplied, so a relative or
82
+ # synthetic-fs value would put these writes somewhere unintended. The exit 2 is
83
+ # converted to 0 by the EXIT trap above, which is the fail-open contract -- the
84
+ # hook refuses to write and says nothing, rather than writing to a bad path.
85
+ assert_fixture_dir() {
86
+ case "${1-}" in
87
+ "") printf 'FATAL: fixture dir is EMPTY; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
88
+ */../*|*/..) printf 'FATAL: fixture dir %s contains ..; refusing\n' "$1" >&2; exit 2 ;;
89
+ /proc/*|/sys/*|/dev/*) printf 'FATAL: fixture dir %s is a synthetic-fs path; refusing\n' "$1" >&2; exit 2 ;;
90
+ /|//|/.) printf 'FATAL: fixture dir resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
91
+ /*) : ;;
92
+ *) printf 'FATAL: fixture dir %s is RELATIVE; refusing\n' "$1" >&2; exit 2 ;;
93
+ esac
94
+ }
95
+
96
+ # Written before every guard, so it certifies INVOCATION rather than success.
97
+ # The suite floors on this: a harness that asserts without spawning the hook
98
+ # produces none of these lines.
99
+ [[ "${SOLEUR_DISABLE_COMPACTION_HOOKS:-0}" == "1" ]] && exit 0
100
+
101
+ # Coverage trace, BELOW the kill switch. It sat above it, which made the README's
102
+ # "no directive, no summary shaping, nothing written" false -- measured: with the
103
+ # switch set, the hook still appended. `assert_fixture_dir` validates a path
104
+ # STRING (absolute, no `..`, not a synthetic fs); it says nothing about symlinks,
105
+ # ownership, or file-vs-directory, so on its own it authorises an append to any
106
+ # absolute path the process can write. Require an EXISTING regular non-symlink
107
+ # file: a harness creates it deliberately, a stray export cannot conjure one.
108
+ if [[ -n "${SOLEUR_HOOK_TRACE:-}" ]]; then
109
+ assert_fixture_dir "$SOLEUR_HOOK_TRACE"
110
+ if [[ -f "$SOLEUR_HOOK_TRACE" && ! -L "$SOLEUR_HOOK_TRACE" && -O "$SOLEUR_HOOK_TRACE" ]]; then
111
+ printf 'ran\n' >> "$SOLEUR_HOOK_TRACE"
112
+ fi
113
+ fi
114
+
115
+ # Deliberate set -u fault, reachable only through this seam. It is the only way
116
+ # to drive the EXIT arm of the trap above from a test: an ERR-only trap leaves
117
+ # the fail-open contract broken on exactly this fault, and nothing else in the
118
+ # script can be made to raise it on demand.
119
+ if [[ "${SOLEUR_COMPACTION_SELFTEST_UNBOUND:-0}" == "1" ]]; then
120
+ printf '%s' "$__soleur_deliberately_unbound_variable"
121
+ fi
122
+
123
+ # `timeout` is the point, not `cat`. Every other external call here is bounded;
124
+ # the one reading a stream this hook does not own was not, and `trap exit 0`
125
+ # bounds failure, never time. A hook that HANGS at SessionStart is worse than
126
+ # one that crashes: the session never starts, and no marker can explain it
127
+ # because the process is still alive. hooks.json declares no per-binding
128
+ # timeout, so the harness default was the only bound.
129
+ RAW="$(timeout 5 cat 2>/dev/null)" || RAW=""
130
+
131
+ HAVE_JQ=0
132
+ command -v jq >/dev/null 2>&1 && HAVE_JQ=1
133
+
134
+ # Flat top-level scalar read. Every field this hook consumes is a top-level
135
+ # string in the measured envelopes, so the no-jq fallback is adequate rather
136
+ # than a partial JSON parser pretending otherwise.
137
+ jget() { # <key>
138
+ local k="$1"
139
+ if (( HAVE_JQ )); then
140
+ printf '%s' "$RAW" | jq -r --arg k "$k" '.[$k] // empty' 2>/dev/null
141
+ return 0
142
+ fi
143
+ printf '%s' "$RAW" \
144
+ | grep -oE "\"$k\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" 2>/dev/null \
145
+ | head -1 \
146
+ | sed 's/.*:[[:space:]]*"\(.*\)"$/\1/' 2>/dev/null
147
+ }
148
+
149
+ EVENT="$(jget hook_event_name)"
150
+ CWD="$(jget cwd)"
151
+ # Caller-supplied, and the input to the scope walk, `git -C "$ROOT"` and two
152
+ # globs -- so it gets the same gate as the ledger root rather than being trusted
153
+ # because it comes from the CLI. A relative or `..`-bearing value would make the
154
+ # walk test paths against whatever cwd the hook inherited.
155
+ [[ -n "$CWD" ]] || CWD="$PWD"
156
+ case "$CWD" in
157
+ /*) [[ "$CWD" == */../* || "$CWD" == */.. ]] && CWD="$PWD" ;;
158
+ *) CWD="$PWD" ;;
159
+ esac
160
+ # A non-existent cwd makes every test at the leaf false, so the walk climbs to a
161
+ # real Soleur ancestor and reports ITS branch and plan for a directory that is
162
+ # not there. Refuse instead of guessing.
163
+ [[ -d "$CWD" ]] || exit 0
164
+
165
+ # --- TR1 scope guard ---------------------------------------------------------
166
+ # A plugin hook is global. `git rev-parse --is-inside-work-tree` is true in
167
+ # EVERY customer repo, so gating on it would let PreCompact tell a stranger's
168
+ # summarizer to preserve "PR #, plan path, unchecked ACs, operator holds" while
169
+ # summarizing work that has none. The guard is welcome-hook.sh's sentinel -- a
170
+ # plugins/soleur directory -- AND a Soleur plan/spec artifact. Both conjuncts
171
+ # are load-bearing: a plugin developer's checkout has the first without the
172
+ # second.
173
+ # CTO ruling 2 (ADR-227 amendment). This is a RELEVANCE test -- is this project
174
+ # one Soleur manages -- and explicitly NOT an authenticity test; no cheap
175
+ # filesystem predicate can distinguish "my Soleur project" from "a repo I cloned
176
+ # that looks like one", because a clone carries tracked files and Soleur's
177
+ # artifacts are tracked. That limit is named rather than papered over, and the
178
+ # platform baseline already exceeds it: a cloned repo reaches the model at equal
179
+ # authority through CLAUDE.md / AGENTS.md, unconditionally and with no guard.
180
+ #
181
+ # The former first conjunct was a `plugins/soleur` directory, copied from
182
+ # welcome-hook.sh. That tests whether the OPENED REPO is the Soleur monorepo --
183
+ # which no marketplace install ever is, since `claude plugin install` puts the
184
+ # plugin under ~/.claude/plugins/. It excluded the entire installed base, for a
185
+ # feature whose consumers (plan/SKILL.md, work/SKILL.md) run wherever Soleur is
186
+ # installed. Shipping that guard alongside this PR's retirement of the
187
+ # unconditional /clear prose would have REMOVED working advice from a population
188
+ # it could not serve. Installation itself needs no test: this file only exists
189
+ # inside an installed, enabled plugin, so reaching this line IS the proof.
190
+ #
191
+ # ANCHORED at the enclosing repository, matching welcome-hook.sh's one-GIT_ROOT
192
+ # shape: the walk stops at the first directory carrying .git (a FILE in a linked
193
+ # worktree, a directory in a normal clone), so a stranger repo nested under a
194
+ # Soleur checkout -- this repo's own .worktrees/ layout -- does not inherit scope.
195
+ soleur_root() {
196
+ local d="$CWD" i=0
197
+ while [[ -n "$d" && "$d" != "/" && $i -lt 40 ]]; do
198
+ if [[ -d "$d/knowledge-base/project/plans" ]] || [[ -d "$d/knowledge-base/project/specs" ]]; then
199
+ printf '%s' "$d"
200
+ return 0
201
+ fi
202
+ # Repo boundary: climbing past it is what admits the nested-repo case.
203
+ # `-e` is FALSE for a DANGLING symlink, so `-L` is needed too or a broken
204
+ # .git link silently stops being a boundary.
205
+ { [[ -e "$d/.git" ]] || [[ -L "$d/.git" ]]; } && return 1
206
+ d="$(dirname "$d")"
207
+ i=$((i + 1))
208
+ done
209
+ return 1
210
+ }
211
+ ROOT="$(soleur_root)" || exit 0
212
+ [[ -n "$ROOT" ]] || exit 0
213
+
214
+ # --- ledger ------------------------------------------------------------------
215
+ SID_RAW="$(jget session_id)"
216
+ SID="$(printf '%s' "$SID_RAW" | tr -cd 'A-Za-z0-9_-' | cut -c1-64)"
217
+ # Non-injective on two axes: `x/y`, `x.y` and `xy` all map to `xy`, and two ids
218
+ # differing past char 64 map together. Harmless for today's UUIDs, and a
219
+ # collision makes one session count another's compactions -- the over-firing
220
+ # direction. Refuse a lossy id instead of sharing a key.
221
+ [[ "$SID" == "$SID_RAW" ]] || SID=""
222
+ umask 077 # ledger files were 0644; protection rested entirely on the dir mode
223
+ LEDGER_DIR="${TMPDIR:-/tmp}/soleur-compaction"
224
+ assert_fixture_dir "$LEDGER_DIR"
225
+ # FAIL CLOSED on squatting. With TMPDIR unset this is /tmp/soleur-compaction,
226
+ # world-reachable on a multi-user host. `mkdir -p || true` + `chmod || true`
227
+ # degrades SILENTLY if another user pre-created the directory -- and a
228
+ # pre-seeded <sid>.pending then flows through COMMITTED -> TRIGGER -> the
229
+ # directive, which the model reads at elevated authority. Refuse instead:
230
+ # the EXIT trap turns this into a silent exit 0, which is the fail-open
231
+ # contract for the FEATURE and fail-closed for the WRITE.
232
+ # Two calls, not `mkdir -m 0700 -p`: with -p the mode applies only to the
233
+ # DEEPEST directory (shellcheck SC2174), so any parent this creates would take
234
+ # the umask. The leaf is created WITHOUT -p so it is either made 0700 here or
235
+ # already exists, and the ownership check below is what actually decides.
236
+ mkdir -p "${LEDGER_DIR%/*}" 2>/dev/null || true
237
+ mkdir -m 0700 "$LEDGER_DIR" 2>/dev/null || true
238
+ # `-L` FIRST: `-d` and `-O` both stat rather than lstat, so a symlink planted at
239
+ # this predictable path satisfied both -- measured, the hook wrote through it into
240
+ # a victim-owned directory and chmod 700'd the TARGET.
241
+ if [[ -L "$LEDGER_DIR" ]] || [[ ! -d "$LEDGER_DIR" ]] || [[ ! -O "$LEDGER_DIR" ]]; then
242
+ LEDGER_DIR_UNUSABLE=1
243
+ else
244
+ LEDGER_DIR_UNUSABLE=0
245
+ chmod 700 "$LEDGER_DIR" 2>/dev/null || true
246
+ fi
247
+ LEDGER="$LEDGER_DIR/${SID}.ledger"
248
+ PENDING="$LEDGER_DIR/${SID}.pending"
249
+
250
+ # Bounded growth. Entries are disposable by construction -- a lost ledger costs
251
+ # one directive, never correctness.
252
+ find "$LEDGER_DIR" -maxdepth 1 -type f \( -name '*.ledger' -o -name '*.pending' \) \
253
+ -mmin +10080 -delete 2>/dev/null || true
254
+
255
+ # Every value interpolated into `additionalContext` is read by the model at
256
+ # ELEVATED AUTHORITY, so each one is an injection surface. `trigger` and
257
+ # `threshold` are closed-set / digits-only; these are free text from sources the
258
+ # hook does not own -- a git ref name is chosen by whoever created the branch, and
259
+ # a GIT FILENAME MAY CONTAIN NEWLINES, which `jq --arg` faithfully preserves as
260
+ # real newlines inside the string the model reads. Reduce to a conservative
261
+ # display charset and cap the length; an empty result becomes `unknown`.
262
+ sanitize_display() { # <value> <fallback>
263
+ local v
264
+ v="$(printf '%s' "${1-}" | tr -cd 'A-Za-z0-9._/+@-' | cut -c1-200)"
265
+ printf '%s' "${v:-${2-unknown}}"
266
+ }
267
+
268
+ # --- PreCompact (FR3) --------------------------------------------------------
269
+ if [[ "$EVENT" == "PreCompact" ]]; then
270
+ # AP-020: check a contracted field's SHAPE rather than assuming it. `trigger`
271
+ # is model-adjacent input that (a) gates the recommendation and (b) is
272
+ # interpolated into text the model reads at elevated authority. Unvalidated, a
273
+ # multi-line value inflates the ledger's line count -- which IS count_total --
274
+ # and forces recommend=true. Closed set, measured at CLI 2.1.273.
275
+ TRIGGER="$(jget trigger)"
276
+ case "$TRIGGER" in
277
+ manual|auto) : ;;
278
+ *) TRIGGER="unknown" ;;
279
+ esac
280
+ # Summary shaping does not need the ledger, so an unusable root suppresses the
281
+ # WRITE and not the FR3 prose.
282
+ if [[ -n "$SID" ]] && (( ! LEDGER_DIR_UNUSABLE )); then
283
+ # OVERWRITE, never append: PreCompact fires on no-op compactions, and only
284
+ # SessionStart:compact proves one actually happened.
285
+ assert_fixture_dir "$LEDGER_DIR"
286
+ printf '%s\n' "$TRIGGER" > "$PENDING" 2>/dev/null || true
287
+ fi
288
+ # Plain text, never JSON: this stream is read by the summarizer, and never
289
+ # exits 2 -- blocking a compaction trades a recoverable context loss for a
290
+ # dead session (NG3).
291
+ cat <<'PRECOMPACT'
292
+ When summarizing, preserve these verbatim -- a resume depends on them:
293
+ - the git branch and the worktree directory currently in use
294
+ - the PR # and the issue # under work, and the plan path
295
+ - the active skill and phase, and every unchecked acceptance criteria item
296
+ - anything recorded under Operator Holds
297
+ - every file path mentioned, spelled exactly as written
298
+ Keep the paths themselves. Summarize what was done to them; do not reproduce
299
+ what they contain.
300
+ PRECOMPACT
301
+ exit 0
302
+ fi
303
+
304
+ [[ "$EVENT" == "SessionStart" ]] || exit 0
305
+
306
+ # Reached here with an unusable ledger root: PreCompact already returned above,
307
+ # so this is the SessionStart arm and it owes the model a reason. Emitting
308
+ # nothing made a permanent per-host disable indistinguishable from "this session
309
+ # has not compacted" -- and the plan's own Observability block promises every
310
+ # failure path emits a named marker.
311
+
312
+ SOURCE="$(jget source)"
313
+
314
+ # --- envelope emission -------------------------------------------------------
315
+ # stdout carries the JSON envelope and NOTHING else; a stray byte invalidates
316
+ # the whole output. Diagnostics go to stderr.
317
+ emit() { # <additionalContext>
318
+ local ctx="${1:0:8000}"
319
+ if (( HAVE_JQ )); then
320
+ jq -nc --arg c "$ctx" \
321
+ '{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:$c}}'
322
+ else
323
+ # The envelope cannot be built with jq in this state, so it is emitted
324
+ # literally -- no interpolation, hence nothing to escape.
325
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"SOLEUR_COMPACTION_SKIPPED reason=jq-unavailable -- compaction state could not be reported. Context was just compacted: re-read the plan and spec before editing (hr-always-read-a-file-before-editing-it)."}}'
326
+ fi
327
+ }
328
+
329
+
330
+ # --- SessionStart, window reset ----------------------------------------------
331
+ # startup / resume / clear all open a new window. Guarding only `resume` would
332
+ # leave two of the three unscoped, which is how a long session pins
333
+ # recommend=true forever (TR2).
334
+ case "$SOURCE" in
335
+ startup|resume|clear) SOURCE_CLASS=reset ;;
336
+ compact) SOURCE_CLASS=compact ;;
337
+ *) SOURCE_CLASS=unknown ;;
338
+ esac
339
+
340
+ if [[ "$SOURCE_CLASS" != "compact" ]]; then
341
+ # `unknown` must not RESET -- the matcher admits any source containing one of
342
+ # the four words, and a future `precompact` would otherwise truncate the
343
+ # ledger at the event it counts. But it must not be SILENT either.
344
+ #
345
+ # This is the one arm whose failure is permanent and total. `compact` is the
346
+ # only source the gate counts, and the Phase 0 addendum measured SessionStart
347
+ # only after MANUAL compactions (`claude -p --continue "/compact"`); that an
348
+ # AUTOMATIC one also arrives with the literal source `compact` is marked
349
+ # Inferential there, not measured. If it ever arrives as anything else
350
+ # (`auto_compact`, say), every install loses the feature forever -- and a bare
351
+ # `exit 0` makes that byte-identical to "this session has not compacted".
352
+ #
353
+ # stderr is NOT the channel: this hook exits 0, and stderr on an exit-0 hook is
354
+ # discarded. That is precisely the defect the design-validity pass deleted the
355
+ # drift canary over; reintroducing it here would repeat it.
356
+ if [[ "$SOURCE_CLASS" != "reset" ]]; then
357
+ emit "SOLEUR_COMPACTION_SKIPPED reason=unknown-source source=$(sanitize_display "$SOURCE" empty) -- this SessionStart source is outside the measured set (startup|resume|clear|compact), so no compaction state was read or written. If this appears after an automatic compaction, the recommendation gate is dark on this harness and the matcher needs the observed spelling."
358
+ exit 0
359
+ fi
360
+ # The `LEDGER_DIR_UNUSABLE` conjunct is the half scenario 23 was missing. Its
361
+ # stated thesis is "the WRITE fails closed", and PreCompact's write does --
362
+ # but this DELETE did not, so a symlinked ledger root made one SessionStart
363
+ # unlink `<sid>.ledger` and `<sid>.pending` inside the link target. The names
364
+ # are session-id-derived so it is not an arbitrary-file delete, but "refuses
365
+ # to touch a root it has already judged hostile" is the invariant, and it was
366
+ # false on exactly one of the two paths.
367
+ if [[ -n "$SID" ]] && (( ! LEDGER_DIR_UNUSABLE )); then
368
+ assert_fixture_dir "$LEDGER_DIR"
369
+ rm -f "$LEDGER" "$PENDING" 2>/dev/null || true
370
+ if [[ -s "$LEDGER" ]]; then
371
+ # A surviving ledger carries the PREVIOUS window's rows into this one and
372
+ # is the only state that over-counts. Never silent -- and not via stderr,
373
+ # which an exit-0 hook discards.
374
+ emit "SOLEUR_COMPACTION_SKIPPED reason=window-reset-failed path=$(sanitize_display "$LEDGER" unknown) -- the previous window's compaction rows survived this session reset, so any recommendation in this window may over-count."
375
+ fi
376
+ fi
377
+ exit 0
378
+ fi
379
+
380
+ if (( ! HAVE_JQ )); then
381
+ emit ""
382
+ exit 0
383
+ fi
384
+
385
+ if (( LEDGER_DIR_UNUSABLE )); then
386
+ emit "SOLEUR_COMPACTION_SKIPPED reason=ledger-dir-unusable -- the compaction ledger directory is missing, foreign-owned or a symlink, so no compaction state could be recorded. Context was just compacted: re-read the plan and spec before editing (hr-always-read-a-file-before-editing-it)."
387
+ exit 0
388
+ fi
389
+
390
+ if [[ -z "$SID" ]]; then
391
+ emit "SOLEUR_COMPACTION_SKIPPED reason=no-session-id"
392
+ exit 0
393
+ fi
394
+
395
+ # Commit the pending slot. Reached exactly once per real compaction.
396
+ COMMITTED=""
397
+ if [[ -f "$PENDING" ]]; then
398
+ COMMITTED="$(head -1 "$PENDING" 2>/dev/null || true)"
399
+ # Re-assert the closed set BEFORE the append. The pending file is same-uid
400
+ # writable and its value reaches count_total and the "compaction N" sentence
401
+ # even where it cannot reach `recommend`.
402
+ case "$COMMITTED" in
403
+ manual|auto) : ;;
404
+ *) COMMITTED="unknown" ;;
405
+ esac
406
+ assert_fixture_dir "$LEDGER_DIR"
407
+ printf '%s\n' "$COMMITTED" >> "$LEDGER" 2>/dev/null || true
408
+ rm -f "$PENDING" 2>/dev/null || true
409
+ fi
410
+
411
+ COUNT_TOTAL=0
412
+ COUNT_AUTO=0
413
+ if [[ -r "$LEDGER" ]]; then
414
+ COUNT_TOTAL="$(LC_ALL=C grep -acxE 'manual|auto|unknown' "$LEDGER" 2>/dev/null || true)"
415
+ COUNT_AUTO="$(LC_ALL=C grep -acx 'auto' "$LEDGER" 2>/dev/null || true)"
416
+ fi
417
+ COUNT_TOTAL="${COUNT_TOTAL:-0}"
418
+ COUNT_AUTO="${COUNT_AUTO:-0}"
419
+
420
+ if [[ "$COUNT_TOTAL" -eq 0 ]]; then
421
+ # No PreCompact was seen for this window. Honest silence beats a guess: the
422
+ # transcript cannot supply the answer (finding 1 above).
423
+ emit "SOLEUR_COMPACTION_SKIPPED reason=no-ledger-entry -- context was compacted but this session's compaction ledger is empty. Re-read the plan and spec before editing (hr-always-read-a-file-before-editing-it)."
424
+ exit 0
425
+ fi
426
+
427
+ # `tail -1 "$LEDGER"` as the fallback reinstated, on the missing-pending path,
428
+ # exactly what alternative (a) is rejected for: it reports the PREVIOUS
429
+ # compaction's trigger for the current event. Measured -- a third compaction with
430
+ # no pending slot inherited `trigger=auto` and was not counted. Unknown is the
431
+ # honest answer, and the closed-set rule already stops it recommending.
432
+ TRIGGER="$COMMITTED"
433
+ case "$TRIGGER" in
434
+ manual|auto) : ;;
435
+ *) TRIGGER="unknown" ;;
436
+ esac
437
+
438
+ CLI="${SOLEUR_COMPACTION_CLI_VERSION:-}"
439
+ if [[ -z "$CLI" ]] && command -v claude >/dev/null 2>&1; then
440
+ # `command -v` first: this runs with the cwd of an arbitrary repo, so resolving
441
+ # `claude` by bare name is a PATH question, not a given.
442
+ CLI="$(timeout 5 claude --version 2>/dev/null | head -1 | awk '{print $1}' || true)"
443
+ fi
444
+ CLI="$(sanitize_display "$CLI" unknown)"
445
+
446
+ # `symbolic-ref --short -q` is this repo's precedent for exactly this
447
+ # (.claude/hooks/ship-unpushed-commits-gate.sh): it exits non-zero on a detached
448
+ # HEAD, where `rev-parse --abbrev-ref` returns the literal string `HEAD` and
449
+ # would have the directive assert `Branch: HEAD.` to the model. CI checks out a
450
+ # detached HEAD on pull_request, so that is the common case, not an edge one.
451
+ BRANCH="$(timeout 5 git -C "$ROOT" symbolic-ref --short -q HEAD 2>/dev/null || true)"
452
+ BRANCH="$(sanitize_display "$BRANCH" unknown)"
453
+
454
+ PLAN=""
455
+ if [[ "$BRANCH" != "unknown" ]]; then
456
+ for p in "$ROOT/knowledge-base/project/plans/"*"-${BRANCH}-plan.md"; do
457
+ [[ -e "$p" ]] && PLAN="$(sanitize_display "knowledge-base/project/plans/$(basename "$p")" "")"
458
+ done
459
+ fi
460
+ SPEC=""
461
+ # Same `unknown` gate as PLAN above. Without it a detached HEAD -- which this
462
+ # file's own comment calls the common case, since CI checks one out for
463
+ # `pull_request` -- makes the directive assert `specs/unknown/` to the model the
464
+ # moment such a directory exists. PLAN was gated and SPEC was not; one sentinel,
465
+ # two consumers, one of them guarded.
466
+ if [[ "$BRANCH" != "unknown" ]]; then
467
+ [[ -d "$ROOT/knowledge-base/project/specs/$BRANCH" ]] \
468
+ && SPEC="$(sanitize_display "knowledge-base/project/specs/$BRANCH/" "")"
469
+ fi
470
+
471
+ THRESHOLD="${SOLEUR_COMPACTION_COUNT_THRESHOLD:-2}"
472
+ case "$THRESHOLD" in
473
+ ''|*[!0-9]*) THRESHOLD=2 ;; # a non-numeric seam makes (( )) evaluate false
474
+ esac # silently, skipping the branch rather than failing
475
+ THRESHOLD=$((10#$THRESHOLD)) # `010` passes the digit filter and (( )) reads octal
476
+ # The CTO ruling requires a floor of at least 1: with the trigger operand gone,
477
+ # THRESHOLD=0 makes the gate true on a ledger holding ZERO auto lines. Floored to
478
+ # the DEFAULT (2) rather than to 1 -- a deviation, recorded in ADR-227. `0` is
479
+ # what an operator types meaning "off", and flooring to 1 would hand that person
480
+ # the MOST aggressive setting, which is the over-firing harm delivered to someone
481
+ # trying to disable the feature. The off switch is
482
+ # SOLEUR_DISABLE_COMPACTION_HOOKS. Written as if/fi, not `(( )) && x`: measured on
483
+ # bash 5.3.15 the && form does not abort under `trap ERR EXIT`, but if/fi does not
484
+ # depend on that exemption.
485
+ if (( THRESHOLD < 1 )); then THRESHOLD=2; fi
486
+
487
+ # CTO ruling 1 (ADR-227 amendment): the gate is COUNT_AUTO alone. The current
488
+ # event's trigger was a second operand that could only ever REVOKE -- COUNT_AUTO
489
+ # rises only on a SessionStart:compact that commits an `auto` line, so the first
490
+ # emission crossing the threshold always had trigger=auto and fired either way.
491
+ # Its sole behavioural delta was retracting a recommendation already issued,
492
+ # which overwrites a correct recommend=true with an affirmative recommend=false
493
+ # at the moment the model can least reconstruct it. The ledger is append-only
494
+ # within a window, so RECOMMEND is already monotonic without a sticky bit.
495
+ RECOMMEND=false
496
+ if (( COUNT_AUTO >= THRESHOLD )); then
497
+ RECOMMEND=true
498
+ fi
499
+
500
+ # Pointers, never content. Nothing read out of the transcript is echoed: the
501
+ # only transcript-derived value here is an integer (NG5, and the
502
+ # elevated-authority framing hook-delivered text carries).
503
+ CTX="SOLEUR_COMPACTION_DIRECTIVE count_auto=${COUNT_AUTO} count_total=${COUNT_TOTAL} trigger=${TRIGGER} recommend=${RECOMMEND} threshold=${THRESHOLD} cli=${CLI} branch=${BRANCH}
504
+
505
+ Context was just compacted (compaction ${COUNT_TOTAL} of this session, trigger=${TRIGGER}).
506
+ The summary above is a paraphrase written by another model. Before editing any
507
+ file, re-read the artifacts it names -- hr-always-read-a-file-before-editing-it.
508
+ Branch: ${BRANCH}."
509
+ [[ -n "$PLAN" ]] && CTX="${CTX}
510
+ Plan: ${PLAN}"
511
+ [[ -n "$SPEC" ]] && CTX="${CTX}
512
+ Spec and tasks: ${SPEC}"
513
+
514
+ if [[ "$RECOMMEND" == "true" ]]; then
515
+ CTX="${CTX}
516
+
517
+ ${COUNT_AUTO} automatic compactions have now occurred in this session window.
518
+ At the next phase boundary -- not mid-pipeline -- emit the resume prompt per
519
+ wg-end-of-work-emit-resume-prompt and recommend continuing in a fresh session.
520
+ Inside /soleur:one-shot, never pause for this: carry the recommendation into the
521
+ final resume prompt instead."
522
+ fi
523
+
524
+ emit "$CTX"
525
+ exit 0