@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,767 @@
1
+ const HARNESSES = new Set(['pi', 'codex', 'claude-code']);
2
+ const COMPLETENESS = new Set(['partial', 'full']);
3
+ const RUNTIME_MODEL_SOURCES = new Set(['current-turn', 'runtime-enumeration']);
4
+
5
+ export const HARNESS_RUNTIME_ERROR_CODES = Object.freeze({
6
+ INVALID_CAPABILITIES: 'invalid-capabilities',
7
+ INVALID_QUESTION: 'invalid-question',
8
+ INVALID_ANSWERS: 'invalid-answers',
9
+ INVALID_MODEL_AVAILABILITY: 'invalid-model-availability',
10
+ CAPABILITY_UNAVAILABLE: 'capability-unavailable',
11
+ UNSUPPORTED_QUESTION: 'unsupported-question',
12
+ FALLBACK_FORBIDDEN: 'fallback-forbidden',
13
+ });
14
+
15
+ function deepFreeze(value) {
16
+ if (value && typeof value === 'object' && !Object.isFrozen(value)) {
17
+ for (const child of Object.values(value)) deepFreeze(child);
18
+ Object.freeze(value);
19
+ }
20
+ return value;
21
+ }
22
+
23
+ function clone(value) {
24
+ return structuredClone(value);
25
+ }
26
+
27
+ export class HarnessRuntimeError extends Error {
28
+ constructor(code, message, details = {}) {
29
+ super(message);
30
+ this.name = 'HarnessRuntimeError';
31
+ this.code = code;
32
+ this.details = deepFreeze(clone(details));
33
+ }
34
+ }
35
+
36
+ export class CapabilityUnavailableError extends HarnessRuntimeError {
37
+ constructor(capability, details = {}) {
38
+ super(
39
+ HARNESS_RUNTIME_ERROR_CODES.CAPABILITY_UNAVAILABLE,
40
+ `Required harness capability is unavailable: ${capability}`,
41
+ { ...details, capability },
42
+ );
43
+ this.name = 'CapabilityUnavailableError';
44
+ this.capability = capability;
45
+ }
46
+ }
47
+
48
+ export class UnsupportedQuestionError extends HarnessRuntimeError {
49
+ constructor(reason, details = {}) {
50
+ super(
51
+ HARNESS_RUNTIME_ERROR_CODES.UNSUPPORTED_QUESTION,
52
+ `Question cannot be represented by the selected native adapter: ${reason}`,
53
+ { ...details, reason },
54
+ );
55
+ this.name = 'UnsupportedQuestionError';
56
+ this.reason = reason;
57
+ }
58
+ }
59
+
60
+ export const QUESTION_ADAPTER_PRIORITY = Object.freeze([
61
+ 'ask_user_question',
62
+ 'request_user_input',
63
+ 'AskUserQuestion',
64
+ ]);
65
+
66
+ export const QUESTION_FALLBACK_POLICY = deepFreeze({
67
+ noNativeQuestionTool: {
68
+ freeText: 'concise-free-text-only',
69
+ multipleChoice: 'forbidden',
70
+ },
71
+ unsupportedMultiSelect: 'error',
72
+ secretInput: 'error',
73
+ });
74
+
75
+ function isRecord(value) {
76
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
77
+ }
78
+
79
+ function hasExactFields(value, required, optional = []) {
80
+ if (!isRecord(value)) return false;
81
+ const allowed = new Set([...required, ...optional]);
82
+ return required.every((field) => Object.hasOwn(value, field))
83
+ && Object.keys(value).every((field) => allowed.has(field));
84
+ }
85
+
86
+ function nonEmptyString(value) {
87
+ return typeof value === 'string' && value.trim().length > 0;
88
+ }
89
+
90
+ function stringList(value, { allowEmpty = true } = {}) {
91
+ return Array.isArray(value)
92
+ && (allowEmpty || value.length > 0)
93
+ && value.every(nonEmptyString)
94
+ && new Set(value).size === value.length;
95
+ }
96
+
97
+ function invalid(code, label, details = {}) {
98
+ throw new HarnessRuntimeError(code, `Invalid harness runtime ${label}.`, details);
99
+ }
100
+
101
+ export function defineCurrentTurnCapabilities(value) {
102
+ if (!hasExactFields(value, ['nativeTools', 'spawnModelIds'])
103
+ || !stringList(value.nativeTools)
104
+ || !stringList(value.spawnModelIds)) {
105
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_CAPABILITIES, 'current-turn capabilities');
106
+ }
107
+ return deepFreeze(clone(value));
108
+ }
109
+
110
+ function validOption(option) {
111
+ return hasExactFields(option, ['id', 'label'], ['description'])
112
+ && nonEmptyString(option.id)
113
+ && nonEmptyString(option.label)
114
+ && (option.description === undefined || nonEmptyString(option.description));
115
+ }
116
+
117
+ export function defineQuestionSpec(value) {
118
+ if (!hasExactFields(
119
+ value,
120
+ ['id', 'header', 'prompt'],
121
+ ['options', 'recommendationOrder', 'multiSelect', 'secret'],
122
+ ) || !nonEmptyString(value.id)
123
+ || !nonEmptyString(value.header)
124
+ || !nonEmptyString(value.prompt)) {
125
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question');
126
+ }
127
+
128
+ const options = value.options ?? [];
129
+ const optionIds = options.map((option) => option?.id);
130
+ const recommendationOrder = value.recommendationOrder ?? [];
131
+ if (!Array.isArray(options)
132
+ || !options.every(validOption)
133
+ || new Set(optionIds).size !== optionIds.length
134
+ || !stringList(recommendationOrder)
135
+ || recommendationOrder.some((id) => !optionIds.includes(id))
136
+ || (value.multiSelect !== undefined && typeof value.multiSelect !== 'boolean')
137
+ || (value.secret !== undefined && typeof value.secret !== 'boolean')) {
138
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', { questionId: value.id });
139
+ }
140
+
141
+ return deepFreeze({
142
+ id: value.id,
143
+ header: value.header,
144
+ prompt: value.prompt,
145
+ options: clone(options),
146
+ recommendationOrder: clone(recommendationOrder),
147
+ multiSelect: value.multiSelect ?? false,
148
+ secret: value.secret ?? false,
149
+ });
150
+ }
151
+
152
+ function orderedQuestionOptions(question) {
153
+ const byId = new Map(question.options.map((option) => [option.id, option]));
154
+ return [
155
+ ...question.recommendationOrder.map((id) => byId.get(id)),
156
+ ...question.options.filter((option) => !question.recommendationOrder.includes(option.id)),
157
+ ];
158
+ }
159
+
160
+ function answerMappings(batch, optionLabel = (_question, option) => option.label) {
161
+ return batch.map((question) => ({
162
+ questionId: question.id,
163
+ prompt: question.prompt,
164
+ multiSelect: question.multiSelect,
165
+ options: orderedQuestionOptions(question).map((option) => ({
166
+ id: option.id,
167
+ label: optionLabel(question, option),
168
+ })),
169
+ }));
170
+ }
171
+
172
+ function validateNativeOptionLabels(question, adapter, optionLabel = (_question, option) => option.label) {
173
+ const nativeOptions = orderedQuestionOptions(question).map((option) => ({
174
+ id: option.id,
175
+ label: optionLabel(question, option),
176
+ }));
177
+ const labels = new Map();
178
+ for (const option of nativeOptions) {
179
+ const existingId = labels.get(option.label);
180
+ if (existingId !== undefined) {
181
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', {
182
+ reason: 'native-option-label-collision',
183
+ adapter,
184
+ questionId: question.id,
185
+ label: option.label,
186
+ optionIds: [existingId, option.id],
187
+ });
188
+ }
189
+ labels.set(option.label, option.id);
190
+ }
191
+ return nativeOptions;
192
+ }
193
+
194
+ function claudeMultiAnswerMappings(options) {
195
+ const mappings = [];
196
+ for (let mask = 1; mask < (1 << options.length); mask += 1) {
197
+ const subset = options.filter((_, index) => mask & (1 << index));
198
+ for (const candidate of permutations(subset)) {
199
+ mappings.push({
200
+ answer: candidate.map((option) => option.label).join(', '),
201
+ optionIds: candidate.map((option) => option.id),
202
+ });
203
+ }
204
+ }
205
+ return mappings;
206
+ }
207
+
208
+ function validateClaudeMultiAnswerFormats(question, nativeOptions) {
209
+ if (!question.multiSelect) return;
210
+ const formats = new Map();
211
+ for (const mapping of claudeMultiAnswerMappings(nativeOptions)) {
212
+ const existing = formats.get(mapping.answer);
213
+ if (existing !== undefined
214
+ && JSON.stringify(existing) !== JSON.stringify(mapping.optionIds)) {
215
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', {
216
+ reason: 'native-answer-format-collision',
217
+ adapter: 'claude-code',
218
+ questionId: question.id,
219
+ answer: mapping.answer,
220
+ optionIdSets: [existing, mapping.optionIds],
221
+ });
222
+ }
223
+ formats.set(mapping.answer, mapping.optionIds);
224
+ }
225
+ }
226
+
227
+ function validateQuestionBatch(values) {
228
+ if (!Array.isArray(values) || values.length === 0) {
229
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question batch', {
230
+ reason: 'empty-question-batch',
231
+ });
232
+ }
233
+ const questions = values.map(defineQuestionSpec);
234
+ const duplicateId = questions.find((question, index) =>
235
+ questions.findIndex((candidate) => candidate.id === question.id) !== index);
236
+ if (duplicateId) {
237
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question batch', {
238
+ reason: 'duplicate-question-id',
239
+ questionId: duplicateId.id,
240
+ });
241
+ }
242
+ const duplicatePrompt = questions.find((question, index) =>
243
+ questions.findIndex((candidate) => candidate.prompt === question.prompt) !== index);
244
+ if (duplicatePrompt) {
245
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question batch', {
246
+ reason: 'duplicate-question-prompt',
247
+ questionId: duplicatePrompt.id,
248
+ });
249
+ }
250
+ return questions;
251
+ }
252
+
253
+ function validatePiQuestion(question) {
254
+ if (question.secret) {
255
+ throw new UnsupportedQuestionError('secret-input', { adapter: 'pi', questionId: question.id });
256
+ }
257
+ if (question.header.length > 16) {
258
+ throw new UnsupportedQuestionError('header-too-long', {
259
+ adapter: 'pi',
260
+ questionId: question.id,
261
+ maximum: 16,
262
+ });
263
+ }
264
+ if (question.options.length < 2 || question.options.length > 4) {
265
+ throw new UnsupportedQuestionError('option-count', {
266
+ adapter: 'pi',
267
+ questionId: question.id,
268
+ minimum: 2,
269
+ maximum: 4,
270
+ });
271
+ }
272
+ const duplicateLabel = question.options.find((option, index) =>
273
+ question.options.findIndex((candidate) => candidate.label === option.label) !== index);
274
+ if (duplicateLabel) {
275
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', {
276
+ reason: 'duplicate-option-label',
277
+ questionId: question.id,
278
+ label: duplicateLabel.label,
279
+ });
280
+ }
281
+ validateNativeOptionLabels(question, 'pi');
282
+ for (const option of question.options) {
283
+ if (['Other', 'Type something.', 'Next'].includes(option.label)) {
284
+ throw new UnsupportedQuestionError('reserved-option-label', {
285
+ adapter: 'pi',
286
+ questionId: question.id,
287
+ optionId: option.id,
288
+ label: option.label,
289
+ });
290
+ }
291
+ if (option.description === undefined) {
292
+ throw new UnsupportedQuestionError('option-description-required', {
293
+ adapter: 'pi',
294
+ questionId: question.id,
295
+ optionId: option.id,
296
+ });
297
+ }
298
+ if (option.label.length > 60) {
299
+ throw new UnsupportedQuestionError('option-label-too-long', {
300
+ adapter: 'pi',
301
+ questionId: question.id,
302
+ optionId: option.id,
303
+ maximum: 60,
304
+ });
305
+ }
306
+ }
307
+ }
308
+
309
+ function chunk(values, size) {
310
+ const batches = [];
311
+ for (let index = 0; index < values.length; index += size) {
312
+ batches.push(values.slice(index, index + size));
313
+ }
314
+ return batches;
315
+ }
316
+
317
+ function batchingResult(calls) {
318
+ return {
319
+ required: calls.length > 1,
320
+ reason: calls.length > 1 ? 'adapter-capacity' : null,
321
+ callCount: calls.length,
322
+ };
323
+ }
324
+
325
+ function planPiQuestions(questions) {
326
+ for (const question of questions) validatePiQuestion(question);
327
+ const calls = chunk(questions, 4).map((batch, index) => ({
328
+ index,
329
+ questionIds: batch.map((question) => question.id),
330
+ answerMappings: answerMappings(batch),
331
+ payload: {
332
+ questions: batch.map((question) => ({
333
+ question: question.prompt,
334
+ header: question.header,
335
+ options: orderedQuestionOptions(question).map((option) => ({
336
+ label: option.label,
337
+ description: option.description,
338
+ })),
339
+ multiSelect: question.multiSelect,
340
+ })),
341
+ },
342
+ }));
343
+ return deepFreeze({
344
+ kind: 'native',
345
+ adapter: 'pi',
346
+ toolName: 'ask_user_question',
347
+ capacity: 4,
348
+ requiresMultipleCalls: calls.length > 1,
349
+ batching: batchingResult(calls),
350
+ calls,
351
+ });
352
+ }
353
+
354
+ function validateNativeOptions(question, adapter, maximum) {
355
+ if (question.options.length < 2 || question.options.length > maximum) {
356
+ throw new UnsupportedQuestionError('option-count', {
357
+ adapter,
358
+ questionId: question.id,
359
+ minimum: 2,
360
+ maximum,
361
+ });
362
+ }
363
+ const duplicateLabel = question.options.find((option, index) =>
364
+ question.options.findIndex((candidate) => candidate.label === option.label) !== index);
365
+ if (duplicateLabel) {
366
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_QUESTION, 'question', {
367
+ reason: 'duplicate-option-label',
368
+ questionId: question.id,
369
+ label: duplicateLabel.label,
370
+ });
371
+ }
372
+ const missingDescription = question.options.find((option) => option.description === undefined);
373
+ if (missingDescription) {
374
+ throw new UnsupportedQuestionError('option-description-required', {
375
+ adapter,
376
+ questionId: question.id,
377
+ optionId: missingDescription.id,
378
+ });
379
+ }
380
+ }
381
+
382
+ function codexOptionLabel(question, option) {
383
+ return question.recommendationOrder[0] === option.id
384
+ ? `${option.label} (Recommended)`
385
+ : option.label;
386
+ }
387
+
388
+ function planCodexQuestions(questions) {
389
+ for (const question of questions) {
390
+ if (question.secret) {
391
+ throw new UnsupportedQuestionError('secret-input', {
392
+ adapter: 'codex',
393
+ questionId: question.id,
394
+ });
395
+ }
396
+ if (question.multiSelect) {
397
+ throw new UnsupportedQuestionError('multi-select', {
398
+ adapter: 'codex',
399
+ questionId: question.id,
400
+ });
401
+ }
402
+ if (!/^[a-z][a-z0-9_]*$/.test(question.id)) {
403
+ throw new UnsupportedQuestionError('invalid-question-id', {
404
+ adapter: 'codex',
405
+ questionId: question.id,
406
+ format: 'snake_case',
407
+ });
408
+ }
409
+ if (question.header.length > 12) {
410
+ throw new UnsupportedQuestionError('header-too-long', {
411
+ adapter: 'codex',
412
+ questionId: question.id,
413
+ maximum: 12,
414
+ });
415
+ }
416
+ validateNativeOptions(question, 'codex', 3);
417
+ validateNativeOptionLabels(question, 'codex', codexOptionLabel);
418
+ }
419
+ const calls = chunk(questions, 3).map((batch, index) => ({
420
+ index,
421
+ questionIds: batch.map((question) => question.id),
422
+ answerMappings: answerMappings(batch, codexOptionLabel),
423
+ payload: {
424
+ questions: batch.map((question) => ({
425
+ id: question.id,
426
+ header: question.header,
427
+ question: question.prompt,
428
+ options: orderedQuestionOptions(question).map((option) => ({
429
+ label: codexOptionLabel(question, option),
430
+ description: option.description,
431
+ })),
432
+ })),
433
+ },
434
+ }));
435
+ return deepFreeze({
436
+ kind: 'native',
437
+ adapter: 'codex',
438
+ toolName: 'request_user_input',
439
+ capacity: 3,
440
+ requiresMultipleCalls: calls.length > 1,
441
+ batching: batchingResult(calls),
442
+ calls,
443
+ });
444
+ }
445
+
446
+ function planClaudeQuestions(questions) {
447
+ for (const question of questions) {
448
+ if (question.secret) {
449
+ throw new UnsupportedQuestionError('secret-input', {
450
+ adapter: 'claude-code',
451
+ questionId: question.id,
452
+ });
453
+ }
454
+ if (question.header.length > 12) {
455
+ throw new UnsupportedQuestionError('header-too-long', {
456
+ adapter: 'claude-code',
457
+ questionId: question.id,
458
+ maximum: 12,
459
+ });
460
+ }
461
+ validateNativeOptions(question, 'claude-code', 4);
462
+ const nativeOptions = validateNativeOptionLabels(question, 'claude-code');
463
+ validateClaudeMultiAnswerFormats(question, nativeOptions);
464
+ }
465
+ const calls = chunk(questions, 4).map((batch, index) => ({
466
+ index,
467
+ questionIds: batch.map((question) => question.id),
468
+ answerMappings: answerMappings(batch),
469
+ payload: {
470
+ questions: batch.map((question) => ({
471
+ question: question.prompt,
472
+ header: question.header,
473
+ options: orderedQuestionOptions(question).map((option) => ({
474
+ label: option.label,
475
+ description: option.description,
476
+ })),
477
+ multiSelect: question.multiSelect,
478
+ })),
479
+ },
480
+ }));
481
+ return deepFreeze({
482
+ kind: 'native',
483
+ adapter: 'claude-code',
484
+ toolName: 'AskUserQuestion',
485
+ capacity: 4,
486
+ requiresMultipleCalls: calls.length > 1,
487
+ batching: batchingResult(calls),
488
+ calls,
489
+ });
490
+ }
491
+
492
+ function planQuestionFallback(capabilities, questions) {
493
+ const secret = questions.find((question) => question.secret);
494
+ if (secret) {
495
+ throw new UnsupportedQuestionError('secret-input', {
496
+ adapter: null,
497
+ questionId: secret.id,
498
+ });
499
+ }
500
+ const multiSelect = questions.find((question) => question.multiSelect);
501
+ if (multiSelect) {
502
+ throw new UnsupportedQuestionError('multi-select', {
503
+ adapter: null,
504
+ questionId: multiSelect.id,
505
+ });
506
+ }
507
+ const hasOptions = questions.some((question) => question.options.length > 0);
508
+ const oneFreeTextQuestion = questions.length === 1 && !hasOptions;
509
+ return deepFreeze({
510
+ kind: 'fallback',
511
+ adapter: null,
512
+ reason: 'no-supported-native-question-tool',
513
+ decision: oneFreeTextQuestion
514
+ ? 'concise-free-text'
515
+ : 'textual-multiple-choice-forbidden',
516
+ freeText: oneFreeTextQuestion
517
+ ? {
518
+ allowed: true,
519
+ questionId: questions[0].id,
520
+ prompt: questions[0].prompt,
521
+ }
522
+ : {
523
+ allowed: false,
524
+ reason: hasOptions ? 'logical-question-has-options' : 'multiple-questions',
525
+ },
526
+ textualMultipleChoice: {
527
+ allowed: false,
528
+ reason: QUESTION_FALLBACK_POLICY.noNativeQuestionTool.multipleChoice,
529
+ },
530
+ availableTools: clone(capabilities.nativeTools),
531
+ });
532
+ }
533
+
534
+ export function planStructuredQuestions(capabilitiesValue, questionValues) {
535
+ const capabilities = defineCurrentTurnCapabilities(capabilitiesValue);
536
+ const questions = validateQuestionBatch(questionValues);
537
+ if (capabilities.nativeTools.includes('ask_user_question')) {
538
+ return planPiQuestions(questions);
539
+ }
540
+ if (capabilities.nativeTools.includes('request_user_input')) {
541
+ return planCodexQuestions(questions);
542
+ }
543
+ if (capabilities.nativeTools.includes('AskUserQuestion')) {
544
+ return planClaudeQuestions(questions);
545
+ }
546
+ return planQuestionFallback(capabilities, questions);
547
+ }
548
+
549
+ function invalidAnswers(reason, details = {}) {
550
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_ANSWERS, 'question answers', {
551
+ reason,
552
+ ...details,
553
+ });
554
+ }
555
+
556
+ function mappedOption(mapping, label) {
557
+ const matches = mapping.options.filter((option) => option.label === label);
558
+ if (matches.length > 1) {
559
+ invalidAnswers('ambiguous-option-label', {
560
+ questionId: mapping.questionId,
561
+ answer: label,
562
+ optionIds: matches.map((option) => option.id),
563
+ });
564
+ }
565
+ return matches[0];
566
+ }
567
+
568
+ function mapSingleAnswer(mapping, value, { custom = true } = {}) {
569
+ if (!nonEmptyString(value)) invalidAnswers('empty-answer', { questionId: mapping.questionId });
570
+ const option = mappedOption(mapping, value);
571
+ if (option) return option.id;
572
+ if (custom) return value;
573
+ invalidAnswers('unknown-option-label', { questionId: mapping.questionId, answer: value });
574
+ }
575
+
576
+ function requireCompleteAnswers(call, answers) {
577
+ const missingQuestionIds = call.answerMappings
578
+ .map((mapping) => mapping.questionId)
579
+ .filter((questionId) => !Object.hasOwn(answers, questionId));
580
+ if (missingQuestionIds.length > 0) {
581
+ invalidAnswers('incomplete-native-response', {
582
+ callIndex: call.index,
583
+ missingQuestionIds,
584
+ });
585
+ }
586
+ return answers;
587
+ }
588
+
589
+ function normalizePiResponse(call, response) {
590
+ if (!isRecord(response) || !isRecord(response.details)
591
+ || !Array.isArray(response.details.answers)
592
+ || response.details.cancelled !== false) {
593
+ invalidAnswers('malformed-pi-response', { callIndex: call.index });
594
+ }
595
+ const answers = {};
596
+ const seenIndexes = new Set();
597
+ for (const nativeAnswer of response.details.answers) {
598
+ if (!isRecord(nativeAnswer)
599
+ || !Number.isInteger(nativeAnswer.questionIndex)
600
+ || seenIndexes.has(nativeAnswer.questionIndex)) {
601
+ invalidAnswers('malformed-pi-answer', { callIndex: call.index });
602
+ }
603
+ const mapping = call.answerMappings[nativeAnswer.questionIndex];
604
+ if (!mapping || nativeAnswer.question !== mapping.prompt) {
605
+ invalidAnswers('unknown-pi-question', { callIndex: call.index });
606
+ }
607
+ seenIndexes.add(nativeAnswer.questionIndex);
608
+ if (nativeAnswer.kind === 'multi') {
609
+ if (!mapping.multiSelect
610
+ || !Array.isArray(nativeAnswer.selected)
611
+ || nativeAnswer.selected.length === 0
612
+ || !nativeAnswer.selected.every(nonEmptyString)) {
613
+ invalidAnswers('malformed-pi-multi-answer', { questionId: mapping.questionId });
614
+ }
615
+ answers[mapping.questionId] = nativeAnswer.selected.map((label) =>
616
+ mapSingleAnswer(mapping, label, { custom: false }));
617
+ } else if (nativeAnswer.kind === 'option') {
618
+ answers[mapping.questionId] = [
619
+ mapSingleAnswer(mapping, nativeAnswer.answer, { custom: false }),
620
+ ];
621
+ } else if (nativeAnswer.kind === 'custom') {
622
+ if (!nonEmptyString(nativeAnswer.answer)) {
623
+ invalidAnswers('empty-answer', { questionId: mapping.questionId });
624
+ }
625
+ answers[mapping.questionId] = [nativeAnswer.answer];
626
+ } else {
627
+ invalidAnswers('unknown-pi-answer-kind', { questionId: mapping.questionId });
628
+ }
629
+ }
630
+ return requireCompleteAnswers(call, answers);
631
+ }
632
+
633
+ function normalizeCodexResponse(call, response) {
634
+ if (!hasExactFields(response, ['answers']) || !isRecord(response.answers)) {
635
+ invalidAnswers('malformed-codex-response', { callIndex: call.index });
636
+ }
637
+ const mappings = new Map(call.answerMappings.map((mapping) => [mapping.questionId, mapping]));
638
+ const answers = {};
639
+ for (const [questionId, nativeAnswer] of Object.entries(response.answers)) {
640
+ const mapping = mappings.get(questionId);
641
+ if (!mapping || !hasExactFields(nativeAnswer, ['answers'])
642
+ || !stringList(nativeAnswer.answers, { allowEmpty: false })
643
+ || nativeAnswer.answers.length !== 1) {
644
+ invalidAnswers('malformed-codex-answer', { callIndex: call.index, questionId });
645
+ }
646
+ answers[questionId] = nativeAnswer.answers.map((value) => mapSingleAnswer(mapping, value));
647
+ }
648
+ return requireCompleteAnswers(call, answers);
649
+ }
650
+
651
+ function permutations(values) {
652
+ if (values.length === 0) return [[]];
653
+ return values.flatMap((value, index) =>
654
+ permutations(values.filter((_, candidateIndex) => candidateIndex !== index))
655
+ .map((rest) => [value, ...rest]));
656
+ }
657
+
658
+ function parseClaudeMultiAnswer(mapping, value) {
659
+ const matches = claudeMultiAnswerMappings(mapping.options)
660
+ .filter((candidate) => candidate.answer === value)
661
+ .map((candidate) => candidate.optionIds);
662
+ const unique = [...new Map(matches.map((match) => [JSON.stringify(match), match])).values()];
663
+ if (unique.length > 1) {
664
+ invalidAnswers('ambiguous-claude-multi-answer', { questionId: mapping.questionId });
665
+ }
666
+ return unique[0] ?? [value];
667
+ }
668
+
669
+ function normalizeClaudeResponse(call, response) {
670
+ if (!isRecord(response) || !isRecord(response.answers)) {
671
+ invalidAnswers('malformed-claude-response', { callIndex: call.index });
672
+ }
673
+ const mappings = new Map(call.answerMappings.map((mapping) => [mapping.prompt, mapping]));
674
+ const answers = {};
675
+ for (const [prompt, value] of Object.entries(response.answers)) {
676
+ const mapping = mappings.get(prompt);
677
+ if (!mapping || !nonEmptyString(value)) {
678
+ invalidAnswers('malformed-claude-answer', { callIndex: call.index, prompt });
679
+ }
680
+ answers[mapping.questionId] = mapping.multiSelect
681
+ ? parseClaudeMultiAnswer(mapping, value)
682
+ : [mapSingleAnswer(mapping, value)];
683
+ }
684
+ return requireCompleteAnswers(call, answers);
685
+ }
686
+
687
+ function responseCancelled(adapter, response) {
688
+ if (isRecord(response) && response.cancelled === true) return true;
689
+ return adapter === 'pi'
690
+ && isRecord(response)
691
+ && isRecord(response.details)
692
+ && response.details.cancelled === true;
693
+ }
694
+
695
+ export function normalizeQuestionResponses(plan, nativeResponses) {
696
+ if (!isRecord(plan) || plan.kind !== 'native'
697
+ || !['pi', 'codex', 'claude-code'].includes(plan.adapter)
698
+ || !Array.isArray(plan.calls)) {
699
+ invalidAnswers('invalid-question-plan');
700
+ }
701
+ if (!Array.isArray(nativeResponses) || nativeResponses.length !== plan.calls.length) {
702
+ invalidAnswers('response-count', {
703
+ expected: plan.calls.length,
704
+ actual: Array.isArray(nativeResponses) ? nativeResponses.length : null,
705
+ });
706
+ }
707
+ if (nativeResponses.some((response) => responseCancelled(plan.adapter, response))) {
708
+ return defineQuestionAnswers({});
709
+ }
710
+ const answers = {};
711
+ for (let index = 0; index < plan.calls.length; index += 1) {
712
+ const call = plan.calls[index];
713
+ const response = nativeResponses[index];
714
+ const normalized = plan.adapter === 'pi'
715
+ ? normalizePiResponse(call, response)
716
+ : plan.adapter === 'codex'
717
+ ? normalizeCodexResponse(call, response)
718
+ : normalizeClaudeResponse(call, response);
719
+ for (const [questionId, values] of Object.entries(normalized)) {
720
+ if (Object.hasOwn(answers, questionId)) {
721
+ invalidAnswers('duplicate-question-answer', { questionId });
722
+ }
723
+ answers[questionId] = values;
724
+ }
725
+ }
726
+ return defineQuestionAnswers(answers);
727
+ }
728
+
729
+ export function defineQuestionAnswers(value) {
730
+ if (!isRecord(value)
731
+ || Object.entries(value).some(([questionId, answers]) =>
732
+ !nonEmptyString(questionId) || !stringList(answers, { allowEmpty: false }))) {
733
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_ANSWERS, 'question answers');
734
+ }
735
+ return deepFreeze(clone(value));
736
+ }
737
+
738
+ function validModel(model) {
739
+ return hasExactFields(model, ['id', 'sources'])
740
+ && nonEmptyString(model.id)
741
+ && stringList(model.sources, { allowEmpty: false });
742
+ }
743
+
744
+ export function defineModelAvailability(value) {
745
+ if (!hasExactFields(value, ['harness', 'completeness', 'models'])
746
+ || !HARNESSES.has(value.harness)
747
+ || !COMPLETENESS.has(value.completeness)
748
+ || !Array.isArray(value.models)
749
+ || !value.models.every(validModel)
750
+ || new Set(value.models.map((model) => model.id)).size !== value.models.length) {
751
+ invalid(HARNESS_RUNTIME_ERROR_CODES.INVALID_MODEL_AVAILABILITY, 'model availability');
752
+ }
753
+
754
+ const runtimeEnumerated = value.models.some((model) =>
755
+ model.sources.some((source) => RUNTIME_MODEL_SOURCES.has(source)));
756
+ if (value.completeness === 'full'
757
+ && ['codex', 'claude-code'].includes(value.harness)
758
+ && !runtimeEnumerated) {
759
+ invalid(
760
+ HARNESS_RUNTIME_ERROR_CODES.INVALID_MODEL_AVAILABILITY,
761
+ 'model availability',
762
+ { reason: 'static-config-is-not-complete', harness: value.harness },
763
+ );
764
+ }
765
+
766
+ return deepFreeze(clone(value));
767
+ }