@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,644 @@
1
+ #!/usr/bin/env bash
2
+ # bsky-community.sh -- Bluesky AT Protocol wrapper for community operations
3
+ #
4
+ # Usage: bsky-community.sh <command> [args]
5
+ # Commands:
6
+ # create-session - Test auth, output session JSON
7
+ # post <text> [--reply-to-uri URI --reply-to-cid CID - Create a post (optionally as reply)
8
+ # --root-uri URI --root-cid CID]
9
+ # get-metrics - Fetch profile stats (followers, etc.)
10
+ # get-notifications [--limit N] [--cursor CURSOR] - Fetch mention notifications
11
+ #
12
+ # Environment variables (required):
13
+ # BSKY_HANDLE - Bluesky handle (e.g., soleur.bsky.social)
14
+ # BSKY_APP_PASSWORD - App password
15
+ # BSKY_ALLOW_POST - Set to "true" to enable posting (defense-in-depth guard)
16
+ #
17
+ # Exit codes:
18
+ # 0 - Success
19
+ # 1 - General error
20
+ # 2 - Rate limit exhausted after retries
21
+ #
22
+ # Output: JSON to stdout
23
+ # Errors: Messages to stderr, exit 1
24
+
25
+ set -euo pipefail
26
+
27
+ # (#7797) Xtrace refusal -- the FIRST thing after `set …`, so nothing above it is
28
+ # traced. This script ships to installed Soleur CLIs: the terminal it runs in
29
+ # belongs to the founder, and `bash -x` would print their live Bluesky
30
+ # credentials. The `:+x` form tests non-emptiness WITHOUT expanding the value, so
31
+ # the guard cannot leak the thing it is refusing over. CONDITIONAL, and that is
32
+ # measured rather than inherited -- and the measurement is NOT "nothing is acquired
33
+ # at runtime", which would be FALSE here: `create_session` POSTs BSKY_APP_PASSWORD
34
+ # and mints an ACCESS_JWT from the response body, which later requests carry as a
35
+ # bearer. The property that actually holds is narrower and is what makes the arm
36
+ # sound: every runtime acquisition on this path is GATED on BSKY_APP_PASSWORD --
37
+ # the same variable this guard tests -- so no password means no JWT, and the guard
38
+ # cannot be empty while any credential is live. A founder tracing with none set
39
+ # keeps full tracing.
40
+ #
41
+ # Stated this way on purpose (#7898 review). The first cut claimed the file
42
+ # acquires nothing at runtime; that is true of discord/linkedin/x-community and
43
+ # false of this one, and a template carrying the wrong reason invites the next
44
+ # author to copy it into a file where the acquisition is NOT gated.
45
+ # Refusal goes to STDOUT, not stderr: agent runtimes surface stdout and swallow
46
+ # stderr (constitution.md > Code Style > Always), and a swallowed security refusal
47
+ # leaves the user with a bare `exit 78` and no text at all.
48
+ case "$-" in
49
+ *x*)
50
+ if [ -n "${BSKY_APP_PASSWORD:+x}" ]; then
51
+ printf 'Refusing to run under `bash -x`: BSKY_APP_PASSWORD is set, and tracing would print it to your terminal. To trace safely, unset it and re-run.\n'
52
+ exit 78
53
+ fi
54
+ ;;
55
+ esac
56
+
57
+ # (#7873) `--disable` closes ~/.curlrc and `--noproxy '*'` closes the proxy
58
+ # variables, but NEITHER touches the trust store or the TLS session-key log. On an
59
+ # installed CLI the environment belongs to someone who is not us, so
60
+ # a substituted `CURL_CA_BUNDLE` is a clean MITM of the founder's platform
61
+ # token with every other guard fully intact, and `SSLKEYLOGFILE` is passive
62
+ # decryption with no MITM at all. Matches the line in scripts/betterstack-query.sh.
63
+ unset SSLKEYLOGFILE CURL_CA_BUNDLE SSL_CERT_FILE SSL_CERT_DIR CURL_HOME \
64
+ HOSTALIASES LOCALDOMAIN RES_OPTIONS
65
+
66
+ # --- Transport-confinement diagnostics (#7873) --------------------------------
67
+ # Every credentialed `curl` below carries `--disable --noproxy '*'` and discards
68
+ # curl's own stderr (which can carry the URL). A failed request then has four
69
+ # competing causes the founder cannot tell apart: the proxy this script
70
+ # deliberately bypassed, a ~/.curlrc that `--disable` dropped, a TLS trust
71
+ # variable it cleared, or an ordinary network failure. So each failure emits ONE
72
+ # structured marker carrying the discriminators, beside a human line that names
73
+ # the bypass instead of blaming the founder's connectivity.
74
+ SOLEUR_TRANSPORT_SCRIPT="bsky-community.sh"
75
+ SOLEUR_TRANSPORT_PLATFORM="Bluesky"
76
+
77
+ # The request helpers below run inside `$(...)`, where fd 1 is the capture pipe.
78
+ # Save the script's real stdout so the marker reaches the founder's terminal (and
79
+ # the always-on PostToolUse Bash extractor) instead of being swallowed into a
80
+ # variable. The marker is on stdout BY DESIGN -- the call sites' `2>/dev/null` is
81
+ # what keeps curl's URL-carrying stderr out of the transcript, and it must not be
82
+ # able to suppress the diagnostic too.
83
+ exec 3>&1
84
+
85
+ # Which proxy variables are non-empty, or `none`.
86
+ proxy_env_names() {
87
+ local names="" n
88
+ for n in HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY http_proxy https_proxy all_proxy no_proxy; do
89
+ if [[ -n "${!n-}" ]]; then
90
+ names="${names},${n}"
91
+ fi
92
+ done
93
+ if [[ -z "$names" ]]; then
94
+ printf 'none'
95
+ else
96
+ printf '%s' "${names#,}"
97
+ fi
98
+ }
99
+
100
+ # True when a proxy this script deliberately bypasses is configured. NO_PROXY
101
+ # alone is not one -- it only ever narrows proxying, so it cannot be the cause.
102
+ proxy_bypassed() {
103
+ [[ -n "${HTTP_PROXY:-}${HTTPS_PROXY:-}${ALL_PROXY:-}${http_proxy:-}${https_proxy:-}${all_proxy:-}" ]]
104
+ }
105
+
106
+ # One line, eight fields, on the saved stdout.
107
+ #
108
+ # Two fields were literals in the first cut and are now MEASURED (#7898 review):
109
+ # `noproxy_applied` was the constant "true", which ASSERTS the property instead of
110
+ # observing it -- dropping --noproxy from a call site left the diagnostic still
111
+ # claiming it was applied. It now reports whether a proxy was actually configured
112
+ # for this request to bypass, which is the fact a reader needs. `refusal` was the
113
+ # constant "none" at every call site, so the cause it exists to discriminate could
114
+ # never appear; the field stays for a caller that can refuse for a named cause, and
115
+ # this script has none, so it passes "none".
116
+ #
117
+ # `tls_env_cleared` is new. The prologue unsets CURL_CA_BUNDLE/SSL_CERT_FILE et al,
118
+ # which is correct against an attacker and BREAKS a founder whose corporate CA
119
+ # arrives that way -- curl then exits 60 and, without this field, the event is
120
+ # indistinguishable from an ordinary network failure.
121
+ emit_transport_diag() {
122
+ local curl_exit="$1" refusal="$2" surface="installed-cli" curlrc="false" noproxy="false"
123
+ # The hosted sandbox always sets this (agent-env.ts > AGENT_ENV_OVERRIDES); an
124
+ # installed CLI does not. A label on the event, not a gate on behaviour.
125
+ if [[ -n "${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-}" ]]; then
126
+ surface="in-sandbox"
127
+ fi
128
+ if [[ -f "${HOME:-}/.curlrc" ]]; then
129
+ curlrc="true"
130
+ fi
131
+ if proxy_bypassed; then
132
+ noproxy="true"
133
+ fi
134
+ printf 'SOLEUR_TRANSPORT_DIAG surface=%s script=%s curl_exit=%s refusal=%s proxy_env=%s curlrc_present=%s noproxy_applied=%s tls_env_cleared=%s\n' \
135
+ "$surface" "$SOLEUR_TRANSPORT_SCRIPT" "$curl_exit" "$refusal" \
136
+ "$(proxy_env_names)" "$curlrc" "$noproxy" "true" >&3
137
+ }
138
+
139
+ # Replaces the bare "Check your network connection and try again." on a
140
+ # credentialed-curl failure. With a proxy set, that line blames the founder for a
141
+ # bypass this script chose.
142
+ report_transport_failure() {
143
+ local curl_exit="${1:-unknown}"
144
+ local detail="${2:-Failed to connect to the ${SOLEUR_TRANSPORT_PLATFORM} API.}"
145
+ emit_transport_diag "$curl_exit" "none"
146
+ echo "Error: ${detail}" >&2
147
+ # Ordered by how specific the evidence is. Each arm names something THIS script
148
+ # did, so the founder is never told to go debug their own network for a choice
149
+ # made here. The bare "check your connection" line is the LAST resort, not the
150
+ # default -- it was the default in the first cut, which meant a founder whose
151
+ # corporate CA or curlrc we had just discarded was blamed for it (#7898 review).
152
+ if [[ "$curl_exit" == "60" || "$curl_exit" == "35" || "$curl_exit" == "77" ]]; then
153
+ # 60 peer-certificate, 35 TLS handshake, 77 CA-bundle unreadable.
154
+ echo "This looks like a TLS trust failure. This script deliberately clears CURL_CA_BUNDLE, SSL_CERT_FILE, SSL_CERT_DIR and SSLKEYLOGFILE before the request, because those variables can redirect or expose a request carrying your ${SOLEUR_TRANSPORT_PLATFORM} credential." >&2
155
+ echo "If your machine needs a corporate CA to reach ${SOLEUR_TRANSPORT_PLATFORM}, that is not currently supported -- please open an issue at https://github.com/jikig-ai/soleur/issues." >&2
156
+ elif proxy_bypassed; then
157
+ echo "This request deliberately bypasses your proxy ($(proxy_env_names)), because a proxy can redirect a request carrying your ${SOLEUR_TRANSPORT_PLATFORM} token." >&2
158
+ echo "If you need Soleur to reach ${SOLEUR_TRANSPORT_PLATFORM} through your proxy, that is not currently supported -- please open an issue at https://github.com/jikig-ai/soleur/issues." >&2
159
+ elif [[ -f "${HOME:-}/.curlrc" ]]; then
160
+ echo "You have a ~/.curlrc, and this request deliberately ignores it (--disable), because a curlrc can redirect a request carrying your ${SOLEUR_TRANSPORT_PLATFORM} token. If it configures a proxy or a CA bundle you need, that is why this failed." >&2
161
+ echo "That is not currently supported -- please open an issue at https://github.com/jikig-ai/soleur/issues." >&2
162
+ else
163
+ echo "Check your network connection and try again." >&2
164
+ fi
165
+ }
166
+
167
+ # readonly (#7898 review): `cmd_verify` and friends run `set -a; source "$env_file"; set +a`
168
+ # BELOW this line, so a plain assignment here is rebindable by the repo's .env --
169
+ # which retargets the credentialed request while every transport flag stays intact.
170
+ # That is the "--disable and --noproxy are intact and irrelevant" shape this change
171
+ # exists to close, one layer up. readonly makes the destination non-rebindable.
172
+ readonly BSKY_API="https://bsky.social/xrpc"
173
+
174
+ # --- Session state (per-invocation, not cached) ---
175
+
176
+ ACCESS_JWT=""
177
+ USER_DID=""
178
+
179
+ # --- Bearer transport (#7843) ---
180
+ # ACCESS_JWT is parsed out of an API reply, so it is RESPONSE-DERIVED: untrusted bytes. It
181
+ # rides curl's STDIN config channel (`--config -`), never its argument list, where every
182
+ # local user would read it from /proc/<pid>/cmdline. That channel is line-oriented, so a
183
+ # token holding a quote and a newline could append a `url = "..."` directive and make curl
184
+ # issue a second request. The guard refuses anything outside the JWT/base64url alphabet
185
+ # BEFORE the value is formatted into the stream, and never echoes it.
186
+ _bearer_ok() { local LC_ALL=C; case "${1:-}" in ''|*[!A-Za-z0-9._~+/=-]*) return 1 ;; esac; }
187
+
188
+ # Every authenticated request goes through here: ONE place owns the transport flags
189
+ # (`--disable` first, `--noproxy '*'`), the token-shape guard and the header. Returns 120
190
+ # with zero curl calls when the token is unusable; callers map that to a refusal.
191
+ bsky_authed_curl() {
192
+ _bearer_ok "$ACCESS_JWT" || return 120
193
+ curl --disable --noproxy '*' "$@" --config - \
194
+ < <(printf 'header = "Authorization: Bearer %s"\n' "$ACCESS_JWT")
195
+ }
196
+
197
+ # --- createSession body transport (#9597) ---
198
+ # The createSession body carries the app password and a user-supplied handle. Neither may
199
+ # ride curl's argument list (readable by every local user in /proc/<pid>/cmdline). The
200
+ # createSession call has no bearer config, so curl's stdin is free: `jq` builds the body and
201
+ # pipes it to `curl --data-binary @-` (NOT `-d @-`, which strips CR/LF). The values reach
202
+ # `jq` through its ENVIRONMENT as an inline assignment prefix (`$ENV.X`), never `jq --arg`
203
+ # (jq's own argv is world-readable too). This script never `export`s them: the BSKY_ID /
204
+ # BSKY_PW aliases live on the one jq child only. (BSKY_HANDLE / BSKY_APP_PASSWORD themselves
205
+ # are whatever the CALLER exported, so later children inherit those regardless.) No file, no
206
+ # trap: the secret exists only in the processes' memory and the pipe.
207
+
208
+ # A control character can never be part of a handle or an app password. Refusing one
209
+ # before anything is sent keeps garbage off the wire; jq escapes everything else (a handle
210
+ # holding a double quote is escaped, never injected into the JSON).
211
+ _bsky_cred_ok() { local LC_ALL=C; case "${1:-}" in ''|*[[:cntrl:]]*) return 1 ;; esac; }
212
+
213
+ # A fixed, value-free marker plus ONE human line on stderr, naming only which FIELD was
214
+ # refused (never the handle or the password), and a non-zero exit. $2 is the variable name.
215
+ # `post` also runs HOSTED, from scripts/content-publisher.sh, which captures stderr into its
216
+ # fallback-issue path: the exit is 1, never 0 or 3.
217
+ bsky_refuse() {
218
+ printf 'SOLEUR_CREDENTIAL_REFUSED script=%s reason=%s\n' "$SOLEUR_TRANSPORT_SCRIPT" "$1" >&2
219
+ echo "Error: ${2} is empty or contains a control character (for example a stray carriage return or newline from a copy-paste or a CRLF .env file), so nothing was sent. Remove it and retry. The value is not shown." >&2
220
+ exit 1
221
+ }
222
+
223
+ # --- Dependency checks ---
224
+
225
+ require_jq() {
226
+ if ! command -v jq &>/dev/null; then
227
+ echo "Error: jq is required but not installed." >&2
228
+ echo "Install it: https://jqlang.github.io/jq/download/" >&2
229
+ exit 1
230
+ fi
231
+ }
232
+
233
+ require_credentials() {
234
+ local missing=()
235
+
236
+ if [[ -z "${BSKY_HANDLE:-}" ]]; then
237
+ missing+=("BSKY_HANDLE")
238
+ fi
239
+ if [[ -z "${BSKY_APP_PASSWORD:-}" ]]; then
240
+ missing+=("BSKY_APP_PASSWORD")
241
+ fi
242
+
243
+ if [[ ${#missing[@]} -gt 0 ]]; then
244
+ echo "Error: Missing Bluesky credentials: ${missing[*]}" >&2
245
+ echo "" >&2
246
+ echo "To configure:" >&2
247
+ echo " 1. Create an account at https://bsky.app" >&2
248
+ echo " 2. Go to Settings > App Passwords > Add App Password" >&2
249
+ echo " 3. Export BSKY_HANDLE and BSKY_APP_PASSWORD as environment variables, without typing a value into the command (its text is kept in the transcript and the shell history): in a terminal, read -rs BSKY_APP_PASSWORD; export BSKY_APP_PASSWORD" >&2
250
+ exit 1
251
+ fi
252
+ }
253
+
254
+ # --- Session management ---
255
+
256
+ # Create a fresh session. Sets ACCESS_JWT and USER_DID globals.
257
+ create_session() {
258
+ local response http_code body
259
+
260
+ local __curl_rc=0
261
+ # Refuse BEFORE the body is built so a refused value never reaches a child process.
262
+ _bsky_cred_ok "${BSKY_HANDLE:-}" || bsky_refuse control_char BSKY_HANDLE
263
+ _bsky_cred_ok "${BSKY_APP_PASSWORD:-}" || bsky_refuse control_char BSKY_APP_PASSWORD
264
+ # The body is built into a variable FIRST, so a jq failure is classified as what it is (a
265
+ # body-build failure) and never reaches curl: it does not depend on `pipefail`, and it can
266
+ # never read as a transport failure or as a successful empty POST. The credentials reach jq
267
+ # only through its inline environment prefix; `printf` is a builtin, so the body (which holds
268
+ # the password) is on no argv; curl reads it from stdin.
269
+ local req_body
270
+ req_body=$(BSKY_ID="$BSKY_HANDLE" BSKY_PW="$BSKY_APP_PASSWORD" \
271
+ jq -n '{identifier: $ENV.BSKY_ID, password: $ENV.BSKY_PW}') || {
272
+ echo "Error: could not build the Bluesky createSession request body (jq failed); nothing was sent." >&2
273
+ exit 1
274
+ }
275
+ response=$(printf '%s' "$req_body" \
276
+ | curl --disable --noproxy '*' -s -w "\n%{http_code}" \
277
+ -X POST \
278
+ -H "Content-Type: application/json" \
279
+ --data-binary @- \
280
+ "${BSKY_API}/com.atproto.server.createSession" 2>/dev/null) || __curl_rc=$?
281
+ if (( __curl_rc != 0 )); then
282
+ report_transport_failure "$__curl_rc" "Failed to connect to Bluesky API."
283
+ exit 1
284
+ fi
285
+
286
+ http_code=$(echo "$response" | tail -1)
287
+ body=$(echo "$response" | sed '$d')
288
+
289
+ case "$http_code" in
290
+ 2[0-9][0-9])
291
+ if ! echo "$body" | jq . >/dev/null 2>&1; then
292
+ echo "Error: Bluesky API returned malformed JSON for createSession." >&2
293
+ exit 1
294
+ fi
295
+ ACCESS_JWT=$(echo "$body" | jq -r '.accessJwt // empty')
296
+ USER_DID=$(echo "$body" | jq -r '.did // empty')
297
+ if [[ -z "$ACCESS_JWT" || -z "$USER_DID" ]]; then
298
+ echo "Error: Session response missing accessJwt or DID." >&2
299
+ exit 1
300
+ fi
301
+ if ! _bearer_ok "$ACCESS_JWT"; then
302
+ ACCESS_JWT=""
303
+ echo "Error: Session response carried an accessJwt with an unexpected shape; refusing to use it." >&2
304
+ exit 1
305
+ fi
306
+ ;;
307
+ 401)
308
+ echo "Error: Bluesky returned 401 Unauthorized." >&2
309
+ echo "Your handle or app password may be incorrect." >&2
310
+ exit 1
311
+ ;;
312
+ *)
313
+ local message
314
+ message=$(echo "$body" | jq -r '.message // .error // "Unknown error"' 2>/dev/null || echo "Unknown error")
315
+ echo "Error: Bluesky API returned HTTP ${http_code}: ${message}" >&2
316
+ exit 1
317
+ ;;
318
+ esac
319
+ }
320
+
321
+ # --- Response handling ---
322
+
323
+ # Handle HTTP response from Bluesky API
324
+ # Arguments: http_code body endpoint depth retry_cmd...
325
+ handle_response() {
326
+ local http_code="$1"
327
+ local body="$2"
328
+ local endpoint="$3"
329
+ local depth="$4"
330
+ shift 4
331
+ local -a retry_cmd=("$@")
332
+
333
+ case "$http_code" in
334
+ 2[0-9][0-9])
335
+ if ! echo "$body" | jq . >/dev/null 2>&1; then
336
+ echo "Error: Bluesky API returned malformed JSON for ${endpoint}." >&2
337
+ exit 1
338
+ fi
339
+ echo "$body"
340
+ ;;
341
+ 401)
342
+ echo "Error: Bluesky API returned 401 Unauthorized for ${endpoint}." >&2
343
+ echo "Your credentials may be expired or invalid." >&2
344
+ exit 1
345
+ ;;
346
+ 429)
347
+ # Bluesky uses ratelimit-reset header (Unix timestamp).
348
+ # In curl response body, fall back to a sensible default.
349
+ local retry_after=5
350
+ echo "Rate limited. Retrying after ${retry_after}s (attempt $((depth + 1))/3)..." >&2
351
+ sleep "$retry_after"
352
+ "${retry_cmd[@]}"
353
+ ;;
354
+ *)
355
+ local message
356
+ message=$(echo "$body" | jq -r '.message // .error // "Unknown error"' 2>/dev/null || echo "Unknown error")
357
+ echo "Error: Bluesky API returned HTTP ${http_code} for ${endpoint}: ${message}" >&2
358
+ exit 1
359
+ ;;
360
+ esac
361
+ }
362
+
363
+ # --- Request helpers ---
364
+
365
+ # Make an authenticated GET request
366
+ # Arguments: endpoint [query_string] [depth]
367
+ get_request() {
368
+ local endpoint="$1"
369
+ local query_string="${2:-}"
370
+ local depth="${3:-0}"
371
+
372
+ if (( depth >= 3 )); then
373
+ echo "Error: Bluesky API rate limit exceeded after 3 retries for ${endpoint}." >&2
374
+ exit 2
375
+ fi
376
+
377
+ local url="${BSKY_API}/${endpoint}"
378
+ if [[ -n "$query_string" ]]; then
379
+ url="${url}?${query_string}"
380
+ fi
381
+
382
+ local response http_code body
383
+ local __curl_rc=0
384
+ response=$(bsky_authed_curl -s -w "\n%{http_code}" \
385
+ "$url" 2>/dev/null) || __curl_rc=$?
386
+ if (( __curl_rc == 120 )); then
387
+ echo "Error: Bluesky session token has an unexpected shape; refusing to send it." >&2
388
+ exit 1
389
+ fi
390
+ if (( __curl_rc != 0 )); then
391
+ report_transport_failure "$__curl_rc" "Failed to connect to Bluesky API."
392
+ exit 1
393
+ fi
394
+
395
+ http_code=$(echo "$response" | tail -1)
396
+ body=$(echo "$response" | sed '$d')
397
+
398
+ handle_response "$http_code" "$body" "$endpoint" "$depth" \
399
+ get_request "$endpoint" "$query_string" "$((depth + 1))"
400
+ }
401
+
402
+ # Make an authenticated POST request
403
+ # Arguments: endpoint [json_body] [depth]
404
+ post_request() {
405
+ local endpoint="$1"
406
+ local json_body="${2:-}"
407
+ local depth="${3:-0}"
408
+
409
+ if (( depth >= 3 )); then
410
+ echo "Error: Bluesky API rate limit exceeded after 3 retries for ${endpoint}." >&2
411
+ exit 2
412
+ fi
413
+
414
+ local url="${BSKY_API}/${endpoint}"
415
+ # `--disable` first and `--noproxy '*'` plus the bearer are added by bsky_authed_curl.
416
+ local -a curl_args=(
417
+ -s -w "\n%{http_code}"
418
+ -H "Content-Type: application/json"
419
+ )
420
+
421
+ if [[ -n "$json_body" ]]; then
422
+ curl_args+=(-X POST -d "$json_body")
423
+ fi
424
+
425
+ local response http_code body
426
+ local __curl_rc=0
427
+ response=$(bsky_authed_curl "${curl_args[@]}" "$url" 2>/dev/null) || __curl_rc=$?
428
+ if (( __curl_rc == 120 )); then
429
+ echo "Error: Bluesky session token has an unexpected shape; refusing to send it." >&2
430
+ exit 1
431
+ fi
432
+ if (( __curl_rc != 0 )); then
433
+ report_transport_failure "$__curl_rc" "Failed to connect to Bluesky API."
434
+ exit 1
435
+ fi
436
+
437
+ http_code=$(echo "$response" | tail -1)
438
+ body=$(echo "$response" | sed '$d')
439
+
440
+ handle_response "$http_code" "$body" "$endpoint" "$depth" \
441
+ post_request "$endpoint" "$json_body" "$((depth + 1))"
442
+ }
443
+
444
+ # --- Commands ---
445
+
446
+ cmd_create_session() {
447
+ create_session
448
+ echo "{\"did\": \"${USER_DID}\", \"handle\": \"${BSKY_HANDLE}\"}" | jq .
449
+ echo "Session created for @${BSKY_HANDLE} (${USER_DID})" >&2
450
+ }
451
+
452
+ cmd_post() {
453
+ # Guard: require explicit opt-in to post.
454
+ if [[ "${BSKY_ALLOW_POST:-}" != "true" ]]; then
455
+ echo "Error: BSKY_ALLOW_POST is not set to 'true'." >&2
456
+ echo "Set BSKY_ALLOW_POST=true to enable posting." >&2
457
+ return 1
458
+ fi
459
+
460
+ local text=""
461
+ local reply_to_uri="" reply_to_cid="" root_uri="" root_cid=""
462
+
463
+ # Parse arguments
464
+ while [[ $# -gt 0 ]]; do
465
+ case "$1" in
466
+ --reply-to-uri) reply_to_uri="$2"; shift 2 ;;
467
+ --reply-to-cid) reply_to_cid="$2"; shift 2 ;;
468
+ --root-uri) root_uri="$2"; shift 2 ;;
469
+ --root-cid) root_cid="$2"; shift 2 ;;
470
+ *)
471
+ if [[ -z "$text" ]]; then
472
+ text="$1"
473
+ else
474
+ echo "Error: Unexpected argument '$1'" >&2
475
+ exit 1
476
+ fi
477
+ shift
478
+ ;;
479
+ esac
480
+ done
481
+
482
+ if [[ -z "$text" ]]; then
483
+ echo "Error: Post text is required." >&2
484
+ echo "Usage: bsky-community.sh post <text> [--reply-to-uri URI --reply-to-cid CID --root-uri URI --root-cid CID]" >&2
485
+ exit 1
486
+ fi
487
+
488
+ # Validate length (codepoint count as grapheme approximation)
489
+ local char_count
490
+ char_count=$(printf '%s' "$text" | wc -m)
491
+ if (( char_count > 300 )); then
492
+ echo "Error: Post exceeds 300 character limit (${char_count} characters)." >&2
493
+ exit 1
494
+ fi
495
+
496
+ create_session
497
+
498
+ # Build record JSON
499
+ local created_at
500
+ created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
501
+
502
+ local record
503
+ record=$(jq -n \
504
+ --arg type "app.bsky.feed.post" \
505
+ --arg text "$text" \
506
+ --arg created_at "$created_at" \
507
+ '{
508
+ "$type": $type,
509
+ "text": $text,
510
+ "createdAt": $created_at
511
+ }')
512
+
513
+ # Add reply references if provided
514
+ if [[ -n "$reply_to_uri" && -n "$reply_to_cid" ]]; then
515
+ # If root not specified, parent is the root (first reply in thread)
516
+ if [[ -z "$root_uri" ]]; then
517
+ root_uri="$reply_to_uri"
518
+ root_cid="$reply_to_cid"
519
+ fi
520
+
521
+ record=$(echo "$record" | jq \
522
+ --arg parent_uri "$reply_to_uri" \
523
+ --arg parent_cid "$reply_to_cid" \
524
+ --arg root_uri "$root_uri" \
525
+ --arg root_cid "$root_cid" \
526
+ '. + {
527
+ "reply": {
528
+ "root": {"uri": $root_uri, "cid": $root_cid},
529
+ "parent": {"uri": $parent_uri, "cid": $parent_cid}
530
+ }
531
+ }')
532
+ fi
533
+
534
+ local request_body
535
+ request_body=$(jq -n \
536
+ --arg repo "$USER_DID" \
537
+ --arg collection "app.bsky.feed.post" \
538
+ --argjson record "$record" \
539
+ '{
540
+ "repo": $repo,
541
+ "collection": $collection,
542
+ "record": $record
543
+ }')
544
+
545
+ local result
546
+ result=$(post_request "com.atproto.repo.createRecord" "$request_body")
547
+
548
+ # Return uri and cid for thread chaining
549
+ echo "$result" | jq '{uri, cid}'
550
+ }
551
+
552
+ cmd_get_metrics() {
553
+ create_session
554
+
555
+ local body
556
+ body=$(get_request "app.bsky.actor.getProfile" "actor=${USER_DID}")
557
+
558
+ echo "$body" | jq '{
559
+ handle: .handle,
560
+ displayName: .displayName,
561
+ followersCount: .followersCount,
562
+ followsCount: .followsCount,
563
+ postsCount: .postsCount,
564
+ description: .description
565
+ }'
566
+ }
567
+
568
+ cmd_get_notifications() {
569
+ local limit=50
570
+ local cursor=""
571
+
572
+ while [[ $# -gt 0 ]]; do
573
+ case "$1" in
574
+ --limit) limit="$2"; shift 2 ;;
575
+ --cursor) cursor="$2"; shift 2 ;;
576
+ *)
577
+ echo "Error: Unknown option '$1'" >&2
578
+ exit 1
579
+ ;;
580
+ esac
581
+ done
582
+
583
+ create_session
584
+
585
+ local query="limit=${limit}"
586
+ if [[ -n "$cursor" ]]; then
587
+ query="${query}&cursor=${cursor}"
588
+ fi
589
+
590
+ local body
591
+ body=$(get_request "app.bsky.notification.listNotifications" "$query")
592
+
593
+ # Filter for mentions only and extract relevant fields
594
+ echo "$body" | jq '{
595
+ notifications: [.notifications[] | select(.reason == "mention") | {
596
+ uri: .uri,
597
+ cid: .cid,
598
+ author_handle: .author.handle,
599
+ author_name: (.author.displayName // .author.handle),
600
+ text: (.record.text // ""),
601
+ created_at: .indexedAt,
602
+ reason: .reason
603
+ }],
604
+ cursor: .cursor
605
+ }'
606
+ }
607
+
608
+ # --- Main ---
609
+
610
+ main() {
611
+ local command="${1:-}"
612
+ shift || true
613
+
614
+ if [[ -z "$command" ]]; then
615
+ echo "Usage: bsky-community.sh <command> [args]" >&2
616
+ echo "" >&2
617
+ echo "Commands:" >&2
618
+ echo " create-session - Test auth, output session info" >&2
619
+ echo " post <text> [reply flags] - Create a post" >&2
620
+ echo " get-metrics - Fetch profile stats" >&2
621
+ echo " get-notifications [--limit N] - Fetch mention notifications" >&2
622
+ exit 1
623
+ fi
624
+
625
+ require_jq
626
+ require_credentials
627
+
628
+ case "$command" in
629
+ create-session) cmd_create_session ;;
630
+ post) cmd_post "$@" ;;
631
+ get-metrics) cmd_get_metrics ;;
632
+ get-notifications) cmd_get_notifications "$@" ;;
633
+ *)
634
+ echo "Error: Unknown command '${command}'" >&2
635
+ echo "Run 'bsky-community.sh' without arguments for usage." >&2
636
+ exit 1
637
+ ;;
638
+ esac
639
+ }
640
+
641
+ # Guard: allow sourcing without executing main (for test harness)
642
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
643
+ main "$@"
644
+ fi