@1aboveio/skills 0.10.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 (397) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +90 -0
  3. package/bin/1aboveio-skills.mjs +18 -0
  4. package/package.json +28 -0
  5. package/runtime/skills/distribution/generated/recipes.json +1189 -0
  6. package/runtime/skills/distribution/scripts/bundles.mjs +280 -0
  7. package/runtime/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
  8. package/skills/backend/airflow-dag-develop/LICENSE +3 -0
  9. package/skills/backend/airflow-dag-develop/SKILL.md +111 -0
  10. package/skills/backend/app-debug/LICENSE +3 -0
  11. package/skills/backend/app-debug/SKILL.md +109 -0
  12. package/skills/backend/app-debug/references/common-errors.md +128 -0
  13. package/skills/backend/python-backend/LICENSE +3 -0
  14. package/skills/backend/python-backend/SKILL.md +326 -0
  15. package/skills/cicd-pipeline/cloud-build/LICENSE +3 -0
  16. package/skills/cicd-pipeline/cloud-build/SKILL.md +707 -0
  17. package/skills/cicd-pipeline/cloud-debug/LICENSE +3 -0
  18. package/skills/cicd-pipeline/cloud-debug/SKILL.md +316 -0
  19. package/skills/cicd-pipeline/cloud-debug/references/build-failures.md +238 -0
  20. package/skills/cicd-pipeline/cloud-debug/references/deploy-failures.md +376 -0
  21. package/skills/cicd-pipeline/cloud-debug/references/pipeline-failures.md +378 -0
  22. package/skills/cicd-pipeline/cloud-deploy/LICENSE +3 -0
  23. package/skills/cicd-pipeline/cloud-deploy/SKILL.md +229 -0
  24. package/skills/cicd-pipeline/cloud-deploy/references/config-templates.md +257 -0
  25. package/skills/cicd-pipeline/docker/LICENSE +3 -0
  26. package/skills/cicd-pipeline/docker/SKILL.md +126 -0
  27. package/skills/cicd-pipeline/google-cloud/LICENSE +3 -0
  28. package/skills/cicd-pipeline/google-cloud/SKILL.md +118 -0
  29. package/skills/cicd-pipeline/google-cloud/references/gcs.md +469 -0
  30. package/skills/cicd-pipeline/google-cloud/references/iam.md +451 -0
  31. package/skills/cicd-pipeline/google-cloud/references/project.md +349 -0
  32. package/skills/cicd-pipeline/google-cloud/references/secrets.md +336 -0
  33. package/skills/cicd-pipeline/google-cloud/references/vpc.md +312 -0
  34. package/skills/cicd-pipeline/google-cloud/scripts/create-sa.sh +36 -0
  35. package/skills/cicd-pipeline/google-cloud/scripts/gcp-config.sh +31 -0
  36. package/skills/cicd-pipeline/google-cloud/scripts/grant-iap.sh +41 -0
  37. package/skills/cicd-pipeline/google-cloud/scripts/setup-secrets.sh +48 -0
  38. package/skills/cicd-pipeline/mergify/LICENSE +3 -0
  39. package/skills/cicd-pipeline/mergify/SKILL.md +138 -0
  40. package/skills/cicd-pipeline/mergify/assets/templates/mergify.yml +237 -0
  41. package/skills/cicd-pipeline/mergify/assets/templates/ruleset.json +46 -0
  42. package/skills/cicd-pipeline/mergify/references/branch-protection.md +277 -0
  43. package/skills/cicd-pipeline/mergify/references/configuration.md +183 -0
  44. package/skills/cicd-pipeline/mergify/references/diagnosis.md +73 -0
  45. package/skills/cicd-pipeline/mergify/references/traps.md +78 -0
  46. package/skills/cicd-pipeline/mergify/references/watch-contract.md +218 -0
  47. package/skills/cicd-pipeline/mergify/scripts/audit-core.mjs +131 -0
  48. package/skills/cicd-pipeline/mergify/scripts/audit.mjs +4 -0
  49. package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery-core.mjs +663 -0
  50. package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery.mjs +4 -0
  51. package/skills/cicd-pipeline/podman/LICENSE +3 -0
  52. package/skills/cicd-pipeline/podman/SKILL.md +70 -0
  53. package/skills/cicd-pipeline/podman/agents/openai.yaml +4 -0
  54. package/skills/cicd-pipeline/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
  55. package/skills/cicd-pipeline/podman/assets/templates/podman-service-override.conf +3 -0
  56. package/skills/cicd-pipeline/podman/references/compose-compatibility.md +70 -0
  57. package/skills/cicd-pipeline/podman/references/networking-and-ports.md +74 -0
  58. package/skills/cicd-pipeline/podman/references/rootless-services-and-sockets.md +156 -0
  59. package/skills/cicd-pipeline/podman/references/troubleshooting.md +98 -0
  60. package/skills/engineering/e2e-test/LICENSE +3 -0
  61. package/skills/engineering/e2e-test/SKILL.md +156 -0
  62. package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +272 -0
  63. package/skills/engineering/e2e-test/assets/ci-gates.github.yml +451 -0
  64. package/skills/engineering/e2e-test/assets/e2e-workflow.yml +282 -0
  65. package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
  66. package/skills/engineering/e2e-test/references/authoring/playwright-config.md +71 -0
  67. package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +219 -0
  68. package/skills/engineering/e2e-test/references/authoring/test-skipping.md +44 -0
  69. package/skills/engineering/e2e-test/references/ci-integration.md +121 -0
  70. package/skills/engineering/e2e-test/references/ci-playwright-container.md +280 -0
  71. package/skills/engineering/e2e-test/references/debugging.md +36 -0
  72. package/skills/engineering/e2e-test/references/presentation-sweep.md +131 -0
  73. package/skills/engineering/e2e-test/references/reviewing.md +39 -0
  74. package/skills/engineering/e2e-test/references/route-discovery.md +50 -0
  75. package/skills/engineering/e2e-test/references/route-manifest.md +44 -0
  76. package/skills/engineering/e2e-test/scripts/detect-routes-fastapi.py +290 -0
  77. package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
  78. package/skills/engineering/e2e-test/scripts/post-visual-evidence.mjs +158 -0
  79. package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
  80. package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
  81. package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
  82. package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
  83. package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +148 -0
  84. package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
  85. package/skills/engineering/e2e-test/scripts/presentation-visual.mjs +84 -0
  86. package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +75 -0
  87. package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
  88. package/skills/engineering/engineering-runtime/LICENSE +3 -0
  89. package/skills/engineering/engineering-runtime/SKILL.md +10 -0
  90. package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
  91. package/skills/engineering/engineering-runtime/coherence/workflow.json +553 -0
  92. package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
  93. package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
  94. package/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
  95. package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
  96. package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
  97. package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
  98. package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
  99. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +576 -0
  100. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +166 -0
  101. package/skills/engineering/ensure-coverage/LICENSE +3 -0
  102. package/skills/engineering/ensure-coverage/SKILL.md +136 -0
  103. package/skills/engineering/ensure-coverage/evals/evals.json +125 -0
  104. package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +91 -0
  105. package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +83 -0
  106. package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
  107. package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
  108. package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
  109. package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +25 -0
  110. package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
  111. package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +87 -0
  112. package/skills/engineering/ensure-coverage/references/depth/test-smells.md +23 -0
  113. package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +164 -0
  114. package/skills/engineering/ensure-coverage/references/enforcement/hooks.md +85 -0
  115. package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +109 -0
  116. package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +33 -0
  117. package/skills/engineering/ensure-coverage/references/presentation/axis.md +78 -0
  118. package/skills/engineering/ensure-coverage/references/presentation/runner-contract.md +74 -0
  119. package/skills/engineering/ensure-coverage/references/process/audit-mode.md +33 -0
  120. package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
  121. package/skills/engineering/ensure-coverage/references/process/review-contract-template.md +119 -0
  122. package/skills/engineering/ensure-coverage/references/process/scope-class.md +178 -0
  123. package/skills/engineering/ensure-coverage/references/process/test-strategy.md +55 -0
  124. package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +45 -0
  125. package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +93 -0
  126. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +178 -0
  127. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +101 -0
  128. package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +358 -0
  129. package/skills/engineering/ensure-coverage/scripts/coverage-checklist.mjs +494 -0
  130. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +663 -0
  131. package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
  132. package/skills/engineering/ensure-coverage/scripts/evidence-block.mjs +367 -0
  133. package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +269 -0
  134. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
  135. package/skills/engineering/ensure-coverage/scripts/package-lock.json +76 -0
  136. package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
  137. package/skills/engineering/ensure-coverage/scripts/scope-class.mjs +554 -0
  138. package/skills/engineering/harness-runtime/LICENSE +3 -0
  139. package/skills/engineering/harness-runtime/SKILL.md +18 -0
  140. package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
  141. package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
  142. package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
  143. package/skills/engineering/harness-runtime/contracts.md +15 -0
  144. package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
  145. package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
  146. package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
  147. package/skills/engineering/harness-runtime/index.mjs +767 -0
  148. package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
  149. package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
  150. package/skills/engineering/harness-runtime/references/model-catalog-seed.json +159 -0
  151. package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
  152. package/skills/engineering/implement-and-pr/LICENSE +3 -0
  153. package/skills/engineering/implement-and-pr/SKILL.md +176 -0
  154. package/skills/engineering/implement-and-pr/references/ci-iteration.md +10 -0
  155. package/skills/engineering/implement-and-pr/references/closeout.md +27 -0
  156. package/skills/engineering/implement-and-pr/references/contract-complete-fix-rounds.md +34 -0
  157. package/skills/engineering/implement-and-pr/references/evidence-rules.md +39 -0
  158. package/skills/engineering/implement-and-pr/references/incremental-plan.md +16 -0
  159. package/skills/engineering/implement-and-pr/references/self-review.md +23 -0
  160. package/skills/engineering/implement-and-pr/references/tdd-mode.md +18 -0
  161. package/skills/engineering/resolve-issues/LICENSE +3 -0
  162. package/skills/engineering/resolve-issues/SKILL.md +167 -0
  163. package/skills/engineering/resolve-issues/generated/workflow-repair-policy.json +448 -0
  164. package/skills/engineering/resolve-issues/references/breaker.md +82 -0
  165. package/skills/engineering/resolve-issues/references/deliverables.md +27 -0
  166. package/skills/engineering/resolve-issues/references/delivery.md +108 -0
  167. package/skills/engineering/resolve-issues/references/evidence-lane.md +21 -0
  168. package/skills/engineering/resolve-issues/references/exact-head-ci.md +287 -0
  169. package/skills/engineering/resolve-issues/references/fan-out.md +33 -0
  170. package/skills/engineering/resolve-issues/references/finalization.md +68 -0
  171. package/skills/engineering/resolve-issues/references/guarantees.md +10 -0
  172. package/skills/engineering/resolve-issues/references/high-risk.md +29 -0
  173. package/skills/engineering/resolve-issues/references/incidents/848/README.md +156 -0
  174. package/skills/engineering/resolve-issues/references/intake.md +86 -0
  175. package/skills/engineering/resolve-issues/references/integration-gate.md +53 -0
  176. package/skills/engineering/resolve-issues/references/interference.md +87 -0
  177. package/skills/engineering/resolve-issues/references/loop.md +134 -0
  178. package/skills/engineering/resolve-issues/references/model-catalog.md +9 -0
  179. package/skills/engineering/resolve-issues/references/postmortem.md +27 -0
  180. package/skills/engineering/resolve-issues/references/pre-flight-model-slots.md +41 -0
  181. package/skills/engineering/resolve-issues/references/pre-flight-recording-and-checkout.md +48 -0
  182. package/skills/engineering/resolve-issues/references/pre-flight.md +41 -0
  183. package/skills/engineering/resolve-issues/references/regression-checklist.md +26 -0
  184. package/skills/engineering/resolve-issues/references/run-state.md +288 -0
  185. package/skills/engineering/resolve-issues/references/sandboxed-testing.md +48 -0
  186. package/skills/engineering/resolve-issues/references/spawn-contract.md +96 -0
  187. package/skills/engineering/resolve-issues/references/terminal-evidence-journal.md +40 -0
  188. package/skills/engineering/resolve-issues/references/why.md +653 -0
  189. package/skills/engineering/resolve-issues/schemas/fix-round.schema.json +49 -0
  190. package/skills/engineering/resolve-issues/scripts/combine-and-verify.mjs +721 -0
  191. package/skills/engineering/resolve-issues/scripts/component-candidate.mjs +962 -0
  192. package/skills/engineering/resolve-issues/scripts/contract-revision.mjs +220 -0
  193. package/skills/engineering/resolve-issues/scripts/detect-delivery-mode.mjs +420 -0
  194. package/skills/engineering/resolve-issues/scripts/detect-target-branch.mjs +256 -0
  195. package/skills/engineering/resolve-issues/scripts/detect-workspace-mode.mjs +168 -0
  196. package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
  197. package/skills/engineering/resolve-issues/scripts/doctrine.mjs +62 -0
  198. package/skills/engineering/resolve-issues/scripts/evidence-lifecycle-contract.mjs +191 -0
  199. package/skills/engineering/resolve-issues/scripts/exact-head-ci.mjs +413 -0
  200. package/skills/engineering/resolve-issues/scripts/exact-head-github-provider.mjs +332 -0
  201. package/skills/engineering/resolve-issues/scripts/finalize.mjs +488 -0
  202. package/skills/engineering/resolve-issues/scripts/fix-rounds.mjs +3307 -0
  203. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-circular-1001.json +16 -0
  204. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-valid-sequencing.json +51 -0
  205. package/skills/engineering/resolve-issues/scripts/fixtures/fmm-express-830-component-candidate.json +17 -0
  206. package/skills/engineering/resolve-issues/scripts/fixtures/head-check-set-1081.json +166 -0
  207. package/skills/engineering/resolve-issues/scripts/gate-value-series.mjs +92 -0
  208. package/skills/engineering/resolve-issues/scripts/guide-index.mjs +73 -0
  209. package/skills/engineering/resolve-issues/scripts/head-check-set.mjs +159 -0
  210. package/skills/engineering/resolve-issues/scripts/interference.mjs +427 -0
  211. package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
  212. package/skills/engineering/resolve-issues/scripts/next-operations.mjs +419 -0
  213. package/skills/engineering/resolve-issues/scripts/postmortem.mjs +909 -0
  214. package/skills/engineering/resolve-issues/scripts/preflight-questions.mjs +322 -0
  215. package/skills/engineering/resolve-issues/scripts/reconcile-contained-unit-prs.mjs +415 -0
  216. package/skills/engineering/resolve-issues/scripts/release-state-contract.mjs +697 -0
  217. package/skills/engineering/resolve-issues/scripts/report.mjs +494 -0
  218. package/skills/engineering/resolve-issues/scripts/required-check-plan.mjs +172 -0
  219. package/skills/engineering/resolve-issues/scripts/round-metadata.mjs +79 -0
  220. package/skills/engineering/resolve-issues/scripts/run-state-review6-cases.mjs +334 -0
  221. package/skills/engineering/resolve-issues/scripts/run-state.mjs +4784 -0
  222. package/skills/engineering/resolve-issues/scripts/sandbox-selftest.mjs +395 -0
  223. package/skills/engineering/resolve-issues/scripts/spawn-contract.mjs +290 -0
  224. package/skills/engineering/resolve-issues/scripts/terminal-dispositions.mjs +170 -0
  225. package/skills/engineering/resolve-issues/scripts/terminal-evidence-journal.mjs +293 -0
  226. package/skills/engineering/resolve-issues/scripts/unit-kind.mjs +197 -0
  227. package/skills/engineering/resolve-issues/scripts/unit-lifecycle.mjs +127 -0
  228. package/skills/engineering/resolve-issues/scripts/watch-delivery.mjs +893 -0
  229. package/skills/engineering/resolve-issues/scripts/workspaces.mjs +829 -0
  230. package/skills/engineering/resolve-issues/workflows/independent-review.workflow.js +290 -0
  231. package/skills/engineering/resolve-issues/workflows/prior-art-scan.workflow.js +80 -0
  232. package/skills/engineering/resolve-issues/workflows/workflow-smoke.mjs +102 -0
  233. package/skills/engineering/resolve-release/LICENSE +3 -0
  234. package/skills/engineering/resolve-release/SKILL.md +112 -0
  235. package/skills/engineering/resolve-release/references/assembly.md +137 -0
  236. package/skills/engineering/resolve-release/references/auto-when-green.md +56 -0
  237. package/skills/engineering/resolve-release/references/candidate.md +167 -0
  238. package/skills/engineering/resolve-release/references/exposure.md +178 -0
  239. package/skills/engineering/resolve-release/references/handoff.md +24 -0
  240. package/skills/engineering/resolve-release/references/postmortem.md +230 -0
  241. package/skills/engineering/resolve-release/references/preflight.md +207 -0
  242. package/skills/engineering/resolve-release/references/principles.md +94 -0
  243. package/skills/engineering/resolve-release/references/regression-checklist.md +36 -0
  244. package/skills/engineering/resolve-release/references/related-skills.md +12 -0
  245. package/skills/engineering/resolve-release/references/routing.md +149 -0
  246. package/skills/engineering/resolve-release/references/verified-sha-github-flow.md +285 -0
  247. package/skills/engineering/resolve-release/references/versioning.md +202 -0
  248. package/skills/engineering/resolve-release/references/why.md +53 -0
  249. package/skills/engineering/resolve-release/scripts/adapter-completion-artifact.mjs +389 -0
  250. package/skills/engineering/resolve-release/scripts/build-changes.mjs +209 -0
  251. package/skills/engineering/resolve-release/scripts/candidate-hygiene.mjs +407 -0
  252. package/skills/engineering/resolve-release/scripts/candidate-identity.mjs +904 -0
  253. package/skills/engineering/resolve-release/scripts/candidate-traffic.mjs +81 -0
  254. package/skills/engineering/resolve-release/scripts/checked-adapter-loader.mjs +612 -0
  255. package/skills/engineering/resolve-release/scripts/close-attempt.mjs +135 -0
  256. package/skills/engineering/resolve-release/scripts/closeout-release.mjs +161 -0
  257. package/skills/engineering/resolve-release/scripts/doctrine.mjs +106 -0
  258. package/skills/engineering/resolve-release/scripts/durable-processing.mjs +522 -0
  259. package/skills/engineering/resolve-release/scripts/ensure-target-green.mjs +659 -0
  260. package/skills/engineering/resolve-release/scripts/evidence-bundle.mjs +1014 -0
  261. package/skills/engineering/resolve-release/scripts/finalize-release.mjs +526 -0
  262. package/skills/engineering/resolve-release/scripts/fixtures/durable-processing-adapter.mjs +169 -0
  263. package/skills/engineering/resolve-release/scripts/green-gate.mjs +599 -0
  264. package/skills/engineering/resolve-release/scripts/isolated-adapter-evaluator.mjs +752 -0
  265. package/skills/engineering/resolve-release/scripts/metadata-pr-status.mjs +56 -0
  266. package/skills/engineering/resolve-release/scripts/metadata-sync.mjs +1538 -0
  267. package/skills/engineering/resolve-release/scripts/postmortem.mjs +381 -0
  268. package/skills/engineering/resolve-release/scripts/preflight-probes.mjs +498 -0
  269. package/skills/engineering/resolve-release/scripts/production-endpoints.mjs +326 -0
  270. package/skills/engineering/resolve-release/scripts/rc-circuit-breaker.mjs +272 -0
  271. package/skills/engineering/resolve-release/scripts/report.mjs +417 -0
  272. package/skills/engineering/resolve-release/scripts/reprobe-credentials.mjs +114 -0
  273. package/skills/engineering/resolve-release/scripts/revalidate-candidate.mjs +238 -0
  274. package/skills/engineering/resolve-release/scripts/review-packet.mjs +503 -0
  275. package/skills/engineering/resolve-release/scripts/rollback-floor.mjs +263 -0
  276. package/skills/engineering/resolve-release/scripts/version-assert.mjs +339 -0
  277. package/skills/engineering/resolve-release/scripts/version-postmortem.mjs +485 -0
  278. package/skills/engineering/resolve-release/scripts/version.mjs +1199 -0
  279. package/skills/engineering/resolve-release/scripts/watch-candidate-delivery.mjs +449 -0
  280. package/skills/engineering/resolve-release/vendor/ACORN-LICENSE +21 -0
  281. package/skills/engineering/resolve-release/vendor/README.md +60 -0
  282. package/skills/engineering/resolve-release/vendor/acorn.mjs +6233 -0
  283. package/skills/engineering/resolve-release/vendor/quickjs/core/LICENSE +21 -0
  284. package/skills/engineering/resolve-release/vendor/quickjs/core/README.md +341 -0
  285. package/skills/engineering/resolve-release/vendor/quickjs/core/README.template.md +70 -0
  286. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs +2 -0
  287. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs.map +1 -0
  288. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs +7 -0
  289. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs.map +1 -0
  290. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.mts +2033 -0
  291. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.ts +2033 -0
  292. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js +7 -0
  293. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js.map +1 -0
  294. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs +2 -0
  295. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs.map +1 -0
  296. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs +2 -0
  297. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs.map +1 -0
  298. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs +2 -0
  299. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs.map +1 -0
  300. package/skills/engineering/resolve-release/vendor/quickjs/core/package.json +49 -0
  301. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/LICENSE +21 -0
  302. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/README.md +5 -0
  303. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.mts +549 -0
  304. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.ts +549 -0
  305. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js +2 -0
  306. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js.map +1 -0
  307. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs +2 -0
  308. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs.map +1 -0
  309. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/package.json +36 -0
  310. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/LICENSE +47 -0
  311. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/README.md +82 -0
  312. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.d.ts +11 -0
  313. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.mjs +22 -0
  314. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cjs +21 -0
  315. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.cjs +21 -0
  316. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.d.ts +11 -0
  317. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.d.ts +11 -0
  318. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.mjs +25 -0
  319. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.wasm +0 -0
  320. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.mts +85 -0
  321. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.ts +85 -0
  322. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js +2 -0
  323. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js.map +1 -0
  324. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs +2 -0
  325. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs.map +1 -0
  326. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.mts +20 -0
  327. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.ts +20 -0
  328. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js +2 -0
  329. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js.map +1 -0
  330. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs +2 -0
  331. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs.map +1 -0
  332. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/package.json +61 -0
  333. package/skills/engineering/review-pr/LICENSE +3 -0
  334. package/skills/engineering/review-pr/SKILL.md +123 -0
  335. package/skills/engineering/review-pr/references/adversarial-reviewer-prompt.md +42 -0
  336. package/skills/engineering/review-pr/references/code-correctness.md +5 -0
  337. package/skills/engineering/review-pr/references/contract-freshness.md +9 -0
  338. package/skills/engineering/review-pr/references/coordination.md +18 -0
  339. package/skills/engineering/review-pr/references/domain-hazards.md +123 -0
  340. package/skills/engineering/review-pr/references/finding-themes.md +7 -0
  341. package/skills/engineering/review-pr/references/github-posting.md +98 -0
  342. package/skills/engineering/review-pr/references/golden-path-smoke.md +5 -0
  343. package/skills/engineering/review-pr/references/incremental-output.md +16 -0
  344. package/skills/engineering/review-pr/references/inputs-and-discovery.md +31 -0
  345. package/skills/engineering/review-pr/references/output-format.md +99 -0
  346. package/skills/engineering/review-pr/references/over-mock-screen.md +7 -0
  347. package/skills/engineering/review-pr/references/promotion-prs.md +16 -0
  348. package/skills/engineering/review-pr/references/re-review.md +18 -0
  349. package/skills/engineering/review-pr/references/review-method.md +199 -0
  350. package/skills/engineering/review-pr/references/review-mode.md +30 -0
  351. package/skills/engineering/review-pr/references/review-posture.md +53 -0
  352. package/skills/engineering/review-pr/references/round1-depth.md +62 -0
  353. package/skills/engineering/review-pr/references/scripts.md +17 -0
  354. package/skills/engineering/review-pr/references/workflow.md +16 -0
  355. package/skills/engineering/review-pr/schemas/findings.schema.json +282 -0
  356. package/skills/engineering/review-pr/scripts/finding-contract.mjs +285 -0
  357. package/skills/engineering/review-pr/scripts/post-review.mjs +405 -0
  358. package/skills/engineering/review-pr/scripts/pr-context.mjs +207 -0
  359. package/skills/engineering/review-pr/scripts/scan-diff.mjs +365 -0
  360. package/skills/engineering/review-pr/scripts/theme-contract.mjs +57 -0
  361. package/skills/engineering/smoke/LICENSE +3 -0
  362. package/skills/engineering/smoke/SKILL.md +131 -0
  363. package/skills/engineering/smoke/assets/smoke.manifest.example.json +53 -0
  364. package/skills/engineering/smoke/references/manifest.md +192 -0
  365. package/skills/engineering/smoke/scripts/smoke.mjs +713 -0
  366. package/skills/fullstack/better-auth/LICENSE +3 -0
  367. package/skills/fullstack/better-auth/SKILL.md +601 -0
  368. package/skills/fullstack/better-auth/references/feishu-api.md +270 -0
  369. package/skills/fullstack/monorepo/LICENSE +3 -0
  370. package/skills/fullstack/monorepo/SKILL.md +465 -0
  371. package/skills/fullstack/nextjs-fullstack/LICENSE +3 -0
  372. package/skills/fullstack/nextjs-fullstack/SKILL.md +210 -0
  373. package/skills/fullstack/nextjs-fullstack/conventions.md +318 -0
  374. package/skills/fullstack/nextjs-fullstack/frontend-conventions.md +61 -0
  375. package/skills/fullstack/nextjs-fullstack/nextjs16.md +287 -0
  376. package/skills/fullstack/nextjs-fullstack/server-actions.md +409 -0
  377. package/skills/fullstack/prisma-setup/LICENSE +3 -0
  378. package/skills/fullstack/prisma-setup/SKILL.md +180 -0
  379. package/skills/fullstack/prisma-setup/nextjs.md +258 -0
  380. package/skills/fullstack/prisma-setup/turborepo.md +301 -0
  381. package/skills/fullstack/shadcn/LICENSE +3 -0
  382. package/skills/fullstack/shadcn/SKILL.md +119 -0
  383. package/skills/fullstack/shadcn/assets/shadcn-small.png +0 -0
  384. package/skills/fullstack/shadcn/assets/shadcn.png +0 -0
  385. package/skills/fullstack/shadcn/cli.md +411 -0
  386. package/skills/fullstack/shadcn/customization.md +224 -0
  387. package/skills/fullstack/shadcn/evals/evals.json +90 -0
  388. package/skills/fullstack/shadcn/mcp.md +101 -0
  389. package/skills/fullstack/shadcn/rules/base-vs-radix.md +323 -0
  390. package/skills/fullstack/shadcn/rules/component-selection.md +67 -0
  391. package/skills/fullstack/shadcn/rules/composition.md +195 -0
  392. package/skills/fullstack/shadcn/rules/data-table.md +201 -0
  393. package/skills/fullstack/shadcn/rules/forms.md +255 -0
  394. package/skills/fullstack/shadcn/rules/icons.md +103 -0
  395. package/skills/fullstack/shadcn/rules/styling.md +167 -0
  396. package/skills/fullstack/zod-v4/LICENSE +3 -0
  397. package/skills/fullstack/zod-v4/SKILL.md +287 -0
