@1aboveio/skills 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 (633) hide show
  1. package/README.md +30 -2
  2. package/bin/cli.mjs +14 -0
  3. package/bin/select-core.mjs +172 -0
  4. package/package.json +146 -4
  5. package/skills/app-dev/airflow/LICENSE +3 -0
  6. package/skills/app-dev/airflow/SKILL.md +199 -0
  7. package/skills/app-dev/airflow/release-check.mjs +93 -0
  8. package/skills/app-dev/android-foundation/LICENSE +3 -0
  9. package/skills/app-dev/android-foundation/SKILL.md +192 -0
  10. package/skills/app-dev/android-foundation/assets/android-ci-job.yml +217 -0
  11. package/skills/app-dev/android-foundation/references/ci.md +87 -0
  12. package/skills/app-dev/android-foundation/references/gotchas.md +221 -0
  13. package/skills/app-dev/android-foundation/references/setup.md +164 -0
  14. package/skills/app-dev/android-foundation/release-check.mjs +93 -0
  15. package/skills/app-dev/android-foundation/scripts/device-run.sh +176 -0
  16. package/skills/app-dev/android-foundation/scripts/device-run.test.mjs +172 -0
  17. package/skills/app-dev/app-debug/LICENSE +3 -0
  18. package/skills/app-dev/app-debug/SKILL.md +110 -0
  19. package/skills/app-dev/app-debug/references/common-errors.md +128 -0
  20. package/skills/app-dev/app-debug/release-check.mjs +93 -0
  21. package/skills/app-dev/better-auth/LICENSE +3 -0
  22. package/skills/app-dev/better-auth/SKILL.md +598 -0
  23. package/skills/app-dev/better-auth/references/feishu-api.md +270 -0
  24. package/skills/app-dev/better-auth/release-check.mjs +93 -0
  25. package/skills/app-dev/data-catalog/LICENSE +3 -0
  26. package/skills/app-dev/data-catalog/SKILL.md +204 -0
  27. package/skills/app-dev/data-catalog/agents/openai.yaml +3 -0
  28. package/skills/app-dev/data-catalog/references/data-catalog-conventions.md +75 -0
  29. package/skills/app-dev/data-catalog/references/field-definitions.md +116 -0
  30. package/skills/app-dev/data-catalog/references/format.md +121 -0
  31. package/skills/app-dev/data-catalog/release-check.mjs +93 -0
  32. package/skills/app-dev/data-catalog/scripts/data-catalog.test.mjs +36 -0
  33. package/skills/app-dev/data-catalog/scripts/data_catalog.py +1392 -0
  34. package/skills/app-dev/data-catalog/scripts/persist-conventions-core.mjs +117 -0
  35. package/skills/app-dev/data-catalog/scripts/persist-conventions.mjs +17 -0
  36. package/skills/app-dev/data-catalog/scripts/test_data_catalog.py +571 -0
  37. package/skills/app-dev/ios-foundation/LICENSE +3 -0
  38. package/skills/app-dev/ios-foundation/SKILL.md +184 -0
  39. package/skills/app-dev/ios-foundation/references/setup.md +243 -0
  40. package/skills/app-dev/ios-foundation/release-check.mjs +93 -0
  41. package/skills/app-dev/monorepo/LICENSE +3 -0
  42. package/skills/app-dev/monorepo/SKILL.md +462 -0
  43. package/skills/app-dev/monorepo/release-check.mjs +93 -0
  44. package/skills/app-dev/nextjs-fullstack/LICENSE +3 -0
  45. package/skills/app-dev/nextjs-fullstack/SKILL.md +211 -0
  46. package/skills/app-dev/nextjs-fullstack/conventions.md +318 -0
  47. package/skills/app-dev/nextjs-fullstack/frontend-conventions.md +61 -0
  48. package/skills/app-dev/nextjs-fullstack/nextjs16.md +287 -0
  49. package/skills/app-dev/nextjs-fullstack/release-check.mjs +93 -0
  50. package/skills/app-dev/nextjs-fullstack/server-actions.md +409 -0
  51. package/skills/app-dev/prisma-setup/LICENSE +3 -0
  52. package/skills/app-dev/prisma-setup/SKILL.md +181 -0
  53. package/skills/app-dev/prisma-setup/nextjs.md +258 -0
  54. package/skills/app-dev/prisma-setup/release-check.mjs +93 -0
  55. package/skills/app-dev/prisma-setup/turborepo.md +301 -0
  56. package/skills/app-dev/pyspark/LICENSE +3 -0
  57. package/skills/app-dev/pyspark/SKILL.md +127 -0
  58. package/skills/app-dev/pyspark/assets/templates/etl.py +748 -0
  59. package/skills/app-dev/pyspark/assets/templates/utils/__init__.py +1 -0
  60. package/skills/app-dev/pyspark/assets/templates/utils/hudi_metadata.py +14 -0
  61. package/skills/app-dev/pyspark/references/diagnosis-and-profiling.md +169 -0
  62. package/skills/app-dev/pyspark/references/etl-contract.md +129 -0
  63. package/skills/app-dev/pyspark/references/production-validation.md +131 -0
  64. package/skills/app-dev/pyspark/references/reconciliation.md +38 -0
  65. package/skills/app-dev/pyspark/references/transformation-design.md +190 -0
  66. package/skills/app-dev/pyspark/references/velocity-feature-calculation.md +193 -0
  67. package/skills/app-dev/pyspark/release-check.mjs +93 -0
  68. package/skills/app-dev/pyspark/scripts/spark_eventlog_summary.py +223 -0
  69. package/skills/app-dev/python-backend/LICENSE +3 -0
  70. package/skills/app-dev/python-backend/SKILL.md +325 -0
  71. package/skills/app-dev/python-backend/assets/uv-install.sh +48 -0
  72. package/skills/app-dev/python-backend/references/uv-installs.md +83 -0
  73. package/skills/app-dev/python-backend/release-check.mjs +93 -0
  74. package/skills/app-dev/shadcn/LICENSE +3 -0
  75. package/skills/app-dev/shadcn/SKILL.md +120 -0
  76. package/skills/app-dev/shadcn/assets/shadcn-small.png +0 -0
  77. package/skills/app-dev/shadcn/assets/shadcn.png +0 -0
  78. package/skills/app-dev/shadcn/cli.md +411 -0
  79. package/skills/app-dev/shadcn/customization.md +224 -0
  80. package/skills/app-dev/shadcn/mcp.md +101 -0
  81. package/skills/app-dev/shadcn/release-check.mjs +93 -0
  82. package/skills/app-dev/shadcn/rules/base-vs-radix.md +323 -0
  83. package/skills/app-dev/shadcn/rules/component-selection.md +67 -0
  84. package/skills/app-dev/shadcn/rules/composition.md +195 -0
  85. package/skills/app-dev/shadcn/rules/data-table.md +201 -0
  86. package/skills/app-dev/shadcn/rules/forms.md +255 -0
  87. package/skills/app-dev/shadcn/rules/icons.md +103 -0
  88. package/skills/app-dev/shadcn/rules/styling.md +167 -0
  89. package/skills/app-dev/zod-v4/LICENSE +3 -0
  90. package/skills/app-dev/zod-v4/SKILL.md +286 -0
  91. package/skills/app-dev/zod-v4/release-check.mjs +93 -0
  92. package/skills/cicd/cloud-build/LICENSE +3 -0
  93. package/skills/cicd/cloud-build/SKILL.md +707 -0
  94. package/skills/cicd/cloud-build/release-check.mjs +93 -0
  95. package/skills/cicd/cloud-debug/LICENSE +3 -0
  96. package/skills/cicd/cloud-debug/SKILL.md +315 -0
  97. package/skills/cicd/cloud-debug/references/build-failures.md +238 -0
  98. package/skills/cicd/cloud-debug/references/deploy-failures.md +376 -0
  99. package/skills/cicd/cloud-debug/references/pipeline-failures.md +378 -0
  100. package/skills/cicd/cloud-debug/release-check.mjs +93 -0
  101. package/skills/cicd/cloud-deploy/LICENSE +3 -0
  102. package/skills/cicd/cloud-deploy/SKILL.md +230 -0
  103. package/skills/cicd/cloud-deploy/references/config-templates.md +257 -0
  104. package/skills/cicd/cloud-deploy/release-check.mjs +93 -0
  105. package/skills/cicd/docker/LICENSE +3 -0
  106. package/skills/cicd/docker/SKILL.md +151 -0
  107. package/skills/cicd/docker/release-check.mjs +93 -0
  108. package/skills/cicd/github-actions/LICENSE +3 -0
  109. package/skills/cicd/github-actions/SKILL.md +111 -0
  110. package/skills/cicd/github-actions/references/audit-profile-optimize.md +150 -0
  111. package/skills/cicd/github-actions/references/ci-case-studies.md +141 -0
  112. package/skills/cicd/github-actions/references/conditional-ci.md +214 -0
  113. package/skills/cicd/github-actions/references/debugging.md +13 -0
  114. package/skills/cicd/github-actions/references/pipeline.md +87 -0
  115. package/skills/cicd/github-actions/references/post-deploy-and-publishing.md +33 -0
  116. package/skills/cicd/github-actions/references/runners.md +253 -0
  117. package/skills/cicd/github-actions/references/security.md +29 -0
  118. package/skills/cicd/github-actions/references/speed-and-audit.md +115 -0
  119. package/skills/cicd/github-actions/references/two-pass-reading.md +92 -0
  120. package/skills/cicd/github-actions/release-check.mjs +93 -0
  121. package/skills/cicd/github-actions/scripts/ci-run-audit-core.mjs +612 -0
  122. package/skills/cicd/github-actions/scripts/ci-run-audit.mjs +4 -0
  123. package/skills/cicd/github-actions/scripts/ci-run-audit.test.mjs +637 -0
  124. package/skills/cicd/github-flow/LICENSE +3 -0
  125. package/skills/cicd/github-flow/SKILL.md +123 -0
  126. package/skills/cicd/github-flow/references/ci-conventions.md +14 -0
  127. package/skills/cicd/github-flow/release-check.mjs +93 -0
  128. package/skills/cicd/github-flow/scripts/flow-core.mjs +105 -0
  129. package/skills/cicd/github-flow/scripts/flow.mjs +81 -0
  130. package/skills/cicd/github-flow/scripts/flow.test.mjs +114 -0
  131. package/skills/cicd/github-flow/scripts/persist-conventions-core.mjs +117 -0
  132. package/skills/cicd/github-flow/scripts/persist-conventions.mjs +49 -0
  133. package/skills/cicd/github-flow/scripts/persist-conventions.test.mjs +108 -0
  134. package/skills/cicd/google-cloud/LICENSE +3 -0
  135. package/skills/cicd/google-cloud/SKILL.md +119 -0
  136. package/skills/cicd/google-cloud/references/gcs.md +469 -0
  137. package/skills/cicd/google-cloud/references/iam.md +451 -0
  138. package/skills/cicd/google-cloud/references/project.md +349 -0
  139. package/skills/cicd/google-cloud/references/secrets.md +336 -0
  140. package/skills/cicd/google-cloud/references/vpc.md +312 -0
  141. package/skills/cicd/google-cloud/release-check.mjs +93 -0
  142. package/skills/cicd/google-cloud/scripts/create-sa.sh +36 -0
  143. package/skills/cicd/google-cloud/scripts/gcp-config.sh +31 -0
  144. package/skills/cicd/google-cloud/scripts/grant-iap.sh +41 -0
  145. package/skills/cicd/google-cloud/scripts/setup-secrets.sh +48 -0
  146. package/skills/cicd/mergify/LICENSE +3 -0
  147. package/skills/cicd/mergify/SKILL.md +102 -0
  148. package/skills/cicd/mergify/assets/templates/mergify.yml +215 -0
  149. package/skills/cicd/mergify/assets/templates/ruleset.json +46 -0
  150. package/skills/cicd/mergify/references/branch-protection.md +282 -0
  151. package/skills/cicd/mergify/references/configuration.md +274 -0
  152. package/skills/cicd/mergify/references/diagnosis.md +109 -0
  153. package/skills/cicd/mergify/references/stacks.md +84 -0
  154. package/skills/cicd/mergify/references/traps.md +119 -0
  155. package/skills/cicd/mergify/references/watch-contract.md +274 -0
  156. package/skills/cicd/mergify/release-check.mjs +93 -0
  157. package/skills/cicd/mergify/scripts/audit-core.mjs +208 -0
  158. package/skills/cicd/mergify/scripts/audit.mjs +4 -0
  159. package/skills/cicd/mergify/scripts/audit.test.mjs +201 -0
  160. package/skills/cicd/mergify/scripts/entrypoints.test.mjs +106 -0
  161. package/skills/cicd/mergify/scripts/pr-620-mergify-comments.fixture.json +30 -0
  162. package/skills/cicd/mergify/scripts/stack-push-core.mjs +258 -0
  163. package/skills/cicd/mergify/scripts/stack-push.mjs +4 -0
  164. package/skills/cicd/mergify/scripts/stack-push.test.mjs +233 -0
  165. package/skills/cicd/mergify/scripts/watch-pr-delivery-core.mjs +1065 -0
  166. package/skills/cicd/mergify/scripts/watch-pr-delivery.mjs +4 -0
  167. package/skills/cicd/mergify/scripts/watch-pr-delivery.test.mjs +1826 -0
  168. package/skills/cicd/podman/LICENSE +3 -0
  169. package/skills/cicd/podman/SKILL.md +71 -0
  170. package/skills/cicd/podman/agents/openai.yaml +4 -0
  171. package/skills/cicd/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
  172. package/skills/cicd/podman/assets/templates/podman-service-override.conf +3 -0
  173. package/skills/cicd/podman/references/compose-compatibility.md +70 -0
  174. package/skills/cicd/podman/references/networking-and-ports.md +74 -0
  175. package/skills/cicd/podman/references/rootless-services-and-sockets.md +156 -0
  176. package/skills/cicd/podman/references/troubleshooting.md +98 -0
  177. package/skills/cicd/podman/release-check.mjs +93 -0
  178. package/skills/content/article-review/LICENSE +3 -0
  179. package/skills/content/article-review/SKILL.md +66 -0
  180. package/skills/content/article-review/references/report-format.md +68 -0
  181. package/skills/content/article-review/references/template-guide.md +79 -0
  182. package/skills/content/article-review/references/template-wechat-payments.md +125 -0
  183. package/skills/content/article-review/release-check.mjs +93 -0
  184. package/skills/content/article-to-image/LICENSE +3 -0
  185. package/skills/content/article-to-image/SKILL.md +91 -0
  186. package/skills/content/article-to-image/references/formats.md +53 -0
  187. package/skills/content/article-to-image/release-check.mjs +93 -0
  188. package/skills/content/flowchart-svg/LICENSE +3 -0
  189. package/skills/content/flowchart-svg/SKILL.md +43 -0
  190. package/skills/content/flowchart-svg/release-check.mjs +93 -0
  191. package/skills/content/flowchart-svg/scripts/export_png.sh +8 -0
  192. package/skills/content/image-gen/LICENSE +3 -0
  193. package/skills/content/image-gen/SKILL.md +192 -0
  194. package/skills/content/image-gen/release-check.mjs +93 -0
  195. package/skills/content/image-gen/scripts/credentials.mjs +217 -0
  196. package/skills/content/image-gen/scripts/credentials.test.mjs +212 -0
  197. package/skills/content/image-gen/scripts/generate.mjs +240 -0
  198. package/skills/content/image-gen/scripts/options.mjs +293 -0
  199. package/skills/content/image-gen/scripts/options.test.mjs +245 -0
  200. package/skills/content/mermaid/LICENSE +3 -0
  201. package/skills/content/mermaid/SKILL.md +635 -0
  202. package/skills/content/mermaid/release-check.mjs +93 -0
  203. package/skills/content/wechat-article-writer/LICENSE +3 -0
  204. package/skills/content/wechat-article-writer/SKILL.md +92 -0
  205. package/skills/content/wechat-article-writer/references/style-selector.md +133 -0
  206. package/skills/content/wechat-article-writer/references/writing-rules.md +152 -0
  207. package/skills/content/wechat-article-writer/release-check.mjs +93 -0
  208. package/skills/content/wechat-article-writer/templates/wechat-comparison.md +52 -0
  209. package/skills/content/wechat-article-writer/templates/wechat-howto.md +51 -0
  210. package/skills/content/wechat-article-writer/templates/wechat-insight.md +50 -0
  211. package/skills/content/wechat-article-writer/templates/wechat-pitfall.md +52 -0
  212. package/skills/content/wechat-publisher/LICENSE +3 -0
  213. package/skills/content/wechat-publisher/SKILL.md +171 -0
  214. package/skills/content/wechat-publisher/references/api.md +105 -0
  215. package/skills/content/wechat-publisher/references/layout-rules.md +57 -0
  216. package/skills/content/wechat-publisher/references/wechat-safe-template.html +86 -0
  217. package/skills/content/wechat-publisher/release-check.mjs +93 -0
  218. package/skills/content/wechat-publisher/scripts/md_to_wechat_html.py +194 -0
  219. package/skills/content/wechat-publisher/scripts/publish.py +239 -0
  220. package/skills/content/wechat-search/LICENSE +3 -0
  221. package/skills/content/wechat-search/SKILL.md +211 -0
  222. package/skills/content/wechat-search/release-check.mjs +93 -0
  223. package/skills/content/wechat-search/scripts/start-chrome.sh +83 -0
  224. package/skills/content/xai-search/LICENSE +3 -0
  225. package/skills/content/xai-search/SKILL.md +79 -0
  226. package/skills/content/xai-search/release-check.mjs +93 -0
  227. package/skills/content/xai-search/scripts/xai_search.sh +187 -0
  228. package/skills/content/xai-search/tests/smoke_test.sh +36 -0
  229. package/skills/core/distill-writing/LICENSE +3 -0
  230. package/skills/core/distill-writing/SKILL.md +74 -0
  231. package/skills/core/distill-writing/references/extraction.md +95 -0
  232. package/skills/core/distill-writing/references/updating.md +46 -0
  233. package/skills/core/distill-writing/release-check.mjs +93 -0
  234. package/skills/core/doc-to-md/LICENSE +3 -0
  235. package/skills/core/doc-to-md/SKILL.md +78 -0
  236. package/skills/core/doc-to-md/release-check.mjs +93 -0
  237. package/skills/core/doc-to-md/scripts/convert.py +157 -0
  238. package/skills/core/editorial-review/LICENSE +3 -0
  239. package/skills/core/editorial-review/SKILL.md +79 -0
  240. package/skills/core/editorial-review/references/checklist.md +94 -0
  241. package/skills/core/editorial-review/release-check.mjs +93 -0
  242. package/skills/core/house-style/LICENSE +3 -0
  243. package/skills/core/house-style/SKILL.md +33 -0
  244. package/skills/core/house-style/references/defaults.md +66 -0
  245. package/skills/core/house-style/references/rules.md +267 -0
  246. package/skills/core/house-style/references/sources.md +27 -0
  247. package/skills/core/house-style/references/style-en.md +131 -0
  248. package/skills/core/house-style/references/style-zh.md +141 -0
  249. package/skills/core/house-style/references/terminology-zh.md +223 -0
  250. package/skills/core/house-style/release-check.mjs +93 -0
  251. package/skills/core/house-style/templates/brd.md +103 -0
  252. package/skills/core/house-style/templates/commercial-proposal.md +93 -0
  253. package/skills/core/house-style/templates/compliance-policy.md +109 -0
  254. package/skills/core/house-style/templates/gap-analysis.md +105 -0
  255. package/skills/core/house-style/templates/general.md +63 -0
  256. package/skills/core/house-style/templates/integration-guide.md +98 -0
  257. package/skills/core/house-style/templates/prd.md +81 -0
  258. package/skills/core/house-style/templates/risk-operations-procedure.md +94 -0
  259. package/skills/core/house-style/templates/technical-spec.md +96 -0
  260. package/skills/core/polish-cn/LICENSE +3 -0
  261. package/skills/core/polish-cn/SKILL.md +102 -0
  262. package/skills/core/polish-cn/references/brief.md +93 -0
  263. package/skills/core/polish-cn/references/models.md +76 -0
  264. package/skills/core/polish-cn/release-check.mjs +93 -0
  265. package/skills/core/polish-cn/scripts/polish-cn.test.mjs +244 -0
  266. package/skills/core/polish-cn/scripts/polish_blocks.py +489 -0
  267. package/skills/core/reg-parser/LICENSE +3 -0
  268. package/skills/core/reg-parser/SKILL.md +212 -0
  269. package/skills/core/reg-parser/references/checklist-schema.md +223 -0
  270. package/skills/core/reg-parser/references/checklists/hk-amlo-checklist.json +1306 -0
  271. package/skills/core/reg-parser/references/checklists/hk-amlo-checklist.md +469 -0
  272. package/skills/core/reg-parser/references/checklists/hk-fi-corporate-onboarding-cdd-checklist.json +634 -0
  273. package/skills/core/reg-parser/references/checklists/hk-fi-corporate-onboarding-cdd-checklist.md +233 -0
  274. package/skills/core/reg-parser/references/checklists/hk-mso-guideline-checklist.json +2194 -0
  275. package/skills/core/reg-parser/references/checklists/hk-mso-guideline-checklist.md +771 -0
  276. package/skills/core/reg-parser/references/checklists/kyc-aml-checklist.md +258 -0
  277. package/skills/core/reg-parser/references/checklists/visa-vars-checklist.md +1058 -0
  278. package/skills/core/reg-parser/references/mandates/hk-amlo-cap615.md +389 -0
  279. package/skills/core/reg-parser/references/mandates/visa-vars.md +205 -0
  280. package/skills/core/reg-parser/release-check.mjs +93 -0
  281. package/skills/core/reg-parser/scripts/compare_checklist.py +230 -0
  282. package/skills/core/reg-parser/scripts/dump_checklist.py +361 -0
  283. package/skills/core/reg-parser/scripts/preprocess-mandate.sh +187 -0
  284. package/skills/core/reg-parser/scripts/reg-parser.test.mjs +165 -0
  285. package/skills/core/reg-parser/scripts/test_quarantine.sh +105 -0
  286. package/skills/core/reg-parser/scripts/validate_checklist.py +563 -0
  287. package/skills/core/reg-parser/scripts/validate_mandate.py +273 -0
  288. package/skills/core/terminology/LICENSE +3 -0
  289. package/skills/core/terminology/SKILL.md +62 -0
  290. package/skills/core/terminology/references/format.md +50 -0
  291. package/skills/core/terminology/references/init.md +32 -0
  292. package/skills/core/terminology/release-check.mjs +93 -0
  293. package/skills/core/write-doc/LICENSE +3 -0
  294. package/skills/core/write-doc/SKILL.md +141 -0
  295. package/skills/core/write-doc/references/bilingual.md +60 -0
  296. package/skills/core/write-doc/release-check.mjs +93 -0
  297. package/skills/engineering/better-review/LICENSE +3 -0
  298. package/skills/engineering/better-review/SKILL.md +249 -0
  299. package/skills/engineering/better-review/agents/openai.yaml +9 -0
  300. package/skills/engineering/better-review/references/domain-hazards.md +53 -0
  301. package/skills/engineering/better-review/references/passes.md +147 -0
  302. package/skills/engineering/better-review/references/result.md +151 -0
  303. package/skills/engineering/better-review/release-check.mjs +93 -0
  304. package/skills/engineering/better-review/scripts/pr-context.mjs +212 -0
  305. package/skills/engineering/better-review/scripts/pr-context.test.mjs +168 -0
  306. package/skills/engineering/better-review/scripts/rereview-scope.mjs +503 -0
  307. package/skills/engineering/better-review/scripts/rereview-scope.test.mjs +587 -0
  308. package/skills/engineering/better-review/scripts/scan-diff.mjs +365 -0
  309. package/skills/engineering/better-review/scripts/scan-diff.test.mjs +414 -0
  310. package/skills/engineering/better-review/scripts/vendor-sync.test.mjs +96 -0
  311. package/skills/engineering/e2e-test/LICENSE +3 -0
  312. package/skills/engineering/e2e-test/SKILL.md +98 -0
  313. package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +24 -0
  314. package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
  315. package/skills/engineering/e2e-test/references/authoring/playwright-config.md +73 -0
  316. package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +144 -0
  317. package/skills/engineering/e2e-test/references/ci-integration.md +25 -0
  318. package/skills/engineering/e2e-test/references/ci-playwright-container.md +290 -0
  319. package/skills/engineering/e2e-test/references/presentation-sweep.md +104 -0
  320. package/skills/engineering/e2e-test/references/reviewing.md +41 -0
  321. package/skills/engineering/e2e-test/references/route-manifest.md +51 -0
  322. package/skills/engineering/e2e-test/release-check.mjs +93 -0
  323. package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
  324. package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
  325. package/skills/engineering/e2e-test/scripts/presentation-checks.test.mjs +106 -0
  326. package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
  327. package/skills/engineering/e2e-test/scripts/presentation-perceivability.test.mjs +117 -0
  328. package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
  329. package/skills/engineering/e2e-test/scripts/presentation-reachability.test.mjs +69 -0
  330. package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
  331. package/skills/engineering/e2e-test/scripts/presentation-render-health.test.mjs +98 -0
  332. package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +147 -0
  333. package/skills/engineering/e2e-test/scripts/presentation-sweep.test.mjs +71 -0
  334. package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
  335. package/skills/engineering/e2e-test/scripts/presentation-temporal.test.mjs +59 -0
  336. package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +82 -0
  337. package/skills/engineering/e2e-test/scripts/project-route-manifest.test.mjs +76 -0
  338. package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
  339. package/skills/engineering/engineering-runtime/LICENSE +3 -0
  340. package/skills/engineering/engineering-runtime/SKILL.md +11 -0
  341. package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
  342. package/skills/engineering/engineering-runtime/coherence/workflow.json +597 -0
  343. package/skills/engineering/engineering-runtime/engineering-runtime.test.mjs +68 -0
  344. package/skills/engineering/engineering-runtime/release-check.mjs +93 -0
  345. package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
  346. package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
  347. package/skills/engineering/engineering-runtime/scripts/invocation-policy.mjs +187 -0
  348. package/skills/engineering/engineering-runtime/scripts/invocation-policy.test.mjs +95 -0
  349. package/skills/engineering/engineering-runtime/scripts/main-module.mjs +79 -0
  350. package/skills/engineering/engineering-runtime/scripts/main-module.test.mjs +288 -0
  351. package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
  352. package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
  353. package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
  354. package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
  355. package/skills/engineering/engineering-runtime/scripts/required-check-plan.test.mjs +96 -0
  356. package/skills/engineering/engineering-runtime/scripts/review-completion.mjs +56 -0
  357. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +595 -0
  358. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +189 -0
  359. package/skills/engineering/engineering-runtime/scripts/yaml-mapping.mjs +18 -0
  360. package/skills/engineering/ensure-coverage/LICENSE +3 -0
  361. package/skills/engineering/ensure-coverage/SKILL.md +129 -0
  362. package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +92 -0
  363. package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +85 -0
  364. package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
  365. package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
  366. package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
  367. package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +19 -0
  368. package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
  369. package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +57 -0
  370. package/skills/engineering/ensure-coverage/references/depth/test-smells.md +39 -0
  371. package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +44 -0
  372. package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +110 -0
  373. package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +35 -0
  374. package/skills/engineering/ensure-coverage/references/presentation/axis.md +64 -0
  375. package/skills/engineering/ensure-coverage/references/process/audit-mode.md +27 -0
  376. package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
  377. package/skills/engineering/ensure-coverage/references/process/test-strategy.md +56 -0
  378. package/skills/engineering/ensure-coverage/release-check.mjs +93 -0
  379. package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +67 -0
  380. package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +140 -0
  381. package/skills/engineering/ensure-coverage/scripts/README.md +99 -0
  382. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +182 -0
  383. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.test.mjs +96 -0
  384. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +105 -0
  385. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.test.mjs +47 -0
  386. package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +137 -0
  387. package/skills/engineering/ensure-coverage/scripts/ci-audit.test.mjs +86 -0
  388. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +674 -0
  389. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.test.mjs +447 -0
  390. package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
  391. package/skills/engineering/ensure-coverage/scripts/design-parity.test.mjs +552 -0
  392. package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +282 -0
  393. package/skills/engineering/ensure-coverage/scripts/lint-tests.test.mjs +289 -0
  394. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
  395. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.test.mjs +119 -0
  396. package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
  397. package/skills/engineering/golden-path/LICENSE +3 -0
  398. package/skills/engineering/golden-path/SKILL.md +230 -0
  399. package/skills/engineering/golden-path/agents/openai.yaml +3 -0
  400. package/skills/engineering/golden-path/assets/golden-paths.example.json +57 -0
  401. package/skills/engineering/golden-path/references/contract.md +239 -0
  402. package/skills/engineering/golden-path/references/migration.md +111 -0
  403. package/skills/engineering/golden-path/release-check.mjs +93 -0
  404. package/skills/engineering/golden-path/scripts/golden-path-core.mjs +1779 -0
  405. package/skills/engineering/golden-path/scripts/golden-path.mjs +6 -0
  406. package/skills/engineering/golden-path/scripts/golden-path.test.mjs +1457 -0
  407. package/skills/engineering/harness-runtime/LICENSE +3 -0
  408. package/skills/engineering/harness-runtime/SKILL.md +19 -0
  409. package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
  410. package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
  411. package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
  412. package/skills/engineering/harness-runtime/contracts.md +15 -0
  413. package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
  414. package/skills/engineering/harness-runtime/discover-models.test.mjs +363 -0
  415. package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
  416. package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
  417. package/skills/engineering/harness-runtime/harness-runtime.test.mjs +967 -0
  418. package/skills/engineering/harness-runtime/index.mjs +767 -0
  419. package/skills/engineering/harness-runtime/model-catalog-seed.test.mjs +829 -0
  420. package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
  421. package/skills/engineering/harness-runtime/model-catalog.test.mjs +366 -0
  422. package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
  423. package/skills/engineering/harness-runtime/references/model-catalog-seed.json +408 -0
  424. package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
  425. package/skills/engineering/harness-runtime/release-check.mjs +93 -0
  426. package/skills/engineering/resolve-issues/LICENSE +3 -0
  427. package/skills/engineering/resolve-issues/SKILL.md +250 -0
  428. package/skills/engineering/resolve-issues/agents/openai.yaml +9 -0
  429. package/skills/engineering/resolve-issues/plugin-hooks.json +17 -0
  430. package/skills/engineering/resolve-issues/references/canary.md +28 -0
  431. package/skills/engineering/resolve-issues/references/ci.md +105 -0
  432. package/skills/engineering/resolve-issues/references/done.md +25 -0
  433. package/skills/engineering/resolve-issues/references/dropbox.md +90 -0
  434. package/skills/engineering/resolve-issues/references/expire.md +318 -0
  435. package/skills/engineering/resolve-issues/references/exploration.md +202 -0
  436. package/skills/engineering/resolve-issues/references/implementation.md +303 -0
  437. package/skills/engineering/resolve-issues/references/preflight.md +445 -0
  438. package/skills/engineering/resolve-issues/references/review.md +228 -0
  439. package/skills/engineering/resolve-issues/references/shared-modules.md +44 -0
  440. package/skills/engineering/resolve-issues/references/task-plan.md +264 -0
  441. package/skills/engineering/resolve-issues/release-check.mjs +93 -0
  442. package/skills/engineering/resolve-issues/scripts/cleanup-runs.mjs +364 -0
  443. package/skills/engineering/resolve-issues/scripts/cleanup-runs.test.mjs +280 -0
  444. package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
  445. package/skills/engineering/resolve-issues/scripts/dropbox.mjs +473 -0
  446. package/skills/engineering/resolve-issues/scripts/dropbox.test.mjs +346 -0
  447. package/skills/engineering/resolve-issues/scripts/findings-reuse.mjs +98 -0
  448. package/skills/engineering/resolve-issues/scripts/findings-reuse.test.mjs +88 -0
  449. package/skills/engineering/resolve-issues/scripts/github-reviews.mjs +384 -0
  450. package/skills/engineering/resolve-issues/scripts/github-reviews.test.mjs +264 -0
  451. package/skills/engineering/resolve-issues/scripts/install-hooks.mjs +135 -0
  452. package/skills/engineering/resolve-issues/scripts/install-hooks.test.mjs +79 -0
  453. package/skills/engineering/resolve-issues/scripts/issue-tree.mjs +162 -0
  454. package/skills/engineering/resolve-issues/scripts/issue-tree.test.mjs +107 -0
  455. package/skills/engineering/resolve-issues/scripts/manual-invocation.test.mjs +14 -0
  456. package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
  457. package/skills/engineering/resolve-issues/scripts/next-actions-capacity.test.mjs +149 -0
  458. package/skills/engineering/resolve-issues/scripts/next-actions.mjs +856 -0
  459. package/skills/engineering/resolve-issues/scripts/next-actions.test.mjs +915 -0
  460. package/skills/engineering/resolve-issues/scripts/plan-sync.mjs +269 -0
  461. package/skills/engineering/resolve-issues/scripts/plan-sync.test.mjs +156 -0
  462. package/skills/engineering/resolve-issues/scripts/preflight-models.mjs +736 -0
  463. package/skills/engineering/resolve-issues/scripts/preflight-models.test.mjs +448 -0
  464. package/skills/engineering/resolve-issues/scripts/ready-check.mjs +185 -0
  465. package/skills/engineering/resolve-issues/scripts/ready-check.test.mjs +217 -0
  466. package/skills/engineering/resolve-issues/scripts/rehydrate.mjs +98 -0
  467. package/skills/engineering/resolve-issues/scripts/rehydrate.test.mjs +91 -0
  468. package/skills/engineering/resolve-issues/scripts/review-verdict.mjs +509 -0
  469. package/skills/engineering/resolve-issues/scripts/review-verdict.test.mjs +1060 -0
  470. package/skills/engineering/resolve-issues/scripts/size-check.mjs +492 -0
  471. package/skills/engineering/resolve-issues/scripts/size-check.test.mjs +458 -0
  472. package/skills/engineering/resolve-release/LICENSE +3 -0
  473. package/skills/engineering/resolve-release/SKILL.md +215 -0
  474. package/skills/engineering/resolve-release/agents/openai.yaml +8 -0
  475. package/skills/engineering/resolve-release/flows/cloud-run-canary.md +13 -0
  476. package/skills/engineering/resolve-release/flows/cloud-run.md +7 -0
  477. package/skills/engineering/resolve-release/flows/root-tag-npm.md +13 -0
  478. package/skills/engineering/resolve-release/flows/workspace-npm.md +22 -0
  479. package/skills/engineering/resolve-release/references/canary.md +51 -0
  480. package/skills/engineering/resolve-release/references/candidate.md +41 -0
  481. package/skills/engineering/resolve-release/references/cut.md +131 -0
  482. package/skills/engineering/resolve-release/references/dark-launch.md +66 -0
  483. package/skills/engineering/resolve-release/references/flows.md +150 -0
  484. package/skills/engineering/resolve-release/references/preflight.md +154 -0
  485. package/skills/engineering/resolve-release/references/prepared-metadata.md +260 -0
  486. package/skills/engineering/resolve-release/references/promotion.md +82 -0
  487. package/skills/engineering/resolve-release/references/publish.md +232 -0
  488. package/skills/engineering/resolve-release/references/workspace-npm.md +103 -0
  489. package/skills/engineering/resolve-release/release-check.mjs +93 -0
  490. package/skills/engineering/resolve-release/scripts/apply.mjs +212 -0
  491. package/skills/engineering/resolve-release/scripts/apply.test.mjs +99 -0
  492. package/skills/engineering/resolve-release/scripts/dark-flags.mjs +134 -0
  493. package/skills/engineering/resolve-release/scripts/dark-flags.test.mjs +100 -0
  494. package/skills/engineering/resolve-release/scripts/flow.mjs +500 -0
  495. package/skills/engineering/resolve-release/scripts/flow.test.mjs +340 -0
  496. package/skills/engineering/resolve-release/scripts/green-head.mjs +231 -0
  497. package/skills/engineering/resolve-release/scripts/green-head.test.mjs +101 -0
  498. package/skills/engineering/resolve-release/scripts/npm-version-absence.mjs +138 -0
  499. package/skills/engineering/resolve-release/scripts/npm-version-absence.test.mjs +426 -0
  500. package/skills/engineering/resolve-release/scripts/plan-npm.test.mjs +659 -0
  501. package/skills/engineering/resolve-release/scripts/plan-toml-boundary.test.mjs +317 -0
  502. package/skills/engineering/resolve-release/scripts/plan-uv.test.mjs +291 -0
  503. package/skills/engineering/resolve-release/scripts/plan.mjs +806 -0
  504. package/skills/engineering/resolve-release/scripts/plan.test.mjs +428 -0
  505. package/skills/engineering/rush-issues/LICENSE +3 -0
  506. package/skills/engineering/rush-issues/SKILL.md +58 -0
  507. package/skills/engineering/rush-issues/agents/openai.yaml +8 -0
  508. package/skills/engineering/rush-issues/rehydrate.mjs +10 -0
  509. package/skills/engineering/rush-issues/release-check.mjs +93 -0
  510. package/skills/engineering/rush-release/LICENSE +3 -0
  511. package/skills/engineering/rush-release/SKILL.md +35 -0
  512. package/skills/engineering/rush-release/agents/openai.yaml +8 -0
  513. package/skills/engineering/rush-release/release-check.mjs +93 -0
  514. package/skills/engineering/test-quality/LICENSE +3 -0
  515. package/skills/engineering/test-quality/SKILL.md +79 -0
  516. package/skills/engineering/test-quality/references/audit.md +80 -0
  517. package/skills/engineering/test-quality/references/lint.md +24 -0
  518. package/skills/engineering/test-quality/references/principles.md +143 -0
  519. package/skills/engineering/test-quality/references/testing-conventions.md +9 -0
  520. package/skills/engineering/test-quality/release-check.mjs +93 -0
  521. package/skills/engineering/test-quality/scripts/lint-tests.mjs +574 -0
  522. package/skills/engineering/test-quality/scripts/lint-tests.test.mjs +591 -0
  523. package/skills/engineering/test-quality/scripts/mock-policy-config.mjs +176 -0
  524. package/skills/engineering/test-quality/scripts/mock-policy-config.test.mjs +119 -0
  525. package/skills/engineering/test-quality/scripts/persist-conventions-core.mjs +117 -0
  526. package/skills/engineering/test-quality/scripts/persist-conventions.mjs +17 -0
  527. package/skills/engineering/test-quality/scripts/persist-conventions.test.mjs +104 -0
  528. package/skills/risk-compliance/compliance-audit/LICENSE +3 -0
  529. package/skills/risk-compliance/compliance-audit/SKILL.md +439 -0
  530. package/skills/risk-compliance/compliance-audit/references/findings-schema.md +293 -0
  531. package/skills/risk-compliance/compliance-audit/references/normalization-rules.md +45 -0
  532. package/skills/risk-compliance/compliance-audit/references/vars-checklist.md +1068 -0
  533. package/skills/risk-compliance/compliance-audit/references/vars-findings-schema.md +398 -0
  534. package/skills/risk-compliance/compliance-audit/release-check.mjs +93 -0
  535. package/skills/risk-compliance/compliance-audit/scripts/compliance-audit.test.mjs +14 -0
  536. package/skills/risk-compliance/compliance-audit/scripts/export_tracker_xlsx.py +221 -0
  537. package/skills/risk-compliance/compliance-audit/scripts/reconcile_tracker.py +458 -0
  538. package/skills/risk-compliance/compliance-audit/scripts/test_export_tracker_xlsx.py +97 -0
  539. package/skills/risk-compliance/compliance-audit/scripts/test_validate_tracker.py +157 -0
  540. package/skills/risk-compliance/compliance-audit/scripts/validate_tracker.py +829 -0
  541. package/skills/risk-compliance/contract-compare/LICENSE +3 -0
  542. package/skills/risk-compliance/contract-compare/SKILL.md +199 -0
  543. package/skills/risk-compliance/contract-compare/references/comparison-dimensions.md +209 -0
  544. package/skills/risk-compliance/contract-compare/release-check.mjs +93 -0
  545. package/skills/risk-compliance/contract-review/LICENSE +3 -0
  546. package/skills/risk-compliance/contract-review/SKILL.md +240 -0
  547. package/skills/risk-compliance/contract-review/references/review-criteria.md +223 -0
  548. package/skills/risk-compliance/contract-review/release-check.mjs +93 -0
  549. package/skills/risk-compliance/doc-authenticity/LICENSE +3 -0
  550. package/skills/risk-compliance/doc-authenticity/SKILL.md +160 -0
  551. package/skills/risk-compliance/doc-authenticity/agents/openai.yaml +8 -0
  552. package/skills/risk-compliance/doc-authenticity/manual-invocation.test.mjs +12 -0
  553. package/skills/risk-compliance/doc-authenticity/references/agreement.md +66 -0
  554. package/skills/risk-compliance/doc-authenticity/references/bank-statement.md +150 -0
  555. package/skills/risk-compliance/doc-authenticity/references/forensic-signals.md +157 -0
  556. package/skills/risk-compliance/doc-authenticity/references/image-signals.md +114 -0
  557. package/skills/risk-compliance/doc-authenticity/references/invoice.md +66 -0
  558. package/skills/risk-compliance/doc-authenticity/references/issuer-profiles.md +86 -0
  559. package/skills/risk-compliance/doc-authenticity/references/verdict-and-report.md +95 -0
  560. package/skills/risk-compliance/doc-authenticity/references/verdict.schema.json +81 -0
  561. package/skills/risk-compliance/doc-authenticity/release-check.mjs +93 -0
  562. package/skills/risk-compliance/doc-authenticity/scripts/image_forensics.py +294 -0
  563. package/skills/risk-compliance/doc-authenticity/scripts/pdf_forensics.py +401 -0
  564. package/skills/risk-compliance/doc-authenticity/scripts/validate_codes.py +224 -0
  565. package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.py +308 -0
  566. package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.test.mjs +212 -0
  567. package/skills/risk-compliance/fraud-analysis/LICENSE +3 -0
  568. package/skills/risk-compliance/fraud-analysis/SKILL.md +114 -0
  569. package/skills/risk-compliance/fraud-analysis/references/archetypes/authorized-payment-scam.md +41 -0
  570. package/skills/risk-compliance/fraud-analysis/references/archetypes/first-party-fraud.md +44 -0
  571. package/skills/risk-compliance/fraud-analysis/references/archetypes/third-party-fraud.md +27 -0
  572. package/skills/risk-compliance/fraud-analysis/references/contexts/bank-transfer.md +24 -0
  573. package/skills/risk-compliance/fraud-analysis/references/contexts/card-payment.md +30 -0
  574. package/skills/risk-compliance/fraud-analysis/references/contexts/payment-collection.md +20 -0
  575. package/skills/risk-compliance/fraud-analysis/references/contexts/payout.md +20 -0
  576. package/skills/risk-compliance/fraud-analysis/references/feature-engineering.md +158 -0
  577. package/skills/risk-compliance/fraud-analysis/references/mechanisms/account-takeover.md +36 -0
  578. package/skills/risk-compliance/fraud-analysis/references/report-rationale.md +45 -0
  579. package/skills/risk-compliance/fraud-analysis/references/report-template.md +190 -0
  580. package/skills/risk-compliance/fraud-analysis/references/review-checklist.md +175 -0
  581. package/skills/risk-compliance/fraud-analysis/references/taxonomy.md +79 -0
  582. package/skills/risk-compliance/fraud-analysis/references/terminology.md +108 -0
  583. package/skills/risk-compliance/fraud-analysis/references/workflow.md +175 -0
  584. package/skills/risk-compliance/fraud-analysis/release-check.mjs +93 -0
  585. package/skills/risk-compliance/payment-analysis/LICENSE +3 -0
  586. package/skills/risk-compliance/payment-analysis/SKILL.md +180 -0
  587. package/skills/risk-compliance/payment-analysis/references/auth-rate-actions.md +30 -0
  588. package/skills/risk-compliance/payment-analysis/references/chargebacks.md +208 -0
  589. package/skills/risk-compliance/payment-analysis/references/chinese-polish.md +51 -0
  590. package/skills/risk-compliance/payment-analysis/references/event-layers.md +127 -0
  591. package/skills/risk-compliance/payment-analysis/references/fx.md +59 -0
  592. package/skills/risk-compliance/payment-analysis/references/journey.md +79 -0
  593. package/skills/risk-compliance/payment-analysis/references/metrics.md +67 -0
  594. package/skills/risk-compliance/payment-analysis/references/report-template.md +119 -0
  595. package/skills/risk-compliance/payment-analysis/references/terminology.md +95 -0
  596. package/skills/risk-compliance/payment-analysis/references/visualization.md +56 -0
  597. package/skills/risk-compliance/payment-analysis/release-check.mjs +93 -0
  598. package/skills/risk-compliance/report-writing/LICENSE +3 -0
  599. package/skills/risk-compliance/report-writing/SKILL.md +220 -0
  600. package/skills/risk-compliance/report-writing/references/audit-report-template.md +121 -0
  601. package/skills/risk-compliance/report-writing/references/external-assessment-template.md +167 -0
  602. package/skills/risk-compliance/report-writing/references/management-report-template.md +145 -0
  603. package/skills/risk-compliance/report-writing/references/vars-report-template.md +224 -0
  604. package/skills/risk-compliance/report-writing/release-check.mjs +93 -0
  605. package/skills/risk-compliance/similar-domain/LICENSE +3 -0
  606. package/skills/risk-compliance/similar-domain/SKILL.md +203 -0
  607. package/skills/risk-compliance/similar-domain/references/entities.md +67 -0
  608. package/skills/risk-compliance/similar-domain/references/fingerprints.md +134 -0
  609. package/skills/risk-compliance/similar-domain/references/pivots.md +82 -0
  610. package/skills/risk-compliance/similar-domain/references/report-template.md +93 -0
  611. package/skills/risk-compliance/similar-domain/references/scoring.md +130 -0
  612. package/skills/risk-compliance/similar-domain/references/terminology.md +41 -0
  613. package/skills/risk-compliance/similar-domain/references/workflow.md +85 -0
  614. package/skills/risk-compliance/similar-domain/release-check.mjs +93 -0
  615. package/skills/risk-compliance/tld-detection/LICENSE +3 -0
  616. package/skills/risk-compliance/tld-detection/SKILL.md +245 -0
  617. package/skills/risk-compliance/tld-detection/agents/openai.yaml +9 -0
  618. package/skills/risk-compliance/tld-detection/references/chinese-polish.md +55 -0
  619. package/skills/risk-compliance/tld-detection/references/clean.md +51 -0
  620. package/skills/risk-compliance/tld-detection/references/clustering.md +235 -0
  621. package/skills/risk-compliance/tld-detection/references/decision.md +189 -0
  622. package/skills/risk-compliance/tld-detection/references/fx-conversion.md +232 -0
  623. package/skills/risk-compliance/tld-detection/references/report-template.md +272 -0
  624. package/skills/risk-compliance/tld-detection/references/streams.md +141 -0
  625. package/skills/risk-compliance/tld-detection/references/terminology.md +95 -0
  626. package/skills/risk-compliance/tld-detection/references/workflow.md +95 -0
  627. package/skills/risk-compliance/tld-detection/release-check.mjs +93 -0
  628. package/skills/risk-compliance/tld-detection/scripts/detect_ladders.py +390 -0
  629. package/skills/risk-compliance/tld-detection/scripts/detect_ladders.test.mjs +14 -0
  630. package/skills/risk-compliance/tld-detection/scripts/detect_streams.py +650 -0
  631. package/skills/risk-compliance/tld-detection/scripts/detect_streams.test.mjs +14 -0
  632. package/skills/risk-compliance/tld-detection/tests/test_detect_ladders.py +134 -0
  633. package/skills/risk-compliance/tld-detection/tests/test_detect_streams.py +520 -0
