@mmerterden/multi-agent-pipeline 20.2.1 → 20.3.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 (621) hide show
  1. package/CHANGELOG.md +912 -1
  2. package/README.md +104 -81
  3. package/README.tr.md +103 -62
  4. package/docs/FIGMA_PIPELINE.md +35 -35
  5. package/docs/adr/0006-skills-core-external-split.md +1 -1
  6. package/docs/adr/0007-multi-tool-adapter-framework.md +6 -0
  7. package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +7 -0
  8. package/docs/architecture.md +50 -14
  9. package/docs/best-practices.md +1 -1
  10. package/docs/ecosystem.md +56 -32
  11. package/docs/facts.json +10 -10
  12. package/docs/features.md +97 -5
  13. package/docs/recovery-guide.md +7 -14
  14. package/docs/server-readiness.md +31 -24
  15. package/index.js +1 -1
  16. package/install/_common.mjs +3 -5
  17. package/install/_platform-filter.mjs +23 -1
  18. package/install/_unattended-profile.mjs +321 -75
  19. package/install/claude.mjs +51 -10
  20. package/install/codex.mjs +2 -0
  21. package/install/copilot.mjs +2 -0
  22. package/install/index.mjs +30 -17
  23. package/install/templates/claude-hooks.json +16 -5
  24. package/install/templates/copilot-instructions.md +1 -1
  25. package/install/templates/multi-agent-autopilot-awake.plist.template +48 -0
  26. package/install/templates/multi-agent-autopilot.plist.template +12 -5
  27. package/install/unattended-profile-legacy.json +80 -0
  28. package/manifest.json +616 -483
  29. package/package.json +8 -3
  30. package/pipeline/agents/code-reviewer.md +10 -0
  31. package/pipeline/agents/plan-critic.md +98 -0
  32. package/pipeline/agents/security-auditor.md +10 -0
  33. package/pipeline/agents/task-clarifier.md +10 -0
  34. package/pipeline/commands/multi-agent/SKILL.md +2 -2
  35. package/pipeline/commands/multi-agent/analysis/SKILL.md +6 -2
  36. package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +12 -1
  37. package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +4 -0
  38. package/pipeline/commands/multi-agent/autopilot/SKILL.md +6 -2
  39. package/pipeline/commands/multi-agent/autopilot-off/SKILL.md +36 -6
  40. package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +77 -12
  41. package/pipeline/commands/multi-agent/autopilot-status/SKILL.md +29 -8
  42. package/pipeline/commands/multi-agent/build-optimize/SKILL.md +4 -0
  43. package/pipeline/commands/multi-agent/channels/SKILL.md +9 -9
  44. package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +5 -1
  45. package/pipeline/commands/multi-agent/create-jira/SKILL.md +4 -0
  46. package/pipeline/commands/multi-agent/design-check/SKILL.md +16 -11
  47. package/pipeline/commands/multi-agent/diff-explain/SKILL.md +4 -0
  48. package/pipeline/commands/multi-agent/doctor/SKILL.md +4 -0
  49. package/pipeline/commands/multi-agent/feedback/SKILL.md +5 -1
  50. package/pipeline/commands/multi-agent/forget/SKILL.md +4 -0
  51. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +4 -0
  52. package/pipeline/commands/multi-agent/graph/SKILL.md +4 -0
  53. package/pipeline/commands/multi-agent/help/SKILL.md +37 -39
  54. package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +4 -0
  55. package/pipeline/commands/multi-agent/issue/SKILL.md +7 -1
  56. package/pipeline/commands/multi-agent/jira/SKILL.md +7 -1
  57. package/pipeline/commands/multi-agent/kill/SKILL.md +9 -3
  58. package/pipeline/commands/multi-agent/language/SKILL.md +4 -0
  59. package/pipeline/commands/multi-agent/log/SKILL.md +4 -0
  60. package/pipeline/commands/multi-agent/manual-test/SKILL.md +5 -0
  61. package/pipeline/commands/multi-agent/model/SKILL.md +4 -0
  62. package/pipeline/commands/multi-agent/prune-logs/SKILL.md +4 -0
  63. package/pipeline/commands/multi-agent/prune-prompts/SKILL.md +4 -0
  64. package/pipeline/commands/multi-agent/purge/SKILL.md +4 -0
  65. package/pipeline/commands/multi-agent/refactor/SKILL.md +5 -0
  66. package/pipeline/commands/multi-agent/research/SKILL.md +49 -0
  67. package/pipeline/commands/multi-agent/resume/SKILL.md +29 -6
  68. package/pipeline/commands/multi-agent/review/SKILL.md +28 -9
  69. package/pipeline/commands/multi-agent/review-analysis/SKILL.md +5 -1
  70. package/pipeline/commands/multi-agent/review-issue/SKILL.md +4 -0
  71. package/pipeline/commands/multi-agent/review-jira/SKILL.md +4 -0
  72. package/pipeline/commands/multi-agent/route-off/SKILL.md +4 -0
  73. package/pipeline/commands/multi-agent/route-on/SKILL.md +4 -0
  74. package/pipeline/commands/multi-agent/route-status/SKILL.md +4 -0
  75. package/pipeline/commands/multi-agent/routines/SKILL.md +4 -0
  76. package/pipeline/commands/multi-agent/save/SKILL.md +6 -2
  77. package/pipeline/commands/multi-agent/scaffold/SKILL.md +47 -0
  78. package/pipeline/commands/multi-agent/scan/SKILL.md +4 -0
  79. package/pipeline/commands/multi-agent/search/SKILL.md +12 -8
  80. package/pipeline/commands/multi-agent/security-review/SKILL.md +4 -0
  81. package/pipeline/commands/multi-agent/serve/SKILL.md +62 -0
  82. package/pipeline/commands/multi-agent/setup/SKILL.md +27 -36
  83. package/pipeline/commands/multi-agent/stack/SKILL.md +4 -0
  84. package/pipeline/commands/multi-agent/status/SKILL.md +10 -9
  85. package/pipeline/commands/multi-agent/steer/SKILL.md +5 -1
  86. package/pipeline/commands/multi-agent/store-ready/SKILL.md +4 -0
  87. package/pipeline/commands/multi-agent/sync/SKILL.md +13 -13
  88. package/pipeline/commands/multi-agent/test/SKILL.md +4 -0
  89. package/pipeline/commands/multi-agent/test-accessibility/SKILL.md +4 -0
  90. package/pipeline/commands/multi-agent/test-dark-mode/SKILL.md +4 -0
  91. package/pipeline/commands/multi-agent/test-dynamic-type/SKILL.md +4 -0
  92. package/pipeline/commands/multi-agent/test-screenshots/SKILL.md +5 -1
  93. package/pipeline/commands/multi-agent/testflight-validation/SKILL.md +4 -0
  94. package/pipeline/commands/multi-agent/uninstall/SKILL.md +5 -1
  95. package/pipeline/commands/multi-agent/update/SKILL.md +4 -0
  96. package/pipeline/contract/CHANGELOG.md +74 -0
  97. package/pipeline/contract/README.md +126 -0
  98. package/pipeline/contract/build.mjs +427 -0
  99. package/pipeline/contract/fixtures/answer-result.json +11 -0
  100. package/pipeline/contract/fixtures/error-invalid-request.json +8 -0
  101. package/pipeline/contract/fixtures/error-unauthorized.json +5 -0
  102. package/pipeline/contract/fixtures/error-unsigned.json +5 -0
  103. package/pipeline/contract/fixtures/issues-empty.json +18 -0
  104. package/pipeline/contract/fixtures/launch-plan.json +31 -0
  105. package/pipeline/contract/fixtures/runs-awaiting-question.json +70 -0
  106. package/pipeline/contract/fixtures/runs-empty.json +6 -0
  107. package/pipeline/contract/fixtures/runs-failed.json +84 -0
  108. package/pipeline/contract/fixtures/runs-old-schema.json +70 -0
  109. package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +101 -0
  110. package/pipeline/contract/fixtures/runs-pr-opened.json +106 -0
  111. package/pipeline/contract/fixtures/runs-running.json +84 -0
  112. package/pipeline/contract/fixtures/worktrees-empty.json +4 -0
  113. package/pipeline/contract/frozen/toolbox.json +107 -0
  114. package/pipeline/contract/manifest.json +263 -0
  115. package/pipeline/contract/types/index.d.ts +343 -0
  116. package/pipeline/lib/_jira-auth.sh +6 -2
  117. package/pipeline/lib/account-resolver.sh +1 -1
  118. package/pipeline/lib/autopilot-state.sh +19 -0
  119. package/pipeline/lib/context-link-extractor.sh +12 -5
  120. package/pipeline/lib/credential-inventory.sh +12 -5
  121. package/pipeline/lib/credential-store.sh +116 -185
  122. package/pipeline/lib/fetch-confluence.sh +44 -3
  123. package/pipeline/lib/fetch-document.sh +3 -4
  124. package/pipeline/lib/fetch-fortify.sh +1 -1
  125. package/pipeline/lib/figma-mcp-refresh.sh +2 -2
  126. package/pipeline/lib/figma-token.sh +5 -1
  127. package/pipeline/lib/issue-fetcher.sh +233 -16
  128. package/pipeline/lib/json-file-lock.mjs +172 -0
  129. package/pipeline/lib/model-dispatch.sh +21 -12
  130. package/pipeline/lib/model-rung.sh +6 -1
  131. package/pipeline/lib/multi-repo-pipeline.sh +1 -1
  132. package/pipeline/lib/outbound-gate.mjs +46 -16
  133. package/pipeline/lib/parse-complaints.sh +14 -7
  134. package/pipeline/lib/plan-todos.sh +3 -3
  135. package/pipeline/lib/post-pr-review.sh +9 -9
  136. package/pipeline/lib/pr-request-location.mjs +85 -0
  137. package/pipeline/lib/regular-file.mjs +153 -0
  138. package/pipeline/lib/repo-hygiene.sh +17 -0
  139. package/pipeline/lib/route-state.sh +5 -1
  140. package/pipeline/lib/run-paths.sh +3 -2
  141. package/pipeline/lib/stack-detect.sh +19 -1
  142. package/pipeline/lib/unattended-profile-check.mjs +178 -0
  143. package/pipeline/lib/unattended-settings-location.mjs +28 -0
  144. package/pipeline/lib/unattended.mjs +76 -0
  145. package/pipeline/lib/unattended.sh +32 -0
  146. package/pipeline/lib/untrusted.mjs +76 -0
  147. package/pipeline/lib/user-facing.mjs +82 -0
  148. package/pipeline/lib/user-facing.sh +58 -0
  149. package/pipeline/multi-agent-refs/_dev-context.md +1 -1
  150. package/pipeline/multi-agent-refs/analysis/evidence.md +4 -0
  151. package/pipeline/multi-agent-refs/analysis/locked.md +2 -2
  152. package/pipeline/multi-agent-refs/analysis/render.md +4 -3
  153. package/pipeline/multi-agent-refs/analysis/resolve.md +3 -1
  154. package/pipeline/multi-agent-refs/analysis/synthesis.md +4 -5
  155. package/pipeline/multi-agent-refs/analysis-template.md +10 -17
  156. package/pipeline/multi-agent-refs/channels/jira.md +1 -1
  157. package/pipeline/multi-agent-refs/component-dispatch.md +3 -3
  158. package/pipeline/multi-agent-refs/conventions-defaults.md +32 -32
  159. package/pipeline/multi-agent-refs/cross-cli-contract.md +10 -17
  160. package/pipeline/multi-agent-refs/features/autopilot-circuit-breaker.md +37 -9
  161. package/pipeline/multi-agent-refs/features/autopilot-operations.md +277 -0
  162. package/pipeline/multi-agent-refs/features/constitution.md +196 -0
  163. package/pipeline/multi-agent-refs/features/doctor.md +6 -3
  164. package/pipeline/multi-agent-refs/features/external-context-injection.md +6 -1
  165. package/pipeline/multi-agent-refs/features/jira-context.md +1 -1
  166. package/pipeline/multi-agent-refs/features/maturity-followup.md +43 -23
  167. package/pipeline/multi-agent-refs/features/model-fallback.md +9 -0
  168. package/pipeline/multi-agent-refs/features/phone-api.md +306 -0
  169. package/pipeline/multi-agent-refs/features/plan-critic.md +159 -0
  170. package/pipeline/multi-agent-refs/features/research.md +150 -0
  171. package/pipeline/multi-agent-refs/features/review-decision.md +185 -0
  172. package/pipeline/multi-agent-refs/features/scaffold.md +160 -0
  173. package/pipeline/multi-agent-refs/features/security-audit.md +6 -2
  174. package/pipeline/multi-agent-refs/features/skill-conformance.md +4 -1
  175. package/pipeline/multi-agent-refs/features/stack-adapters.md +116 -0
  176. package/pipeline/multi-agent-refs/features/unattended-gates.md +316 -0
  177. package/pipeline/multi-agent-refs/features/unattended-security.md +731 -0
  178. package/pipeline/multi-agent-refs/features/url-enrichment.md +2 -2
  179. package/pipeline/multi-agent-refs/features/usage-reporting.md +127 -35
  180. package/pipeline/multi-agent-refs/features/verify-by-test.md +1 -1
  181. package/pipeline/multi-agent-refs/features/visual-evidence.md +7 -7
  182. package/pipeline/multi-agent-refs/keychain.md +6 -11
  183. package/pipeline/multi-agent-refs/payload-contracts.md +2 -2
  184. package/pipeline/multi-agent-refs/phases/log-format.md +2 -3
  185. package/pipeline/multi-agent-refs/phases/modes.md +10 -12
  186. package/pipeline/multi-agent-refs/phases/operations.md +11 -5
  187. package/pipeline/multi-agent-refs/phases/phase-0-init.md +73 -81
  188. package/pipeline/multi-agent-refs/phases/phase-1-plan.md +22 -22
  189. package/pipeline/multi-agent-refs/phases/phase-2-dev.md +42 -66
  190. package/pipeline/multi-agent-refs/phases/phase-3-review.md +45 -79
  191. package/pipeline/multi-agent-refs/phases/phase-4-commit.md +28 -38
  192. package/pipeline/multi-agent-refs/phases/phase-5-report.md +27 -25
  193. package/pipeline/multi-agent-refs/phases.md +1 -1
  194. package/pipeline/multi-agent-refs/picker-contract.md +1 -1
  195. package/pipeline/multi-agent-refs/progress-contract.md +13 -16
  196. package/pipeline/multi-agent-refs/readiness-review.md +1 -1
  197. package/pipeline/multi-agent-refs/research/engine.md +91 -0
  198. package/pipeline/multi-agent-refs/rules.md +6 -4
  199. package/pipeline/multi-agent-refs/setup/repo-discovery.md +2 -2
  200. package/pipeline/multi-agent-refs/tracker-contract.md +2 -2
  201. package/pipeline/multi-agent-refs/unattended-contract.md +68 -16
  202. package/pipeline/rules/figma-pipeline.md +12 -12
  203. package/pipeline/schemas/agent-state.schema.json +480 -18
  204. package/pipeline/schemas/analysis-spec.schema.json +4 -4
  205. package/pipeline/schemas/answer-request.schema.json +24 -0
  206. package/pipeline/schemas/answer-result.schema.json +28 -0
  207. package/pipeline/schemas/autopilot-config.schema.json +111 -13
  208. package/pipeline/schemas/command-parameters.schema.json +99 -0
  209. package/pipeline/schemas/constitution.schema.json +56 -0
  210. package/pipeline/schemas/contract-error.schema.json +52 -0
  211. package/pipeline/schemas/design-check-config.schema.json +5 -1
  212. package/pipeline/schemas/issues.schema.json +61 -0
  213. package/pipeline/schemas/launch-plan.schema.json +46 -0
  214. package/pipeline/schemas/launch-request.schema.json +45 -0
  215. package/pipeline/schemas/launch.json +61 -0
  216. package/pipeline/schemas/launch.schema.json +84 -0
  217. package/pipeline/schemas/phases.json +2 -2
  218. package/pipeline/schemas/phases.schema.json +68 -0
  219. package/pipeline/schemas/phone-devices.schema.json +61 -0
  220. package/pipeline/schemas/phone-signed-request.schema.json +67 -0
  221. package/pipeline/schemas/plan-critique.schema.json +99 -0
  222. package/pipeline/schemas/plan-todos.schema.json +7 -7
  223. package/pipeline/schemas/planning-output.schema.json +5 -0
  224. package/pipeline/schemas/pr-request.schema.json +46 -0
  225. package/pipeline/schemas/prefs.schema.json +79 -8
  226. package/pipeline/schemas/research-output.schema.json +118 -0
  227. package/pipeline/schemas/review-file-exclusions.schema.json +25 -0
  228. package/pipeline/schemas/reviewer-output.schema.json +40 -4
  229. package/pipeline/schemas/run-questions.json +392 -0
  230. package/pipeline/schemas/run-questions.schema.json +118 -0
  231. package/pipeline/schemas/runs-index.schema.json +189 -0
  232. package/pipeline/schemas/scaffold-manifest.schema.json +43 -0
  233. package/pipeline/schemas/secret-patterns.schema.json +28 -0
  234. package/pipeline/schemas/stack-adapters.json +527 -0
  235. package/pipeline/schemas/stack-adapters.schema.json +184 -0
  236. package/pipeline/schemas/token-budget.json +1 -1
  237. package/pipeline/schemas/token-budget.schema.json +26 -0
  238. package/pipeline/schemas/triage-output.schema.json +64 -3
  239. package/pipeline/schemas/unattended-policy.json +139 -0
  240. package/pipeline/schemas/unattended-policy.schema.json +73 -0
  241. package/pipeline/schemas/unattended-profile.json +248 -0
  242. package/pipeline/schemas/unattended-profile.schema.json +198 -0
  243. package/pipeline/schemas/worktrees.schema.json +51 -0
  244. package/pipeline/scripts/README.md +1 -0
  245. package/pipeline/scripts/_autopilot-config.mjs +130 -0
  246. package/pipeline/scripts/_autopilot-ops.mjs +567 -0
  247. package/pipeline/scripts/_autopilot-outcomes.mjs +174 -0
  248. package/pipeline/scripts/_command-contract.mjs +384 -0
  249. package/pipeline/scripts/_cost.mjs +40 -0
  250. package/pipeline/scripts/_notices.mjs +160 -0
  251. package/pipeline/scripts/_phone-auth.mjs +485 -0
  252. package/pipeline/scripts/_pre-existing.mjs +294 -0
  253. package/pipeline/scripts/_redact.mjs +77 -0
  254. package/pipeline/scripts/_run-paths.mjs +4 -2
  255. package/pipeline/scripts/_stack-adapter.mjs +678 -0
  256. package/pipeline/scripts/_stack-routing.mjs +1 -1
  257. package/pipeline/scripts/agent-guard.py +348 -37
  258. package/pipeline/scripts/agent-guard.sh +41 -13
  259. package/pipeline/scripts/analysis-story-tree.mjs +79 -3
  260. package/pipeline/scripts/answer-question.mjs +181 -0
  261. package/pipeline/scripts/audit-log-rotate.sh +1 -4
  262. package/pipeline/scripts/audit-log.sh +4 -4
  263. package/pipeline/scripts/autopilot-arming.mjs +389 -21
  264. package/pipeline/scripts/autopilot-awake.mjs +255 -0
  265. package/pipeline/scripts/autopilot-intake.mjs +137 -36
  266. package/pipeline/scripts/autopilot-menubar.swift +156 -44
  267. package/pipeline/scripts/autopilot-publish.mjs +1625 -0
  268. package/pipeline/scripts/autopilot-runner.mjs +1678 -222
  269. package/pipeline/scripts/autopilot-status.sh +198 -33
  270. package/pipeline/scripts/build-lock.sh +120 -0
  271. package/pipeline/scripts/build-references.mjs +4 -1
  272. package/pipeline/scripts/build-stack-plugins.mjs +59 -22
  273. package/pipeline/scripts/capture-flush.sh +1 -1
  274. package/pipeline/scripts/capture-resume.sh +13 -9
  275. package/pipeline/scripts/check-derived-drift.mjs +52 -11
  276. package/pipeline/scripts/commands.mjs +88 -0
  277. package/pipeline/scripts/constitution.mjs +362 -0
  278. package/pipeline/scripts/contract-server.mjs +776 -0
  279. package/pipeline/scripts/cost-analyze.mjs +89 -39
  280. package/pipeline/scripts/diff-explain.mjs +12 -1
  281. package/pipeline/scripts/doctor.mjs +77 -28
  282. package/pipeline/scripts/evidence-gate.mjs +192 -12
  283. package/pipeline/scripts/feedback-send.mjs +4 -2
  284. package/pipeline/scripts/gate-ledger.mjs +449 -0
  285. package/pipeline/scripts/gc-abandoned.sh +132 -13
  286. package/pipeline/scripts/gen-facts.mjs +31 -15
  287. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -3
  288. package/pipeline/scripts/github-ssh-setup.sh +140 -29
  289. package/pipeline/scripts/graph-mermaid.mjs +4 -1
  290. package/pipeline/scripts/issues.mjs +236 -0
  291. package/pipeline/scripts/jira-attach.sh +6 -2
  292. package/pipeline/scripts/jira-search.sh +4 -3
  293. package/pipeline/scripts/keychain-save.sh +125 -24
  294. package/pipeline/scripts/keychain.py +63 -93
  295. package/pipeline/scripts/launch-request.mjs +747 -0
  296. package/pipeline/scripts/localize-commands.mjs +4 -10
  297. package/pipeline/scripts/log-metric.sh +6 -5
  298. package/pipeline/scripts/maturity-followup.mjs +13 -4
  299. package/pipeline/scripts/memory-save.sh +25 -0
  300. package/pipeline/scripts/migrate-prefs.mjs +4 -3
  301. package/pipeline/scripts/open-questions-gate.mjs +276 -0
  302. package/pipeline/scripts/phase-tracker.sh +41 -27
  303. package/pipeline/scripts/phase0-exit-gate.mjs +22 -4
  304. package/pipeline/scripts/phone-devices.mjs +224 -0
  305. package/pipeline/scripts/plan-coverage-gate.mjs +200 -66
  306. package/pipeline/scripts/plan-critique-gate.mjs +591 -0
  307. package/pipeline/scripts/pr-request.mjs +188 -0
  308. package/pipeline/scripts/pre-commit-check.sh +115 -4
  309. package/pipeline/scripts/probe-evidence-capability.sh +44 -5
  310. package/pipeline/scripts/record-phase.mjs +71 -0
  311. package/pipeline/scripts/render-agent-log-cost.sh +17 -2
  312. package/pipeline/scripts/render-cost-summary.sh +1 -1
  313. package/pipeline/scripts/render-work-summary.sh +1 -1
  314. package/pipeline/scripts/require-supported-version.sh +4 -1
  315. package/pipeline/scripts/research-gate.mjs +704 -0
  316. package/pipeline/scripts/review-decision-gate.mjs +403 -0
  317. package/pipeline/scripts/routine-registry.mjs +5 -2
  318. package/pipeline/scripts/runs-index.mjs +135 -27
  319. package/pipeline/scripts/scaffold-gate.mjs +393 -0
  320. package/pipeline/scripts/skill-conformance.mjs +25 -8
  321. package/pipeline/scripts/skill-siblings.mjs +2 -1
  322. package/pipeline/scripts/smoke-cross-cli-behavior.sh +32 -6
  323. package/pipeline/scripts/smoke-schema-validation.sh +6 -2
  324. package/pipeline/scripts/spec-consistency-gate.mjs +469 -0
  325. package/pipeline/scripts/symbol-existence-gate.mjs +450 -0
  326. package/pipeline/scripts/test-gap-scan.mjs +40 -2
  327. package/pipeline/scripts/test-integrity-gate.mjs +20 -4
  328. package/pipeline/scripts/test-strength.mjs +484 -0
  329. package/pipeline/scripts/test-summary.mjs +651 -0
  330. package/pipeline/scripts/triage-memory.mjs +49 -9
  331. package/pipeline/scripts/unattended_policy.py +2786 -0
  332. package/pipeline/scripts/uninstall.mjs +10 -10
  333. package/pipeline/scripts/update-issue-progress.sh +1 -1
  334. package/pipeline/scripts/usage-identity.mjs +288 -0
  335. package/pipeline/scripts/usage-register.mjs +185 -65
  336. package/pipeline/scripts/usage-report.mjs +230 -66
  337. package/pipeline/scripts/validate-complaint-doc.mjs +28 -10
  338. package/pipeline/scripts/validate-planning.mjs +6 -0
  339. package/pipeline/scripts/verify-citations.mjs +151 -38
  340. package/pipeline/scripts/verify.mjs +58 -18
  341. package/pipeline/scripts/worktree-prepare.sh +126 -0
  342. package/pipeline/scripts/worktrees.mjs +124 -0
  343. package/pipeline/scripts/write-state.mjs +48 -17
  344. package/pipeline/skills/.skill-manifest.json +222 -226
  345. package/pipeline/skills/.skills-index.json +77 -88
  346. package/pipeline/skills/shared/README.md +44 -45
  347. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +3 -2
  348. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +3 -2
  349. package/pipeline/skills/shared/core/multi-agent/SKILL.md +10 -9
  350. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +6 -5
  351. package/pipeline/skills/shared/core/multi-agent-analysis-jira/SKILL.md +11 -3
  352. package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +2 -1
  353. package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +4 -3
  354. package/pipeline/skills/shared/core/multi-agent-autopilot-off/SKILL.md +32 -6
  355. package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +66 -8
  356. package/pipeline/skills/shared/core/multi-agent-autopilot-status/SKILL.md +27 -9
  357. package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +2 -1
  358. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +7 -4
  359. package/pipeline/skills/shared/core/multi-agent-complaint-analysis/SKILL.md +3 -2
  360. package/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md +2 -1
  361. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +7 -5
  362. package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +2 -1
  363. package/pipeline/skills/shared/core/multi-agent-doctor/SKILL.md +3 -2
  364. package/pipeline/skills/shared/core/multi-agent-feedback/SKILL.md +2 -1
  365. package/pipeline/skills/shared/core/multi-agent-forget/SKILL.md +2 -1
  366. package/pipeline/skills/shared/core/multi-agent-garbage-collect/SKILL.md +2 -1
  367. package/pipeline/skills/shared/core/multi-agent-graph/SKILL.md +2 -1
  368. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +2 -1
  369. package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +2 -1
  370. package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +3 -2
  371. package/pipeline/skills/shared/core/multi-agent-jira/SKILL.md +2 -1
  372. package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +7 -4
  373. package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +2 -1
  374. package/pipeline/skills/shared/core/multi-agent-log/SKILL.md +2 -1
  375. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +2 -1
  376. package/pipeline/skills/shared/core/multi-agent-model/SKILL.md +2 -1
  377. package/pipeline/skills/shared/core/multi-agent-prune-logs/SKILL.md +2 -1
  378. package/pipeline/skills/shared/core/multi-agent-prune-prompts/SKILL.md +2 -1
  379. package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +2 -1
  380. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +2 -1
  381. package/pipeline/skills/shared/core/multi-agent-research/SKILL.md +35 -0
  382. package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +7 -3
  383. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +7 -5
  384. package/pipeline/skills/shared/core/multi-agent-review-analysis/SKILL.md +2 -1
  385. package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +3 -2
  386. package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +2 -1
  387. package/pipeline/skills/shared/core/multi-agent-route-off/SKILL.md +2 -1
  388. package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +2 -1
  389. package/pipeline/skills/shared/core/multi-agent-route-status/SKILL.md +2 -1
  390. package/pipeline/skills/shared/core/multi-agent-routines/SKILL.md +2 -1
  391. package/pipeline/skills/shared/core/multi-agent-save/SKILL.md +3 -2
  392. package/pipeline/skills/shared/core/multi-agent-scaffold/SKILL.md +30 -0
  393. package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +2 -1
  394. package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +4 -3
  395. package/pipeline/skills/shared/core/multi-agent-security-review/SKILL.md +2 -1
  396. package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +60 -0
  397. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +8 -8
  398. package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +2 -1
  399. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +7 -8
  400. package/pipeline/skills/shared/core/multi-agent-steer/SKILL.md +2 -1
  401. package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +2 -1
  402. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +10 -10
  403. package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +2 -1
  404. package/pipeline/skills/shared/core/multi-agent-test-accessibility/SKILL.md +2 -1
  405. package/pipeline/skills/shared/core/multi-agent-test-dark-mode/SKILL.md +2 -1
  406. package/pipeline/skills/shared/core/multi-agent-test-dynamic-type/SKILL.md +2 -1
  407. package/pipeline/skills/shared/core/multi-agent-test-screenshots/SKILL.md +2 -1
  408. package/pipeline/skills/shared/core/multi-agent-testflight-validation/SKILL.md +2 -1
  409. package/pipeline/skills/shared/core/multi-agent-uninstall/SKILL.md +3 -2
  410. package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +2 -1
  411. package/pipeline/skills/shared/external/NOTICE-avdlee-swiftui-agent-skill.md +46 -0
  412. package/pipeline/skills/shared/external/NOTICE-dimillian-skills.md +9 -3
  413. package/pipeline/skills/shared/external/NOTICE-paul-hudson-skills.md +54 -0
  414. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +9 -11
  415. package/pipeline/skills/shared/external/NOTICE-vibeship-spawner-skills.md +203 -0
  416. package/pipeline/skills/shared/external/NOTICE-xcode-build-skills.md +10 -3
  417. package/pipeline/skills/shared/external/accessibility-compliance-accessibility-audit/SKILL.md +131 -25
  418. package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +4 -3
  419. package/pipeline/skills/shared/external/alarmkit/SKILL.md +2 -1
  420. package/pipeline/skills/shared/external/android-architecture/SKILL.md +85 -76
  421. package/pipeline/skills/shared/external/android-build-quality-gates/SKILL.md +51 -3
  422. package/pipeline/skills/shared/external/android-build-quality-gates/references/patterns.md +9 -0
  423. package/pipeline/skills/shared/external/android-datastore/SKILL.md +4 -3
  424. package/pipeline/skills/shared/external/android-design-tokens-codegen/SKILL.md +4 -3
  425. package/pipeline/skills/shared/external/android-jetpack-compose-expert/SKILL.md +106 -181
  426. package/pipeline/skills/shared/external/android-jetpack-compose-expert/references/patterns.md +147 -0
  427. package/pipeline/skills/shared/external/android-mvi-viewmodel/SKILL.md +45 -4
  428. package/pipeline/skills/shared/external/android-performance/SKILL.md +27 -2
  429. package/pipeline/skills/shared/external/android-performance/references/patterns.md +37 -37
  430. package/pipeline/skills/shared/external/api-patterns/SKILL.md +111 -67
  431. package/pipeline/skills/shared/external/api-patterns/references/contract-details.md +128 -0
  432. package/pipeline/skills/shared/external/api-security-best-practices/SKILL.md +136 -186
  433. package/pipeline/skills/shared/external/api-security-best-practices/references/abuse-controls.md +140 -0
  434. package/pipeline/skills/shared/external/api-security-best-practices/references/identity-and-access.md +207 -0
  435. package/pipeline/skills/shared/external/api-security-best-practices/references/operations.md +66 -0
  436. package/pipeline/skills/shared/external/api-security-best-practices/references/request-handling.md +175 -0
  437. package/pipeline/skills/shared/external/app-clips/SKILL.md +2 -0
  438. package/pipeline/skills/shared/external/app-intents/SKILL.md +2 -0
  439. package/pipeline/skills/shared/external/app-store-changelog/SKILL.md +4 -3
  440. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +2 -0
  441. package/pipeline/skills/shared/external/app-store-review/SKILL.md +2 -0
  442. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +2 -0
  443. package/pipeline/skills/shared/external/architecture/SKILL.md +106 -39
  444. package/pipeline/skills/shared/external/architecture/references/adr-and-review.md +76 -0
  445. package/pipeline/skills/shared/external/authentication/SKILL.md +2 -0
  446. package/pipeline/skills/shared/external/avkit/SKILL.md +2 -0
  447. package/pipeline/skills/shared/external/background-processing/SKILL.md +2 -1
  448. package/pipeline/skills/shared/external/backlog/SKILL.md +3 -2
  449. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +2 -0
  450. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +1 -1
  451. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +3 -2
  452. package/pipeline/skills/shared/external/clean-code/SKILL.md +192 -90
  453. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +2 -1
  454. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +1 -1
  455. package/pipeline/skills/shared/external/compose-components/SKILL.md +4 -4
  456. package/pipeline/skills/shared/external/compose-navigation/SKILL.md +22 -22
  457. package/pipeline/skills/shared/external/compose-navigation/references/patterns.md +10 -10
  458. package/pipeline/skills/shared/external/compose-testing/SKILL.md +13 -6
  459. package/pipeline/skills/shared/external/compose-testing/references/patterns.md +59 -59
  460. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +2 -0
  461. package/pipeline/skills/shared/external/context-compression/SKILL.md +118 -250
  462. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +2 -0
  463. package/pipeline/skills/shared/external/core-data/SKILL.md +2 -0
  464. package/pipeline/skills/shared/external/core-motion/SKILL.md +2 -0
  465. package/pipeline/skills/shared/external/core-nfc/SKILL.md +2 -0
  466. package/pipeline/skills/shared/external/coreml/SKILL.md +2 -1
  467. package/pipeline/skills/shared/external/council/SKILL.md +2 -1
  468. package/pipeline/skills/shared/external/cryptokit/SKILL.md +2 -0
  469. package/pipeline/skills/shared/external/css-modern/SKILL.md +3 -2
  470. package/pipeline/skills/shared/external/database-patterns/SKILL.md +3 -2
  471. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +2 -0
  472. package/pipeline/skills/shared/external/debugging-strategies/SKILL.md +130 -20
  473. package/pipeline/skills/shared/external/debugging-strategies/references/hard-cases.md +54 -0
  474. package/pipeline/skills/shared/external/device-integrity/SKILL.md +2 -0
  475. package/pipeline/skills/shared/external/docker-expert/SKILL.md +137 -381
  476. package/pipeline/skills/shared/external/docker-expert/references/patterns.md +98 -0
  477. package/pipeline/skills/shared/external/energykit/SKILL.md +2 -1
  478. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +3 -1
  479. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +2 -2
  480. package/pipeline/skills/shared/external/fastapi-pro/SKILL.md +116 -185
  481. package/pipeline/skills/shared/external/fastapi-pro/references/app-structure.md +235 -0
  482. package/pipeline/skills/shared/external/fastapi-pro/references/testing-and-deployment.md +69 -0
  483. package/pipeline/skills/shared/external/firebase/SKILL.md +4 -3
  484. package/pipeline/skills/shared/external/github-actions-templates/SKILL.md +151 -293
  485. package/pipeline/skills/shared/external/github-actions-templates/references/patterns.md +96 -0
  486. package/pipeline/skills/shared/external/healthkit/SKILL.md +2 -0
  487. package/pipeline/skills/shared/external/hig-components-content/SKILL.md +69 -72
  488. package/pipeline/skills/shared/external/hig-components-content/references/content-views.md +111 -0
  489. package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +77 -86
  490. package/pipeline/skills/shared/external/hig-components-layout/references/containers.md +98 -0
  491. package/pipeline/skills/shared/external/hig-components-status/SKILL.md +150 -78
  492. package/pipeline/skills/shared/external/hig-components-system/SKILL.md +76 -97
  493. package/pipeline/skills/shared/external/hig-components-system/references/surfaces.md +98 -0
  494. package/pipeline/skills/shared/external/hig-foundations/SKILL.md +48 -76
  495. package/pipeline/skills/shared/external/hig-foundations/references/foundations-detail.md +132 -0
  496. package/pipeline/skills/shared/external/hig-inputs/SKILL.md +147 -106
  497. package/pipeline/skills/shared/external/hig-patterns/SKILL.md +61 -77
  498. package/pipeline/skills/shared/external/hig-patterns/references/patterns.md +92 -0
  499. package/pipeline/skills/shared/external/hig-platforms/SKILL.md +147 -77
  500. package/pipeline/skills/shared/external/hig-technologies/SKILL.md +61 -121
  501. package/pipeline/skills/shared/external/hig-technologies/references/technologies.md +108 -0
  502. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +2 -0
  503. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +1 -1
  504. package/pipeline/skills/shared/external/html-semantic/SKILL.md +3 -2
  505. package/pipeline/skills/shared/external/humanizer/SKILL.md +2 -1
  506. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +2 -0
  507. package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +2 -1
  508. package/pipeline/skills/shared/external/ios-coding-standard/references/STANDARD.md +14 -2
  509. package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +2 -2
  510. package/pipeline/skills/shared/external/ios-debugger-agent/SKILL.md +4 -3
  511. package/pipeline/skills/shared/external/ios-localization/SKILL.md +8 -6
  512. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +2 -2
  513. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +11 -11
  514. package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +2 -1
  515. package/pipeline/skills/shared/external/ios-networking/SKILL.md +2 -0
  516. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +2 -0
  517. package/pipeline/skills/shared/external/kotlin-coroutines-expert/SKILL.md +102 -193
  518. package/pipeline/skills/shared/external/kotlin-coroutines-expert/references/patterns.md +103 -0
  519. package/pipeline/skills/shared/external/live-activities/SKILL.md +4 -2
  520. package/pipeline/skills/shared/external/live-activities/evals/evals.json +2 -2
  521. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +7 -9
  522. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +3 -3
  523. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +2 -2
  524. package/pipeline/skills/shared/external/macos-menubar-tuist-app/SKILL.md +4 -3
  525. package/pipeline/skills/shared/external/macos-spm-app-packaging/SKILL.md +5 -3
  526. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +2 -0
  527. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +1 -1
  528. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +2 -0
  529. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +1 -1
  530. package/pipeline/skills/shared/external/monorepo-architect/SKILL.md +149 -46
  531. package/pipeline/skills/shared/external/monorepo-architect/references/patterns.md +70 -0
  532. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +2 -0
  533. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +1 -1
  534. package/pipeline/skills/shared/external/natural-language/SKILL.md +2 -0
  535. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +3 -2
  536. package/pipeline/skills/shared/external/nodejs-backend-patterns/SKILL.md +91 -21
  537. package/pipeline/skills/shared/external/nodejs-backend-patterns/references/runtime-patterns.md +247 -0
  538. package/pipeline/skills/shared/external/nodejs-backend-patterns/references/testing-and-frameworks.md +57 -0
  539. package/pipeline/skills/shared/external/observability-engineer/SKILL.md +155 -232
  540. package/pipeline/skills/shared/external/observability-engineer/references/patterns.md +75 -0
  541. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +2 -0
  542. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +2 -2
  543. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +18 -18
  544. package/pipeline/skills/shared/external/pdfkit/SKILL.md +2 -1
  545. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +2 -0
  546. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +1 -1
  547. package/pipeline/skills/shared/external/permissionkit/SKILL.md +2 -0
  548. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +2 -1
  549. package/pipeline/skills/shared/external/push-notifications/SKILL.md +2 -0
  550. package/pipeline/skills/shared/external/python-patterns/SKILL.md +3 -2
  551. package/pipeline/skills/shared/external/react-best-practices/SKILL.md +3 -2
  552. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +2 -2
  553. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +1 -1
  554. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +3 -2
  555. package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +7 -7
  556. package/pipeline/skills/shared/external/retrofit-networking/references/patterns.md +69 -69
  557. package/pipeline/skills/shared/external/room-database/references/patterns.md +126 -126
  558. package/pipeline/skills/shared/external/search-first/SKILL.md +2 -1
  559. package/pipeline/skills/shared/external/security-review/SKILL.md +4 -3
  560. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +2 -2
  561. package/pipeline/skills/shared/external/signal-community/SKILL.md +1 -1
  562. package/pipeline/skills/shared/external/skill-creator/SKILL.md +2 -1
  563. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +2 -1
  564. package/pipeline/skills/shared/external/spm-build-analysis/SKILL.md +2 -0
  565. package/pipeline/skills/shared/external/storekit/SKILL.md +2 -0
  566. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +2 -0
  567. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +2 -1
  568. package/pipeline/skills/shared/external/swift-charts/SKILL.md +2 -1
  569. package/pipeline/skills/shared/external/swift-codable/SKILL.md +2 -0
  570. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +3 -1
  571. package/pipeline/skills/shared/external/swift-concurrency-expert/SKILL.md +5 -4
  572. package/pipeline/skills/shared/external/swift-concurrency-pro/SKILL.md +2 -1
  573. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +2 -0
  574. package/pipeline/skills/shared/external/swift-language/SKILL.md +3 -1
  575. package/pipeline/skills/shared/external/swift-security/SKILL.md +2 -1
  576. package/pipeline/skills/shared/external/swift-testing/SKILL.md +2 -0
  577. package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +2 -1
  578. package/pipeline/skills/shared/external/swift-testing-pro/references/new-features.md +10 -0
  579. package/pipeline/skills/shared/external/swiftdata/SKILL.md +2 -0
  580. package/pipeline/skills/shared/external/swiftdata-pro/SKILL.md +2 -1
  581. package/pipeline/skills/shared/external/swiftlint/SKILL.md +2 -0
  582. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +2 -0
  583. package/pipeline/skills/shared/external/swiftui-expert-skill/SKILL.md +3 -1
  584. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +2 -0
  585. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +2 -0
  586. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +2 -0
  587. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +2 -0
  588. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +3 -1
  589. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +3 -1
  590. package/pipeline/skills/shared/external/swiftui-performance-audit/SKILL.md +5 -4
  591. package/pipeline/skills/shared/external/swiftui-pro/SKILL.md +2 -1
  592. package/pipeline/skills/shared/external/swiftui-ui-patterns/SKILL.md +5 -4
  593. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +2 -0
  594. package/pipeline/skills/shared/external/swiftui-view-refactor/SKILL.md +4 -3
  595. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +2 -0
  596. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +3 -2
  597. package/pipeline/skills/shared/external/testing-backend/SKILL.md +3 -2
  598. package/pipeline/skills/shared/external/tipkit/SKILL.md +2 -0
  599. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +3 -2
  600. package/pipeline/skills/shared/external/vision-framework/SKILL.md +2 -0
  601. package/pipeline/skills/shared/external/vue-composition/SKILL.md +3 -2
  602. package/pipeline/skills/shared/external/weatherkit/SKILL.md +2 -0
  603. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +3 -2
  604. package/pipeline/skills/shared/external/web-performance/SKILL.md +3 -2
  605. package/pipeline/skills/shared/external/web-testing/SKILL.md +3 -2
  606. package/pipeline/skills/shared/external/widgetkit/SKILL.md +2 -0
  607. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +1 -1
  608. package/pipeline/skills/shared/external/xcode-build-benchmark/SKILL.md +2 -0
  609. package/pipeline/skills/shared/external/xcode-build-fixer/SKILL.md +2 -0
  610. package/pipeline/skills/shared/external/xcode-build-orchestrator/SKILL.md +2 -0
  611. package/pipeline/skills/shared/external/xcode-compilation-analyzer/SKILL.md +2 -0
  612. package/pipeline/skills/shared/external/xcode-project-analyzer/SKILL.md +2 -0
  613. package/pipeline/skills/skills-index.md +40 -41
  614. package/docs/token-budget-history.md +0 -24
  615. package/pipeline/skills/shared/external/agentflow/SKILL.md +0 -199
  616. package/pipeline/skills/shared/external/android-ui-verification/SKILL.md +0 -66
  617. package/pipeline/skills/shared/external/api-security-best-practices/references/auth.md +0 -299
  618. package/pipeline/skills/shared/external/api-security-best-practices/references/input-validation.md +0 -255
  619. package/pipeline/skills/shared/external/api-security-best-practices/references/rate-limiting.md +0 -167
  620. package/pipeline/skills/shared/external/closed-loop-delivery/SKILL.md +0 -116
  621. package/pipeline/skills/shared/external/ios-developer/SKILL.md +0 -216
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * autopilot-awake.mjs - the launchd job that keeps the Mac awake while
4
+ * autopilot is on.
5
+ *
6
+ * The schedule's StartInterval does not wake a sleeping Mac. The in-flight lock
7
+ * (`caffeinate -s -w <runner pid>`, _autopilot-ops.mjs) covers a run while it is
8
+ * going, and nothing covers the gap between ticks: the machine sleeps, the next
9
+ * tick never fires, and the queue stops with nothing to say so. This job closes
10
+ * that gap. It is a second, separate launchd agent that runs
11
+ * `/usr/bin/caffeinate -s -i` (plus `-d` with `awake.display: true`) for as long
12
+ * as it is loaded, and it is loaded exactly while the mode is on.
13
+ *
14
+ * render [--display|--no-display] print the plist
15
+ * install [--display|--no-display] write it into LaunchAgents and load it;
16
+ * without a flag, awake.display from the
17
+ * config decides. awake.enabled: false
18
+ * removes the job instead.
19
+ * remove unload it and delete the plist
20
+ * status [--json] { held, display }
21
+ *
22
+ * Injectable for tests: MA_AP_LAUNCH_AGENTS (the LaunchAgents dir),
23
+ * MA_AP_LAUNCHCTL_BIN, MA_AP_PS_BIN, MA_AP_AWAKE_TEMPLATE, MA_AUTOPILOT_ROOT.
24
+ *
25
+ * Exit: 0 on success, 1 when launchd refused the job, 2 on usage.
26
+ */
27
+
28
+ import { spawnSync } from "node:child_process";
29
+ import {
30
+ chmodSync,
31
+ existsSync,
32
+ mkdirSync,
33
+ readFileSync,
34
+ renameSync,
35
+ rmSync,
36
+ writeFileSync,
37
+ } from "node:fs";
38
+ import { homedir } from "node:os";
39
+ import { dirname, join } from "node:path";
40
+ import { fileURLToPath } from "node:url";
41
+ import { invokedDirectly } from "../lib/invoked-directly.mjs";
42
+
43
+ export const AWAKE_LABEL = "com.multi-agent.autopilot-awake";
44
+ export const CAFFEINATE = "/usr/bin/caffeinate";
45
+ const TEMPLATE_NAME = "multi-agent-autopilot-awake.plist.template";
46
+ const HERE = dirname(fileURLToPath(import.meta.url));
47
+ const LAUNCHCTL_TIMEOUT_MS = 15000;
48
+
49
+ function home(env) {
50
+ return env.HOME || homedir();
51
+ }
52
+
53
+ function readJson(p) {
54
+ try {
55
+ return JSON.parse(readFileSync(p, "utf-8"));
56
+ } catch {
57
+ return null;
58
+ }
59
+ }
60
+
61
+ /** The config's `awake` block with its defaults: on, display allowed to sleep. */
62
+ export function awakeSettings(config) {
63
+ const a = config?.awake;
64
+ return { enabled: a?.enabled !== false, display: a?.display === true };
65
+ }
66
+
67
+ /**
68
+ * `-s` holds system sleep off and macOS honours it on AC only; `-i` holds idle
69
+ * sleep off on battery as well; `-d` keeps the display on and is opt-in,
70
+ * because nothing autopilot runs needs a lit screen.
71
+ */
72
+ export function caffeinateArgs({ display = false } = {}) {
73
+ return display ? ["-s", "-i", "-d"] : ["-s", "-i"];
74
+ }
75
+
76
+ /** The installed tree keeps templates/ beside scripts/; the repo keeps it in install/. */
77
+ export function templatePath(env = process.env) {
78
+ const candidates = [
79
+ env.MA_AP_AWAKE_TEMPLATE,
80
+ join(HERE, "..", "templates", TEMPLATE_NAME),
81
+ join(HERE, "..", "..", "install", "templates", TEMPLATE_NAME),
82
+ ...[".claude", ".copilot", ".codex"].map((d) => join(home(env), d, "templates", TEMPLATE_NAME)),
83
+ ].filter(Boolean);
84
+ return candidates.find((p) => existsSync(p)) || null;
85
+ }
86
+
87
+ function xmlEscape(s) {
88
+ return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
89
+ }
90
+
91
+ export function renderAwakePlist({ display = false, label = AWAKE_LABEL, env = process.env } = {}) {
92
+ const tpl = templatePath(env);
93
+ if (!tpl) throw new Error(`${TEMPLATE_NAME} is not installed - re-run the installer`);
94
+ const args = [CAFFEINATE, ...caffeinateArgs({ display })]
95
+ .map((a) => ` <string>${xmlEscape(a)}</string>`)
96
+ .join("\n");
97
+ return readFileSync(tpl, "utf-8")
98
+ .replace(/\{\{LABEL\}\}/g, xmlEscape(label))
99
+ .replace(/\{\{ARGS\}\}/g, args);
100
+ }
101
+
102
+ export function launchAgentsDir(env = process.env) {
103
+ return env.MA_AP_LAUNCH_AGENTS || join(home(env), "Library", "LaunchAgents");
104
+ }
105
+
106
+ export function awakePlistPath(env = process.env) {
107
+ return join(launchAgentsDir(env), `${AWAKE_LABEL}.plist`);
108
+ }
109
+
110
+ function autopilotConfig(env) {
111
+ const root = env.MA_AUTOPILOT_ROOT || join(home(env), ".claude", "autopilot");
112
+ return readJson(join(root, "config.json"));
113
+ }
114
+
115
+ function launchctl(args, env) {
116
+ const r = spawnSync(env.MA_AP_LAUNCHCTL_BIN || "launchctl", args, {
117
+ encoding: "utf-8",
118
+ stdio: ["ignore", "pipe", "pipe"],
119
+ timeout: LAUNCHCTL_TIMEOUT_MS,
120
+ });
121
+ return { ok: !r.error && r.status === 0, stdout: String(r.stdout || "") };
122
+ }
123
+
124
+ function domain() {
125
+ return `gui/${process.getuid()}`;
126
+ }
127
+
128
+ /** Unload the job and delete its plist. Absent is success. */
129
+ export function removeAwake({ env = process.env } = {}) {
130
+ const path = awakePlistPath(env);
131
+ if (!launchctl(["bootout", `${domain()}/${AWAKE_LABEL}`], env).ok && existsSync(path)) {
132
+ launchctl(["unload", path], env);
133
+ }
134
+ rmSync(path, { force: true });
135
+ return { path, removed: true };
136
+ }
137
+
138
+ /**
139
+ * Write the plist and load it. A job already loaded is booted out first, so a
140
+ * changed display answer takes effect now rather than at the next login.
141
+ *
142
+ * @returns {{path:string|null, loaded:boolean, display:boolean, enabled:boolean}}
143
+ */
144
+ export function installAwake({ env = process.env, display } = {}) {
145
+ const settings = awakeSettings(autopilotConfig(env));
146
+ if (!settings.enabled) {
147
+ removeAwake({ env });
148
+ return { path: null, loaded: false, display: false, enabled: false };
149
+ }
150
+ const shown = typeof display === "boolean" ? display : settings.display;
151
+ const xml = renderAwakePlist({ display: shown, env });
152
+ const path = awakePlistPath(env);
153
+ mkdirSync(dirname(path), { recursive: true });
154
+ const tmp = `${path}.${process.pid}.tmp`;
155
+ writeFileSync(tmp, xml, { mode: 0o644 });
156
+ chmodSync(tmp, 0o644);
157
+ launchctl(["bootout", `${domain()}/${AWAKE_LABEL}`], env);
158
+ renameSync(tmp, path);
159
+ const loaded =
160
+ launchctl(["bootstrap", domain(), path], env).ok || launchctl(["load", path], env).ok;
161
+ return { path, loaded, display: shown, enabled: true };
162
+ }
163
+
164
+ /** `caffeinate -s -i [-d]` and nothing after it: the in-flight lock carries `-w <pid>`. */
165
+ const AWAKE_PS = /(^|\/)caffeinate -s -i( -d)?\s*$/;
166
+
167
+ /**
168
+ * Held when launchd reports a running PID for the label, or, when launchd
169
+ * cannot say, when a `caffeinate -s -i` process is running. The display answer
170
+ * comes from the installed plist, else from that process's arguments.
171
+ *
172
+ * @returns {{held:boolean, display:boolean}}
173
+ */
174
+ export function awakeStatus({ env = process.env } = {}) {
175
+ const path = awakePlistPath(env);
176
+ let plistDisplay = null;
177
+ if (existsSync(path)) {
178
+ try {
179
+ plistDisplay = /<string>-d<\/string>/.test(readFileSync(path, "utf-8"));
180
+ } catch {
181
+ plistDisplay = null;
182
+ }
183
+ }
184
+ const listed = launchctl(["list", AWAKE_LABEL], env);
185
+ if (listed.ok && /"PID"\s*=\s*\d+/.test(listed.stdout)) {
186
+ return { held: true, display: plistDisplay === true };
187
+ }
188
+ const ps = spawnSync(env.MA_AP_PS_BIN || "ps", ["-axo", "command="], {
189
+ encoding: "utf-8",
190
+ stdio: ["ignore", "pipe", "ignore"],
191
+ timeout: LAUNCHCTL_TIMEOUT_MS,
192
+ });
193
+ const line = String(ps.stdout || "")
194
+ .split("\n")
195
+ .map((l) => l.trim().replace(/^\d+\s+/, ""))
196
+ .find((l) => AWAKE_PS.test(l));
197
+ if (line) return { held: true, display: plistDisplay ?? / -d\s*$/.test(line) };
198
+ return { held: false, display: plistDisplay === true };
199
+ }
200
+
201
+ function displayFlag(args) {
202
+ if (args.includes("--display")) return true;
203
+ if (args.includes("--no-display")) return false;
204
+ return undefined;
205
+ }
206
+
207
+ function main(argv) {
208
+ const [cmd, ...rest] = argv;
209
+ const env = process.env;
210
+ switch (cmd) {
211
+ case "render":
212
+ process.stdout.write(renderAwakePlist({ display: displayFlag(rest) === true, env }));
213
+ return 0;
214
+ case "install": {
215
+ const r = installAwake({ env, display: displayFlag(rest) });
216
+ if (!r.enabled) {
217
+ console.log("awake: disabled in the config (awake.enabled: false) - no job installed");
218
+ return 0;
219
+ }
220
+ if (!r.loaded) {
221
+ console.error(`awake: launchd refused ${r.path}`);
222
+ return 1;
223
+ }
224
+ console.log(`awake: ${r.path} loaded (display ${r.display ? "kept on" : "may sleep"})`);
225
+ return 0;
226
+ }
227
+ case "remove":
228
+ removeAwake({ env });
229
+ console.log(`awake: ${AWAKE_LABEL} removed`);
230
+ return 0;
231
+ case "status": {
232
+ const s = awakeStatus({ env });
233
+ if (rest.includes("--json")) console.log(JSON.stringify(s));
234
+ else
235
+ console.log(
236
+ `awake: ${s.held ? "held" : "not held"}, display ${s.display ? "on" : "may sleep"}`,
237
+ );
238
+ return 0;
239
+ }
240
+ default:
241
+ console.error(
242
+ "usage: autopilot-awake.mjs {render|install|remove|status} [--display|--no-display|--json]",
243
+ );
244
+ return 2;
245
+ }
246
+ }
247
+
248
+ if (invokedDirectly(import.meta.url)) {
249
+ try {
250
+ process.exitCode = main(process.argv.slice(2));
251
+ } catch (e) {
252
+ console.error(`awake: ${e?.message || e}`);
253
+ process.exitCode = 1;
254
+ }
255
+ }
@@ -32,7 +32,9 @@
32
32
  *