@@ -0,0 +1,389 @@
1
+ #!/usr/bin/env node
2
+
3
+ import crypto from 'node:crypto'
4
+ import fs from 'node:fs'
5
+ import { TextDecoder } from 'node:util'
6
+ import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
7
+
8
+ export const COMPLETION_SCHEMA = 'resolve-release/isolated-adapter-completion@2'
9
+ export const COMPLETION_ARTIFACT_MAX_BYTES = 1024 * 1024
10
+ export const COMPLETION_COUNT_MAX = 1_000_000
11
+ export const COMPLETION_MATRICES = Object.freeze({
12
+ ambient: 81,
13
+ processAdjacent: 18,
14
+ generated: 81,
15
+ })
16
+ export const COMPLETION_POLICY = Object.freeze({
17
+ id: 'resolve-release/isolated-adapter-completion-policy@1',
18
+ suites: Object.freeze({
19
+ focused: Object.freeze({
20
+ id: 'resolve-release/isolated-adapter-focused@1',
21
+ minimumPassed: 77,
22
+ }),
23
+ full: Object.freeze({
24
+ id: 'resolve-release/full-suite@1',
25
+ minimumPassed: 900,
26
+ }),
27
+ }),
28
+ })
29
+
30
+ const SHA_PATTERN = /^[a-f0-9]{40}$/
31
+ const HASH_PATTERN = /^[a-f0-9]{64}$/
32
+ const ROOT_FIELDS = Object.freeze([
33
+ 'schema', 'status', 'issue', 'parent', 'epic', 'componentHead',
34
+ 'callerVerifiedHead', 'publicLoaderExecuted', 'matrices', 'policy', 'tests', 'integrity',
35
+ ])
36
+ const TEST_FIELDS = Object.freeze(['suite', 'passed', 'failed', 'floor'])
37
+ const INTEGRITY_FIELDS = Object.freeze(['algorithm', 'sha256'])
38
+ const UTF8_DECODER = new TextDecoder('utf-8', { fatal: true })
39
+
40
+ function fail(code) {
41
+ const error = new Error(code)
42
+ error.code = code
43
+ throw error
44
+ }
45
+
46
+ function isObject(value) {
47
+ return value != null && typeof value === 'object' && !Array.isArray(value)
48
+ }
49
+
50
+ function exactFields(value, expected, code) {
51
+ if (!isObject(value) || Object.keys(value).sort().join('\0') !== [...expected].sort().join('\0')) fail(code)
52
+ }
53
+
54
+ function positiveInteger(value, code) {
55
+ if (!Number.isSafeInteger(value) || value <= 0 || value > COMPLETION_COUNT_MAX) fail(code)
56
+ return value
57
+ }
58
+
59
+ function boundedInteger(value, code) {
60
+ if (!Number.isSafeInteger(value) || value < 0 || value > COMPLETION_COUNT_MAX) fail(code)
61
+ return value
62
+ }
63
+
64
+ function canonicalize(value) {
65
+ if (Array.isArray(value)) return `[${value.map(canonicalize).join(',')}]`
66
+ if (isObject(value)) {
67
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalize(value[key])}`).join(',')}}`
68
+ }
69
+ const encoded = JSON.stringify(value)
70
+ if (encoded === undefined) fail('e:completion-not-serializable')
71
+ return encoded
72
+ }
73
+
74
+ function digestBody(body) {
75
+ return crypto.createHash('sha256').update(canonicalize(body)).digest('hex')
76
+ }
77
+
78
+ function completionBody({
79
+ componentHead,
80
+ callerVerifiedHead,
81
+ focusedPassed,
82
+ focusedFailed = 0,
83
+ focusedFloor,
84
+ fullPassed,
85
+ fullFailed = 0,
86
+ fullFloor,
87
+ }) {
88
+ if (!SHA_PATTERN.test(componentHead ?? '') || !SHA_PATTERN.test(callerVerifiedHead ?? '')) {
89
+ fail('e:completion-head-invalid')
90
+ }
91
+ if (componentHead !== callerVerifiedHead) fail('e:completion-caller-head-mismatch')
92
+ const focused = {
93
+ suite: COMPLETION_POLICY.suites.focused.id,
94
+ passed: positiveInteger(focusedPassed, 'e:completion-focused-count-invalid'),
95
+ failed: boundedInteger(focusedFailed, 'e:completion-focused-count-invalid'),
96
+ floor: positiveInteger(focusedFloor, 'e:completion-focused-floor-invalid'),
97
+ }
98
+ const full = {
99
+ suite: COMPLETION_POLICY.suites.full.id,
100
+ passed: positiveInteger(fullPassed, 'e:completion-full-count-invalid'),
101
+ failed: boundedInteger(fullFailed, 'e:completion-full-count-invalid'),
102
+ floor: positiveInteger(fullFloor, 'e:completion-full-floor-invalid'),
103
+ }
104
+ if (focused.floor !== COMPLETION_POLICY.suites.focused.minimumPassed) {
105
+ fail('e:completion-focused-policy-floor-mismatch')
106
+ }
107
+ if (full.floor !== COMPLETION_POLICY.suites.full.minimumPassed) {
108
+ fail('e:completion-full-policy-floor-mismatch')
109
+ }
110
+ if (focused.failed !== 0 || focused.passed < focused.floor) fail('e:completion-focused-floor-unmet')
111
+ if (full.failed !== 0 || full.passed < full.floor) fail('e:completion-full-floor-unmet')
112
+ return {
113
+ schema: COMPLETION_SCHEMA,
114
+ status: 'complete',
115
+ issue: 980,
116
+ parent: 939,
117
+ epic: 904,
118
+ componentHead,
119
+ callerVerifiedHead,
120
+ publicLoaderExecuted: true,
121
+ matrices: { ...COMPLETION_MATRICES },
122
+ policy: COMPLETION_POLICY.id,
123
+ tests: { focused, full },
124
+ }
125
+ }
126
+
127
+ export function createCompletionArtifact(input) {
128
+ const body = completionBody(input)
129
+ return Object.freeze({
130
+ ...body,
131
+ matrices: Object.freeze(body.matrices),
132
+ tests: Object.freeze({
133
+ focused: Object.freeze(body.tests.focused),
134
+ full: Object.freeze(body.tests.full),
135
+ }),
136
+ integrity: Object.freeze({ algorithm: 'sha256', sha256: digestBody(body) }),
137
+ })
138
+ }
139
+
140
+ function artifactStat(file, code) {
141
+ try {
142
+ return fs.lstatSync(file, { bigint: true })
143
+ } catch {
144
+ fail(code)
145
+ }
146
+ }
147
+
148
+ function sameArtifactIdentity(left, right) {
149
+ return left.dev === right.dev
150
+ && left.ino === right.ino
151
+ && left.mode === right.mode
152
+ && left.size === right.size
153
+ && left.mtimeNs === right.mtimeNs
154
+ && left.ctimeNs === right.ctimeNs
155
+ }
156
+
157
+ function validateArtifactStat(stat) {
158
+ if (stat.isSymbolicLink()) fail('e:completion-artifact-symlink')
159
+ if (!stat.isFile()) fail('e:completion-artifact-not-regular-file')
160
+ if ((stat.mode & 0o222n) !== 0n) fail('e:completion-artifact-writable')
161
+ if (stat.size > BigInt(COMPLETION_ARTIFACT_MAX_BYTES)) fail('e:completion-artifact-too-large')
162
+ }
163
+
164
+ function openArtifact(file) {
165
+ if (!Number.isInteger(fs.constants.O_NOFOLLOW)) fail('e:completion-artifact-nofollow-unsupported')
166
+ if (!Number.isInteger(fs.constants.O_NONBLOCK)) fail('e:completion-artifact-nonblock-unsupported')
167
+ try {
168
+ return fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK)
169
+ } catch {
170
+ fail('e:completion-artifact-unreadable')
171
+ }
172
+ }
173
+
174
+ function readArtifactBytes(fd, expectedSize) {
175
+ const size = Number(expectedSize)
176
+ const bytes = Buffer.alloc(size)
177
+ let offset = 0
178
+ while (offset < size) {
179
+ const count = fs.readSync(fd, bytes, offset, size - offset, offset)
180
+ if (count === 0) fail('e:completion-artifact-changed-during-acquisition')
181
+ offset += count
182
+ }
183
+ const extra = Buffer.alloc(1)
184
+ if (fs.readSync(fd, extra, 0, 1, offset) !== 0) {
185
+ fail('e:completion-artifact-changed-during-acquisition')
186
+ }
187
+ return bytes
188
+ }
189
+
190
+ function readCheckedCompletionArtifact(file) {
191
+ if (typeof file !== 'string' || file.length === 0) fail('e:completion-artifact-unreadable')
192
+ const approved = artifactStat(file, 'e:completion-artifact-unreadable')
193
+ validateArtifactStat(approved)
194
+
195
+ const fd = openArtifact(file)
196
+ let bytes
197
+ let opened
198
+ let acquisitionError
199
+ try {
200
+ opened = fs.fstatSync(fd, { bigint: true })
201
+ validateArtifactStat(opened)
202
+ if (!sameArtifactIdentity(approved, opened)) fail('e:completion-artifact-replaced-before-open')
203
+
204
+ const afterOpenPath = artifactStat(file, 'e:completion-artifact-replaced-after-open')
205
+ if (!sameArtifactIdentity(opened, afterOpenPath)) {
206
+ fail('e:completion-artifact-replaced-after-open')
207
+ }
208
+
209
+ bytes = readArtifactBytes(fd, opened.size)
210
+ const afterRead = fs.fstatSync(fd, { bigint: true })
211
+ if (!sameArtifactIdentity(opened, afterRead)) {
212
+ fail('e:completion-artifact-changed-during-acquisition')
213
+ }
214
+ const afterReadPath = artifactStat(file, 'e:completion-artifact-replaced-after-open')
215
+ if (!sameArtifactIdentity(opened, afterReadPath)) {
216
+ fail('e:completion-artifact-replaced-after-open')
217
+ }
218
+ } catch (error) {
219
+ acquisitionError = error?.code?.startsWith?.('e:completion-')
220
+ ? error
221
+ : Object.assign(new Error('e:completion-artifact-unreadable'), {
222
+ code: 'e:completion-artifact-unreadable',
223
+ })
224
+ } finally {
225
+ try {
226
+ fs.closeSync(fd)
227
+ } catch {
228
+ if (acquisitionError == null) {
229
+ acquisitionError = Object.assign(new Error('e:completion-artifact-close-failed'), {
230
+ code: 'e:completion-artifact-close-failed',
231
+ })
232
+ }
233
+ }
234
+ }
235
+ if (acquisitionError != null) throw acquisitionError
236
+
237
+ try {
238
+ return UTF8_DECODER.decode(bytes)
239
+ } catch {
240
+ fail('e:completion-artifact-invalid-utf8')
241
+ }
242
+ }
243
+
244
+ function parseCheckedCompletionArtifact(file) {
245
+ const text = readCheckedCompletionArtifact(file)
246
+ try {
247
+ return JSON.parse(text)
248
+ } catch {
249
+ fail('e:completion-artifact-json-invalid')
250
+ }
251
+ }
252
+
253
+ function validateTestResult(value, name) {
254
+ exactFields(value, TEST_FIELDS, `e:completion-${name}-shape-invalid`)
255
+ const trusted = COMPLETION_POLICY.suites[name]
256
+ if (value.suite !== trusted.id) fail(`e:completion-${name}-suite-unsupported`)
257
+ const passed = positiveInteger(value.passed, `e:completion-${name}-count-invalid`)
258
+ const failed = boundedInteger(value.failed, `e:completion-${name}-count-invalid`)
259
+ const floor = positiveInteger(value.floor, `e:completion-${name}-floor-invalid`)
260
+ if (floor !== trusted.minimumPassed) fail(`e:completion-${name}-policy-floor-mismatch`)
261
+ if (failed !== 0 || passed < floor) fail(`e:completion-${name}-floor-unmet`)
262
+ }
263
+
264
+ function verifyCompletionValue(artifact, { expectedComponentHead, expectedSha256 }) {
265
+ exactFields(artifact, ROOT_FIELDS, 'e:completion-shape-invalid')
266
+ if (artifact.schema !== COMPLETION_SCHEMA || artifact.status !== 'complete'
267
+ || artifact.issue !== 980 || artifact.parent !== 939 || artifact.epic !== 904
268
+ || artifact.publicLoaderExecuted !== true || artifact.policy !== COMPLETION_POLICY.id) {
269
+ fail('e:completion-contract-invalid')
270
+ }
271
+ if (!SHA_PATTERN.test(expectedComponentHead ?? '') || artifact.componentHead !== expectedComponentHead
272
+ || artifact.callerVerifiedHead !== expectedComponentHead) {
273
+ fail('e:completion-finalizer-head-mismatch')
274
+ }
275
+ exactFields(artifact.matrices, Object.keys(COMPLETION_MATRICES), 'e:completion-matrices-invalid')
276
+ if (Object.entries(COMPLETION_MATRICES).some(([name, count]) => artifact.matrices[name] !== count)) {
277
+ fail('e:completion-matrices-invalid')
278
+ }
279
+ exactFields(artifact.tests, ['focused', 'full'], 'e:completion-tests-shape-invalid')
280
+ validateTestResult(artifact.tests.focused, 'focused')
281
+ validateTestResult(artifact.tests.full, 'full')
282
+ exactFields(artifact.integrity, INTEGRITY_FIELDS, 'e:completion-integrity-invalid')
283
+ if (artifact.integrity.algorithm !== 'sha256' || !HASH_PATTERN.test(artifact.integrity.sha256 ?? '')
284
+ || !HASH_PATTERN.test(expectedSha256 ?? '')) {
285
+ fail('e:completion-integrity-invalid')
286
+ }
287
+ const { integrity, ...body } = artifact
288
+ const actual = digestBody(body)
289
+ if (integrity.sha256 !== actual || expectedSha256 !== actual) fail('e:completion-sha256-mismatch')
290
+ return Object.freeze({
291
+ status: 'verified',
292
+ policy: COMPLETION_POLICY.id,
293
+ componentHead: artifact.componentHead,
294
+ callerVerifiedHead: artifact.callerVerifiedHead,
295
+ sha256: actual,
296
+ tests: Object.freeze({
297
+ focused: Object.freeze({
298
+ suite: artifact.tests.focused.suite,
299
+ passed: artifact.tests.focused.passed,
300
+ minimumPassed: COMPLETION_POLICY.suites.focused.minimumPassed,
301
+ }),
302
+ full: Object.freeze({
303
+ suite: artifact.tests.full.suite,
304
+ passed: artifact.tests.full.passed,
305
+ minimumPassed: COMPLETION_POLICY.suites.full.minimumPassed,
306
+ }),
307
+ }),
308
+ })
309
+ }
310
+
311
+ export function verifyCompletionArtifact(file, expected) {
312
+ const artifact = parseCheckedCompletionArtifact(file)
313
+ return verifyCompletionValue(artifact, expected)
314
+ }
315
+
316
+ function parseArgs(argv) {
317
+ const positional = []
318
+ const options = {}
319
+ const known = new Set([
320
+ '--component-head', '--caller-verified-head', '--focused-passed', '--focused-failed',
321
+ '--focused-floor', '--full-passed', '--full-failed', '--full-floor', '--artifact',
322
+ '--sha256', '--output',
323
+ ])
324
+ for (let index = 0; index < argv.length; index += 1) {
325
+ const value = argv[index]
326
+ if (!value.startsWith('--')) positional.push(value)
327
+ else {
328
+ if (!known.has(value) || options[value] !== undefined) fail('e:completion-option-invalid')
329
+ const next = argv[++index]
330
+ if (next == null || next.startsWith('--')) fail('e:completion-option-invalid')
331
+ options[value] = next
332
+ }
333
+ }
334
+ return { positional, options }
335
+ }
336
+
337
+ function numberOption(options, name, defaultValue) {
338
+ if (options[name] == null) return defaultValue
339
+ if (!/^\d+$/.test(options[name])) fail('e:completion-option-invalid')
340
+ return Number(options[name])
341
+ }
342
+
343
+ function writeOutput(value, output) {
344
+ const text = `${JSON.stringify(value)}\n`
345
+ if (output == null) process.stdout.write(text)
346
+ else fs.writeFileSync(output, text, { encoding: 'utf8', flag: 'wx', mode: 0o444 })
347
+ }
348
+
349
+ export function main(argv) {
350
+ const { positional, options } = parseArgs(argv)
351
+ const command = positional[0]
352
+ if (positional.length !== 1 || !['emit', 'verify'].includes(command)) fail('e:completion-command-invalid')
353
+ const commandOptions = command === 'emit'
354
+ ? new Set(['--component-head', '--caller-verified-head', '--focused-passed',
355
+ '--focused-failed', '--focused-floor', '--full-passed', '--full-failed',
356
+ '--full-floor', '--output'])
357
+ : new Set(['--artifact', '--component-head', '--sha256', '--output'])
358
+ if (Object.keys(options).some((name) => !commandOptions.has(name))) fail('e:completion-option-invalid')
359
+ if (command === 'emit') {
360
+ const artifact = createCompletionArtifact({
361
+ componentHead: options['--component-head'],
362
+ callerVerifiedHead: options['--caller-verified-head'],
363
+ focusedPassed: numberOption(options, '--focused-passed'),
364
+ focusedFailed: numberOption(options, '--focused-failed', 0),
365
+ focusedFloor: numberOption(options, '--focused-floor'),
366
+ fullPassed: numberOption(options, '--full-passed'),
367
+ fullFailed: numberOption(options, '--full-failed', 0),
368
+ fullFloor: numberOption(options, '--full-floor'),
369
+ })
370
+ writeOutput(artifact, options['--output'])
371
+ return 0
372
+ }
373
+ if (options['--artifact'] == null) fail('e:completion-option-invalid')
374
+ const verified = verifyCompletionArtifact(options['--artifact'], {
375
+ expectedComponentHead: options['--component-head'],
376
+ expectedSha256: options['--sha256'],
377
+ })
378
+ writeOutput(verified, options['--output'])
379
+ return 0
380
+ }
381
+
382
+ if (isMainModule(import.meta.url)) {
383
+ try {
384
+ process.exitCode = main(process.argv.slice(2))
385
+ } catch (error) {
386
+ process.stderr.write(`${error?.code ?? 'e:completion-failed'}\n`)
387
+ process.exitCode = 1
388
+ }
389
+ }
@@ -0,0 +1,209 @@
1
+ // build-changes — assemble the `--changes` JSON that `version.mjs plan|changelog` consumes,
2
+ // from the constituent PRs, WITHOUT the two silent failures the hand-run gh→jq recipe carries.
3
+ //
4
+ // `version.mjs plan --changes <json>` reads an array of `{ pr, title, labels?, body?, issues? }`
5
+ // (see version.mjs `readChanges` / `classifyChange`). `gh pr view --json` does NOT emit that
6
+ // shape, and copying its output straight through fails SILENTLY in two ways this script closes:
7
+ //
8
+ // #407 — number → pr, and the vanishing close-links. gh emits `number`, not `pr`, and emits
9
+ // no `issues` field at all. `classifyChange` still computes the bump off `title`/`labels`,
10
+ // so `plan` LOOKS correct — while every `closes #n` link silently vanishes from the cut
11
+ // CHANGELOG, discovered only when a human reads the published notes. This script renames
12
+ // `number` → `pr` and derives `issues` (from gh's `closingIssuesReferences` PLUS a parse of
13
+ // `Closes/Fixes/Resolves #N` in the body), so the links survive.
14
+ //
15
+ // #408 — a BREAKING CHANGE in the body escaping the bump. `classifyChange` (version.mjs:~112)
16
+ // reads `BREAKING[ -]CHANGE:` out of `change.body`, but the hand recipe never fetched
17
+ // `body`, so a breaking footer living only in a PR body was invisible → a `minor` bump where
18
+ // a `major` was owed, a silently under-versioned release. This script fetches `body` and
19
+ // carries it through, so `classifyChange` sees the footer and bumps major.
20
+ //
21
+ // The `gh pr view --json` query below therefore MUST include `body` (for #408) and
22
+ // `closingIssuesReferences` (for #407) alongside `number`/`title`/`labels`. Dropping either from
23
+ // the field list re-opens the corresponding silent failure — the CLI test asserts the query
24
+ // carries both.
25
+
26
+ import fs from 'node:fs'
27
+ import { spawnSync } from 'node:child_process'
28
+ import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
29
+
30
+ // The gh `--json` field list the query MUST request. `body` is load-bearing for #408 and
31
+ // `closingIssuesReferences` for #407 — see the header. Exported so the test can assert the
32
+ // query the CLI builds still carries both rather than silently regressing.
33
+ export const GH_JSON_FIELDS = ['number', 'title', 'labels', 'body', 'closingIssuesReferences']
34
+
35
+ // GitHub's closing keywords (https://docs.github.com/issues/tracking-your-work-with-issues/
36
+ // linking-a-pull-request-to-an-issue): close/closes/closed, fix/fixes/fixed, resolve/resolves/
37
+ // resolved, case-insensitive, followed by `#N`. This is the same set gh resolves into
38
+ // `closingIssuesReferences`; we parse it out of the body too because a body may name a link gh
39
+ // did not resolve (a cross-repo `owner/repo#N`, a PR opened before the issue existed), and
40
+ // because a caller feeding a captured body without that gh field still gets its links.
41
+ const CLOSING_RE = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\b[:\s]+#(\d+)/gi
42
+
43
+ // Parse `Closes #N` / `Fixes #N` / `Resolves #N` (and their case/tense variants) out of a PR
44
+ // body, returning `#N` strings in first-seen order. Never throws on a null/empty body.
45
+ export function parseClosingIssues(body) {
46
+ const out = []
47
+ const seen = new Set()
48
+ for (const m of String(body || '').matchAll(CLOSING_RE)) {
49
+ const ref = `#${m[1]}`
50
+ if (!seen.has(ref)) {
51
+ seen.add(ref)
52
+ out.push(ref)
53
+ }
54
+ }
55
+ return out
56
+ }
57
+
58
+ // Normalize gh's `labels` (array of `{name}` objects) OR an already-flattened array of strings
59
+ // into a `string[]`. `classifyChange` lowercases labels itself, so we keep the raw name.
60
+ function normalizeLabels(labels) {
61
+ if (!Array.isArray(labels)) return []
62
+ return labels.map((l) => (typeof l === 'string' ? l : l && l.name ? String(l.name) : null)).filter(Boolean)
63
+ }
64
+
65
+ // The `issues` a change closes: gh's resolved `closingIssuesReferences` FIRST (the authoritative
66
+ // linked-issue field), then any body-parsed `Closes #N` the field did not already carry. Deduped,
67
+ // order-preserving, each as `#N`.
68
+ function deriveIssues(raw) {
69
+ const out = []
70
+ const seen = new Set()
71
+ const push = (ref) => {
72
+ const norm = `#${String(ref).replace(/^#/, '')}`
73
+ if (!seen.has(norm)) {
74
+ seen.add(norm)
75
+ out.push(norm)
76
+ }
77
+ }
78
+ if (Array.isArray(raw.closingIssuesReferences)) {
79
+ for (const ref of raw.closingIssuesReferences) {
80
+ if (ref && ref.number != null) push(ref.number)
81
+ }
82
+ }
83
+ for (const ref of parseClosingIssues(raw.body)) push(ref)
84
+ return out
85
+ }
86
+
87
+ // The pure transform: one raw gh PR object → one `{ pr, title, labels, body, issues }` change.
88
+ // This is where #407's `number` → `pr` rename and `issues` derivation, and #408's `body`
89
+ // pass-through, actually happen.
90
+ export function buildChange(raw) {
91
+ if (!raw || typeof raw !== 'object') {
92
+ throw new TypeError('build-changes: each gh PR record must be an object')
93
+ }
94
+ if (raw.number == null) {
95
+ throw new Error('build-changes: gh PR record has no `number` — was the query missing `number`?')
96
+ }
97
+ return {
98
+ pr: `#${String(raw.number).replace(/^#/, '')}`,
99
+ title: String(raw.title || ''),
100
+ labels: normalizeLabels(raw.labels),
101
+ body: raw.body == null ? '' : String(raw.body),
102
+ issues: deriveIssues(raw),
103
+ }
104
+ }
105
+
106
+ // The pure transform over a whole gh result: accepts either the array `gh pr list --json` emits
107
+ // or a single object from `gh pr view --json`, and returns the `--changes` array `version.mjs
108
+ // plan` accepts. No gh, no network — this is the unit under test.
109
+ export function buildChanges(rawGhJson) {
110
+ const records = Array.isArray(rawGhJson) ? rawGhJson : [rawGhJson]
111
+ return records.map(buildChange)
112
+ }
113
+
114
+ // ---- gh (CLI only) ----
115
+
116
+ // Fetch one PR's raw gh JSON. The `--json` list MUST carry GH_JSON_FIELDS (body +
117
+ // closingIssuesReferences included) or the silent failures re-open. `run` is injectable so the
118
+ // CLI path is testable without a live gh (the test puts a captured-gh shim on PATH, which is the
119
+ // default `gh` here).
120
+ function fetchPr(pr, { repo, run = defaultGh } = {}) {
121
+ const args = ['pr', 'view', String(pr), '--json', GH_JSON_FIELDS.join(',')]
122
+ if (repo) args.push('--repo', repo)
123
+ const r = run(args)
124
+ if (r.status !== 0) {
125
+ throw new Error(`build-changes: \`gh ${args.join(' ')}\` failed (exit ${r.status}): ${(r.stderr || '').trim()}`)
126
+ }
127
+ return JSON.parse(r.stdout)
128
+ }
129
+
130
+ function defaultGh(args) {
131
+ const r = spawnSync('gh', args, { encoding: 'utf8' })
132
+ return { status: r.status ?? 1, stdout: r.stdout || '', stderr: r.stderr || '' }
133
+ }
134
+
135
+ const USAGE = `build-changes — assemble the \`--changes\` JSON for \`version.mjs plan|changelog\`.
136
+
137
+ Runs \`gh pr view --json\` for each constituent PR (including \`body\` and
138
+ \`closingIssuesReferences\`), renames gh's \`number\` → the \`pr\` field \`version.mjs\` expects,
139
+ derives \`issues\` (from \`closingIssuesReferences\` + \`Closes/Fixes/Resolves #N\` in the body),
140
+ and carries \`body\` through so a \`BREAKING CHANGE:\` living only in a PR body still bumps major.
141
+
142
+ Usage:
143
+ build-changes <pr>... [--repo owner/name] query gh for each PR, emit the --changes array
144
+ build-changes --raw <file>|- transform captured gh JSON (array or object); no gh call
145
+ build-changes --help | -h print this usage and exit 0
146
+
147
+ Output: a JSON array of { pr, title, labels, body, issues } on stdout — feed it to
148
+ \`version.mjs plan --changes -\` (pipe) or \`--changes <file>\`.
149
+
150
+ Why a script and not the raw gh→jq recipe (both fail SILENTLY):
151
+ #407 gh emits \`number\`, not \`pr\`, and no \`issues\` — copied straight through, the bump still
152
+ computes off titles/labels so \`plan\` looks correct while every \`closes #n\` link vanishes
153
+ from the published notes. This renames number→pr and derives issues.
154
+ #408 the hand recipe never fetched \`body\`, so a \`BREAKING CHANGE:\` in a PR body escaped
155
+ classification → a minor bump where major was owed. This fetches and carries body.
156
+
157
+ Doctrine: references/versioning.md (§6, the bump). Bump/flag reference: version.mjs --help.`
158
+
159
+ export function main(argv, { run = defaultGh, readStdin = () => fs.readFileSync(0, 'utf8') } = {}) {
160
+ const args = [...argv]
161
+ const prs = []
162
+ let repo = null
163
+ let rawSource = null
164
+
165
+ for (let i = 0; i < args.length; i++) {
166
+ const a = args[i]
167
+ if (a === '--help' || a === '-h' || a === 'help') {
168
+ console.log(USAGE)
169
+ return 0
170
+ }
171
+ if (a === '--repo') {
172
+ repo = args[++i]
173
+ continue
174
+ }
175
+ if (a === '--raw') {
176
+ rawSource = args[++i] ?? '-'
177
+ continue
178
+ }
179
+ if (a.startsWith('-') && a !== '-') {
180
+ console.error(`build-changes: unknown flag "${a}" (see --help).`)
181
+ return 2
182
+ }
183
+ prs.push(a)
184
+ }
185
+
186
+ try {
187
+ let changes
188
+ if (rawSource != null) {
189
+ const text = rawSource === '-' ? readStdin() : fs.readFileSync(rawSource, 'utf8')
190
+ changes = buildChanges(JSON.parse(text))
191
+ } else {
192
+ if (prs.length === 0) {
193
+ console.error('build-changes: give one or more PR numbers, or --raw <file>|- (see --help).')
194
+ return 2
195
+ }
196
+ changes = buildChanges(prs.map((pr) => fetchPr(pr, { repo, run })))
197
+ }
198
+ console.log(JSON.stringify(changes, null, 2))
199
+ return 0
200
+ } catch (err) {
201
+ console.error(`build-changes: ${err.message}`)
202
+ return 1
203
+ }
204
+ }
205
+
206
+ // Only run the CLI when invoked directly (so tests import the pure transforms).
207
+ if (isMainModule(import.meta.url)) {
208
+ process.exit(main(process.argv.slice(2)))
209
+ }