@@ -0,0 +1,365 @@
1
+ // Cheap scan of a unified diff. It emits TWO channels, and the distinction is
2
+ // load-bearing:
3
+ // • LEADS (heuristic) — "look here and verify"; the reviewer reads the code and
4
+ // builds the counterexample before any becomes a finding (see references/passes.md).
5
+ // • FINDINGS (decidable) — near-zero-false-positive checks that ARE blockers on
6
+ // their own. Currently: `over-mock-internal-seam` (a vi/jest.mock of a
7
+ // first-party seam = Over-mocked, zero-tolerance). This makes better-review the
8
+ // standalone first line of enforcement — no dependency on ensure-coverage's
9
+ // gate being wired in the repo.
10
+ //
11
+ // git diff <merge-base>...HEAD | node scan-diff.mjs # leads + findings from stdin
12
+ // node scan-diff.mjs --diff changes.patch
13
+ //
14
+ // Best-effort and JS/TS-oriented (regex/branch heuristics are language-bound; the
15
+ // mock/interception checks are framework-specific). On other languages it simply
16
+ // finds fewer — it is additive, and absence means "the scanner found nothing,"
17
+ // not "the code is fine."
18
+
19
+ import fs from 'node:fs'
20
+ import path from 'node:path'
21
+ import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
22
+
23
+ // ---- pure core ----
24
+
25
+ // Parse a unified diff into added lines with their NEW-file line numbers.
26
+ export function parseAddedLines(diffText) {
27
+ const out = []
28
+ let file = null
29
+ let newLine = 0
30
+ for (const raw of (diffText || '').split(/\r?\n/)) {
31
+ if (raw.startsWith('+++ ')) {
32
+ const m = raw.match(/^\+\+\+ b\/(.+)$/)
33
+ file = m ? m[1] : raw.slice(4).replace(/^b\//, '')
34
+ continue
35
+ }
36
+ if (raw.startsWith('diff --git')) { file = null; continue }
37
+ const hm = raw.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/)
38
+ if (hm) { newLine = parseInt(hm[1], 10); continue }
39
+ if (raw.startsWith('+')) { out.push({ file, line: newLine, text: raw.slice(1) }); newLine++; continue }
40
+ if (raw.startsWith('-')) continue // removed line: no advance in new file
41
+ if (raw.startsWith('\\')) continue // ""
42
+ newLine++ // context line
43
+ }
44
+ return out
45
+ }
46
+
47
+ const TEST_FILE = /\.(test|spec)\.[jt]sx?$/
48
+ const INTERCEPT = /\broute\.fulfill\b|\bpage\.route\s*\(|\bsetupServer\s*\(|\bsetupWorker\s*\(|from\s+['"]msw['"]/
49
+
50
+ export function interceptionLeads(added) {
51
+ return added
52
+ .filter((a) => a.file && TEST_FILE.test(a.file) && INTERCEPT.test(a.text))
53
+ .map((a) => ({ type: 'first-party-interception', file: a.file, line: a.line, snippet: a.text.trim(),
54
+ note: 'first-party interception in a test — over-mock risk; verify the real path is actually proven (browser/journey, not stub). Skip if: the route is a third-party/external boundary, or this is a Tier-2 functional failure-injection test (interception is correct there).' }))
55
+ }
56
+
57
+ // Regex literals / RegExp() added without ^ or $ anchors → boundary-leak risk.
58
+ export function regexLeads(added) {
59
+ const out = []
60
+ for (const a of added) {
61
+ for (const lit of a.text.match(/\/(?:[^/\n\\]|\\.){2,}\/[gimsuy]*/g) || []) {
62
+ const body = lit.replace(/\/[gimsuy]*$/, '').slice(1)
63
+ if (!/[\^$]/.test(body) && /[A-Za-z0-9]/.test(body)) {
64
+ out.push({ type: 'unanchored-pattern', file: a.file, line: a.line, snippet: lit,
65
+ note: 'regex without ^/$ anchors — verify prefix/substring leakage at boundaries (does /foo also match /foobar?). Skip if: inputs are a closed/validated set where leakage cannot occur, or a substring match is intended — produce the breaking input or drop it.' })
66
+ }
67
+ }
68
+ const re = a.text.match(/new RegExp\(([^)]*)\)/)
69
+ if (re && !/[\^$]/.test(re[1])) {
70
+ out.push({ type: 'unanchored-pattern', file: a.file, line: a.line, snippet: re[0].trim(),
71
+ note: 'RegExp without ^/$ — verify boundary behavior.' })
72
+ }
73
+ }
74
+ return out
75
+ }
76
+
77
+ // Weakened assertions in tests → a test that can't fail the way its name promises.
78
+ // Two tells from real "smoke wearing a journey label" specs:
79
+ // - `.catch(() => false)` (or null/undefined/0/'') swallows a locator/await throw
80
+ // into a falsy, defeating Playwright's web-first retry and any assertion on it.
81
+ // - `expect(a || b || c).toBeTruthy()` / `.toBe(true)` — a disjunctive truthiness
82
+ // assertion passes if ANY branch holds, so it pins down no specific behavior.
83
+ // Reviewer then checks the test's @level: a journey/functional test asserting only
84
+ // these is Wrong Level (references/passes.md → Spec).
85
+ const CATCH_SWALLOW = /\.catch\s*\(\s*\(\s*\)\s*=>\s*(?:false|null|undefined|0|''|""|``)\s*\)/
86
+ const DISJUNCTIVE_TRUTHY = /\bexpect\s*\([^;]*\|\|[^;]*\)\s*\.\s*(?:toBeTruthy\b|toBe\s*\(\s*true\s*\))/
87
+ export function weakAssertionLeads(added) {
88
+ const out = []
89
+ for (const a of added) {
90
+ if (!a.file || !TEST_FILE.test(a.file)) continue
91
+ if (CATCH_SWALLOW.test(a.text)) out.push({ type: 'swallowed-assertion', file: a.file, line: a.line, snippet: a.text.trim(),
92
+ note: 'catch swallows a locator/await throw into a falsy — defeats web-first retry and hides real failures; assert directly (web-first expect), do not catch-to-false. Skip if: the falsy genuinely feeds a non-assertion control-flow decision and the real outcome is asserted separately.' })
93
+ if (DISJUNCTIVE_TRUTHY.test(a.text)) out.push({ type: 'weak-assertion', file: a.file, line: a.line, snippet: a.text.trim(),
94
+ note: 'disjunctive truthiness — passes if any branch holds, so it proves nothing specific; if this is a @level journey/functional test it is Wrong Level (drive the flow to a concrete outcome). Skip if: this is a @level render-health test (alias: smoke) where "renders at all" is the whole contract.' })
95
+ }
96
+ return out
97
+ }
98
+
99
+ // A test that *names itself* a race but reads state some earlier test already created
100
+ // cannot exercise the first-writer path: both "concurrent" callers take the
101
+ // already-exists early return, and the contended create never runs. The tell is a
102
+ // pre-existing capture (`x!.id`, `find*OrThrow`) reached before the `Promise.all`.
103
+ // Kept a LEAD, not a finding: post-seal/replay races legitimately look exactly like
104
+ // this. What makes it a defect is the test being cited as first-writer proof — a
105
+ // judgment about the AC mapping that no regex can make.
106
+ const ANY_TEST_TITLE = /\b(?:it|test)\s*(?:\.\w+)?\s*\(\s*['"`]/
107
+ const CONCURRENCY_TEST_TITLE = /\b(?:it|test)\s*(?:\.\w+)?\s*\(\s*['"`][^'"`]*\b(?:race|races|racing|concurrent|concurrently|simultaneous(?:ly)?|parallel)\b/i
108
+ const PREEXISTING_CAPTURE = /\w\s*!\s*\.\s*\w|\bfind(?:First|Unique)OrThrow\s*\(/
109
+ const CONCURRENT_CALL = /\bPromise\s*\.\s*(?:all|allSettled|race)\s*\(/
110
+
111
+ export function concurrencyFixtureLeads(added) {
112
+ const out = []
113
+ const byFile = new Map()
114
+ for (const a of added) {
115
+ if (!a.file || !TEST_FILE_ANY.test(a.file)) continue
116
+ if (!byFile.has(a.file)) byFile.set(a.file, [])
117
+ byFile.get(a.file).push(a)
118
+ }
119
+ for (const [, lines] of byFile) {
120
+ lines.sort((x, y) => x.line - y.line)
121
+ let title = null // the concurrency-named test we are inside
122
+ let capture = null // first pre-existing capture seen since that title
123
+ for (const a of lines) {
124
+ // Any test title closes the previous body. Tracking only concurrency titles
125
+ // would leave scope open across the rest of the file, so the next ordinary
126
+ // test's fixture would be attributed to a race test that already ended.
127
+ if (ANY_TEST_TITLE.test(a.text)) {
128
+ title = CONCURRENCY_TEST_TITLE.test(a.text) ? a : null
129
+ capture = null
130
+ continue
131
+ }
132
+ if (!title) continue
133
+ if (!capture && PREEXISTING_CAPTURE.test(a.text)) { capture = a; continue }
134
+ if (capture && CONCURRENT_CALL.test(a.text)) {
135
+ out.push({ type: 'concurrency-test-preexisting-fixture', file: capture.file, line: capture.line, snippet: capture.text.trim(),
136
+ note: `test named as a race/concurrent case reads pre-existing state before ${a.text.trim().slice(0, 40)}… — if that state is what the concurrent calls are supposed to be creating, every caller takes the already-exists path and the contended first-write is never exercised (a green test for an untested race). Verify the fixture starts from ABSENT, with independent clients/connections and a barrier. Skip if: this is deliberately a post-create replay/idempotency case AND a separate test covers the first-write race — then check that the AC cites that one, not this.` })
137
+ title = null; capture = null
138
+ }
139
+ }
140
+ }
141
+ return out
142
+ }
143
+
144
+ // New conditional branches → each needs a test (line coverage ≠ branch coverage).
145
+ export function branchLeads(added) {
146
+ return added
147
+ .filter((a) => /\b(if|else if|case)\b/.test(a.text) || /\?[^?]*:/.test(a.text))
148
+ .map((a) => ({ type: 'new-branch', file: a.file, line: a.line, snippet: a.text.trim(),
149
+ note: 'new branch — name a test that exercises it; line coverage is not branch coverage. Skip if: an integration/E2E test already drives it, or the branch is a trivial guard whose failure is inert.' }))
150
+ }
151
+
152
+ // Files whose EXISTING behavior is modified (edited/removed lines in a non-test
153
+ // SOURCE file) owe a characterization test pinning prior behavior before the
154
+ // change (ensure-coverage → depth/characterization.md). A new file or a test
155
+ // file is excluded; only changed/removed content in a non-test source file
156
+ // signals an existing-behavior modification. The *detection* is decidable; the
157
+ // adjudication ("is there an adequate @characterizes test, or a declared intended
158
+ // change?") is the reviewer's — hence a lead, not a finding.
159
+ const TEST_FILE_ANY = /\.(test|spec)\.[cm]?[jt]sx?$|(^|\/)(e2e|tests?|__tests__)\/|(^|\/)test_[^/]*\.py$|_test\.py$/
160
+ const NON_SOURCE = /\.(md|markdown|json|ya?ml|txt|lock|svg|png|jpe?g|gif|webp|ico|csv|tsv|toml|ini|cfg|snap)$/i
161
+
162
+ // Parse a diff into per-file change shape: { isNew, removed, added, firstLine }.
163
+ // `removed` counts changed/deleted content lines (the modify signal); a new file
164
+ // (--- /dev/null or `new file mode`) is flagged so it's treated as addition.
165
+ export function parseFileChanges(diffText) {
166
+ const files = new Map()
167
+ let file = null
168
+ let pendingNew = false
169
+ let newLine = 0
170
+ for (const raw of (diffText || '').split(/\r?\n/)) {
171
+ if (raw.startsWith('diff --git')) { file = null; pendingNew = false; continue }
172
+ if (raw.startsWith('new file mode')) { pendingNew = true; continue }
173
+ if (raw.startsWith('--- ')) { if (/\/dev\/null/.test(raw)) pendingNew = true; continue }
174
+ if (raw.startsWith('+++ ')) {
175
+ const m = raw.match(/^\+\+\+ (?:b\/)?(.+)$/)
176
+ file = m && m[1] !== '/dev/null' ? m[1] : null
177
+ if (file && !files.has(file)) files.set(file, { isNew: pendingNew, removed: 0, added: 0, firstLine: 0 })
178
+ pendingNew = false
179
+ continue
180
+ }
181
+ if (!file) continue
182
+ const hm = raw.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/)
183
+ if (hm) { newLine = parseInt(hm[1], 10); continue }
184
+ const rec = files.get(file)
185
+ if (!rec) continue
186
+ if (raw.startsWith('-')) { rec.removed++; if (!rec.firstLine) rec.firstLine = newLine; continue } // no new-line advance
187
+ if (raw.startsWith('+')) { rec.added++; if (!rec.firstLine) rec.firstLine = newLine; newLine++; continue }
188
+ if (raw.startsWith('\\')) continue
189
+ newLine++ // context
190
+ }
191
+ return files
192
+ }
193
+
194
+ export function characterizationLeads(diffText) {
195
+ const out = []
196
+ for (const [file, rec] of parseFileChanges(diffText)) {
197
+ if (rec.isNew) continue // new file = new behavior, not a modification
198
+ if (TEST_FILE_ANY.test(file)) continue // editing tests is not modifying production behavior
199
+ if (NON_SOURCE.test(file)) continue // docs/config/snapshots carry no behavior to pin
200
+ if (rec.removed === 0) continue // pure addition into an existing file = added behavior
201
+ out.push({ type: 'modifies-existing-behavior', file, line: rec.firstLine || 1,
202
+ snippet: `${rec.removed} existing line(s) changed/removed`,
203
+ note: 'existing behavior modified — verify a characterization test pins the PRIOR behavior (authored to pass on the pre-change tree) so this diff is proven not to shift observable behavior unintentionally; tag it `// @characterizes <surface>`. Skip if: an existing behavior test already covers this exact path and still passes unchanged (cite it), this is a declared intended behavior change with its AC and the assertion delta is in the diff, or the edit is trivial/generated/non-behavioral. See ensure-coverage depth/characterization.md.' })
204
+ }
205
+ return out
206
+ }
207
+
208
+ // ---- VENDORED over-mock classifier — DECIDABLE FINDING, not a lead ----
209
+ //
210
+ // Self-contained copy of ensure-coverage's `mock-internal-seam` classifier
211
+ // (skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs), vendored
212
+ // here so better-review enforces no-over-mock with ZERO dependency on ensure-coverage
213
+ // being installed/wired. ensure-coverage stays CANONICAL: if the two diverge,
214
+ // ensure-coverage wins and this copy is stale → resync. Kept tiny on purpose.
215
+ //
216
+ // The "externals-allowlist inversion": you can't enumerate internal seams, but
217
+ // the legitimately-fakeable set (third-party/stdlib) is small and known — so a
218
+ // mock whose target resolves to first-party code is a seam (a defect), and the
219
+ // declared externals / stdlib / bare packages are exempt. Unlike the heuristic
220
+ // leads above this is DECIDABLE, so its hits are emitted as `findings`.
221
+
222
+ export const DEFAULT_MOCK_TOPOLOGY = {
223
+ firstPartyAliasPrefixes: ['@/', '~/'],
224
+ firstPartyPackages: [], // e.g. a monorepo's own scope '@acme/'
225
+ externals: [], // regex SOURCES for first-party-looking-but-external targets
226
+ testUtilHints: ['__mocks__', '__fixtures__', 'fixtures', 'mocks', 'helpers',
227
+ 'test-utils', 'testing', 'support', 'stubs', 'factories'],
228
+ }
229
+
230
+ // Best-effort read of coverage.config.json topology (so a monorepo's own @scope
231
+ // is recognized); never throws — defaults to conventional @/ ~/ when absent.
232
+ // Config declares TOPOLOGY only; it cannot disable the check (zero-tolerance).
233
+ export function loadMockTopology(cwd = process.cwd()) {
234
+ for (const name of ['coverage.config.json', '.coverage.config.json']) {
235
+ try {
236
+ const mp = (JSON.parse(fs.readFileSync(path.join(cwd, name), 'utf8')).mockPolicy) || {}
237
+ return {
238
+ firstPartyAliasPrefixes: mp.firstPartyAliasPrefixes ?? DEFAULT_MOCK_TOPOLOGY.firstPartyAliasPrefixes,
239
+ firstPartyPackages: mp.firstPartyPackages ?? DEFAULT_MOCK_TOPOLOGY.firstPartyPackages,
240
+ externals: mp.externals ?? DEFAULT_MOCK_TOPOLOGY.externals,
241
+ testUtilHints: mp.testUtilHints ?? DEFAULT_MOCK_TOPOLOGY.testUtilHints,
242
+ }
243
+ } catch { /* missing or malformed → try next, else defaults */ }
244
+ }
245
+ return { ...DEFAULT_MOCK_TOPOLOGY }
246
+ }
247
+
248
+ // Pull the mocked specifier from a vi/jest/vitest `.mock`/`.doMock(...)` call.
249
+ export function extractMockTarget(codeLine) {
250
+ const m = /\b(?:vi|jest|vitest)\s*\.\s*(?:mock|doMock)\s*\(\s*(['"`])([^'"`]+)\1/.exec(codeLine || '')
251
+ return m ? m[2] : null
252
+ }
253
+
254
+ // Classify a mock target as an internal seam (a defect) or an allowed external.
255
+ // Precedence: declared externals > stdlib > relative(util vs source) >
256
+ // first-party alias > first-party package > bare package (external default).
257
+ export function classifyMockTarget(target, topo = DEFAULT_MOCK_TOPOLOGY) {
258
+ if (!target) return { internal: false, reason: 'no target' }
259
+ for (const src of topo.externals || []) {
260
+ try { if (new RegExp(src).test(target)) return { internal: false, reason: 'declared external' } } catch { /* ignore bad regex */ }
261
+ }
262
+ if (target.startsWith('node:')) return { internal: false, reason: 'node builtin' }
263
+ if (target.startsWith('.')) {
264
+ if (target.split('/').some((s) => (topo.testUtilHints || []).includes(s))) return { internal: false, reason: 'relative test util/fixture/mock' }
265
+ return { internal: true, reason: 'relative import into first-party source' }
266
+ }
267
+ for (const pre of topo.firstPartyAliasPrefixes || []) {
268
+ if (target.startsWith(pre)) return { internal: true, reason: `first-party alias "${pre}"` }
269
+ }
270
+ for (const fp of topo.firstPartyPackages || []) {
271
+ const base = fp.endsWith('/') ? fp.slice(0, -1) : fp
272
+ if (target === base || target.startsWith(`${base}/`)) return { internal: true, reason: `first-party package "${fp}"` }
273
+ }
274
+ return { internal: false, reason: 'external package' }
275
+ }
276
+
277
+ // Diff-scoped over-mock FINDINGS: a vi/jest/vitest.mock of a first-party internal
278
+ // seam ADDED in a test file → Over-mocked (a blocker), not a lead. Diff-scoped is
279
+ // the right scope for a PR review (review the diff; pre-existing mocks are notes by
280
+ // diff-discipline) — the whole-tree inherited burndown is ensure-coverage's audit lint.
281
+ export function overMockFindings(added, topo = DEFAULT_MOCK_TOPOLOGY) {
282
+ const out = []
283
+ for (const a of added) {
284
+ if (!a.file || !TEST_FILE_ANY.test(a.file)) continue
285
+ const target = extractMockTarget(a.text)
286
+ if (!target) continue
287
+ const { internal, reason } = classifyMockTarget(target, topo)
288
+ if (!internal) continue
289
+ out.push({ type: 'over-mock-internal-seam', file: a.file, line: a.line, snippet: a.text.trim(), target, reason,
290
+ note: 'mocks a first-party internal seam → Over-mocked (dishonest green): zero-tolerance, NO @mock-ok waiver and no "approved with justification" (ensure-coverage depth/mock-policy.md). Resolve by making the test real, faking only the external, or DELETING it (over-mock is worse than no test). Only NOT a finding if the target is genuinely external — then declare it as topology in coverage.config.json.' })
291
+ }
292
+ return out
293
+ }
294
+
295
+ export function scanDiff(diffText, topo = DEFAULT_MOCK_TOPOLOGY) {
296
+ const added = parseAddedLines(diffText)
297
+ const byPlace = (a, b) => (a.file || '').localeCompare(b.file || '') || a.line - b.line
298
+ const leads = [...interceptionLeads(added), ...regexLeads(added), ...weakAssertionLeads(added), ...branchLeads(added),
299
+ ...concurrencyFixtureLeads(added), ...characterizationLeads(diffText)].sort(byPlace)
300
+ const findings = overMockFindings(added, topo).sort(byPlace)
301
+ const tally = (xs) => xs.reduce((m, l) => ((m[l.type] = (m[l.type] || 0) + 1), m), {})
302
+ // `counts`/`leads` kept for back-compat; `findings` is the decidable, blocker-grade channel.
303
+ return { kind: 'leads+findings', counts: tally(leads), leads, findingCounts: tally(findings), findings }
304
+ }
305
+
306
+ // ---- CLI ----
307
+
308
+ // Exit codes. Both are usage errors (distinct from 0 = scanned OK, and from a
309
+ // generic crash). NO_INPUT is the fail-open this tool exists NOT to have: a
310
+ // parity proof that returns "all clear" on zero bytes proved nothing about the
311
+ // diff (issue #416). USAGE catches the `--base/--head` invocation producers
312
+ // invented — flags this tool never had, which used to fall through to an empty
313
+ // stdin read and a vacuous clean result.
314
+ export const NO_INPUT_EXIT = 2
315
+ export const USAGE_EXIT = 2
316
+
317
+ // The ONE correct invocation, echoed in every error so a wrong call self-corrects.
318
+ const USAGE = 'Pipe the net diff: git diff <merge-base>...HEAD | node scan-diff.mjs (or: node scan-diff.mjs --diff <file>). This tool takes NO --base/--head.'
319
+
320
+ // A usage/no-input error carrying its own process exit code. Thrown by the arg
321
+ // parser and the empty-input guard; main() prints .message to stderr and exits.
322
+ export class ScanDiffCliError extends Error {
323
+ constructor(message, code = USAGE_EXIT) { super(message); this.name = 'ScanDiffCliError'; this.code = code }
324
+ }
325
+
326
+ // Parse argv (already sliced of node + script). Returns { diffPath } — null means
327
+ // read stdin. Anything that isn't `--diff <file>` HARD-FAILS: an unknown flag
328
+ // (the `--base/--head` mistake) or a stray positional would otherwise be silently
329
+ // ignored, dropping through to an empty stdin read and a false-clean proof.
330
+ export function parseCliArgs(argv) {
331
+ let diffPath = null
332
+ for (let i = 0; i < argv.length; i++) {
333
+ const arg = argv[i]
334
+ if (arg === '--diff') {
335
+ diffPath = argv[i + 1]
336
+ if (diffPath == null) throw new ScanDiffCliError(`scan-diff: --diff requires a file path. ${USAGE}`)
337
+ i++
338
+ continue
339
+ }
340
+ if (arg.startsWith('-')) throw new ScanDiffCliError(`scan-diff: unknown flag "${arg}". ${USAGE}`)
341
+ throw new ScanDiffCliError(`scan-diff: unexpected argument "${arg}". ${USAGE}`)
342
+ }
343
+ return { diffPath }
344
+ }
345
+
346
+ function main() {
347
+ let diff
348
+ try {
349
+ const { diffPath } = parseCliArgs(process.argv.slice(2))
350
+ diff = diffPath != null ? fs.readFileSync(diffPath, 'utf8') : fs.readFileSync(0, 'utf8') // --diff <file> or stdin
351
+ // Fail LOUD on no input. Empty/whitespace-only means the diff never arrived
352
+ // (a non-piped context, or the `--base/--head` fall-through) — NOT a clean
353
+ // diff. A real diff with content but zero findings still exits 0 below;
354
+ // "no INPUT" and "input with no findings" are different answers.
355
+ if (!diff.trim()) throw new ScanDiffCliError(`scan-diff: no diff on stdin (or --diff <file> is empty). ${USAGE}`, NO_INPUT_EXIT)
356
+ } catch (err) {
357
+ if (err instanceof ScanDiffCliError) { process.stderr.write(`${err.message}\n`); process.exit(err.code) }
358
+ throw err
359
+ }
360
+ const result = scanDiff(diff, loadMockTopology())
361
+ result.disclaimer = 'TWO channels. `leads` = heuristic "look here and verify" (read the code, build the counterexample first). `findings` = DECIDABLE blockers (over-mock-internal-seam): a vi/jest.mock of a first-party seam is Over-mocked, zero-tolerance, no waiver — fix it, do not merge over it. Best-effort, JS/TS-oriented; absence != code is fine.'
362
+ console.log(JSON.stringify(result, null, 2))
363
+ }
364
+
365
+ if (isMainModule(import.meta.url)) main()