33
33
  * Exit: 0 always when it can read its own state. An empty queue is an answer,
34
34
  * not an error - "no item carries the label yet" is the single most common
35
- * reason nothing is happening and it is not a fault.
35
+ * reason nothing is happening and it is not a fault. 3 when config.json breaks
36
+ * autopilot-config.schema.json: queue.json then holds no queued item and a
37
+ * `blockedReason` naming the field.
36
38
  */
37
39
 
38
40
  import { execFileSync } from "node:child_process";
@@ -40,6 +42,8 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync, renameSync, chmodSy
40
42
  import { join, dirname } from "node:path";
41
43
  import { homedir } from "node:os";
42
44
  import { invokedDirectly } from "../lib/invoked-directly.mjs";
45
+ import { OUTCOME, isParked, isRetryable, isTerminal } from "./_autopilot-outcomes.mjs";
46
+ import { configRefusal } from "./_autopilot-config.mjs";
43
47
 
44
48
  const ROOT = process.env.MA_AUTOPILOT_ROOT || join(homedir(), ".claude", "autopilot");
45
49
 
@@ -55,16 +59,13 @@ const PRIORITY = {
55
59
  lowest: 10,
56
60
  };
57
61
 
58
- /**
59
- * An outcome that means the item is finished with us. Anything not listed is
60
- * either retryable or a waiting state, and the difference matters: treating
61
- * `died` as terminal drops an item because a laptop lid closed once.
62
+ /*
63
+ * What an outcome means - finished, worth another attempt, or waiting for a
64
+ * person - is _autopilot-outcomes.mjs, the one contract the runner writes and
65
+ * this file reads. A `blocked-*` outcome is none of the three: the token being
66
+ * expired is not the item's fault, and it becomes workable again the moment the
67
+ * token is replaced, so it is queued again without counting an attempt.
62
68
  */
