@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,198 @@
1
+ #!/usr/bin/env bash
2
+ # trigger-cron — fire an allowlisted cron manual-trigger via the internal HTTP
3
+ # route (no SSH). See plugins/soleur/skills/trigger-cron/SKILL.md.
4
+ #
5
+ # The no-SSH replacement for the on-host `inngest send` loopback path (#4734,
6
+ # #4742). Reads INNGEST_MANUAL_TRIGGER_SECRET read-only from Doppler and POSTs
7
+ # to https://app.soleur.ai/api/internal/trigger-cron.
8
+ #
9
+ # Allowlisted events are derived from EXPECTED_CRON_FUNCTIONS in
10
+ # apps/web-platform/server/inngest/cron-manifest.ts — there is NO second
11
+ # hand-maintained list here (mirrors lib/inngest/manual-trigger-allowlist.ts).
12
+
13
+ set -euo pipefail
14
+
15
+ # (#7797) Refuse to run under shell tracing. UNCONDITIONAL — deliberately NOT
16
+ # gated on a non-emptiness test of the credential variable, because
17
+ # INNGEST_MANUAL_TRIGGER_SECRET is acquired by `doppler secrets get` BELOW this
18
+ # point, so a conditional arm would test an empty variable at guard time, open,
19
+ # and then trace the acquisition itself.
20
+ #
21
+ # STREAM CONTRACT: this script's stdout is a DATA channel — it prints `HTTP <code>`
22
+ # then the response body, and SKILL.md's preflight block grep-parses
23
+ # `SOLEUR_TRIGGER_CRON_HALT reason=…` markers on stdout. So the refusal is emitted
24
+ # in that documented marker shape rather than as a bare `[FATAL] …` line, which the
25
+ # preflight consumer would read as a data row. Stdout, not stderr, because agent
26
+ # runtimes surface stdout and swallow stderr (constitution.md > Code Style).
27
+ case "$-" in
28
+ *x*)
29
+ printf 'SOLEUR_TRIGGER_CRON_HALT reason=xtrace-credential-bound issue=7797\n'
30
+ printf 'trigger-cron: refusing to run under xtrace — this script handles a live credential and -x would print it. No event has been fired and no secret has been read.\n'
31
+ exit 78
32
+ ;;
33
+ esac
34
+
35
+ # (#7873) `--disable` closes ~/.curlrc and `--noproxy '*'` closes the proxy vars,
36
+ # but neither touches the env that subverts TLS ITSELF. SSLKEYLOGFILE writes the
37
+ # session keys and the CA vars substitute the trust store, so a CURL_CA_BUNDLE
38
+ # MITM of the manual-trigger secret works with every other guard fully intact.
39
+ unset SSLKEYLOGFILE CURL_CA_BUNDLE SSL_CERT_FILE SSL_CERT_DIR CURL_HOME \
40
+ HOSTALIASES LOCALDOMAIN RES_OPTIONS
41
+
42
+ ROUTE_URL="https://app.soleur.ai/api/internal/trigger-cron"
43
+ SECRET_NAME="INNGEST_MANUAL_TRIGGER_SECRET"
44
+ DOPPLER_PROJECT="soleur"
45
+
46
+ usage() {
47
+ cat <<'EOF'
48
+ Usage:
49
+ trigger.sh --list
50
+ trigger.sh --event cron/<name>.manual-trigger [--data '<json-object>'] \
51
+ [--config prd|dev] [--dry-run]
52
+
53
+ Flags:
54
+ --list Print allowlisted events (from cron-manifest.ts) and exit.
55
+ --event <name> The cron/<name>.manual-trigger event to fire.
56
+ --data '<json>' Optional per-cron event.data (JSON object). The route stamps
57
+ trigger/at over it; caller cannot override them.
58
+ --config <env> Doppler config to read the secret from (default: prd).
59
+ --dry-run Print the curl invocation without firing.
60
+ EOF
61
+ }
62
+
63
+ # Locate the cron manifest from the repo root (works from any CWD inside the repo).
64
+ repo_root() {
65
+ git rev-parse --show-toplevel 2>/dev/null || {
66
+ echo "trigger.sh: not inside a git repo (cannot locate cron-manifest.ts)" >&2
67
+ exit 2
68
+ }
69
+ }
70
+
71
+ # Extract the allowlisted manual-trigger events from cron-manifest.ts.
72
+ # Parses the EXPECTED_CRON_FUNCTIONS array literal (cron-<name>) and applies the
73
+ # same transform as manualTriggerEventFor: cron-<name> -> cron/<name>.manual-trigger.
74
+ list_events() {
75
+ local manifest="$1"
76
+ [[ -f "$manifest" ]] || { echo "trigger.sh: manifest not found: $manifest" >&2; exit 2; }
77
+ awk '
78
+ /EXPECTED_CRON_FUNCTIONS/ { inarr=1 }
79
+ inarr && /\];/ { inarr=0 }
80
+ inarr {
81
+ while (match($0, /"cron-[a-z0-9-]+"/)) {
82
+ tok = substr($0, RSTART+1, RLENGTH-2) # strip surrounding quotes
83
+ sub(/^cron-/, "", tok)
84
+ print "cron/" tok ".manual-trigger"
85
+ $0 = substr($0, RSTART+RLENGTH)
86
+ }
87
+ }
88
+ ' "$manifest" | sort -u
89
+ }
90
+
91
+ LIST=0
92
+ EVENT=""
93
+ DATA=""
94
+ CONFIG="prd"
95
+ DRY_RUN=0
96
+
97
+ while [[ $# -gt 0 ]]; do
98
+ case "$1" in
99
+ --list) LIST=1; shift ;;
100
+ --event) EVENT="${2:-}"; shift 2 ;;
101
+ --data) DATA="${2:-}"; shift 2 ;;
102
+ --config) CONFIG="${2:-}"; shift 2 ;;
103
+ --dry-run) DRY_RUN=1; shift ;;
104
+ -h|--help) usage; exit 0 ;;
105
+ *) echo "trigger.sh: unknown flag: $1" >&2; usage >&2; exit 2 ;;
106
+ esac
107
+ done
108
+
109
+ ROOT="$(repo_root)"
110
+ MANIFEST="$ROOT/apps/web-platform/server/inngest/cron-manifest.ts"
111
+
112
+ if [[ "$LIST" -eq 1 ]]; then
113
+ list_events "$MANIFEST"
114
+ exit 0
115
+ fi
116
+
117
+ if [[ -z "$EVENT" ]]; then
118
+ echo "trigger.sh: --event is required (or use --list)" >&2
119
+ usage >&2
120
+ exit 2
121
+ fi
122
+
123
+ case "$CONFIG" in
124
+ prd|dev) ;;
125
+ *) echo "trigger.sh: --config must be 'prd' or 'dev' (got: $CONFIG)" >&2; exit 2 ;;
126
+ esac
127
+
128
+ # Validate the event against the manifest-derived allowlist (fail fast before
129
+ # minting a Doppler read or hitting the route). The `--` stops grep from
130
+ # interpreting an event string that begins with `-` as an option.
131
+ if ! grep -qxF -- "$EVENT" < <(list_events "$MANIFEST"); then
132
+ echo "trigger.sh: '$EVENT' is not an allowlisted manual-trigger event." >&2
133
+ echo "Run 'trigger.sh --list' to see valid events." >&2
134
+ exit 2
135
+ fi
136
+
137
+ # Build the JSON body. --data must be a JSON object if provided.
138
+ if [[ -n "$DATA" ]]; then
139
+ if ! echo "$DATA" | jq -e 'type == "object"' >/dev/null 2>&1; then
140
+ echo "trigger.sh: --data must be a JSON object (got: $DATA)" >&2
141
+ exit 2
142
+ fi
143
+ BODY=$(jq -nc --arg ev "$EVENT" --argjson d "$DATA" '{event: $ev, data: $d}')
144
+ else
145
+ BODY=$(jq -nc --arg ev "$EVENT" '{event: $ev}')
146
+ fi
147
+
148
+ if [[ "$DRY_RUN" -eq 1 ]]; then
149
+ printf '%s\n' "# dry-run (config=$CONFIG): would POST to $ROUTE_URL"
150
+ printf '%s\n' "TOKEN=\$(doppler secrets get $SECRET_NAME -p $DOPPLER_PROJECT -c $CONFIG --plain)"
151
+ # The printed recipe carries a live bearer, so it must TEACH the confined form:
152
+ # `--disable` literally first (it aborts ~/.curlrc parsing, and later is too
153
+ # late) and `--noproxy '*'` (#7873), with the bearer on curl's stdin config
154
+ # channel so a copy-paste never puts the token on argv (#7843).
155
+ printf '%s\n' "curl --disable --noproxy '*' -sS -X POST $ROUTE_URL \\"
156
+ printf '%s\n' " -H 'content-type: application/json' \\"
157
+ printf '%s\n' " -d '$BODY' -w '\\n%{http_code}\\n' \\"
158
+ printf '%s\n' " --config - < <(printf 'header = \"Authorization: Bearer %s\"\\n' \"\$TOKEN\")"
159
+ exit 0
160
+ fi
161
+
162
+ # Read the secret read-only and fire. The token reaches curl on its stdin config
163
+ # channel (never its argument list), is unset right after the call, and is never
164
+ # echoed.
165
+ TOKEN="$(doppler secrets get "$SECRET_NAME" -p "$DOPPLER_PROJECT" -c "$CONFIG" --plain)"
166
+ if [[ -z "$TOKEN" ]]; then
167
+ echo "trigger.sh: $SECRET_NAME is empty in Doppler $DOPPLER_PROJECT/$CONFIG" >&2
168
+ exit 2
169
+ fi
170
+
171
+ # Token-shape guard (never echoes the value): the token is written into curl's stdin
172
+ # config below, so a quote or newline in it would inject a config directive. An unusable
173
+ # token makes zero curl calls and exits 2, the same code as an empty secret, never 0.
174
+ _bearer_ok() { local LC_ALL=C; case "${1:-}" in ''|*[!A-Za-z0-9._~+/=-]*) return 1 ;; esac; }
175
+ if ! _bearer_ok "$TOKEN"; then
176
+ echo "trigger.sh: $SECRET_NAME in Doppler $DOPPLER_PROJECT/$CONFIG has an unexpected shape; nothing was sent" >&2
177
+ exit 2
178
+ fi
179
+
180
+ # mktemp, not $$: a PID is predictable and reused across concurrent runs in shared shells
181
+ # (same reason token-efficiency-report.sh's SHORTSTAT_TMP mktemp+EXIT-trap block rejects it).
182
+ # See ADR-009 Amendment.
183
+ RESP=$(mktemp -t trigger-cron-resp.XXXXXXXX)
184
+ trap 'rm -f "$RESP"' EXIT INT TERM
185
+ HTTP_CODE=$(curl --disable --noproxy '*' -sS -o "$RESP" -w '%{http_code}' \
186
+ -X POST "$ROUTE_URL" \
187
+ -H 'content-type: application/json' \
188
+ -d "$BODY" \
189
+ --config - \
190
+ < <(printf 'header = "Authorization: Bearer %s"\n' "$TOKEN"))
191
+ unset TOKEN
192
+
193
+ echo "HTTP $HTTP_CODE"
194
+ cat "$RESP" 2>/dev/null && echo
195
+ rm -f "$RESP"
196
+
197
+ # 202 = dispatched. Anything else is a failure the caller must act on.
198
+ [[ "$HTTP_CODE" == "202" ]] || exit 1
@@ -0,0 +1,147 @@
1
+ ---
2
+ name: user-set-role
3
+ description: "This skill should be used to promote or demote a user's flag-targeting role across Supabase users.role and the Flagsmith identity trait."
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ <!-- soleur-cloud-mode:start -->
8
+ **Cloud Mode (Devin):** before pipeline work run `bash "${CLAUDE_PLUGIN_ROOT}/scripts/cloud-detect.sh"`. If `CLAUDE_PLUGIN_ROOT` is unset (cloud exec shells do not export it), resolve the root by IDENTITY, never by script basename: for `d` in `"$HOME/.local/share/devin/cli/plugins/cache"` and `/opt/.devin/plugins`, skip unless `[ -d "$d" ]`, then `MANIFEST="$(find "$d" -path '*/.claude-plugin/plugin.json' -exec grep -l '"name"[[:space:]]*:[[:space:]]*"soleur"' {} + 2>/dev/null | head -1)"`, `ROOT="${MANIFEST%/.claude-plugin/plugin.json}"` — one resolution, two consumers: `$ROOT/scripts/cloud-detect.sh` and `$ROOT/scripts/precommit-guard.sh`. (Shape check, not authentication: a planted `{"name":"soleur"}` dir passes — ADR-179 A11.) `local` or `not-local:no-devin-env` proceeds normally; any other `not-local:<reason>` applies `<plugin-root>/devin/INSTRUCTIONS.md` §Cloud Mode: emit the `--banner`, fan out sequentially with `Reviewed-Coverage: sequential-fallback` disclosure (never claim an independent review ran), `message_user` ack before any secrets read or production mutation, and run `precommit-guard.sh` before any `git commit` — hooks do not fire in cloud.
9
+ <!-- soleur-cloud-mode:end -->
10
+
11
+ <!-- grok-harness-invoke:start -->
12
+ **Grok Build (`plugins/soleur/lib/harness.ts` `invokeSkill()`):** Read this SKILL.md in this process and run it to completion. A one-segment `soleur:<name>` in this document names a SKILL — on Grok Build, Read `plugins/soleur/skills/<name>/SKILL.md` in this process; it is not a nested tool_use. A multi-segment id such as `soleur:<domain>:<name>` names an AGENT: spawn it, never Read it, and on Grok Build spawn_subagent takes the id with its colons replaced by hyphens (`agentIdToGrokSubagentType`). **Claude Code:** Skill tool for a skill (`soleur:<name>`), Task tool with `subagent_type` for an agent. Forbidden is executing a subset, not the Read.
13
+ <!-- grok-harness-invoke:end -->
14
+
15
+ # user-set-role
16
+
17
+ The only approved path for mutating `public.users.role`. Migration 054's
18
+ trigger blocks non-service-role connections from updating that column, so
19
+ direct PostgREST writes from authenticated users always fail — this skill
20
+ runs the service-role write + the Flagsmith identity trait write together
21
+ to keep the two sides aligned.
22
+
23
+ ## When to use
24
+
25
+ - Promoting yourself or a teammate to the `dev` cohort so you receive
26
+ per-role flag previews before flags promote to `prd`.
27
+ - Demoting a user back to `prd` when they no longer need preview access.
28
+
29
+ ## When NOT to use
30
+
31
+ - Bulk role changes (>5 users at once) — script doesn't batch; run
32
+ individually for now.
33
+ - Trying to promote a Supabase user that doesn't exist — skill fails
34
+ early with a clear error.
35
+
36
+ ## Arguments
37
+
38
+ <arguments> #$ARGUMENTS </arguments>
39
+
40
+ Required positional args: `<email-or-userId> <prd|dev>`.
41
+
42
+ - `<email-or-userId>`: email address (resolved to UUID via Supabase) OR
43
+ a Supabase auth UUID directly.
44
+ - `<prd|dev>`: target role.
45
+
46
+ Flag `--dry-run` runs lookup + diff (no writes).
47
+
48
+ ## Prerequisites
49
+
50
+ - `doppler` CLI authenticated; access to `soleur/prd` config (for
51
+ `SUPABASE_SERVICE_ROLE_KEY` + `NEXT_PUBLIC_SUPABASE_URL`).
52
+ - `doppler` access to `soleur/cli_ops` (for
53
+ `FLAGSMITH_MANAGEMENT_API_KEY`).
54
+ - `curl` + `python3` on PATH.
55
+
56
+ ## Procedure
57
+
58
+ The agent runs only the preview (`--dry-run` is honoured in the third position
59
+ only; anything else there, or a fourth argument, exits `2`):
60
+
61
+ ```bash
62
+ bash "${CLAUDE_PLUGIN_ROOT}/skills/user-set-role/scripts/set-role.sh" <email|uuid> <prd|dev> --dry-run
63
+ ```
64
+
65
+ ## The write is the one typed-`yes` handoff (ADR-249)
66
+
67
+ The write path asks for a typed `yes` through the operator-script library's TTY
68
+ acknowledgement, because the audit row this script writes records only that kind of
69
+ acknowledgement (ADR-249); moving it to the staged agent-run approval gate that
70
+ generated operator scripts use is tracked in #9387. It has no skip variable and no
71
+ flag. An agent's shell has no TTY, so a write run there stops with exit `64` and `SOLEUR_BOOTSTRAP_INPUT_REQUIRED` on
72
+ stdout, before any credential is fetched. Exit `64` is a refusal, never a success.
73
+ The agent therefore does every other step itself (reads, the dry-run preview,
74
+ preflight, verification) and hands over only the typed-`yes` write:
75
+
76
+ 1. Runs the script with `--dry-run` and shows the preview. That mode needs no TTY
77
+ and makes no writes.
78
+ 2. Prints the exact write command below, in a fenced block, for the operator to type
79
+ at a terminal prompt (Warp), the one step an agent cannot take. It replaces `<WORKTREE>` with the absolute path of
80
+ the worktree that holds this change (`git rev-parse --show-toplevel`) and
81
+ `<ARGS>` with `<email|uuid> <prd|dev>`, without `--dry-run`. It never prints a
82
+ `${CLAUDE_PLUGIN_ROOT}` or repo-relative form. A plugin-root or repo-relative path resolves against whatever directory the operator's terminal happens to be in; the absolute worktree path does not.
83
+ 3. Does not run the command, and does not run it through Claude Code's `!` prefix
84
+ either (whether that gives the command a TTY is unmeasured, ADR-249). The
85
+ printed command is an undone operator step under
86
+ `wg-block-pr-ready-on-undeferred-operator-steps`: record it where the pipeline
87
+ tracks operator steps, and do not mark a PR ready until the operator says it ran.
88
+
89
+ <!-- operator-write-command -->
90
+ ```bash
91
+ cd <WORKTREE> && bash <WORKTREE>/plugins/soleur/skills/user-set-role/scripts/set-role.sh <ARGS>
92
+ ```
93
+
94
+ The operator types `yes` at the prompt. Any other answer stops the script with exit
95
+ `1` and `SOLEUR_BOOTSTRAP_ABORTED stage=ack`, before anything is written.
96
+
97
+ The script (full procedure in [scripts/set-role.sh](./scripts/set-role.sh)):
98
+
99
+ 1. **Validate args** — role in `{prd, dev}`; identifier looks like
100
+ email-or-UUID.
101
+ 2. **Resolve userId** — if input is an email, look up via service-role
102
+ Supabase REST: `GET /rest/v1/users?email=eq.<email>&select=id,role`.
103
+ If input is UUID, use directly + read current role for the diff.
104
+ 3. **Diff** — if `current_role == target_role`, exit 0 ("no change").
105
+ 4. **Print pre/post** — user UUID + email + current role + target role.
106
+ 5. **Operator ack** — a typed `yes` at the TTY prompt per
107
+ `hr-menu-option-ack-not-prod-write-auth` (no flag skips it; no TTY means exit
108
+ `64` before any credential fetch). Both role values change a PRD user.
109
+ 6. **Update Supabase** — `PATCH /rest/v1/users?id=eq.<uuid>` with
110
+ `{ "role": "<target>" }`. Service-role JWT bypasses the trigger.
111
+ 7. **Update Flagsmith identity trait** — POST to
112
+ `/api/v1/environments/{env_id}/identities/{userId}/traits/` with
113
+ `trait_key=role`, `trait_value=<target>`. Done for BOTH dev (env 90722)
114
+ and prd (env 90721) so the user's flag resolution matches in either
115
+ environment.
116
+ 8. **Re-verify** — re-read `users.role` AND the Flagsmith identity trait
117
+ in each env. Assert matches `<target>`.
118
+
119
+ ## Exit codes
120
+
121
+ - `0` — success / no-op / dry-run clean.
122
+ - `1` — validation failure (bad role, malformed identifier), or the operator did
123
+ not type `yes` (`SOLEUR_BOOTSTRAP_ABORTED stage=ack`; nothing written).
124
+ - `2` — prerequisite missing (Doppler, env vars), or a bad third/fourth argument.
125
+ - `3` — user not found in Supabase.
126
+ - `4` — Supabase write failed.
127
+ - `5` — Flagsmith trait write failed (Supabase already updated;
128
+ re-run is idempotent on Supabase side and will re-apply the trait).
129
+ - `64` — a write run with no TTY (`SOLEUR_BOOTSTRAP_INPUT_REQUIRED`): hand the
130
+ command to the operator (above).
131
+
132
+ ## Sharp edges
133
+
134
+ - **30s flag-cache TTL.** The user's resolved flag values won't pick up
135
+ the new role until the per-replica per-role cache TTL elapses (max 30s).
136
+ Skill prints this hint after success.
137
+ - **Trait write is fire-and-forget on the identity side.** Flagsmith
138
+ upserts traits; calling with the same value twice is a no-op.
139
+ - **Email collision.** If two users somehow share an email (shouldn't
140
+ happen — `public.users(email)` is unique), the skill aborts with
141
+ exit 3 + the conflicting UUIDs.
142
+
143
+ ## Cross-references
144
+
145
+ - Migration: `apps/web-platform/supabase/migrations/054_users_role_column.sql`
146
+ - ADR: `knowledge-base/engineering/architecture/decisions/ADR-038-feature-flags-flagsmith.md`
147
+ - Sibling skills: `soleur:flag-set-role`, `soleur:flag-create`
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env bash
2
+ # Promote/demote a Soleur user's flag-targeting role.
3
+ #
4
+ # Contract: SKILL.md in the parent directory.
5
+ # Usage: bash set-role.sh <email|uuid> <prd|dev> [--dry-run]
6
+ #
7
+ # Every write run changes a PRD user (both role values). Run it in your OWN
8
+ # terminal: the ack below needs a person to type yes. An agent runs only
9
+ # `--dry-run` and prints this command for the operator.
10
+ #
11
+ # Exit codes:
12
+ # 0 — success / dry-run
13
+ # 1 — usage error, or the operator did not type yes at the ack
14
+ # (stdout: SOLEUR_BOOTSTRAP_ABORTED stage=ack; nothing mutated)
15
+ # 2 — prerequisite missing, or more than three arguments / a third argument
16
+ # other than --dry-run
17
+ # 3 — user lookup failed
18
+ # 4 — audit append or Supabase update failed
19
+ # 5 — Flagsmith trait write failed
20
+ # 64 — no TTY on stdin for a write run (stdout: SOLEUR_BOOTSTRAP_INPUT_REQUIRED);
21
+ # refused before any credential fetch or network call (#8486)
22
+
23
+ set -euo pipefail
24
+
25
+ # (#7797) Refuse to run under shell tracing. UNCONDITIONAL — deliberately NOT
26
+ # gated on a non-emptiness test of the credential variable, because
27
+ # every credential this script handles (SUPABASE_SERVICE_ROLE_KEY for soleur/prd,
28
+ # which bypasses RLS across every customer's rows, plus the Flagsmith management
29
+ # key) is acquired by `doppler secrets get` BELOW this point, so a conditional arm
30
+ # would test an empty variable at guard time, open, and then trace the acquisition
31
+ # itself. The refusal prints on STDOUT because agent runtimes surface stdout and
32
+ # swallow stderr (knowledge-base/project/constitution.md > Code Style); a swallowed
33
+ # refusal leaves the operator with a bare exit 78 and no explanation.
34
+ case "$-" in
35
+ *x*)
36
+ printf '[FATAL] refusing to run under xtrace: this script handles a live credential and -x would print it (see #7797)\n'
37
+ exit 78
38
+ ;;
39
+ esac
40
+
41
+ # (#7873) `--disable` closes ~/.curlrc and `--noproxy '*'` closes the proxy vars,
42
+ # but neither touches the env that subverts TLS ITSELF. SSLKEYLOGFILE writes the
43
+ # session keys and the CA vars substitute the trust store, so a CURL_CA_BUNDLE
44
+ # MITM of the service-role key works with every other guard fully intact.
45
+ unset SSLKEYLOGFILE CURL_CA_BUNDLE SSL_CERT_FILE SSL_CERT_DIR CURL_HOME \
46
+ HOSTALIASES LOCALDOMAIN RES_OPTIONS
47
+
48
+ # Shared WORM audit-append helper (PostgREST RPC; no DB-CLI binary). See #4581 PR-1.
49
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
50
+ source "$SCRIPT_DIR/../../../scripts/audit-flag-flip.sh"
51
+
52
+ # Human-presence gate (#8486, ADR-249). Every production write below waits on the
53
+ # operator-script library's class-2 ack, which has NO skip variable and no flag:
54
+ # it needs a person typing `yes` at a terminal, so an agent's tool subprocess
55
+ # (no TTY) is refused with exit 64 before any credential fetch. Clear anything an
56
+ # inherited environment could use to pre-empt the library's double-source guard
57
+ # or to stand in for its ack before sourcing it. (BASH_ENV runs before this
58
+ # script and cannot be cleared from inside it — recorded in ADR-249 as a
59
+ # hijack-class residual.)
60
+ unset _SOLEUR_OPERATOR_SCRIPT_LOADED SOLEUR_OP_ACKED
61
+ unset -f soleur_op_ack_or_die soleur_op_input_required soleur_op_aborted
62
+ # shellcheck source=../../../scripts/lib/operator-script.sh
63
+ source "$SCRIPT_DIR/../../../scripts/lib/operator-script.sh"
64
+ [[ ${SOLEUR_OP_LIB_API:-0} -eq 1 ]] || {
65
+ printf 'SOLEUR_BOOTSTRAP_LIB_INCOMPATIBLE need=1 got=%s\n' "${SOLEUR_OP_LIB_API:-0}"
66
+ exit 64
67
+ }
68
+
69
+ readonly FLAGSMITH_API="https://api.flagsmith.com/api/v1"
70
+ readonly FLAGSMITH_ENV_DEV_ID=90722
71
+ readonly FLAGSMITH_ENV_PRD_ID=90721
72
+
73
+ # The parser honours --dry-run ONLY in position 3, so anything else there (or a
74
+ # fourth argument) is refused rather than silently read as a write (#8486).
75
+ [[ $# -le 3 ]] || { echo "set-role.sh takes at most three arguments (got $#)" >&2; exit 2; }
76
+ [[ -z "${3:-}" || "${3:-}" == "--dry-run" ]] || { echo "third argument must be --dry-run (got: ${3})" >&2; exit 2; }
77
+ DRY_RUN=0
78
+ if [[ "${3:-}" == "--dry-run" ]]; then DRY_RUN=1; fi
79
+
80
+ IDENT="${1:-}"
81
+ TARGET="${2:-}"
82
+
83
+ usage() {
84
+ echo "Usage: set-role.sh <email|uuid> <prd|dev> [--dry-run]" >&2
85
+ exit 1
86
+ }
87
+
88
+ [[ -z "$IDENT" || -z "$TARGET" ]] && usage
89
+ [[ "$TARGET" != "prd" && "$TARGET" != "dev" ]] && { echo "role must be prd|dev (got: $TARGET)" >&2; usage; }
90
+
91
+ # UUID v4 regex (loose — Supabase auth uses standard v4).
92
+ UUID_RE='^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'
93
+
94
+ # --- no TTY, no write: refuse before any credential fetch or network call ---
95
+ if [[ $DRY_RUN -eq 0 ]]; then [[ -t 0 ]] || soleur_op_input_required "destructive-write-ack(no-skip-variable-by-design)" ack; fi
96
+
97
+ command -v curl >/dev/null || { echo "missing: curl" >&2; exit 2; }
98
+ command -v doppler >/dev/null || { echo "missing: doppler" >&2; exit 2; }
99
+ command -v python3 >/dev/null || { echo "missing: python3" >&2; exit 2; }
100
+
101
+ SUPA_URL=$(doppler secrets get NEXT_PUBLIC_SUPABASE_URL -p soleur -c prd --plain 2>/dev/null || true)
102
+ SUPA_KEY=$(doppler secrets get SUPABASE_SERVICE_ROLE_KEY -p soleur -c prd --plain 2>/dev/null || true)
103
+ FLAGSMITH_TOKEN=$(doppler secrets get FLAGSMITH_MANAGEMENT_API_KEY -p soleur -c cli_ops --plain 2>/dev/null || true)
104
+ [[ -z "$SUPA_URL" || -z "$SUPA_KEY" ]] && { echo "missing Supabase secrets in soleur/prd" >&2; exit 2; }
105
+ [[ -z "$FLAGSMITH_TOKEN" ]] && { echo "missing FLAGSMITH_MANAGEMENT_API_KEY in soleur/cli_ops" >&2; exit 2; }
106
+
107
+ # Token-shape guard: a newline in the key would inject a curl config directive on the stdin
108
+ # channel below. Never echoes the value.
109
+ _bearer_ok() { local LC_ALL=C; case "${1:-}" in ''|*[!A-Za-z0-9._~+/=-]*) return 1 ;; esac; }
110
+ _bearer_ok "$SUPA_KEY" || { echo "SUPABASE_SERVICE_ROLE_KEY has an unexpected shape" >&2; exit 2; }
111
+
112
+ # The service-role key travels on curl's stdin config channel (both headers), never on argv.
113
+ supa() {
114
+ curl --disable --noproxy '*' -sS -H "Content-Type: application/json" "$@" --config - \
115
+ < <(printf 'header = "apikey: %s"\nheader = "Authorization: Bearer %s"\n' "$SUPA_KEY" "$SUPA_KEY")
116
+ }
117
+
118
+ # The Flagsmith management key travels the same way: a stdin config header, never argv.
119
+ _bearer_ok "$FLAGSMITH_TOKEN" || { echo "FLAGSMITH_MANAGEMENT_API_KEY has an unexpected shape" >&2; exit 2; }
120
+ fs_api() {
121
+ curl --disable --noproxy '*' -sS -H "Content-Type: application/json" "$@" --config - \
122
+ < <(printf 'header = "Authorization: Api-Key %s"\n' "$FLAGSMITH_TOKEN")
123
+ }
124
+
125
+ # --- resolve user ----------------------------------------------------------
126
+ if [[ "$IDENT" =~ $UUID_RE ]]; then
127
+ USER_ID="$IDENT"
128
+ echo "→ Using UUID directly: $USER_ID"
129
+ else
130
+ echo "→ Resolving email '$IDENT' to UUID via Supabase…"
131
+ # URL-encode the email (`+` → `%2B` etc.) so PostgREST receives it intact.
132
+ EMAIL_ENC=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1], safe=''))" "$IDENT")
133
+ ROWS=$(supa "${SUPA_URL}/rest/v1/users?email=eq.${EMAIL_ENC}&select=id,email,role")
134
+ COUNT=$(echo "$ROWS" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(len(d))')
135
+ [[ "$COUNT" == "0" ]] && { echo "no user with email '$IDENT'" >&2; exit 3; }
136
+ [[ "$COUNT" -gt "1" ]] && { echo "MULTIPLE users with email '$IDENT' — abort." >&2; echo "$ROWS" >&2; exit 3; }
137
+ USER_ID=$(echo "$ROWS" | python3 -c 'import json,sys; print(json.load(sys.stdin)[0]["id"])')
138
+ fi
139
+
140
+ # USER_ID is interpolated into the request URL: only a literal-anchored UUID may reach it.
141
+ [[ "$USER_ID" =~ ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ ]] || { echo "refusing: resolved user id is not a UUID" >&2; exit 3; }
142
+
143
+ # Read current role.
144
+ CUR_ROWS=$(supa "${SUPA_URL}/rest/v1/users?id=eq.${USER_ID}&select=id,email,role")
145
+ [[ "$(echo "$CUR_ROWS" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))')" == "0" ]] && { echo "no users.row for UUID $USER_ID" >&2; exit 3; }
146
+ CUR_ROLE=$(echo "$CUR_ROWS" | python3 -c 'import json,sys; print(json.load(sys.stdin)[0]["role"])')
147
+ EMAIL=$(echo "$CUR_ROWS" | python3 -c 'import json,sys; print(json.load(sys.stdin)[0]["email"])')
148
+
149
+ echo " user: $EMAIL ($USER_ID) current role: $CUR_ROLE target: $TARGET"
150
+
151
+ if [[ "$CUR_ROLE" == "$TARGET" ]]; then
152
+ echo "✓ No change — role is already '$TARGET'. Re-applying Flagsmith trait anyway for idempotency."
153
+ if [[ $DRY_RUN -eq 1 ]]; then exit 0; fi
154
+ fi
155
+
156
+ # --- ack ------------------------------------------------------------------
157
+ if [[ $DRY_RUN -eq 1 ]]; then
158
+ echo "(dry-run — exiting 0)"
159
+ exit 0
160
+ fi
161
+
162
+ soleur_op_ack_or_die "Set the role of ${EMAIL} (${USER_ID}) to '${TARGET}' in Supabase prd and Flagsmith (dev + prd) now? Type yes: "
163
+
164
+ # --- audit append (WORM) — BEFORE the users.role mutation (append-before-flip) -------
165
+ # A failed audit must abort the script before any prod mutation; otherwise a role
166
+ # change could land in prd with no WORM accountability row (#4581 review FINDING 1).
167
+ ACTOR=$(doppler secrets get OPERATOR_EMAIL -p soleur -c cli_ops --plain 2>/dev/null | tr '[:upper:]' '[:lower:]')
168
+ [[ -z "$ACTOR" ]] && { echo "FATAL: OPERATOR_EMAIL not in Doppler soleur/cli_ops" >&2; exit 4; }
169
+
170
+ # Audit DB target = soleur/dev (preserves the historical dev-DB audit destination);
171
+ # distinct from the prd SUPA_URL/SUPA_KEY used for the users.role PATCH below.
172
+ # `|| true` normalizes a Doppler auth/network failure to the exit-4 contract (the
173
+ # [[ -z ]] guard) instead of letting `set -e` abort at the assignment with exit 1.
174
+ AUDIT_URL=$(doppler secrets get SUPABASE_URL -p soleur -c dev --plain 2>/dev/null) || true
175
+ AUDIT_SRK=$(doppler secrets get SUPABASE_SERVICE_ROLE_KEY -p soleur -c dev --plain 2>/dev/null) || true
176
+ [[ -z "$AUDIT_URL" || -z "$AUDIT_SRK" ]] && { echo "FATAL: SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY not in Doppler soleur/dev" >&2; exit 4; }
177
+
178
+ # NOTE(#4581): AUDIT_ACTION tautology (both branches "on") is a pre-existing bug,
179
+ # out of scope for the transport swap; see #4593. Role assignment records "on".
180
+ AUDIT_ACTION=$([[ "$CUR_ROLE" == "$TARGET" ]] && echo "on" || echo "on")
181
+ AUDIT_ID=$(audit_flag_flip_rpc "$AUDIT_URL" "$AUDIT_SRK" "user-role" "prd" "user:$USER_ID" "$AUDIT_ACTION" null null "$ACTOR") || exit 4
182
+ echo " audit_id=$AUDIT_ID"
183
+
184
+ # --- update Supabase (AFTER the audit row is committed) -------------------------------
185
+ if [[ "$CUR_ROLE" != "$TARGET" ]]; then
186
+ echo "→ Updating Supabase users.role…"
187
+ RESP=$(supa -X PATCH "${SUPA_URL}/rest/v1/users?id=eq.${USER_ID}" \
188
+ -H 'Prefer: return=representation' \
189
+ -d "{\"role\": \"$TARGET\"}")
190
+ echo "$RESP" | python3 -c '
191
+ import json, sys
192
+ d = json.load(sys.stdin)
193
+ if not isinstance(d, list) or not d:
194
+ print(json.dumps(d), file=sys.stderr); sys.exit(4)
195
+ print(" updated:", d[0]["email"], "role →", d[0]["role"])
196
+ ' || exit 4
197
+ fi
198
+
199
+ # --- update Flagsmith identity trait (both envs) --------------------------
200
+ for ENV_PAIR in "dev:$FLAGSMITH_ENV_DEV_ID" "prd:$FLAGSMITH_ENV_PRD_ID"; do
201
+ ENV_NAME=${ENV_PAIR%:*}
202
+ ENV_ID=${ENV_PAIR#*:}
203
+ echo "→ Writing Flagsmith trait role=$TARGET for identity $USER_ID in env=$ENV_NAME ($ENV_ID)…"
204
+ fs_api -X POST "${FLAGSMITH_API}/environments/${ENV_ID}/identities/${USER_ID}/traits/" \
205
+ -d "{\"trait_key\":\"role\",\"trait_value\":\"$TARGET\"}" \
206
+ | python3 -c '
207
+ import json, sys
208
+ d = json.load(sys.stdin)
209
+ if isinstance(d, dict) and d.get("trait_key") == "role":
210
+ print(" ✓ wrote:", d)
211
+ else:
212
+ print(" ! response:", json.dumps(d), file=sys.stderr); sys.exit(5)
213
+ ' || exit 5
214
+ done
215
+
216
+ echo
217
+ echo "✓ Done. The per-role flag cache TTL is 30s; user's resolved flags update within that window."
218
+ exit 0
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: user-story-writer
3
+ description: "This skill should be used when decomposing feature requirements into granular, implementable user stories. It applies Elephant Carpaccio slicing, INVEST criteria, and story prioritization."
4
+ ---
5
+
6
+ <!-- grok-harness-invoke:start -->
7
+ **Grok Build (`plugins/soleur/lib/harness.ts` `invokeSkill()`):** Read this SKILL.md in this process and run it to completion. A one-segment `soleur:<name>` in this document names a SKILL — on Grok Build, Read `plugins/soleur/skills/<name>/SKILL.md` in this process; it is not a nested tool_use. A multi-segment id such as `soleur:<domain>:<name>` names an AGENT: spawn it, never Read it, and on Grok Build spawn_subagent takes the id with its colons replaced by hyphens (`agentIdToGrokSubagentType`). **Claude Code:** Skill tool for a skill (`soleur:<name>`), Task tool with `subagent_type` for an agent. Forbidden is executing a subset, not the Read.
8
+ <!-- grok-harness-invoke:end -->
9
+
10
+ # User Story Writer
11
+
12
+ Decompose a problem statement or feature requirement into thin, vertical user stories that deliver end-to-end value.
13
+
14
+ ## When to Use
15
+
16
+ - Breaking down a feature into sprint-sized work items
17
+ - Decomposing a vague requirement into concrete stories
18
+ - Prioritizing a backlog by risk and value
19
+
20
+ ## Constraints
21
+
22
+ This is a story-writing role. Do not suggest implementation details, code examples, technical architectures, or testing frameworks. Focus exclusively on user needs, business value, and acceptance criteria in user terms.
23
+
24
+ ## Process
25
+
26
+ ### 1. Analyze the Problem
27
+
28
+ - Identify the core user need and key stakeholders
29
+ - Map the problem domain and user personas
30
+ - Clarify scope boundaries
31
+
32
+ ### 2. Slice with Elephant Carpaccio
33
+
34
+ Break the problem into the thinnest possible vertical slices. Each slice must deliver a complete, working capability a user can interact with -- not a technical layer.
35
+
36
+ ### 3. Write INVEST-Compliant Stories
37
+
38
+ Every story must satisfy all six INVEST criteria (Independent, Negotiable, Valuable, Estimable, Small, Testable).
39
+
40
+ ### 4. Structure Each Story
41
+
42
+ ```
43
+ **Story Title**: [Descriptive name]
44
+ **As a** [user type]
45
+ **I want** [functionality]
46
+ **So that** [business value]
47
+
48
+ **Acceptance Criteria**:
49
+ - [Specific, testable criterion 1]
50
+ - [Specific, testable criterion 2]
51
+
52
+ **Definition of Done**:
53
+ - [User-facing quality requirement]
54
+ - [Business completion criterion]
55
+ ```
56
+
57
+ ### 5. Prioritize and Sequence
58
+
59
+ Order stories by:
60
+
61
+ 1. Risk reduction -- tackle unknowns early
62
+ 2. User value delivery
63
+ 3. Dependencies between stories
64
+ 4. Learning opportunities
65
+
66
+ ### 6. Validate Completeness
67
+
68
+ Confirm the full set of stories covers the original problem without gaps or overlaps.
69
+
70
+ ## Output Format
71
+
72
+ Produce a structured document containing:
73
+
74
+ - Problem summary and user personas
75
+ - Prioritized list of user stories (using the template above)
76
+ - Rationale for decomposition approach and sequencing
77
+ - Summary of how stories collectively solve the original problem