@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,92 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Harness-parity census over the plugin doc population (ADR-226, #8299).
4
+ *
5
+ * Usage:
6
+ * bun plugins/soleur/scripts/harness-parity-census.ts --report # print every non-canonical site; exit 1 if any
7
+ * bun plugins/soleur/scripts/harness-parity-census.ts --fix # rewrite the mechanical shapes in place (idempotent)
8
+ *
9
+ * The gate is `plugins/soleur/test/harness-parity-tree.test.ts`; this CLI is the author's
10
+ * inner loop and the remediation tool. `--fix` inverts only `/soleur:x`, `$soleur:x`,
11
+ * `@agent-soleur:x` and grok `/x` for a known skill; bare agent leaves, `@agent-<leaf>`
12
+ * mentions and grok stems in prose are hand edits (the sentence around them changes).
13
+ *
14
+ * `--fix` REWRITES TRACKED FILES IN PLACE and is the remedy the gate's own failure message
15
+ * prescribes, so it refuses to run against a dirty working tree unless `--force` is passed.
16
+ * That is not ceremony: a grok slash and a root-relative path are lexically identical after a
17
+ * boundary character (`run /plan` vs `POST /invoice`), so a rewrite CAN consume a real byte,
18
+ * and the result then classifies CANONICAL — meaning the census reports clean and the loss is
19
+ * invisible to the gate. Requiring a clean tree makes every rewrite reviewable with `git diff`
20
+ * and revertible with `git checkout`, which is the only guard that covers the whole class
21
+ * rather than one spelling of it.
22
+ */
23
+
24
+ import { execFileSync } from "child_process";
25
+ import { writeFileSync } from "fs";
26
+ import { resolve } from "path";
27
+ import { REPO_ROOT, census, classifyDoc, fixDoc, formatReport, readIndex, readPopulation } from "../lib/harness-parity";
28
+
29
+ const args = new Set(process.argv.slice(2));
30
+ const mode = args.has("--fix") ? "fix" : args.has("--report") ? "report" : undefined;
31
+ if (mode === undefined) {
32
+ console.error("usage: harness-parity-census.ts --report | --fix [--force]");
33
+ process.exit(2);
34
+ }
35
+
36
+ if (mode === "fix" && !args.has("--force")) {
37
+ const dirty = execFileSync("git", ["status", "--porcelain", "--", "plugins/soleur"], {
38
+ cwd: REPO_ROOT,
39
+ encoding: "utf-8",
40
+ }).trim();
41
+ if (dirty.length > 0) {
42
+ console.error(
43
+ [
44
+ "harness-parity --fix: refusing to rewrite a dirty tree — it edits tracked files in place,",
45
+ "and an uncommitted change would be indistinguishable from its own rewrites in `git diff`.",
46
+ "Commit or discard the changes below, then re-run; pass --force to override.",
47
+ "",
48
+ dirty,
49
+ ].join("\n"),
50
+ );
51
+ process.exit(2);
52
+ }
53
+ }
54
+
55
+ const index = readIndex();
56
+ const docs = readPopulation();
57
+
58
+ if (mode === "fix") {
59
+ let changed = 0;
60
+ let skipped = 0;
61
+ for (const doc of docs) {
62
+ // A malformed marker leaves the region state unreliable, and `fixDoc` mirrors that state to
63
+ // decide what is exempt — so rewriting such a doc can edit inside a region the author meant
64
+ // to protect. Report it and leave it; the marker is RED in the gate either way.
65
+ const pre = classifyDoc(doc.text, index, doc.regionPolicy, doc.path);
66
+ if (pre.errors.length > 0) {
67
+ console.log(`skipped ${doc.path} — malformed marker, fix the marker first:`);
68
+ for (const e of pre.errors) console.log(` ${e}`);
69
+ skipped += 1;
70
+ continue;
71
+ }
72
+ const fixed = fixDoc(doc.text, index, doc.regionPolicy);
73
+ if (fixed !== doc.text) {
74
+ writeFileSync(resolve(REPO_ROOT, doc.path), fixed);
75
+ changed += 1;
76
+ console.log(`fixed ${doc.path}`);
77
+ }
78
+ }
79
+ const after = census(readPopulation(), index);
80
+ console.log(`harness-parity --fix: ${changed} docs rewritten, ${skipped} skipped for malformed markers; ${after.noncanonical.length} non-canonical sites remain (hand edits)`);
81
+ process.exit(0);
82
+ }
83
+
84
+ const result = census(docs, index);
85
+ console.log(formatReport(result));
86
+ if (result.noncanonical.length > 0 || result.errors.length > 0) {
87
+ console.log(
88
+ `\nRED: ${result.noncanonical.length} non-canonical sites, ${result.errors.length} marker errors. ` +
89
+ "Run `bun plugins/soleur/scripts/harness-parity-census.ts --fix` for the mechanical shapes (it requires a clean tree, so its rewrites stay reviewable with `git diff`); the rest are hand edits.",
90
+ );
91
+ process.exit(1);
92
+ }
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env bun
2
+ // Discoverability probe for #8296 PR-1: does the SOURCE declare the Inngest wrong-volume
3
+ // Better Stack alert ARMED? Resolves `paused = !var.inngest_luks_cutover_complete` against the
4
+ // variable's declared default through the same code path the drift reconciler uses
5
+ // (../lib/heartbeat-live-reconcile.ts via discoverLogsAlertsFromInfra), so a regression in either
6
+ // the declaration or the resolver prints EXEMPT here before it silences the twice-daily report.
7
+ //
8
+ // Credential-free and sub-second: it reads apps/web-platform/infra/*.tf only. It says nothing
9
+ // about the LIVE alert (a Doppler TF_VAR override, or a vendor-side pause) — that half is the
10
+ // reconciler's job on scheduled-terraform-drift.yml, and PR-2's followthrough probe covers the
11
+ // device the store is actually on.
12
+ //
13
+ // This is a standalone file, not a `bun -e` one-liner, because preflight Check 10 (ADR-175)
14
+ // runs the plan's discoverability command inside a sandbox behind a shell-active-token reject:
15
+ // an arrow function's `=>` and a statement `;` both trip it, by design.
16
+ //
17
+ // Exit 0 + "ARMED" when the declaration resolves to paused=false; exit 1 + "EXEMPT" otherwise
18
+ // (unresolvable variable, non-boolean default, or the alert missing from the root entirely).
19
+ import { discoverLogsAlertsFromInfra } from "./reconcile-live-heartbeats.ts";
20
+
21
+ // argv[2] is a TEST seam only (a synthesized root with the default flipped); the plan's
22
+ // discoverability command passes nothing and reads the real root.
23
+ const INFRA_DIR = process.argv[2] ?? "apps/web-platform/infra";
24
+ const RESOURCE = "inngest_luks_wrong_volume";
25
+
26
+ const alert = discoverLogsAlertsFromInfra(INFRA_DIR).find((a) => a.resourceName === RESOURCE);
27
+ const armed = alert?.pausedResolvesFalse === true;
28
+ console.log(armed ? "ARMED" : "EXEMPT");
29
+ process.exit(armed ? 0 : 1);
@@ -0,0 +1,509 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Install the generated OpenCode front door into an OpenCode config directory.
4
+ *
5
+ * bun plugins/soleur/scripts/install-opencode-adapter.ts # ~/.config/opencode
6
+ * bun plugins/soleur/scripts/install-opencode-adapter.ts --target DIR # e.g. a project .opencode
7
+ * bun plugins/soleur/scripts/install-opencode-adapter.ts --check --target DIR
8
+ *
9
+ * Why this exists: the generated tree commits its paths as `__SOLEUR_PLUGIN_ROOT__` rather
10
+ * than absolute ones, because the tree is shared across machines and an absolute path would
11
+ * make `sync-opencode-adapter.ts --check` machine-dependent. OpenCode's `skills` and
12
+ * `instructions` keys take plain paths with no env expansion, and the config schema has no
13
+ * `import` key (measurement §7.1), so something must resolve the token once, on the
14
+ * operator's machine. That is this script.
15
+ *
16
+ * Shapes here are each forced by a measurement:
17
+ *
18
+ * - `agents/` and `commands/` are copied straight into the config dir, because those are
19
+ * the roots OpenCode discovers (§3.0, §4.0). Skills are **not** copied on a checkout
20
+ * install — they register from the canonical tree through the `skills` key (§2.0), so the
21
+ * config points at the checkout and a second skill tree that could drift is never created.
22
+ * - On an npm install (`--vendor-payload`), the canonical payload is mirrored into
23
+ * `<configdir>/soleur/` so every installed reference points at a durable directory that
24
+ * survives `npx` / `bunx` cache eviction.
25
+ * - The config fragment is merged rather than written, so an operator's existing
26
+ * `skills` / `instructions` entries and every other key survive — for a config this script
27
+ * can READ. A config it cannot parse (JSONC comments, a syntax error, a torn write) is
28
+ * **refused**, not replaced: silently substituting `{}` would discard every key the operator
29
+ * ever set, and report success. `--force` replaces it after writing a `.bak-<ts>` beside it.
30
+ * - Writes are temp-file + rename, so an interrupted install cannot leave a half-written
31
+ * `opencode.json` whose next read takes the unparseable path.
32
+ * - The hook module (`opencode/plugin.ts`, source rather than a generated stub) is copied
33
+ * into `<configdir>/plugins/`, OpenCode's plugin discovery directory (measurement §6.6),
34
+ * with the plugin-root token resolved so the installed copy still reaches the guard scripts.
35
+ *
36
+ * `--check` writes nothing: it compares the target against `expectedInstalled` and exits 1
37
+ * on a difference.
38
+ */
39
+
40
+ import {
41
+ chmodSync,
42
+ copyFileSync,
43
+ existsSync,
44
+ mkdirSync,
45
+ readFileSync,
46
+ readdirSync,
47
+ renameSync,
48
+ rmSync,
49
+ statSync,
50
+ writeFileSync,
51
+ } from "fs";
52
+ import { dirname, join, relative, resolve } from "path";
53
+ import {
54
+ ADAPTER_DIR,
55
+ ADAPTER_SOURCE_FILES,
56
+ PLUGIN_ROOT_TOKEN,
57
+ configFragmentValues,
58
+ expectedOpenCodeAdapter,
59
+ } from "./sync-opencode-adapter";
60
+
61
+ const PLUGIN_ROOT = resolve(dirname(import.meta.filename), "..");
62
+
63
+ /**
64
+ * Where a vendored payload lives, target-relative.
65
+ *
66
+ * `<configdir>/soleur/` is already Soleur's exclusive namespace in a config dir (the installed
67
+ * `INSTRUCTIONS.md` lives there and `installedExtras` treats everything under it as ours by
68
+ * name), so the payload joins it rather than opening a second namespace. One directory is also
69
+ * one thing to remove on uninstall.
70
+ */
71
+ export const VENDOR_DIR = "soleur";
72
+
73
+ /**
74
+ * The plugin-root subtrees a vendored payload carries.
75
+ *
76
+ * Each entry is load-bearing: `skills` is what the `skills` key registers, `agents`/`commands`
77
+ * are what the generated stubs name, `hooks` is what the installed hook module spawns its guards
78
+ * from, `scripts` is what the canonical prose calls as `<root>/scripts/<name>.sh` (404 call
79
+ * sites), `lib` is what those scripts import, `opencode` is the generated tree the installer
80
+ * itself reads, and `.claude-plugin` is the identity marker `plugin-version.sh` and
81
+ * `resolve-regenerable-conflicts.sh` resolve the root by.
82
+ */
83
+ export const PAYLOAD_DIRS = [
84
+ "skills",
85
+ "agents",
86
+ "commands",
87
+ "hooks",
88
+ "scripts",
89
+ "lib",
90
+ ADAPTER_DIR,
91
+ ".claude-plugin",
92
+ ] as const;
93
+
94
+ /**
95
+ * Marker that tells a plugin root apart as a **vendored payload** rather than a checkout.
96
+ *
97
+ * It is what lets the copy's own `scripts/install-opencode-adapter.ts --check` pass: run from
98
+ * `<configdir>/soleur/`, the payload is inside the target, so the extras sweep would otherwise
99
+ * report every one of the ~800 payload files as EXTRA and exit 1 — a correct install graded as
100
+ * broken.
101
+ */
102
+ export const VENDOR_MARKER = ".soleur-vendored.json";
103
+
104
+ /** True when `root` is a payload the installer vendored, not a checkout. */
105
+ export function isVendoredRoot(root: string): boolean {
106
+ return existsSync(join(root, VENDOR_MARKER));
107
+ }
108
+
109
+ function vendorMarkerContent(): string {
110
+ return `${JSON.stringify({ format: 1, kind: "soleur-opencode-payload", owns: [...PAYLOAD_DIRS] }, null, 2)}\n`;
111
+ }
112
+
113
+ export interface PayloadEntry {
114
+ content: string;
115
+ executable: boolean;
116
+ }
117
+
118
+ /**
119
+ * Every regular file under `<root>/<dir>`, keyed `<dir>/<relative path>`, in sorted order.
120
+ * Symlinks are refused so a stray symlink in the source tree can never be dereferenced into
121
+ * the published npm tarball or vendored config directory.
122
+ */
123
+ export function walkPayloadFiles(root: string, dir: string): Array<[string, PayloadEntry]> {
124
+ const found: Array<[string, PayloadEntry]> = [];
125
+ const visit = (relativeDir: string): void => {
126
+ let entries;
127
+ try {
128
+ entries = readdirSync(join(root, relativeDir), { withFileTypes: true });
129
+ } catch {
130
+ return;
131
+ }
132
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
133
+ const path = `${currentPath(relativeDir, entry.name)}`;
134
+ if (entry.isSymbolicLink()) {
135
+ throw new Error(`Refusing symbolic link in payload tree: ${join(root, path)}`);
136
+ }
137
+ if (entry.isDirectory()) {
138
+ visit(path);
139
+ continue;
140
+ }
141
+ if (!entry.isFile()) continue;
142
+ const full = join(root, path);
143
+ const executable = (statSync(full).mode & 0o111) !== 0;
144
+ found.push([path, { content: readFileSync(full, "utf-8"), executable }]);
145
+ }
146
+ };
147
+ visit(dir);
148
+ return found;
149
+ }
150
+
151
+ function currentPath(dir: string, name: string): string {
152
+ return `${dir}/${name}`;
153
+ }
154
+
155
+ /** Full payload map for `root`, shared with `sync-npm-package.ts`. */
156
+ export function expectedPayloadEntries(root: string): Map<string, PayloadEntry> {
157
+ const expected = new Map<string, PayloadEntry>();
158
+ for (const dir of PAYLOAD_DIRS) {
159
+ for (const [path, entry] of walkPayloadFiles(root, dir)) {
160
+ expected.set(path, entry);
161
+ }
162
+ }
163
+ return expected;
164
+ }
165
+
166
+ export interface InstallOptions {
167
+ force?: boolean;
168
+ /**
169
+ * Mirror the canonical payload into `<target>/soleur/` and point every installed file at that
170
+ * copy instead of at `pluginRoot`. Used by the npm distribution, which has no checkout.
171
+ */
172
+ vendorPayload?: boolean;
173
+ }
174
+
175
+ function resolveEffectiveRoot(targetDir: string, pluginRoot: string, options: InstallOptions): string {
176
+ return options.vendorPayload === true ? join(targetDir, VENDOR_DIR) : pluginRoot;
177
+ }
178
+
179
+ /** `__SOLEUR_PLUGIN_ROOT__` → the resolved root. The only substitution in the whole install. */
180
+ function resolveToken(content: string, pluginRoot: string): string {
181
+ return content.split(PLUGIN_ROOT_TOKEN).join(pluginRoot);
182
+ }
183
+
184
+ /** Union a fragment's path arrays into an existing config, preserving every other key. */
185
+ export function mergeFragment(
186
+ existing: Record<string, unknown>,
187
+ fragment: { skills: string[]; instructions: string[] },
188
+ ): Record<string, unknown> {
189
+ const merged: Record<string, unknown> = { ...existing };
190
+ for (const key of ["skills", "instructions"] as const) {
191
+ const present = Array.isArray(existing[key]) ? (existing[key] as unknown[]) : [];
192
+ merged[key] = [...present, ...fragment[key]].filter((value, index, all) => all.indexOf(value) === index);
193
+ }
194
+ return merged;
195
+ }
196
+
197
+ export class UnparseableConfigError extends Error {
198
+ constructor(
199
+ readonly path: string,
200
+ readonly detail: string,
201
+ ) {
202
+ super(
203
+ `${path} exists but is not a JSON object (${detail}). Refusing to overwrite it — that would replace every key you set with the Soleur fragment alone. Fix the file, move it aside, or re-run with --force (which writes a timestamped backup first).`,
204
+ );
205
+ this.name = "UnparseableConfigError";
206
+ }
207
+ }
208
+
209
+ export function expectedInstalled(
210
+ targetDir: string,
211
+ pluginRoot = PLUGIN_ROOT,
212
+ config?: Record<string, unknown>,
213
+ options: InstallOptions = {},
214
+ ): Map<string, string> {
215
+ const expected = new Map<string, string>();
216
+ const effectiveRoot = resolveEffectiveRoot(targetDir, pluginRoot, options);
217
+ for (const [path, content] of expectedOpenCodeAdapter(pluginRoot)) {
218
+ if (path === `${ADAPTER_DIR}/opencode.json`) continue;
219
+ const installed =
220
+ path === `${ADAPTER_DIR}/INSTRUCTIONS.md` ? `soleur/${relative(ADAPTER_DIR, path)}` : relative(ADAPTER_DIR, path);
221
+ expected.set(installed, resolveToken(content, effectiveRoot));
222
+ }
223
+ for (const source of ADAPTER_SOURCE_FILES) {
224
+ if (!source.startsWith(`${ADAPTER_DIR}/`)) continue;
225
+ const installed = `plugins/soleur-${source.slice(ADAPTER_DIR.length + 1)}`;
226
+ expected.set(installed, resolveToken(readFileSync(join(pluginRoot, source), "utf-8"), effectiveRoot));
227
+ }
228
+ for (const [path, entry] of payloadExpected(targetDir, pluginRoot, effectiveRoot, options)) {
229
+ expected.set(path, entry.content);
230
+ }
231
+ const fragment = configFragmentValues(effectiveRoot);
232
+ const merged = mergeFragment(config ?? readConfig(join(targetDir, "opencode.json")), {
233
+ skills: fragment.skills,
234
+ instructions: [join(targetDir, "soleur", "INSTRUCTIONS.md")],
235
+ });
236
+ expected.set("opencode.json", `${JSON.stringify(merged, null, 2)}\n`);
237
+ return expected;
238
+ }
239
+
240
+ function payloadExpected(
241
+ targetDir: string,
242
+ sourceRoot: string,
243
+ effectiveRoot: string,
244
+ options: InstallOptions,
245
+ ): Map<string, PayloadEntry> {
246
+ const owned = options.vendorPayload === true || isVendoredRoot(sourceRoot);
247
+ const result = new Map<string, PayloadEntry>();
248
+ if (!owned) return result;
249
+ const prefix = relative(targetDir, effectiveRoot).split("\\").join("/");
250
+ if (prefix === "" || prefix.startsWith("..")) return result;
251
+ for (const [path, entry] of expectedPayloadEntries(sourceRoot)) {
252
+ result.set(`${prefix}/${path}`, entry);
253
+ }
254
+ result.set(`${prefix}/${VENDOR_MARKER}`, { content: vendorMarkerContent(), executable: false });
255
+ return result;
256
+ }
257
+
258
+ function readConfig(path: string): Record<string, unknown> {
259
+ let raw: string;
260
+ try {
261
+ raw = readFileSync(path, "utf-8");
262
+ } catch (error) {
263
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return {};
264
+ throw new UnparseableConfigError(path, `could not be read: ${String(error)}`);
265
+ }
266
+ let parsed: unknown;
267
+ try {
268
+ parsed = JSON.parse(raw);
269
+ } catch (error) {
270
+ throw new UnparseableConfigError(path, String(error));
271
+ }
272
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
273
+ throw new UnparseableConfigError(
274
+ path,
275
+ `top level is ${Array.isArray(parsed) ? "an array" : parsed === null ? "null" : typeof parsed}`,
276
+ );
277
+ }
278
+ return parsed as Record<string, unknown>;
279
+ }
280
+
281
+ /** Target-relative paths of every regular file under `dir` (skips symlinks; empty when absent). */
282
+ function walkFiles(targetDir: string, dir: string): string[] {
283
+ const found: string[] = [];
284
+ const visit = (relativeDir: string): void => {
285
+ let entries;
286
+ try {
287
+ entries = readdirSync(join(targetDir, relativeDir), { withFileTypes: true });
288
+ } catch {
289
+ return;
290
+ }
291
+ for (const entry of entries) {
292
+ if (entry.isSymbolicLink()) continue;
293
+ const path = `${relativeDir}/${entry.name}`;
294
+ if (entry.isDirectory()) visit(path);
295
+ else if (entry.isFile()) found.push(path);
296
+ }
297
+ };
298
+ visit(dir);
299
+ return found.sort();
300
+ }
301
+
302
+ const STUB_SIGNATURES = ["Stub for the canonical agent `", "Run the canonical `"] as const;
303
+
304
+ function isGeneratedStub(content: string, pluginRoot: string): boolean {
305
+ return content.includes(pluginRoot) && STUB_SIGNATURES.some((signature) => content.includes(signature));
306
+ }
307
+
308
+ export function installedExtras(
309
+ targetDir: string,
310
+ expected: Map<string, string>,
311
+ root = PLUGIN_ROOT,
312
+ ): string[] {
313
+ const extras: string[] = [];
314
+ for (const path of walkFiles(targetDir, "soleur")) if (!expected.has(path)) extras.push(path);
315
+ for (const path of walkFiles(targetDir, "plugins")) {
316
+ if (path.startsWith("plugins/soleur-") && !expected.has(path)) extras.push(path);
317
+ }
318
+ for (const root_ of ["agents", "commands"]) {
319
+ for (const path of walkFiles(targetDir, root_)) {
320
+ if (expected.has(path)) continue;
321
+ let content: string;
322
+ try {
323
+ content = readFileSync(join(targetDir, path), "utf-8");
324
+ } catch {
325
+ continue;
326
+ }
327
+ if (isGeneratedStub(content, root)) extras.push(path);
328
+ }
329
+ }
330
+ return extras.sort();
331
+ }
332
+
333
+ /** Write through a sibling temp file and rename, preserving executable mode when needed. */
334
+ function writeAtomic(full: string, content: string, executable = false): void {
335
+ mkdirSync(dirname(full), { recursive: true });
336
+ const temp = `${full}.soleur-tmp-${process.pid}`;
337
+ writeFileSync(temp, content);
338
+ if (executable) chmodSync(temp, 0o755);
339
+ renameSync(temp, full);
340
+ }
341
+
342
+ export interface InstallResult {
343
+ written: string[];
344
+ unchanged: string[];
345
+ removed: string[];
346
+ }
347
+
348
+ export function installOpenCodeAdapter(
349
+ targetDir: string,
350
+ pluginRoot = PLUGIN_ROOT,
351
+ options: InstallOptions = {},
352
+ ): InstallResult {
353
+ const result: InstallResult = { written: [], unchanged: [], removed: [] };
354
+ const configPath = join(targetDir, "opencode.json");
355
+ let config: Record<string, unknown> | undefined;
356
+ try {
357
+ config = readConfig(configPath);
358
+ } catch (error) {
359
+ if (!(error instanceof UnparseableConfigError)) throw error;
360
+ if (options.force !== true) throw error;
361
+ const backup = `${configPath}.bak-${Date.now()}`;
362
+ copyFileSync(configPath, backup);
363
+ console.error(`[soleur] --force: replaced ${configPath}; the previous bytes are at ${backup}`);
364
+ config = {};
365
+ }
366
+ const effectiveRoot = resolveEffectiveRoot(targetDir, pluginRoot, options);
367
+ const payload = payloadExpected(targetDir, pluginRoot, effectiveRoot, options);
368
+ const expected = expectedInstalled(targetDir, pluginRoot, config, options);
369
+ for (const [path, content] of expected) {
370
+ const full = join(targetDir, path);
371
+ const wantExec = payload.get(path)?.executable === true;
372
+ let current: string | undefined;
373
+ let currentExec = false;
374
+ try {
375
+ current = readFileSync(full, "utf-8");
376
+ currentExec = (statSync(full).mode & 0o111) !== 0;
377
+ } catch {
378
+ current = undefined;
379
+ }
380
+ if (current === content && (!wantExec || currentExec)) {
381
+ result.unchanged.push(path);
382
+ continue;
383
+ }
384
+ writeAtomic(full, content, wantExec);
385
+ result.written.push(path);
386
+ }
387
+ for (const path of installedExtras(targetDir, expected, effectiveRoot)) {
388
+ rmSync(join(targetDir, path), { force: true });
389
+ result.removed.push(path);
390
+ }
391
+ result.written.sort();
392
+ result.unchanged.sort();
393
+ result.removed.sort();
394
+ return result;
395
+ }
396
+
397
+ export function installProblems(targetDir: string, pluginRoot = PLUGIN_ROOT, options: InstallOptions = {}): string[] {
398
+ const problems: string[] = [];
399
+ const effectiveRoot = resolveEffectiveRoot(targetDir, pluginRoot, options);
400
+ const payload = payloadExpected(targetDir, pluginRoot, effectiveRoot, options);
401
+ const expected = expectedInstalled(targetDir, pluginRoot, undefined, options);
402
+ for (const [path, content] of expected) {
403
+ const full = join(targetDir, path);
404
+ const wantExec = payload.get(path)?.executable === true;
405
+ let current: string | undefined;
406
+ let currentExec = false;
407
+ try {
408
+ current = readFileSync(full, "utf-8");
409
+ currentExec = (statSync(full).mode & 0o111) !== 0;
410
+ } catch {
411
+ current = undefined;
412
+ }
413
+ if (current === undefined) problems.push(`MISSING: ${path}`);
414
+ else if (current !== content || (wantExec && !currentExec)) problems.push(`STALE: ${path}`);
415
+ }
416
+ for (const path of installedExtras(targetDir, expected, effectiveRoot)) {
417
+ problems.push(`EXTRA: ${path}`);
418
+ }
419
+ return problems.sort();
420
+ }
421
+
422
+ function parseArg(argv: readonly string[], flag: string): string | undefined {
423
+ const index = argv.indexOf(flag);
424
+ if (index === -1) return undefined;
425
+ return argv[index + 1];
426
+ }
427
+
428
+ const USAGE = [
429
+ "Usage: bun plugins/soleur/scripts/install-opencode-adapter.ts [install] [--target DIR] [--plugin-root DIR] [--vendor-payload] [--check] [--force] [--help]",
430
+ "",
431
+ " --target DIR config dir to install into (default: $HOME/.config/opencode)",
432
+ " --plugin-root DIR checkout (or package) the installed files should point at (default: this checkout)",
433
+ " --vendor-payload copy the payload into <target>/soleur/ and point the installed files at that",
434
+ " copy; required when there is no checkout to point at (the npm distribution)",
435
+ " --check write nothing; report MISSING / STALE / EXTRA",
436
+ " --force replace an existing opencode.json that cannot be parsed (backup first)",
437
+ " --help, -h print this text and exit 0 without writing",
438
+ ].join("\n");
439
+
440
+ function validateArgs(argv: readonly string[], usage = USAGE): void {
441
+ const withValue = new Set(["--target", "--plugin-root"]);
442
+ const known = new Set([...withValue, "--vendor-payload", "--check", "--force", "--help", "-h"]);
443
+ for (let i = 0; i < argv.length; i += 1) {
444
+ const arg = argv[i];
445
+ if (arg === "--help" || arg === "-h") {
446
+ console.log(usage);
447
+ process.exit(0);
448
+ }
449
+ if (!known.has(arg)) {
450
+ console.error(`unknown argument: ${arg}\n${usage}`);
451
+ process.exit(2);
452
+ }
453
+ if (withValue.has(arg)) {
454
+ const next = argv[i + 1];
455
+ if (next === undefined || next.startsWith("-")) {
456
+ console.error(`${arg} requires a directory\n${usage}`);
457
+ process.exit(2);
458
+ }
459
+ i += 1;
460
+ }
461
+ }
462
+ }
463
+
464
+ export function runCli(
465
+ rawArgv: readonly string[],
466
+ defaultPluginRoot = PLUGIN_ROOT,
467
+ defaultVendorPayload = false,
468
+ usage = USAGE,
469
+ ): void {
470
+ const argv = rawArgv[0] === "install" ? rawArgv.slice(1) : rawArgv;
471
+ validateArgs(argv, usage);
472
+ const explicitTarget = parseArg(argv, "--target");
473
+ const home = process.env["HOME"];
474
+ if (explicitTarget === undefined && (home === undefined || home === "")) {
475
+ console.error(
476
+ "HOME is not set and --target was not given: refusing to install into a cwd-relative `.config/opencode`. Pass --target DIR.",
477
+ );
478
+ process.exit(2);
479
+ }
480
+ const targetDir = resolve(explicitTarget ?? join(home as string, ".config", "opencode"));
481
+ const pluginRoot = resolve(parseArg(argv, "--plugin-root") ?? defaultPluginRoot);
482
+ const options: InstallOptions = {
483
+ force: argv.includes("--force"),
484
+ vendorPayload: defaultVendorPayload || argv.includes("--vendor-payload"),
485
+ };
486
+ try {
487
+ if (argv.includes("--check")) {
488
+ const problems = installProblems(targetDir, pluginRoot, options);
489
+ if (problems.length > 0) {
490
+ for (const problem of problems) console.error(problem);
491
+ process.exit(1);
492
+ }
493
+ console.log("opencode-install ok");
494
+ return;
495
+ }
496
+ const result = installOpenCodeAdapter(targetDir, pluginRoot, options);
497
+ console.log(
498
+ `opencode-adapter installed into ${targetDir} (${result.written.length} written, ${result.unchanged.length} unchanged, ${result.removed.length} removed)`,
499
+ );
500
+ } catch (error) {
501
+ if (error instanceof UnparseableConfigError) {
502
+ console.error(error.message);
503
+ process.exit(1);
504
+ }
505
+ throw error;
506
+ }
507
+ }
508
+
509
+ if (import.meta.main) runCli(process.argv.slice(2));