63
- const TERMINAL = new Set(["pr-opened", "merged", "skipped"]);
64
- /** Counted against `maxAttempts`. A credential block is NOT one of these - the
65
- * token being expired is not the item's fault, and it becomes workable again
66
- * the moment the token is replaced. */
67
- const RETRYABLE = new Set(["died", "build-failed"]);
68
69
 
69
70
  export function priorityScore(name) {
70
71
  if (!name) return 0;
@@ -137,7 +138,14 @@ export function orderQueue(items, { maxConsecutivePerRepo = 5 } = {}) {
137
138
  return out;
138
139
  }
139
140
 
140
- /** Attempt history, folded into one record per item. */
141
+ /**
142
+ * Attempt history, folded into one record per item.
143
+ *
144
+ * Every RETRYABLE outcome counts toward `maxAttempts`, and counts ONCE per run:
145
+ * a run whose supervision timed out is recorded as `timed-out`, and when a
146
+ * later tick retires it the same run is recorded again as `died`. Both carry
147
+ * the runner's `taskId`, which is what makes them one attempt and not two.
148
+ */
141
149
  export function foldAttempts(lines) {
142
150
  const byKey = new Map();
143
151
  for (const raw of lines) {
@@ -150,8 +158,14 @@ export function foldAttempts(lines) {
150
158
  continue; // a truncated last line is normal on an append-only log
151
159
  }
152
160
  const key = `${rec.source}:${rec.id}`;
153
- const cur = byKey.get(key) || { attempts: 0, last: null, usd: 0, at: 0 };
154
- if (RETRYABLE.has(rec.outcome)) cur.attempts += 1;
161
+ const cur = byKey.get(key) || { attempts: 0, last: null, usd: 0, at: 0, runs: new Set() };
162
+ if (isRetryable(rec.outcome)) {
163
+ if (!rec.taskId) cur.attempts += 1;
164
+ else if (!cur.runs.has(rec.taskId)) {
165
+ cur.runs.add(rec.taskId);
166
+ cur.attempts += 1;
167
+ }
168
+ }
155
169
  cur.usd += Number(rec.usd || 0);
156
170
  if ((rec.at || 0) >= cur.at) {
157
171
  cur.at = rec.at || 0;
@@ -164,6 +178,18 @@ export function foldAttempts(lines) {
164
178
  return byKey;
165
179
  }
166
180
 
181
+ /**
182
+ * The key a GitHub item was recorded under when its id carried only the short
183
+ * repo name (`app#5`). Read as a fallback so an item finished under the old id
184
+ * is not queued again; where two repos share the short name this errs toward
185
+ * leaving the item alone, never toward running it twice.
186
+ */
187
+ function legacyKey(c) {
188
+ if (c?.source !== "github" || typeof c.id !== "string") return null;
189
+ const m = /^[^/#]+\/([^/#]+)#(\d+)$/.exec(c.id);
190
+ return m ? `github:${m[1]}#${m[2]}` : null;
191
+ }
192
+
167
193
  /**
168
194
  * Which candidates may enter the queue, and WHY each excluded one was excluded.
169
195
  * Every drop carries a reason: a queue that silently shortens is the thing that
@@ -174,17 +200,24 @@ export function selectable(candidates, history, { maxAttempts = 2 } = {}) {
174
200
  const awaiting = [];
175
201
  const dropped = [];
176
202
  for (const c of candidates) {
177
- const h = history.get(`${c.source}:${c.id}`);
203
+ const h = history.get(`${c.source}:${c.id}`) ?? history.get(legacyKey(c));
178
204
  if (!h) {
179
205
  queued.push(c);
180
206
  continue;
181
207
  }
182
- if (TERMINAL.has(h.last)) {
208
+ if (isTerminal(h.last)) {
183
209
  dropped.push({ ...c, reason: `already ${h.last}`, prUrl: h.prUrl });
184
210
  continue;
185
211
  }
186
- if (h.last === "awaiting-answer") {
187
- awaiting.push({ ...c, askedAt: h.at, gapFingerprint: h.gapFingerprint });
212
+ // Parked for a person: never re-run on its own. `awaiting-answer` is the
213
+ // maturity question; the others wait just the same, and say why.
214
+ if (isParked(h.last)) {
215
+ awaiting.push({
216
+ ...c,
217
+ askedAt: h.at,
218
+ gapFingerprint: h.gapFingerprint,
219
+ ...(h.last === OUTCOME.AWAITING_ANSWER ? {} : { waitingOn: h.last }),
220
+ });
188
221
  continue;
189
222
  }
190
223
  if (h.attempts >= maxAttempts) {
@@ -234,10 +267,21 @@ function fetchGitHub(repo) {
234
267
  } catch {
235
268
  return [];
236
269
  }
270
+ return githubCandidates(repo, rows);
271
+ }
272
+
273
+ /**
274
+ * Queue items from `gh issue list` rows. The id carries the full owner/repo:
275
+ * two repos may share a short name, and an id made from the short name alone
276
+ * would let one repo's finished issue drop the other's. `ref` stays short -
277
+ * the run is launched in the repo's own checkout, which names the repo.
278
+ */
279
+ export function githubCandidates(repo, rows) {
280
+ const label = repo.githubLabel || "agent-queue";
237
281
  const short = repo.nameWithOwner.split("/").pop();
238
- return rows.map((r) => ({
282
+ return (rows || []).map((r) => ({
239
283
  source: "github",
240
- id: `${short}#${r.number}`,
284
+ id: `${repo.nameWithOwner}#${r.number}`,
241
285
  ref: `${short}#${r.number}`,
242
286
  repo: repo.nameWithOwner,
243
287
  localPath: repo.localPath,
@@ -278,7 +322,12 @@ function fetchJira(repo) {
278
322
  } catch {
279
323
  return [];
280
324
  }
281
- return rows.map((i) => ({
325
+ return jiraCandidates(repo, rows);
326
+ }
327
+
328
+ /** Queue items from a Jira search's `issues`. The issue key is the id. */
329
+ export function jiraCandidates(repo, issues) {
330
+ return (issues || []).map((i) => ({
282
331
  source: "jira",
283
332
  id: i.key,
284
333
  ref: i.key,
@@ -292,14 +341,42 @@ function fetchJira(repo) {
292
341
  }));
293
342
  }
294
343
 
295
- function gather(config) {
344
+ /**
345
+ * Every candidate from every configured repo.
346
+ *
347
+ * A Jira issue is one item whichever repo's search returned it. The default
348
+ * JQL (assignee plus label) is the same for every repo, so without this each
349
+ * repo with Jira on would queue - and run, and open a PR for - the same issue.
350
+ * The first repo in config order takes it; each other match is returned in
351
+ * `duplicates` with the reason, so the queue says why it is not listed twice.
352
+ *
353
+ * @returns {{items: object[], duplicates: object[]}}
354
+ */
355
+ export function gather(
356
+ config,
357
+ { fetchGitHub: gh = fetchGitHub, fetchJira: jira = fetchJira } = {},
358
+ ) {
296
359
  const items = [];
360
+ const duplicates = [];
361
+ const jiraOwner = new Map();
297
362
  for (const repo of config.repos || []) {
298
363
  const sources = repo.sources || ["github"];
299
- if (sources.includes("github")) items.push(...fetchGitHub(repo));
300
- if (sources.includes("jira")) items.push(...fetchJira(repo));
364
+ if (sources.includes("github")) items.push(...gh(repo));
365
+ if (!sources.includes("jira")) continue;
366
+ for (const it of jira(repo)) {
367
+ const owner = jiraOwner.get(it.id);
368
+ if (owner === undefined) {
369
+ jiraOwner.set(it.id, it.repo);
370
+ items.push(it);
371
+ } else if (owner !== it.repo) {
372
+ duplicates.push({
373
+ ...it,
374
+ reason: `also matched for ${owner}, queued there - give each repo a jiraJql that matches only its own issues`,
375
+ });
376
+ }
377
+ }
301
378
  }
302
- return items;
379
+ return { items, duplicates };
303
380
  }
304
381
 
305
382
  // ---------------------------------------------------------------------------
@@ -313,6 +390,17 @@ function atomicWrite(name, text) {
313
390
  renameSync(tmp, dst);
314
391
  }
315
392
 
393
+ function readQueue() {
394
+ const qPath = join(ROOT, "queue.json");
395
+ if (!existsSync(qPath)) return { queued: [], running: [] };
396
+ try {
397
+ const q = JSON.parse(readFileSync(qPath, "utf-8"));
398
+ return q && typeof q === "object" && !Array.isArray(q) ? q : { queued: [], running: [] };
399
+ } catch {
400
+ return { queued: [], running: [] };
401
+ }
402
+ }
403
+
316
404
  function main(argv) {
317
405
  const args = argv.slice(2);
318
406
  const has = (f) => args.includes(f);
@@ -326,10 +414,31 @@ function main(argv) {
326
414
  }
327
415
 
328
416
  const cfgPath = join(ROOT, "config.json");
329
- const config = existsSync(cfgPath) ? JSON.parse(readFileSync(cfgPath, "utf-8")) : { repos: [] };
417
+ let config = { repos: [] };
418
+ let refusal = null;
419
+ if (existsSync(cfgPath)) {
420
+ try {
421
+ config = JSON.parse(readFileSync(cfgPath, "utf-8"));
422
+ refusal = configRefusal(config);
423
+ } catch (e) {
424
+ refusal = `autopilot config.json cannot be read: ${e?.message || e}`;
425
+ }
426
+ }
427
+ // A ceiling that is not a number compares false with everything, which would
428
+ // retry an item forever. Nothing is queued until the config is corrected.
429
+ if (refusal) {
430
+ const queue = { ...readQueue(), lastTickAt: Math.floor(Date.now() / 1000) };
431
+ queue.queued = [];
432
+ queue.blockedReason = refusal;
433
+ if (!has("--dry-run")) atomicWrite("queue.json", JSON.stringify(queue, null, 2));
434
+ process.stderr.write(`autopilot-intake: ${refusal}\n`);
435
+ return 3;
436
+ }
330
437
 
331
438
  const fromFile = val("--from");
332
- const candidates = fromFile ? JSON.parse(readFileSync(fromFile, "utf-8")) : gather(config);
439
+ const { items: candidates, duplicates } = fromFile
440
+ ? { items: JSON.parse(readFileSync(fromFile, "utf-8")), duplicates: [] }
441
+ : gather(config);
333
442
 
334
443
  const attemptPath = join(ROOT, "attempted.jsonl");
335
444
  const history = foldAttempts(
@@ -347,22 +456,14 @@ function main(argv) {
347
456
  // The existing queue's `running` list is preserved: intake decides what is
348
457
  // NEXT and has no opinion about what is already in flight. Overwriting it here
349
458
  // would make a scan look like a crash to the status reader.
350
- let running = [];
351
- const qPath = join(ROOT, "queue.json");
352
- if (existsSync(qPath)) {
353
- try {
354
- running = JSON.parse(readFileSync(qPath, "utf-8")).running || [];
355
- } catch {
356
- running = [];
357
- }
358
- }
459
+ const running = readQueue().running || [];
359
460
 
360
461
  const queue = {
361
462
  lastTickAt: Math.floor(Date.now() / 1000),
362
463
  running,
363
464
  queued: ordered,
364
465
  awaiting,
365
- dropped,
466
+ dropped: [...dropped, ...duplicates],
366
467
  emptyReason:
367
468
  ordered.length === 0 && awaiting.length === 0
368
469
  ? candidates.length === 0