@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,8 @@
1
+ interface:
2
+ display_name: "Rush Release"
3
+ short_description: "Slash/explicit-only no-questions release shortcut of resolve-release"
4
+
5
+ policy:
6
+ # Codex counterpart to SKILL.md disable-model-invocation: true.
7
+ # Keeps $rush-release / explicit invoke while blocking description-based selection.
8
+ allow_implicit_invocation: false
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { dirname, join } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const DAY_MS = 24 * 60 * 60 * 1000;
9
+ const WEEK_MS = 7 * DAY_MS;
10
+ const here = dirname(fileURLToPath(import.meta.url));
11
+
12
+ function readJson(path, fallback = {}) {
13
+ try { return JSON.parse(readFileSync(path, 'utf8')); } catch { return fallback; }
14
+ }
15
+
16
+ function frontmatterValue(text, key) {
17
+ const frontmatter = /^---\n([\s\S]*?)\n---/.exec(text)?.[1] ?? '';
18
+ const match = new RegExp('^' + key + ':\\s*([^\\n]+)$', 'm').exec(frontmatter);
19
+ return match?.[1].trim().replace(/^['"]|['"]$/g, '') ?? null;
20
+ }
21
+
22
+ function repositoryOf(source) {
23
+ const value = String(source ?? '').trim();
24
+ const match = /^(?:git@github\.com:|https:\/\/github\.com\/)?([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+?)(?:\.git)?$/.exec(value);
25
+ return match?.[1] ?? null;
26
+ }
27
+
28
+ function stableVersion(value) {
29
+ const match = /^v?(\d+)\.(\d+)\.(\d+)$/.exec(String(value ?? '').trim());
30
+ return match ? match.slice(1).map(Number) : null;
31
+ }
32
+
33
+ function newer(left, right) {
34
+ for (let index = 0; index < 3; index += 1) {
35
+ if (left[index] !== right[index]) return left[index] > right[index];
36
+ }
37
+ return false;
38
+ }
39
+
40
+ function writeCache(path, value) {
41
+ try {
42
+ mkdirSync(dirname(path), { recursive: true });
43
+ writeFileSync(path, JSON.stringify(value));
44
+ } catch { /* A read-only cache must not block skill use. */ }
45
+ }
46
+
47
+ function main(now = Date.now()) {
48
+ if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
+ const name = frontmatterValue(skill, 'name');
51
+ const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
52
+ if (!name || !localVersion) return;
53
+
54
+ const lock = readJson(join(process.env.HOME || homedir(), '.agents', '.skill-lock.json'));
55
+ const entry = lock.skills?.[name];
56
+ const repository = repositoryOf(entry?.sourceUrl || entry?.source);
57
+ if (!repository) return;
58
+
59
+ const cacheRoot = process.env.XDG_CACHE_HOME || join(process.env.HOME || homedir(), '.cache');
60
+ const cachePath = join(cacheRoot, '1aboveio-skills', 'release-check.json');
61
+ const all = readJson(cachePath);
62
+ const cache = all[repository] && typeof all[repository] === 'object' ? all[repository] : {};
63
+
64
+ if (!cache.lastCheck || now - cache.lastCheck >= DAY_MS) {
65
+ const result = spawnSync('gh', ['api', 'repos/' + repository + '/releases/latest', '--jq', '.tag_name'], {
66
+ encoding: 'utf8',
67
+ stdio: ['ignore', 'pipe', 'ignore'],
68
+ timeout: 1500,
69
+ });
70
+ cache.lastCheck = now;
71
+ if (result.status === 0 && stableVersion(result.stdout)) cache.latestTag = result.stdout.trim();
72
+ else delete cache.latestTag;
73
+ all[repository] = cache;
74
+ writeCache(cachePath, all);
75
+ }
76
+
77
+ const latestVersion = stableVersion(cache.latestTag);
78
+ if (!latestVersion || !newer(latestVersion, localVersion)) return;
79
+ if (cache.notifiedTag === cache.latestTag && cache.notifiedAt && now - cache.notifiedAt < WEEK_MS) return;
80
+
81
+ cache.notifiedTag = cache.latestTag;
82
+ cache.notifiedAt = now;
83
+ all[repository] = cache;
84
+ writeCache(cachePath, all);
85
+ const command = `npx skills@1.5.23 add '${repository}#${cache.latestTag}' --global --agent universal claude-code --skill ${name} --yes`;
86
+ process.stdout.write(
87
+ `UPDATE_AVAILABLE: A newer 1AboveIO skills release (${cache.latestTag}) is available; this skill is `
88
+ + `v${localVersion.join('.')}. Ask once whether to refresh ${name}. On approval run \`${command}\`. `
89
+ + 'The refreshed instructions apply next session. Either way, continue the current task and do not ask again this session.\n',
90
+ );
91
+ }
92
+
93
+ try { main(); } catch { /* Update checks are advisory and always fail silent. */ }
@@ -0,0 +1,3 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 1AboveIO
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: test-quality
3
+ description: "Seven principles for tests that catch real bugs, and an audit that reports weak, redundant, and not-coverage tests without fixing them. Use when writing, changing, or reviewing tests, or when asked whether tests are useful, redundant, over-mocked, flaky, only assert static text, or test config files, or asked to make a slow test suite faster without losing coverage, or when the user asks to write the testing conventions into a repo's CONTRIBUTING.md. NOT defining what a spec must prove (ensure-coverage) or authoring browser tests (e2e-test)."
4
+ release-version: 0.36.0
5
+ ---
6
+ **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
+ # Test Quality
8
+
9
+ A test is worth keeping when it fails for a real bug and stays green through a harmless change. This skill states seven principles that decide that and audits a suite against them. Each principle's examples, common failures, and look-alikes: [references/principles.md](references/principles.md).
10
+
11
+ - **Write mode**: the principles are the bar while you write or change tests. Check each new assertion against the one question, and before you commit run `node "$SKILL_DIR/scripts/lint-tests.mjs" --diff <base>` from the repo root ([lint](#the-lint)); it covers uncommitted and untracked tests.
12
+ - **Audit mode**: reviewer subagents sweep a suite or a diff and report findings, quick by default ([audit](#audit-mode)). The audit **never edits, rewrites, or deletes a test**. It names the principle broken and the evidence; the fix belongs to the implementer.
13
+ - **Persist mode**: only when the user asks, write the principles into the repo's `CONTRIBUTING.md` ([persist](#persist-mode)).
14
+
15
+ | # | Principle | The failure it names | Quick tell |
16
+ |---|---|---|---|
17
+ | 1 | [Test behavior, not text](references/principles.md#1-test-behavior-not-text) | Reading a file instead of running the code | `readFileSync`/`read_text` of a checked-in file, then `toContain`/`in`/`match` |
18
+ | 2 | [The expected value comes from somewhere other than the code under test](references/principles.md#2-the-expected-value-comes-from-somewhere-other-than-the-code-under-test) | Copying the answer into the test | `expect(CONST).toBe(<its literal>)`; mock returns X, test asserts X |
19
+ | 3 | [Fake only what you don't own](references/principles.md#3-fake-only-what-you-dont-own) | A fake that can't see the bug | first-party module mocked; assertion on the call, not the outcome |
20
+ | 4 | [An assertion must be able to fail](references/principles.md#4-an-assertion-must-be-able-to-fail) | Checks weaker than the test's name | no assertion, `NoError` only, bare `toThrow()`, a skip that always fires |
21
+ | 5 | [Test each behavior once, and only for code that still runs](references/principles.md#5-test-each-behavior-once-and-only-for-code-that-still-runs) | Duplicates and dead weight | identical files; mocked unit twin of a real integration test |
22
+ | 6 | [Don't test config files](references/principles.md#6-dont-test-config-files) | Restating a config file in a test | a Dockerfile, workflow, `cloudbuild.yaml`, `.mergify.yml`, `package.json`, or other JSON/YAML/TOML config read, then any assertion |
23
+ | 7 | [Same code, same result](references/principles.md#7-same-code-same-result) | A result that depends on luck | `Math.random`/`uuid()`/`Date.now()` in checked output; `sleep(…)`; passes in the suite, fails alone |
24
+
25
+ ## The one question
26
+
27
+ For every assertion, answer both halves:
28
+
29
+ 1. **What realistic bug makes this fail?**
30
+ 2. **What harmless change makes this fail?**
31
+
32
+ A good assertion has a concrete answer to (1) and none to (2). An assertion with no answer to (1) is not coverage, however many harmless changes it would catch. Judge **assertions, not whole tests**: one strong check buried among five pins is a good test with five findings.
33
+
34
+ ## The principles
35
+
36
+ 1. **Test behavior, not text.** Run the code and observe what it does. The text of a doc, prompt, source file, or migration is not behavior. A test whose only assertions are text matches over checked-in files is **`Not coverage`** for the behavior the text describes, never partial proof.
37
+ 2. **The expected value comes from somewhere other than the code under test.** Take it from the spec, an external contract, a separately written simpler model, or the input: never from the code under test or a literal copied out of it. When a version really is the contract, pin the major only.
38
+ 3. **Fake only what you don't own.** Fake third-party APIs, providers, the clock, and randomness. Your database and services run for real, because a fake cannot see transactions, tenant filters, locking, or idempotency. An over-mocked test is `Not coverage` for the behavior the fake hides.
39
+ 4. **An assertion must be able to fail.** Every test can go red and checks what its name promises: read the name's verbs ("atomically", "then", "corrected to") and find the assertion for each.
40
+ 5. **Test each behavior once, and only for code that still runs.** Prove each behavior once, at the lowest level that proves it for real. Layering (a pure unit for the decision table plus one real-DB test per rule) is not duplication; many similar cases merge into a table rather than being deleted.
41
+ 6. **Don't test config files.** Dockerfiles, `cloudbuild.yaml`, `.github/workflows/*`, `.mergify.yml`, `package.json`, `tsconfig.json`, `pyproject.toml`, `.env`, and any other JSON, YAML, or TOML a tool reads get no tests: the tool that reads the file is the test. Test the code that reads config; run scripts, because scripts are code. A pin added after a real bug is still a config test: delete it and name the missing behavior check as a follow-up. JSON the app loads as data (locales, price tables) is not config.
42
+ 7. **Same code, same result.** Anything that changes between runs (randomness, the clock, timing, run order, the network) is fixed by the test: seed it, freeze it, wait on the condition, own your state.
43
+
44
+ ## Audit mode
45
+
46
+ Reviewer subagents audit and never fix. The **quick audit** is the default and finishes in under 10 minutes: `lint-tests.mjs --shares 4` splits the flagged files, at most 4 reviewers (or the harness's parallel limit) read only their flagged spots on a 6-minute budget, each writes its report to a file and replies in one line, and the lead merges once and posts once, with no per-reviewer updates. A **deep audit** (every test file read) runs only when the user asks for one. Any request that ends in changed tests ("audit and fix", "clean up the tests", "improve the suite") then runs **fix** (implementer subagents, disjoint files; each opens a `Redundant` test's twin and searches for what depends on a test before deleting it) → **verify** (lint on the diff, fresh reviewer on the fix). A request to make the suite faster without losing coverage measures durations first and collapses slow files by code path ([speed](references/audit.md#when-the-goal-is-speed)). Steps, budgets, and the report template: [references/audit.md](references/audit.md).
47
+
48
+ ### Labels
49
+
50
+ Per assertion, or per test when every assertion shares it:
51
+
52
+ - **`Not coverage`**: cannot catch a realistic bug (text-only, tautology, first-party over-mock, config restated, an assertion that can never go red). Counts as zero proof for the behavior it names.
53
+ - **`Weak`**: catches something, but less than its name claims, or breaks on harmless changes.
54
+ - **`Redundant`**: proven equally or better elsewhere (name the other test), or it tests dead code (name the evidence).
55
+ - **`Lead`**: looks like a failure, not confirmed by reading; state what would confirm it.
56
+
57
+ Every finding carries a real `file:line` you opened. Rank by cost: `Not coverage` on auth, money, or data integrity first.
58
+
59
+ ## Persist mode
60
+
61
+ **Only when the user explicitly asks** to write the testing conventions into the repo. Never on your own initiative, and never as part of write, audit, or fix work. From the target repo's root, with `SKILL_DIR` set to the directory you read this file from:
62
+
63
+ ```bash
64
+ node "$SKILL_DIR/scripts/persist-conventions.mjs" # preview: what would change
65
+ node "$SKILL_DIR/scripts/persist-conventions.mjs" --write # write, once the user asked
66
+ ```
67
+
68
+ It writes the seven principles ([references/testing-conventions.md](references/testing-conventions.md)) as the `## Testing conventions` section of `CONTRIBUTING.md`, between `conventions:testing` markers: a re-run replaces only that section and keeps everything else, including the `## CI conventions` and `## Delivery` sections `github-flow` writes. It adds a pointer to `AGENTS.md` unless that already names `CONTRIBUTING.md`, and creates a missing `CLAUDE.md` as a symlink to `AGENTS.md` (a regular `CLAUDE.md` that names neither file gets the pointer); missing files are created. `CONTRIBUTING.md` is the file `code-review` reads as a standards source, so the principles then apply in review too. Report each file's result line; committing is the user's call.
69
+
70
+ ## The lint
71
+
72
+ Scripts live under **this skill's directory**: set `SKILL_DIR` to the directory you read this file from, never your CWD. `node "$SKILL_DIR/scripts/lint-tests.mjs"` scans the tree; `--diff <base>` only lines changed since the merge-base. A **gate** rule is decidable and fails the exit code; a **lead** also matches legitimate tests, so read each hit against the principle's look-alikes. Rules, flags, and what a clean run proves (little, for Python and Go): [references/lint.md](references/lint.md).
73
+
74
+ ## Common wrong answers
75
+
76
+ - "It's green and it has `@covers`" is not coverage. A tag is a claim; read the assertion.
77
+ - A long test is not a strong test. Count the assertions that survive the one question.
78
+ - A clean lint is not a clean suite. The lint finds shapes; the principles need reading.
79
+ - A top-5 list is not an audit. Report every confirmed finding, clustered.
@@ -0,0 +1,80 @@
1
+ # Audit mode, step by step
2
+
3
+ > Read when: running an audit, or any request that ends in changed tests. Principles and look-alikes: [principles.md](principles.md). Lint rules: [lint.md](lint.md).
4
+
5
+ Reviewer subagents run the audit and never fix. Any request that ends in changed tests, however it is phrased ("audit and fix", "clean up the tests", "remove the useless ones", "improve the suite"), audits first, then fixes. A request for a report alone stops after the report.
6
+
7
+ ## Two depths
8
+
9
+ - **Quick audit (the default): done in under 10 minutes.** Reviewers read only the tests the lint flags, within a fixed time budget. It finds what the lint can point at and says plainly what it did not read.
10
+ - **Deep audit: only when the user asks** for one ("deep audit", "read every test", "full read"). Reviewers read every test file in their share. It finds weak assertions the lint cannot see, and it takes as long as the suite is big.
11
+
12
+ Never pick the deep audit on your own because the suite is large or the request says "full suite": "audit the full suite" names the scope, not the depth.
13
+
14
+ ## Quick audit
15
+
16
+ The lead runs it; the times are wall-clock budgets, not estimates.
17
+
18
+ 1. **Lint and split (about 1 minute).** From the target repo's root, pass vendored, generated, and fixture trees to `--exclude`, and set `--shares` to the reviewer count: 4, or the harness's parallel subagent limit if lower.
19
+
20
+ ```bash
21
+ node "$SKILL_DIR/scripts/lint-tests.mjs" --exclude node_modules,dist,fixtures,vendor --shares 4 --json > "$RUN_DIR/lint.json"
22
+ ```
23
+
24
+ `$RUN_DIR` is a fresh directory for this audit (for example under `$TMPDIR`). The `shares` array holds the flagged files, split by finding count. No findings: report that the lint is clean, that a clean lint proves little ([lint.md](lint.md)), and offer a deep audit. Do not run the test suite; the audit reads code, and tests run in the fix step.
25
+ 2. **Spawn every reviewer at once (6 minutes).** One reviewer per share, all in one batch, so none waits in a queue. Use a balanced-tier model at medium effort: the quick audit reads flagged spots, not whole suites. Each reviewer's prompt names this file, its share's files, `$RUN_DIR/lint.json`, and its report path `$RUN_DIR/share-<k>.md`. Each reviewer follows [the reviewer steps](#reviewer-steps) with a **6-minute budget**: it notes the start time, and when the budget runs out it stops reading and writes what it has, with every unread file under "Not audited".
26
+ 3. **Wait silently.** Reviewers reply with one line: their summary line and report path. Do not read replies page by page, do not post an update per reviewer, and do not update the plan per reviewer. A reviewer that has not replied 8 minutes after spawning is left behind: its share goes under "Not audited".
27
+ 4. **Merge once (about 1 minute).** Read each `share-<k>.md` once, merge into one report (dedupe, cluster, rank), write it to `$RUN_DIR/report.md`, and post it: the summary line, the costliest findings, the Not audited list, and the report path. This is the first message since the audit started.
28
+
29
+ ## Deep audit
30
+
31
+ The same flow with three changes: shares are packages or areas instead of lint shares (merge small packages so there are no more shares than the parallel limit), reviewers read **every** test file in their share, and there is no time budget. Reviewers use a frontier-tier model. Files, silence, and the single merge still apply.
32
+
33
+ ## Fix and verify
34
+
35
+ After the report, and only when the request ends in changed tests:
36
+
37
+ 1. **Fix.** Hand the findings to implementer subagents (Pi's `role.developer`), one per package with disjoint files. Each fixes its findings and runs its package's tests. A reviewer's label is a lead for the implementer too, so before deleting anything:
38
+ - **Open the twin.** Delete as `Redundant` only after reading the named twin and confirming it drives the same branch with the same input condition, on real dependencies, and asserts at least as strongly. A twin that covers a neighbouring branch (a wrong secret instead of a missing one, a suspended user instead of a suspended membership) is not a twin: keep the test, or keep only its unique part.
39
+ - **Find what depends on the test.** Search the repo for the file name and the test title. Audit scripts, coverage ledgers, and docs sometimes require a test by name; deleting it breaks them in CI, far from the diff. Update the dependent or keep the test, and say which.
40
+ - **Name the gap a deletion exposes.** A removed config or text test leaves its behavior unchecked on purpose ([principle 6](principles.md#6-dont-test-config-files)); record the missing behavior check as a follow-up.
41
+ - **Run what you touched for real.** Run edited files with the lane's real dependencies (start a disposable database for DB-backed tests). A test that could not run is reported unverified, never "unrelated".
42
+ 2. **Verify.** Run the lint on the diff, then have a fresh reviewer check the fix diff against the principles. Ask it to compare each deletion with its twin and to look for over-deletion; the fix step errs toward deleting too much, not too little.
43
+
44
+ ## When the goal is speed
45
+
46
+ A request to make a suite faster "without losing coverage" is a fix request with a time target. The principles still decide what may go; measurement decides what is worth touching.
47
+
48
+ - **Budget, unless the repo sets its own.** Measured on the CI runner, test execution only (checkout, install, database start and migrations excluded): the unit and integration lanes together take **3 minutes or less**, and the integration lane alone **under 2 minutes**. Neither lane drives a real browser; browser journeys belong to the E2E lane, which has its own budget of **5 minutes or less**. Over budget is a finding even when every test is sound.
49
+ - **Measure before cutting.** Get per-file and per-test durations from the runner (Vitest's JSON reporter or a small reporter over `TestModule.diagnostic()`, `pytest --durations=0`, `go test -json`). For CI, measure on the CI runner: a laptop is often faster and less CPU-bound, so local timings mislead.
50
+ - **Expect little from deleting fast tests.** Mocked unit tests run in milliseconds; removing duplicates is worth it for refactor noise, rarely for time. A few slow files usually dominate. Look in them for real-time waits ([principle 7](principles.md#7-same-code-same-result)) and combinatorial matrices.
51
+ - **Collapse a matrix by code path, then prove it.** Map each case to the production branch it exercises (which lock, which recheck, which input class). Keep one case per distinct path and drop cases that differ only in data that takes the same path. Prove each kept case by disabling its path in production code, watching that case fail, and restoring the code. End with no production diff.
52
+ - **Shorten a wait only when it stays deterministic.** Prefer faking the clock. When real elapsed time is the behavior, follow principle 7's look-alike for it instead of trimming the margin.
53
+ - **Leave runner tuning to CI work.** Shard counts, worker counts, and test pools change no test and belong to the CI workflow (the `github-actions` skill), measured on the runner's real CPU quota.
54
+
55
+ ## Reviewer steps
56
+
57
+ 1. **Start from the lint.** Your share's findings are in `lint.json`. Every hit, gate or lead, is a candidate, not yet a finding. In a deep audit, also grep your files for the quick tells in [SKILL.md](../SKILL.md)'s principle table.
58
+ 2. **Read each candidate** and the code it tests. The finding needs the one question answered from the code. You may run one test file to confirm a Lead; never run the suite.
59
+ 3. **Check the look-alikes** in each principle's "Not a failure" ([principles.md](principles.md)) before reporting. When unsure, report a `Lead` with the doubt stated.
60
+ 4. **Many hits?** Group them by rule and pattern, read a sample from each group until the verdict is clear, then report the group once as a cluster with its count and the files, not hundreds of rows.
61
+ 5. **Report**, do not fix. No edits, no rewrites, no deletions, no suggested replacement code. Say what the test fails to prove; the implementer chooses the remedy. Write the full report to your report path in the template below, then reply with one line: `<summary line> — <report path>`. Never paste the report into your reply.
62
+
63
+ **Labels** (`Not coverage`, `Weak`, `Redundant`, `Lead`) are defined in [SKILL.md](../SKILL.md#labels).
64
+
65
+ When an audit feeds a coverage grade, `ensure-coverage`'s `references/depth/test-smells.md` maps these labels to its grades (`Not coverage` → `Missing` or `Over-mocked`, `Weak` → `Partial` or `Wrong Level`).
66
+
67
+ Gate hits map directly: a skipped, empty, or swallowed test is `Not coverage`; a fixed sleep is `Weak`.
68
+
69
+ **Deliverable.** Size it to the question. Asked about a handful of tests ("which of these should we keep?"), skip the subagents and answer per test in plain words, keep or drop and why, with the label beside it. For a suite or a diff, use the full report:
70
+
71
+ ```markdown
72
+ ## Summary — <N> findings over <M> test files: <a> Not coverage · <b> Weak · <c> Redundant · <d> Lead
73
+ ## Findings (most costly first)
74
+ | file:line | principle | pattern | label | bug it misses | harmless change that breaks it |
75
+ ## Clusters — repeated patterns and their likely cause (e.g. "logic not exported", "no DB in unit lane")
76
+ ## Look-alikes kept — tests that matched a quick tell and were cleared, one line each with the reason
77
+ ## Not audited — unflagged files (quick audit), paths excluded, unread when the budget ran out, or unreadable, and why
78
+ ```
79
+
80
+ Every finding carries a real `file:line` you opened. Rank by cost: `Not coverage` on auth, money, or data integrity first; noise last.
@@ -0,0 +1,24 @@
1
+ # The lint: rules and limits
2
+
3
+ > Read when: running `lint-tests.mjs` or reading its findings. Each rule's principle, with its look-alikes: [principles.md](principles.md).
4
+
5
+ Scripts live under **this skill's directory**. Set `SKILL_DIR` to the directory you read this file from and run `node "$SKILL_DIR/scripts/lint-tests.mjs"`. Never resolve against your CWD. A missing script in the audited repo is not a blocker; the scripts belong to this skill.
6
+
7
+ A **gate** rule is decidable and fails the exit code; a **lead** rule also matches some legitimate tests, so read each hit against the principle's "Not a failure" cases.
8
+
9
+ | rule | principle | severity | finds |
10
+ |---|---|---|---|
11
+ | `text-oracle` | 1 | lead | a checked-in doc or source file read and text-matched (one hit per file) |
12
+ | `config-read` | 6 | lead | a checked-in config file read, whatever the assertion (one hit per file); recognizes config by name (workflows, `.mergify.yml`, `cloudbuild*`, Dockerfile, compose, `package.json`, `tsconfig*`, `pyproject.toml`, `.env*`, …), so a file found by `readdir` or an unusual name needs reading |
13
+ | `count-pin` | 2 | lead | an exact size of 5 or more (format lengths 26, 32, 36, 40, 64, 128 excluded) |
14
+ | `mock-internal-seam` | 3 | gate | a mock of first-party code (topology in `coverage.config.json`, conventional defaults if absent) |
15
+ | `utility-class` | 3 | lead | a Tailwind-shaped class asserted in a DOM test |
16
+ | `redundant-matcher` | 4 | lead | `getBy*(…)` then `toBeDefined`/`toBeTruthy`; `get(…).exists()` then `toBe(true)` |
17
+ | `no-empty-test` · `no-swallowed-assertion` · `no-skip` | 4 | gate | empty body; assertion eaten by `.catch()`; declared-skipped, focused, or todo test |
18
+ | `no-fixed-timeout` | 7 | gate | fixed sleep |
19
+ | `conditional-skip` | 4 | lead | `skipif`, a runtime `test.skip()` / `t.Skip()` / `pytest.skip()`, `importorskip`, `xfail` |
20
+ | `duplicate-file` | 5 | lead | test files identical after whitespace (whole-tree and `--files` only) |
21
+
22
+ Run from the target repo's root: `node "$SKILL_DIR/scripts/lint-tests.mjs"` scans the tree; `--diff <base>` reports only lines changed since the merge-base, including uncommitted and untracked test files; `--files a,b`, `--rules a,b`, `--exclude dist,vendor,fixtures`, and `--json` narrow or reshape it. `--shares N` also splits the files with findings into at most N shares of about equal finding count, keeping each file whole: one share per audit reviewer ([audit.md](audit.md)). Exit 0 means no gate finding, 1 gate findings, 2 a usage error (unknown flag or rule, missing file).
23
+
24
+ **What a clean run proves.** The rules are written for JS/TS first. `mock-internal-seam`, `redundant-matcher`, and `utility-class` see only JS/TS; Python gets skips, empty tests, `time.sleep`, `text-oracle`, `config-read`, and `count-pin`; Go gets `t.Skip`, `time.Sleep`, `text-oracle`, `config-read`, and `count-pin`. A clean lint on a Python or Go suite proves little: read it.
@@ -0,0 +1,143 @@
1
+ # The seven principles, in full
2
+
3
+ > Read when: writing a test and unsure which side of a principle it falls on, or auditing (every "Not a failure" here is a look-alike to clear before reporting). The principle statements and the one question live in [SKILL.md](../SKILL.md).
4
+
5
+ ## 1. Test behavior, not text
6
+
7
+ **Principle.** Run the code and observe what it does. The text of a file (doc, prompt, source, migration) is not behavior. Config files are [principle 6](#6-dont-test-config-files): not tested at all.
8
+
9
+ **Done right.**
10
+ - Import the config object the code uses and assert the behavior it drives (the OTP expires after 600s: advance the clock, the code is refused).
11
+ - Compare a doc's value to the code's value (`README` port equals `config.port`), so only real drift fails.
12
+ - Scan **every** file for a banned call (no route imports the raw DB client): a rule over the tree, not a line in one file.
13
+ - Assert text the code **produced** from an input (rendered output, CLI error message a user depends on).
14
+
15
+ **Common failures.**
16
+ - *Prose pin:* `assert "Never force-publish" in runbook`. Rewording fails it; deleting the behavior the sentence describes does not.
17
+ - *Source grep:* `expect(readFileSync('auth.ts')).toMatch(/expiresIn:\s*600/)`, `assert "start >> fee_settings" in dag_source`. A rename breaks it; the value overridden one line later passes it.
18
+ - *Migration grep:* asserting a migration file contains a `CHECK`. It proves the file's text, not that the constraint exists in the database.
19
+ - *Tombstone:* `expect(src).not.toContain('oldFunctionName')`. Guards against one string returning, forever.
20
+
21
+ **Coverage rule.** A test whose only assertions are text matches over checked-in files is **not coverage** for the behavior the text describes. Report it as `Not coverage`, never as partial proof.
22
+
23
+ **Not a failure.** A negative pin whose string stands for a forbidden capability in code or output (`not.toContain(secret)` on a response or a log) is behavior: the string is the capability, not wording.
24
+
25
+ **Why it happens.** Usually the logic is hard to reach: not exported, the framework (Airflow, Next.js wiring) is not loadable in tests, or no DB in the unit lane. Name that cause in the finding; it is the implementer's lead to the fix.
26
+
27
+ ## 2. The expected value comes from somewhere other than the code under test
28
+
29
+ **Principle.** The expected value must come from an independent source: the spec, an external contract, a separately written and simpler model, or the input. Not from the code under test, and not from a literal copied out of it.
30
+
31
+ **Done right.**
32
+ - Recompute a webhook HMAC by hand from the provider's published spec.
33
+ - Check pricing against a small, independently written tier table at the boundaries.
34
+ - Derive the expected list from the registry (`readdir(migrations)`, every key in `en` exists in `zh`).
35
+ - Pin a value an outside party depends on: error codes, OIDC discovery fields, wire response keys, a versioned golden that must never change.
36
+ - When a version really is the contract (the runtime needs Node 24), pin the major only: `v24`, not `v24.2.1`. A major version is a compatibility promise; a minor or patch is not.
37
+
38
+ **Common failures.**
39
+ - *Constant mirror:* `expect(MEMBERSHIP_STATUS.ACTIVE).toBe('active')`, `assert.Equal(t, 3, maxRetries)`.
40
+ - *Count pin:* `toHaveLength(19)`, "exactly 28 skills". Every legitimate addition fails; nobody learns anything from the bump.
41
+ - *Version pin:* `'js-yaml': '4.3.1'` or `node === 'v24.2.1'` asserted in a test. A minor or patch bump fails; behavior is untouched.
42
+ - *Release tag pin:* a pre-release tag asserted in a test: `RC01`, `-rc.2`, `beta.3`. It changes with every release cut, and no bug makes it fail.
43
+ - *Mock echo:* `repo.find.mockResolvedValue(row)` then `expect(result).toEqual(row)`. Fails only if the wrapper drops the value.
44
+ - *Production code as oracle:* `expected := rate * group.PeakMultiplierAt(now)`. A bug in the helper cancels out.
45
+ - *Stub echo:* asserting a `data-testid` or `aria-label` that the test's own stub renders.
46
+ - *Format only:* `len(digest) == 64`. The SHA-256 of the wrong content passes.
47
+
48
+ **Not a failure.** A length that encodes an external format (UUID, hex digest) *alongside* a value check; an allowlist frozen on purpose because widening it is the risk. Output the code under test *built* from a faked value: a route that serializes a mocked result (`rotatedAt.toISOString()`), wraps it in an envelope (`{ grant }`), or renames its fields. Only an output identical to the fake's return is an echo.
49
+
50
+ ## 3. Fake only what you don't own
51
+
52
+ **Principle.** Real internals, faked externals. Substitute only what you do not own: third-party APIs, providers, clock, randomness (faking the clock and randomness is also how a test stays repeatable: [principle 7](#7-same-code-same-result)). Your database and services run for real, because a fake cannot see what lives in them: transactions, tenant filters, locking, idempotency.
53
+
54
+ **Done right.**
55
+ - Real Postgres with migrations; only the payment provider faked.
56
+ - A spy at an external boundary where **the call is the behavior**: the backoff delay, the precondition header sent to storage, "the provider was not called after validation failed".
57
+
58
+ **Common failures.**
59
+ - *First-party mock:* `vi.mock('@/lib/prisma')`, patching the class's own `_private` helper. The `mock-internal-seam` rule catches the JS module form. Your own thin adapter around a provider (`@/lib/stripe-client`) *is* the external boundary: declare it in `coverage.config.json` under `mockPolicy.externals` rather than calling it a finding.
60
+ - *Blind injected fake:* a `deps` fake returns rows whatever the query says, and the test asserts `findUnique({ where: { id } })`. Delete the tenant check and it stays green. No rule sees `deps` injection; read for it.
61
+ - *Mocked transaction:* "updates atomically" with `$transaction: (fn) => fn()`.
62
+ - *Layout in jsdom:* `toHaveClass('min-h-11')` to prove a 44px target. jsdom has no layout.
63
+
64
+ An over-mocked test is `Not coverage` **for the behavior the fake hides** (a mocked repo proves nothing about the query or the tenant filter), though it may still cover the caller's own branching. An untested path is an honest gap; an over-mocked one is false green.
65
+
66
+ ## 4. An assertion must be able to fail
67
+
68
+ **Principle.** Every test must be able to go red, and must check what its name promises. Read the name's verbs ("atomically", "then", "decompresses", "corrected to", "byte-stable") and find the assertion for each.
69
+
70
+ **Done right.**
71
+ - A test named "retries then gives up" asserts the attempt count **and** the order **and** the final error.
72
+ - A rejection test asserts the specific error code or message, so it cannot pass for an unrelated reason.
73
+ - `waitForRequest(...)` or `ExpectationsWereMet()` as the assertion: it fails by timing out or by unmet expectation. Not assertion-free.
74
+
75
+ **Common failures.**
76
+ - *No assertion:* a body that runs code and checks nothing, or only `NoError` / `NotNil` on a constructor.
77
+ - *Redundant matcher:* `expect(screen.getByText('x')).toBeDefined()`. `getBy` already throws when the text is missing, so the matcher adds nothing and the test proves presence only. Shallow, not vacuous: `Weak` if its name claims more, otherwise leave it.
78
+ - *Self-skipping:* `if (visible) expect(...) else test.skip()`; `pytest.skip` inside `except ImportError`; an env-gated skip whose variable CI never sets.
79
+ - *Vacuous loop:* `for row in rows: assert isinstance(row, dict); break` passes on zero rows.
80
+ - *Shape only:* `hasattr(dal, 'read')`, `callable(run)`, `typeof processed === 'number'` (passes on 0).
81
+ - *Loose rejection:* `toThrow()` with no type or message; `status !== 0`; `notDeepEqual(errors, [])`.
82
+ - *Name over-promises:* "calling start twice does not create a second timer" with no assertion; "sanitizes the SVG" asserting only a toast.
83
+ - *Deny-list for leaks:* 12 `not.toHaveProperty` on a response. A new sensitive column leaks green; an exact-keys allowlist fails.
84
+
85
+ **Not a failure.** A precondition `toBeDefined()` on a value that can really be `undefined` (an `Array.find` result) followed by real assertions; accept-case `NoError` in a validator whose reject cases sit beside it; a skip on a platform or optional dependency (`skipif(sys.platform == 'win32')`) or a strict `xfail` pinned to an open issue, when CI still runs the test somewhere.
86
+
87
+ ## 5. Test each behavior once, and only for code that still runs
88
+
89
+ **Principle.** Each behavior is proven once, at the lowest level that can prove it for real, for code that still runs.
90
+
91
+ **Done right.**
92
+ - An exhaustive pure unit for the decision table plus one real-DB integration test per rule: that is layering, not duplication.
93
+ - Many similar cases folded into one table-driven test (every route rejects a missing token), so each row adds a branch.
94
+ - A guard test that *asserts* two deliberately mirrored files stay identical, instead of two identical suites.
95
+
96
+ **Common failures.**
97
+ - *Copied files:* the same test file in two directories, both run. They drift, and fixes land in one copy.
98
+ - *Mocked twin:* `service.test.ts` (mocked DB) repeating `service.integration.test.ts` case for case. The mocked copy catches nothing the real one misses.
99
+ - *Extraction leftovers:* logic moved to a shared package; each app kept its own copy of the tests.
100
+ - *Subsumed page-load:* an e2e test that only checks a heading, beside tests that load the same page and act on it.
101
+ - *Dead code:* tests of a spike, a one-off release script, or a module only tests import.
102
+ - *Diverged siblings:* copy-pasted tests that disagree; one pins the bug the others fixed. A duplicate is also a divergence lead.
103
+
104
+ **Not a failure.** 69 near-identical "returns 401" tests prove 69 routes call auth. That is *merge into a table*, not *delete*.
105
+
106
+ ## 6. Don't test config files
107
+
108
+ **Principle.** Config is not code, so it gets no tests. Dockerfiles, `cloudbuild.yaml`, `.github/workflows/*`, `.mergify.yml`, `docker-compose.yml`, Kubernetes and Skaffold manifests, `package.json`, `tsconfig.json`, `pyproject.toml`, `.env` files, and any other JSON, YAML, or TOML file a tool reads: the tool that reads it is the test. CI parses and runs the workflow, `docker build` builds the image, Mergify validates its config, the deploy deploys. A test that reads the file back, as text or parsed, only restates it.
109
+
110
+ **Done right.**
111
+ - Test the code that *reads* config: the app loads `retries: 3` from `config.json`, so make the call fail three times and assert it gives up.
112
+ - Scripts are code, not config. A release or deploy script (`release.mjs`, `deploy.sh`) with real logic is run against a throwaway repo or a fake `gcloud`, and what it did is asserted.
113
+ - Leave the file untested. A broken workflow fails CI; a broken Dockerfile fails the build; a broken queue rule shows in the queue. That failure is the proof.
114
+ - When you delete a config test, name the behavior it stood in for as a follow-up: the smoke, post-deploy, or runtime check that would catch the bug for real. Deleting exposes that gap; keeping the pin hides it.
115
+
116
+ **Common failures.**
117
+ - *Parsed mirror:* `yaml.load('.mergify.yml').queue_rules[0].batch_size === 3`, `JSON.parse(package.json).engines.node`. A deliberate change fails it; nothing that runs is checked.
118
+ - *Text mirror:* `expect(workflowYaml).toContain('postgres:17')`, `assert "--no-traffic" in cloudbuild`. A bump or rename fails; a broken step with the literal intact passes.
119
+ - *Setting mirror:* `concurrency`, `timeout-minutes`, a matrix entry, a Docker base image, or a cloudbuild step read back out of the file.
120
+ - *Policy pin:* "the workflow has no `pull_request_target`", "no `--network=host`". Still a config test; a policy tool (actionlint, a ruleset, an org policy) owns it.
121
+ - *Hand-rolled validity sweep:* a test that parses every workflow to prove it is valid. The tool already refuses an invalid file.
122
+ - *Simulated pipeline:* executing `cloudbuild.yaml` steps under a fake `gcloud` to prove the config. It tests a copy of the runner, not the runner.
123
+ - *Regression pin:* a text match added after a real bug, such as `expect(dockerfile).toMatch(/^COPY content \.\/content$/m)` once `/docs` shipped empty. Still a config test, and it never runs the deployed page. Delete it and file the missing behavior check; do not keep it as the guard.
124
+
125
+ **Not a failure.** JSON the app loads as data is not config: a locale file (every key in `en` exists in `zh`), a price table, a seed catalog. Test fixtures, files the test writes itself, and a config file passed to the code under test (`cli --config fixtures/app.json`) are inputs, not the thing tested.
126
+
127
+ ## 7. Same code, same result
128
+
129
+ **Principle.** A test must pass or fail the same way on every run of the same code. Anything that changes between runs (randomness, the clock, timing, run order, the network) is fixed by the test, not left to chance.
130
+
131
+ **Done right.**
132
+ - All IDs and random numbers come from one seeded generator or fixed ID factory; the seed is logged when randomness must stay.
133
+ - The clock is frozen or injected; the time zone and locale are set by the test.
134
+ - Async work is awaited on the condition it produces, not on a sleep.
135
+ - Each test creates the state it needs and doesn't read what another test left.
136
+
137
+ **Common failures.**
138
+ - *Unseeded randomness:* random values in checked output now and then match a pattern check (a card-number scanner, a snapshot). Fixing values one at a time never ends; fix the source.
139
+ - *Live clock:* passes all day, fails at midnight, at month end, or in another time zone.
140
+ - *Fixed sleep:* `sleep(500)` before asserting async work. Passes on a fast machine, fails under load, and hides the condition the test should wait on.
141
+ - *Order dependence:* passes in the full suite, fails when run alone, or the reverse.
142
+
143
+ **Not a failure.** A property-based or fuzz test that uses randomness on purpose and logs its seed, so any failure can be replayed. Real elapsed time that *is* the behavior, such as a deadline that must pass while a database lock is held, measured by the database clock that a fake cannot move. Wait on the condition (the clock passing the deadline), not a fixed sleep; treat an attempt whose precondition was observed too late as inconclusive and retry it with a longer margin; and assert persisted state afterwards, so a retried attempt cannot hide a bug.
@@ -0,0 +1,9 @@
1
+ ## Testing conventions
2
+
3
+ 1. Run the code and assert what it does; never match the text of docs, prompts, source files, or migrations.
4
+ 2. Take expected values from the spec, an external contract, or the input, never from the code under test; pin versions to the major only.
5
+ 3. Fake only third-party services, the clock, and randomness; run your own database and services for real.
6
+ 4. Make every assertion able to fail, and assert everything the test name promises.
7
+ 5. Test each behavior once, at the lowest level that proves it; delete tests of dead code.
8
+ 6. Don't test config files (Dockerfiles, CI workflows, `cloudbuild.yaml`, merge-queue config, `package.json`, other JSON/YAML/TOML a tool reads); test the code that reads them.
9
+ 7. Seed randomness, freeze the clock, wait on conditions instead of sleeps, and never depend on another test's state.
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { dirname, join } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const DAY_MS = 24 * 60 * 60 * 1000;
9
+ const WEEK_MS = 7 * DAY_MS;
10
+ const here = dirname(fileURLToPath(import.meta.url));
11
+
12
+ function readJson(path, fallback = {}) {
13
+ try { return JSON.parse(readFileSync(path, 'utf8')); } catch { return fallback; }
14
+ }
15
+
16
+ function frontmatterValue(text, key) {
17
+ const frontmatter = /^---\n([\s\S]*?)\n---/.exec(text)?.[1] ?? '';
18
+ const match = new RegExp('^' + key + ':\\s*([^\\n]+)$', 'm').exec(frontmatter);
19
+ return match?.[1].trim().replace(/^['"]|['"]$/g, '') ?? null;
20
+ }
21
+
22
+ function repositoryOf(source) {
23
+ const value = String(source ?? '').trim();
24
+ const match = /^(?:git@github\.com:|https:\/\/github\.com\/)?([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+?)(?:\.git)?$/.exec(value);
25
+ return match?.[1] ?? null;
26
+ }
27
+
28
+ function stableVersion(value) {
29
+ const match = /^v?(\d+)\.(\d+)\.(\d+)$/.exec(String(value ?? '').trim());
30
+ return match ? match.slice(1).map(Number) : null;
31
+ }
32
+
33
+ function newer(left, right) {
34
+ for (let index = 0; index < 3; index += 1) {
35
+ if (left[index] !== right[index]) return left[index] > right[index];
36
+ }
37
+ return false;
38
+ }
39
+
40
+ function writeCache(path, value) {
41
+ try {
42
+ mkdirSync(dirname(path), { recursive: true });
43
+ writeFileSync(path, JSON.stringify(value));
44
+ } catch { /* A read-only cache must not block skill use. */ }
45
+ }
46
+
47
+ function main(now = Date.now()) {
48
+ if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
+ const name = frontmatterValue(skill, 'name');
51
+ const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
52
+ if (!name || !localVersion) return;
53
+
54
+ const lock = readJson(join(process.env.HOME || homedir(), '.agents', '.skill-lock.json'));
55
+ const entry = lock.skills?.[name];
56
+ const repository = repositoryOf(entry?.sourceUrl || entry?.source);
57
+ if (!repository) return;
58
+
59
+ const cacheRoot = process.env.XDG_CACHE_HOME || join(process.env.HOME || homedir(), '.cache');
60
+ const cachePath = join(cacheRoot, '1aboveio-skills', 'release-check.json');
61
+ const all = readJson(cachePath);
62
+ const cache = all[repository] && typeof all[repository] === 'object' ? all[repository] : {};
63
+
64
+ if (!cache.lastCheck || now - cache.lastCheck >= DAY_MS) {
65
+ const result = spawnSync('gh', ['api', 'repos/' + repository + '/releases/latest', '--jq', '.tag_name'], {
66
+ encoding: 'utf8',
67
+ stdio: ['ignore', 'pipe', 'ignore'],
68
+ timeout: 1500,
69
+ });
70
+ cache.lastCheck = now;
71
+ if (result.status === 0 && stableVersion(result.stdout)) cache.latestTag = result.stdout.trim();
72
+ else delete cache.latestTag;
73
+ all[repository] = cache;
74
+ writeCache(cachePath, all);
75
+ }
76
+
77
+ const latestVersion = stableVersion(cache.latestTag);
78
+ if (!latestVersion || !newer(latestVersion, localVersion)) return;
79
+ if (cache.notifiedTag === cache.latestTag && cache.notifiedAt && now - cache.notifiedAt < WEEK_MS) return;
80
+
81
+ cache.notifiedTag = cache.latestTag;
82
+ cache.notifiedAt = now;
83
+ all[repository] = cache;
84
+ writeCache(cachePath, all);
85
+ const command = `npx skills@1.5.23 add '${repository}#${cache.latestTag}' --global --agent universal claude-code --skill ${name} --yes`;
86
+ process.stdout.write(
87
+ `UPDATE_AVAILABLE: A newer 1AboveIO skills release (${cache.latestTag}) is available; this skill is `
88
+ + `v${localVersion.join('.')}. Ask once whether to refresh ${name}. On approval run \`${command}\`. `
89
+ + 'The refreshed instructions apply next session. Either way, continue the current task and do not ask again this session.\n',
90
+ );
91
+ }
92
+
93
+ try { main(); } catch { /* Update checks are advisory and always fail silent. */ }