@mmerterden/multi-agent-pipeline 12.6.0 → 12.8.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 (481) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/README.md +18 -18
  3. package/docs/FIGMA_PIPELINE.md +34 -34
  4. package/docs/adr/0001-three-model-triage.md +12 -12
  5. package/docs/adr/0002-instruction-driven-flag.md +5 -5
  6. package/docs/adr/0003-unified-shared-skills.md +5 -5
  7. package/docs/adr/0004-zero-dependency-philosophy.md +5 -5
  8. package/docs/adr/0005-lazy-phase-docs.md +2 -2
  9. package/docs/adr/0006-skills-core-external-split.md +6 -6
  10. package/docs/adr/0007-multi-tool-adapter-framework.md +19 -19
  11. package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +19 -19
  12. package/docs/adr/README.md +1 -1
  13. package/docs/best-practices.md +3 -3
  14. package/docs/features.md +28 -28
  15. package/docs/performance.md +16 -16
  16. package/docs/recovery-guide.md +39 -39
  17. package/index.js +4 -4
  18. package/install/_common.mjs +53 -11
  19. package/install/_copilot-instructions.mjs +2 -2
  20. package/install/_dev-only-files.mjs +126 -6
  21. package/install/_platform-filter.mjs +1 -1
  22. package/install/_telemetry.mjs +1 -1
  23. package/install/claude.mjs +20 -13
  24. package/install/copilot.mjs +11 -23
  25. package/install/index.mjs +7 -15
  26. package/install/templates/copilot-instructions.md +54 -54
  27. package/install.js +1 -1
  28. package/package.json +29 -11
  29. package/pipeline/commands/multi-agent/SKILL.md +1 -1
  30. package/pipeline/commands/multi-agent/analysis/SKILL.md +2 -2
  31. package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +1 -1
  32. package/pipeline/commands/multi-agent/autopilot/SKILL.md +1 -1
  33. package/pipeline/commands/multi-agent/build-optimize/SKILL.md +1 -1
  34. package/pipeline/commands/multi-agent/create-jira/SKILL.md +1 -1
  35. package/pipeline/commands/multi-agent/design-check/SKILL.md +1 -1
  36. package/pipeline/commands/multi-agent/dev/SKILL.md +1 -1
  37. package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +1 -1
  38. package/pipeline/commands/multi-agent/dev-local/SKILL.md +1 -1
  39. package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +1 -1
  40. package/pipeline/commands/multi-agent/diff-explain/SKILL.md +1 -1
  41. package/pipeline/commands/multi-agent/finish/SKILL.md +6 -6
  42. package/pipeline/commands/multi-agent/forget/SKILL.md +1 -1
  43. package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -1
  44. package/pipeline/commands/multi-agent/help/SKILL.md +3 -3
  45. package/pipeline/commands/multi-agent/issue/SKILL.md +1 -1
  46. package/pipeline/commands/multi-agent/jira/SKILL.md +1 -1
  47. package/pipeline/commands/multi-agent/kill/SKILL.md +1 -1
  48. package/pipeline/commands/multi-agent/language/SKILL.md +1 -1
  49. package/pipeline/commands/multi-agent/local/SKILL.md +1 -1
  50. package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +1 -1
  51. package/pipeline/commands/multi-agent/log/SKILL.md +1 -1
  52. package/pipeline/commands/multi-agent/manual-test/SKILL.md +1 -1
  53. package/pipeline/commands/multi-agent/prune-logs/SKILL.md +1 -1
  54. package/pipeline/commands/multi-agent/purge/SKILL.md +1 -1
  55. package/pipeline/commands/multi-agent/refactor/SKILL.md +16 -8
  56. package/pipeline/commands/multi-agent/resume/SKILL.md +2 -2
  57. package/pipeline/commands/multi-agent/review/SKILL.md +1 -1
  58. package/pipeline/commands/multi-agent/review-issue/SKILL.md +1 -1
  59. package/pipeline/commands/multi-agent/review-jira/SKILL.md +1 -1
  60. package/pipeline/commands/multi-agent/routines/SKILL.md +1 -1
  61. package/pipeline/commands/multi-agent/save/SKILL.md +1 -1
  62. package/pipeline/commands/multi-agent/scan/SKILL.md +1 -1
  63. package/pipeline/commands/multi-agent/search/SKILL.md +1 -1
  64. package/pipeline/commands/multi-agent/setup/SKILL.md +2 -2
  65. package/pipeline/commands/multi-agent/stack/SKILL.md +3 -3
  66. package/pipeline/commands/multi-agent/status/SKILL.md +1 -1
  67. package/pipeline/commands/multi-agent/sync/SKILL.md +5 -5
  68. package/pipeline/commands/multi-agent/test/SKILL.md +1 -1
  69. package/pipeline/commands/multi-agent/uninstall/SKILL.md +1 -1
  70. package/pipeline/commands/multi-agent/update/SKILL.md +3 -3
  71. package/pipeline/lib/account-resolver.sh +1 -1
  72. package/pipeline/lib/channels-multi-repo.sh +1 -1
  73. package/pipeline/lib/context-link-extractor.sh +1 -1
  74. package/pipeline/lib/credential-store.sh +21 -1
  75. package/pipeline/lib/fetch-confluence.sh +1 -1
  76. package/pipeline/lib/fetch-crashlytics.sh +1 -1
  77. package/pipeline/lib/fetch-fortify.sh +1 -1
  78. package/pipeline/lib/fetch-graylog.sh +1 -1
  79. package/pipeline/lib/fetch-swagger.sh +1 -1
  80. package/pipeline/lib/issue-fetcher.sh +1 -1
  81. package/pipeline/lib/multi-repo-pipeline.sh +1 -1
  82. package/pipeline/lib/repo-cache.sh +1 -1
  83. package/pipeline/lib/submodule-detector.sh +1 -1
  84. package/pipeline/multi-agent-refs/_account-picker.md +1 -1
  85. package/pipeline/multi-agent-refs/_dev-context.md +1 -1
  86. package/pipeline/multi-agent-refs/_repo-picker.md +1 -1
  87. package/pipeline/multi-agent-refs/component-dispatch.md +1 -1
  88. package/pipeline/multi-agent-refs/component-generation.md +121 -0
  89. package/pipeline/multi-agent-refs/cross-cli-contract.md +1 -1
  90. package/pipeline/multi-agent-refs/features/model-fallback.md +2 -2
  91. package/pipeline/multi-agent-refs/phases/operations.md +28 -0
  92. package/pipeline/multi-agent-refs/phases/phase-0-init.md +1 -0
  93. package/pipeline/multi-agent-refs/phases/phase-2-planning.md +1 -1
  94. package/pipeline/multi-agent-refs/phases/phase-3-dev.md +1 -2
  95. package/pipeline/multi-agent-refs/phases/phase-4-review.md +50 -5
  96. package/pipeline/preferences-template.json +5 -11
  97. package/pipeline/schemas/agent-state.schema.json +39 -9
  98. package/pipeline/schemas/analysis-output.schema.json +18 -4
  99. package/pipeline/schemas/analysis-spec.schema.json +120 -32
  100. package/pipeline/schemas/clarify-output.schema.json +15 -5
  101. package/pipeline/schemas/design-check-config.schema.json +32 -11
  102. package/pipeline/schemas/dev-critic-output.schema.json +20 -5
  103. package/pipeline/schemas/figma-project-config.schema.json +42 -10
  104. package/pipeline/schemas/learnings-ledger.schema.json +10 -2
  105. package/pipeline/schemas/migrations/figma-config-1.0.0-to-2.0.0.mjs +1 -4
  106. package/pipeline/schemas/migrations/prefs-2.0.0-to-2.1.0.mjs +24 -7
  107. package/pipeline/schemas/plan-todos.schema.json +6 -3
  108. package/pipeline/schemas/planning-output.schema.json +5 -1
  109. package/pipeline/schemas/prefs.schema.json +97 -229
  110. package/pipeline/schemas/test-gap.schema.json +5 -5
  111. package/pipeline/schemas/token-budget.json +8 -8
  112. package/pipeline/schemas/triage-corpus.schema.json +1 -1
  113. package/pipeline/scripts/_smoke-root.sh +61 -0
  114. package/pipeline/scripts/aggregate-metrics.mjs +18 -6
  115. package/pipeline/scripts/audit-log.sh +25 -0
  116. package/pipeline/scripts/build-skills-index.mjs +6 -2
  117. package/pipeline/scripts/build-stack-plugins.mjs +142 -39
  118. package/pipeline/scripts/check-derived-drift.mjs +196 -0
  119. package/pipeline/scripts/classify-plan-safety.mjs +20 -7
  120. package/pipeline/scripts/cost-budget-check.mjs +2 -1
  121. package/pipeline/scripts/cost-table.json +1 -1
  122. package/pipeline/scripts/diff-explain.mjs +7 -3
  123. package/pipeline/scripts/diff-risk-score.mjs +13 -3
  124. package/pipeline/scripts/evidence-gate.mjs +7 -2
  125. package/pipeline/scripts/gen-mode-dispatch.mjs +38 -21
  126. package/pipeline/scripts/gen-skills-index.mjs +18 -3
  127. package/pipeline/scripts/learning-curve.mjs +13 -3
  128. package/pipeline/scripts/learnings-ledger.mjs +103 -36
  129. package/pipeline/scripts/localize-commands.mjs +6 -1
  130. package/pipeline/scripts/match-skills.mjs +15 -4
  131. package/pipeline/scripts/migrate-prefs.mjs +33 -16
  132. package/pipeline/scripts/phase-tracker.sh +3 -1
  133. package/pipeline/scripts/repo-map.mjs +110 -64
  134. package/pipeline/scripts/review-scope.mjs +7 -1
  135. package/pipeline/scripts/routine-registry.mjs +4 -9
  136. package/pipeline/scripts/run-aggregator.mjs +11 -5
  137. package/pipeline/scripts/run-metrics.mjs +13 -8
  138. package/pipeline/scripts/smoke-cross-cli-behavior.sh +21 -7
  139. package/pipeline/scripts/test-gap-scan.mjs +44 -12
  140. package/pipeline/scripts/test-integrity-gate.mjs +5 -1
  141. package/pipeline/scripts/token-budget-report.mjs +44 -21
  142. package/pipeline/scripts/triage-memory.mjs +126 -34
  143. package/pipeline/scripts/uninstall.mjs +74 -30
  144. package/pipeline/scripts/validate-analysis-doc.mjs +15 -5
  145. package/pipeline/scripts/validate-diff-risk.mjs +32 -18
  146. package/pipeline/scripts/validate-test-gap.mjs +17 -7
  147. package/pipeline/scripts/validate-triage.mjs +17 -5
  148. package/pipeline/scripts/write-state.mjs +32 -9
  149. package/pipeline/skills/.skills-index.json +91 -91
  150. package/pipeline/skills/shared/README.md +57 -57
  151. package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +1 -1
  152. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +1 -1
  153. package/pipeline/skills/shared/core/multi-agent/SKILL.md +26 -279
  154. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +1 -1
  155. package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +1 -1
  156. package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +1 -1
  157. package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +1 -1
  158. package/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md +1 -1
  159. package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +1 -1
  160. package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +1 -1
  161. package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +1 -1
  162. package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +1 -1
  163. package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +1 -1
  164. package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +1 -1
  165. package/pipeline/skills/shared/core/multi-agent-finish/SKILL.md +1 -1
  166. package/pipeline/skills/shared/core/multi-agent-forget/SKILL.md +1 -1
  167. package/pipeline/skills/shared/core/multi-agent-garbage-collect/SKILL.md +1 -1
  168. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +1 -1
  169. package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +1 -1
  170. package/pipeline/skills/shared/core/multi-agent-jira/SKILL.md +1 -1
  171. package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +1 -1
  172. package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +1 -1
  173. package/pipeline/skills/shared/core/multi-agent-local/SKILL.md +1 -1
  174. package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +1 -1
  175. package/pipeline/skills/shared/core/multi-agent-log/SKILL.md +1 -1
  176. package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +1 -1
  177. package/pipeline/skills/shared/core/multi-agent-prune-logs/SKILL.md +1 -1
  178. package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +1 -1
  179. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +16 -8
  180. package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +1 -1
  181. package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +1 -1
  182. package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +1 -1
  183. package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +1 -1
  184. package/pipeline/skills/shared/core/multi-agent-routines/SKILL.md +1 -1
  185. package/pipeline/skills/shared/core/multi-agent-save/SKILL.md +1 -1
  186. package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +1 -1
  187. package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +1 -1
  188. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +1 -1
  189. package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +3 -3
  190. package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +1 -1
  191. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +1 -1
  192. package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +1 -1
  193. package/pipeline/skills/shared/core/multi-agent-uninstall/SKILL.md +1 -1
  194. package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +1 -1
  195. package/pipeline/skills/shared/external/accessibility-compliance-accessibility-audit/SKILL.md +1 -1
  196. package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +4 -4
  197. package/pipeline/skills/shared/external/agentflow/SKILL.md +1 -1
  198. package/pipeline/skills/shared/external/android-jetpack-compose-expert/SKILL.md +1 -1
  199. package/pipeline/skills/shared/external/android_ui_verification/SKILL.md +1 -1
  200. package/pipeline/skills/shared/external/api-patterns/SKILL.md +1 -1
  201. package/pipeline/skills/shared/external/api-security-best-practices/SKILL.md +1 -1
  202. package/pipeline/skills/shared/external/app-store-changelog/SKILL.md +1 -1
  203. package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
  204. package/pipeline/skills/shared/external/backlog/SKILL.md +12 -12
  205. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -1
  206. package/pipeline/skills/shared/external/context-compression/SKILL.md +1 -1
  207. package/pipeline/skills/shared/external/council/SKILL.md +3 -3
  208. package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -1
  209. package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -1
  210. package/pipeline/skills/shared/external/debugging-strategies/SKILL.md +1 -1
  211. package/pipeline/skills/shared/external/docker-expert/SKILL.md +1 -1
  212. package/pipeline/skills/shared/external/fastapi-pro/SKILL.md +1 -1
  213. package/pipeline/skills/shared/external/firebase/SKILL.md +1 -1
  214. package/pipeline/skills/shared/external/github-actions-templates/SKILL.md +1 -1
  215. package/pipeline/skills/shared/external/help-skills/SKILL.md +1 -1
  216. package/pipeline/skills/shared/external/hig-components-content/SKILL.md +1 -1
  217. package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +1 -1
  218. package/pipeline/skills/shared/external/hig-components-status/SKILL.md +1 -1
  219. package/pipeline/skills/shared/external/hig-components-system/SKILL.md +1 -1
  220. package/pipeline/skills/shared/external/hig-foundations/SKILL.md +1 -1
  221. package/pipeline/skills/shared/external/hig-inputs/SKILL.md +1 -1
  222. package/pipeline/skills/shared/external/hig-patterns/SKILL.md +1 -1
  223. package/pipeline/skills/shared/external/hig-platforms/SKILL.md +1 -1
  224. package/pipeline/skills/shared/external/hig-technologies/SKILL.md +1 -1
  225. package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -1
  226. package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -1
  227. package/pipeline/skills/shared/external/ios-debugger-agent/SKILL.md +1 -1
  228. package/pipeline/skills/shared/external/ios-developer/SKILL.md +1 -1
  229. package/pipeline/skills/shared/external/kotlin-coroutines-expert/SKILL.md +1 -1
  230. package/pipeline/skills/shared/external/macos-menubar-tuist-app/SKILL.md +1 -1
  231. package/pipeline/skills/shared/external/macos-spm-app-packaging/SKILL.md +1 -1
  232. package/pipeline/skills/shared/external/monorepo-architect/SKILL.md +1 -1
  233. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -1
  234. package/pipeline/skills/shared/external/nodejs-backend-patterns/SKILL.md +1 -1
  235. package/pipeline/skills/shared/external/observability-engineer/SKILL.md +1 -1
  236. package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -1
  237. package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -1
  238. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -1
  239. package/pipeline/skills/shared/external/search-first/SKILL.md +2 -2
  240. package/pipeline/skills/shared/external/skill-creator/SKILL.md +12 -12
  241. package/pipeline/skills/shared/external/skill-creator/audit.md +21 -21
  242. package/pipeline/skills/shared/external/skill-creator/checklist.md +3 -3
  243. package/pipeline/skills/shared/external/skill-creator/examples.md +10 -10
  244. package/pipeline/skills/shared/external/skill-creator/label-check.md +17 -17
  245. package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +86 -50
  246. package/pipeline/skills/shared/external/skill-creator/template.md +9 -9
  247. package/pipeline/skills/shared/external/swift-concurrency-expert/SKILL.md +1 -1
  248. package/pipeline/skills/shared/external/swiftui-performance-audit/SKILL.md +1 -1
  249. package/pipeline/skills/shared/external/swiftui-ui-patterns/SKILL.md +1 -1
  250. package/pipeline/skills/shared/external/swiftui-view-refactor/SKILL.md +1 -1
  251. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -1
  252. package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -1
  253. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -1
  254. package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -1
  255. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -1
  256. package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -1
  257. package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -1
  258. package/pipeline/skills/shared/external/xcode-build-benchmark/schemas/build-benchmark.schema.json +9 -49
  259. package/pipeline/skills/skills-index.md +57 -57
  260. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-1-analysis.json +0 -25
  261. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-2-plan.json +0 -30
  262. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-review.json +0 -20
  263. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-triage.json +0 -15
  264. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/metadata.json +0 -14
  265. package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/task.json +0 -12
  266. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-1-analysis.json +0 -29
  267. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-2-plan.json +0 -43
  268. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-review.json +0 -35
  269. package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-triage.json +0 -35
  270. package/pipeline/eval/golden-tasks/02-android-feature-compose/metadata.json +0 -14
  271. package/pipeline/eval/golden-tasks/02-android-feature-compose/task.json +0 -12
  272. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-1-analysis.json +0 -29
  273. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-2-plan.json +0 -42
  274. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-review.json +0 -20
  275. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-triage.json +0 -15
  276. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/metadata.json +0 -14
  277. package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/task.json +0 -12
  278. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-1-analysis.json +0 -29
  279. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-2-plan.json +0 -40
  280. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-review.json +0 -20
  281. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-triage.json +0 -15
  282. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/metadata.json +0 -14
  283. package/pipeline/eval/golden-tasks/04-frontend-next-hydration/task.json +0 -12
  284. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-1-analysis.json +0 -29
  285. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-2-plan.json +0 -42
  286. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-review.json +0 -28
  287. package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-triage.json +0 -27
  288. package/pipeline/eval/golden-tasks/05-ios-security-keychain/metadata.json +0 -14
  289. package/pipeline/eval/golden-tasks/05-ios-security-keychain/task.json +0 -12
  290. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-1-analysis.json +0 -29
  291. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-2-plan.json +0 -41
  292. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-review.json +0 -12
  293. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-triage.json +0 -6
  294. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/metadata.json +0 -14
  295. package/pipeline/eval/golden-tasks/06-android-refactor-usecase/task.json +0 -12
  296. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-1-analysis.json +0 -29
  297. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-2-plan.json +0 -42
  298. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-review.json +0 -28
  299. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-triage.json +0 -27
  300. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/metadata.json +0 -14
  301. package/pipeline/eval/golden-tasks/07-backend-node-idempotency/task.json +0 -12
  302. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-1-analysis.json +0 -25
  303. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-2-plan.json +0 -31
  304. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-review.json +0 -12
  305. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-triage.json +0 -18
  306. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/metadata.json +0 -14
  307. package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/task.json +0 -12
  308. package/pipeline/eval/golden-tasks/README.md +0 -65
  309. package/pipeline/eval/intent-cases.json +0 -40
  310. package/pipeline/eval/run-metrics-fixture.json +0 -46
  311. package/pipeline/eval/triage/01-empty-findings/expected.json +0 -6
  312. package/pipeline/eval/triage/01-empty-findings/input.json +0 -5
  313. package/pipeline/eval/triage/01-empty-findings/notes.md +0 -7
  314. package/pipeline/eval/triage/02-real-blocker/expected.json +0 -15
  315. package/pipeline/eval/triage/02-real-blocker/input.json +0 -14
  316. package/pipeline/eval/triage/02-real-blocker/notes.md +0 -7
  317. package/pipeline/eval/triage/03-out-of-scope-defer/expected.json +0 -18
  318. package/pipeline/eval/triage/03-out-of-scope-defer/input.json +0 -14
  319. package/pipeline/eval/triage/03-out-of-scope-defer/notes.md +0 -10
  320. package/pipeline/eval/triage/04-false-positive-reject/expected.json +0 -18
  321. package/pipeline/eval/triage/04-false-positive-reject/input.json +0 -14
  322. package/pipeline/eval/triage/04-false-positive-reject/notes.md +0 -10
  323. package/pipeline/eval/triage/05-mixed-classification/expected.json +0 -43
  324. package/pipeline/eval/triage/05-mixed-classification/input.json +0 -38
  325. package/pipeline/eval/triage/05-mixed-classification/notes.md +0 -17
  326. package/pipeline/eval/triage/06-severity-mismatch/expected.json +0 -15
  327. package/pipeline/eval/triage/06-severity-mismatch/input.json +0 -14
  328. package/pipeline/eval/triage/06-severity-mismatch/notes.md +0 -9
  329. package/pipeline/eval/triage/07-duplicate-reviewers/expected.json +0 -27
  330. package/pipeline/eval/triage/07-duplicate-reviewers/input.json +0 -22
  331. package/pipeline/eval/triage/07-duplicate-reviewers/notes.md +0 -9
  332. package/pipeline/eval/triage/08-style-misclassified/expected.json +0 -18
  333. package/pipeline/eval/triage/08-style-misclassified/input.json +0 -14
  334. package/pipeline/eval/triage/08-style-misclassified/notes.md +0 -9
  335. package/pipeline/eval/triage/09-cascading-finding/expected.json +0 -23
  336. package/pipeline/eval/triage/09-cascading-finding/input.json +0 -22
  337. package/pipeline/eval/triage/09-cascading-finding/notes.md +0 -9
  338. package/pipeline/eval/triage/10-deferred-crossref/expected.json +0 -18
  339. package/pipeline/eval/triage/10-deferred-crossref/input.json +0 -14
  340. package/pipeline/eval/triage/10-deferred-crossref/notes.md +0 -9
  341. package/pipeline/eval/triage/11-vercel-token-leak-blocker/expected.json +0 -27
  342. package/pipeline/eval/triage/11-vercel-token-leak-blocker/input.json +0 -22
  343. package/pipeline/eval/triage/11-vercel-token-leak-blocker/notes.md +0 -14
  344. package/pipeline/eval/triage/README.md +0 -54
  345. package/pipeline/scripts/benchmark-phase-0.sh +0 -128
  346. package/pipeline/scripts/check-md-links.mjs +0 -84
  347. package/pipeline/scripts/eval-golden-tasks-live.mjs +0 -297
  348. package/pipeline/scripts/eval-golden-tasks.mjs +0 -212
  349. package/pipeline/scripts/eval-intent.mjs +0 -103
  350. package/pipeline/scripts/eval-mine-corpus.mjs +0 -201
  351. package/pipeline/scripts/eval-triage.mjs +0 -171
  352. package/pipeline/scripts/fixtures/diff-risk-android.diff +0 -40
  353. package/pipeline/scripts/fixtures/diff-risk-ios.diff +0 -48
  354. package/pipeline/scripts/fixtures/diff-risk-test-removal.diff +0 -40
  355. package/pipeline/scripts/fixtures/install-layout.tsv +0 -19
  356. package/pipeline/scripts/fixtures/pack-expected-count.txt +0 -1
  357. package/pipeline/scripts/fixtures/test-gap-node.diff +0 -30
  358. package/pipeline/scripts/fixtures/test-gap-python.diff +0 -32
  359. package/pipeline/scripts/lint-mcp-refs.mjs +0 -207
  360. package/pipeline/scripts/lint-skills.mjs +0 -143
  361. package/pipeline/scripts/run-smokes.mjs +0 -76
  362. package/pipeline/scripts/smoke-add-detail.sh +0 -137
  363. package/pipeline/scripts/smoke-agent-guard.sh +0 -74
  364. package/pipeline/scripts/smoke-agent-log-cost.sh +0 -262
  365. package/pipeline/scripts/smoke-agent-model-routing.sh +0 -87
  366. package/pipeline/scripts/smoke-ask-choice.sh +0 -42
  367. package/pipeline/scripts/smoke-autopilot-circuit-breaker.sh +0 -36
  368. package/pipeline/scripts/smoke-bitbucket-contract.sh +0 -255
  369. package/pipeline/scripts/smoke-changelog-version.sh +0 -47
  370. package/pipeline/scripts/smoke-channels-approval-gate.sh +0 -60
  371. package/pipeline/scripts/smoke-channels-flow.sh +0 -130
  372. package/pipeline/scripts/smoke-ci-workflows.sh +0 -88
  373. package/pipeline/scripts/smoke-clarify.sh +0 -148
  374. package/pipeline/scripts/smoke-command-inventory.sh +0 -81
  375. package/pipeline/scripts/smoke-commands-skills-parity.sh +0 -87
  376. package/pipeline/scripts/smoke-community-gates.sh +0 -75
  377. package/pipeline/scripts/smoke-compliance-skills.sh +0 -119
  378. package/pipeline/scripts/smoke-config-hygiene.sh +0 -58
  379. package/pipeline/scripts/smoke-cost-budget.sh +0 -70
  380. package/pipeline/scripts/smoke-cost-summary.sh +0 -139
  381. package/pipeline/scripts/smoke-cross-phase-cohesion.sh +0 -128
  382. package/pipeline/scripts/smoke-description-tr.sh +0 -82
  383. package/pipeline/scripts/smoke-dev-critic.sh +0 -144
  384. package/pipeline/scripts/smoke-diff-explain.sh +0 -147
  385. package/pipeline/scripts/smoke-diff-risk.sh +0 -190
  386. package/pipeline/scripts/smoke-dynamic-skill-loading.sh +0 -160
  387. package/pipeline/scripts/smoke-eval-live.sh +0 -136
  388. package/pipeline/scripts/smoke-evidence-gate.sh +0 -93
  389. package/pipeline/scripts/smoke-extract-conventions.sh +0 -163
  390. package/pipeline/scripts/smoke-fetchers-offline.sh +0 -448
  391. package/pipeline/scripts/smoke-figma-dispatch.sh +0 -112
  392. package/pipeline/scripts/smoke-gate-hooks.sh +0 -74
  393. package/pipeline/scripts/smoke-gc-tmp.sh +0 -130
  394. package/pipeline/scripts/smoke-gc-worktrees.sh +0 -125
  395. package/pipeline/scripts/smoke-generate-issue.sh +0 -120
  396. package/pipeline/scripts/smoke-handoff-contract.sh +0 -92
  397. package/pipeline/scripts/smoke-identity-isolation.sh +0 -70
  398. package/pipeline/scripts/smoke-install-layout.sh +0 -248
  399. package/pipeline/scripts/smoke-intent-guard.sh +0 -86
  400. package/pipeline/scripts/smoke-issue-comment-template.sh +0 -86
  401. package/pipeline/scripts/smoke-issue-jira-triad.sh +0 -120
  402. package/pipeline/scripts/smoke-keychain.sh +0 -158
  403. package/pipeline/scripts/smoke-language-axis.sh +0 -109
  404. package/pipeline/scripts/smoke-learning-curve.sh +0 -61
  405. package/pipeline/scripts/smoke-learnings-ledger.sh +0 -86
  406. package/pipeline/scripts/smoke-lib-scripts.sh +0 -448
  407. package/pipeline/scripts/smoke-mcp-gate.sh +0 -68
  408. package/pipeline/scripts/smoke-md-links.sh +0 -8
  409. package/pipeline/scripts/smoke-md2confluence.sh +0 -126
  410. package/pipeline/scripts/smoke-metrics-cache-ratio.sh +0 -72
  411. package/pipeline/scripts/smoke-migrate-state.sh +0 -102
  412. package/pipeline/scripts/smoke-mode-dispatch-drift.sh +0 -161
  413. package/pipeline/scripts/smoke-model-fallback.sh +0 -89
  414. package/pipeline/scripts/smoke-multi-repo-integration.sh +0 -116
  415. package/pipeline/scripts/smoke-multi-repo-worktree.sh +0 -61
  416. package/pipeline/scripts/smoke-no-mcp-in-dev-phases.sh +0 -115
  417. package/pipeline/scripts/smoke-no-token-prompt.sh +0 -85
  418. package/pipeline/scripts/smoke-pack-contents.sh +0 -140
  419. package/pipeline/scripts/smoke-pat-audit.sh +0 -128
  420. package/pipeline/scripts/smoke-per-repo-memory.sh +0 -156
  421. package/pipeline/scripts/smoke-phase-0-multi-repo.sh +0 -170
  422. package/pipeline/scripts/smoke-phase-6-multi.sh +0 -79
  423. package/pipeline/scripts/smoke-phase-banner.sh +0 -101
  424. package/pipeline/scripts/smoke-phase-tracker.sh +0 -324
  425. package/pipeline/scripts/smoke-phase0-bridge-contract.sh +0 -241
  426. package/pipeline/scripts/smoke-phase4-gates.sh +0 -45
  427. package/pipeline/scripts/smoke-phase4-triage.sh +0 -229
  428. package/pipeline/scripts/smoke-plan-approval-gate.sh +0 -71
  429. package/pipeline/scripts/smoke-plan-safety.sh +0 -139
  430. package/pipeline/scripts/smoke-plan-todos.sh +0 -196
  431. package/pipeline/scripts/smoke-plugin-validate.sh +0 -64
  432. package/pipeline/scripts/smoke-pr-review-actions.sh +0 -152
  433. package/pipeline/scripts/smoke-pre-commit.sh +0 -170
  434. package/pipeline/scripts/smoke-pref-migration.sh +0 -226
  435. package/pipeline/scripts/smoke-prefs-language.sh +0 -134
  436. package/pipeline/scripts/smoke-progress-contract.sh +0 -127
  437. package/pipeline/scripts/smoke-prune-logs.sh +0 -137
  438. package/pipeline/scripts/smoke-purge.sh +0 -138
  439. package/pipeline/scripts/smoke-push-retry.sh +0 -75
  440. package/pipeline/scripts/smoke-repo-map.sh +0 -300
  441. package/pipeline/scripts/smoke-review-readiness.sh +0 -92
  442. package/pipeline/scripts/smoke-review-watch.sh +0 -146
  443. package/pipeline/scripts/smoke-routines.sh +0 -84
  444. package/pipeline/scripts/smoke-run-aggregator.sh +0 -216
  445. package/pipeline/scripts/smoke-run-metrics.sh +0 -50
  446. package/pipeline/scripts/smoke-search.sh +0 -187
  447. package/pipeline/scripts/smoke-shadow-git.sh +0 -224
  448. package/pipeline/scripts/smoke-skill-authoring.sh +0 -137
  449. package/pipeline/scripts/smoke-skill-language.sh +0 -83
  450. package/pipeline/scripts/smoke-skill-manifest.sh +0 -138
  451. package/pipeline/scripts/smoke-skill-scan.sh +0 -198
  452. package/pipeline/scripts/smoke-source-parity.sh +0 -85
  453. package/pipeline/scripts/smoke-subagent-validators.sh +0 -108
  454. package/pipeline/scripts/smoke-sync-parity.sh +0 -92
  455. package/pipeline/scripts/smoke-tasklist-ordering.sh +0 -112
  456. package/pipeline/scripts/smoke-telemetry.sh +0 -147
  457. package/pipeline/scripts/smoke-test-gap.sh +0 -183
  458. package/pipeline/scripts/smoke-token-budget.sh +0 -67
  459. package/pipeline/scripts/smoke-token-preflight.sh +0 -82
  460. package/pipeline/scripts/smoke-tracker-contract.sh +0 -191
  461. package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +0 -73
  462. package/pipeline/scripts/smoke-triage-memory.sh +0 -174
  463. package/pipeline/scripts/smoke-update-check.sh +0 -135
  464. package/pipeline/scripts/smoke-url-enrichment.sh +0 -70
  465. package/pipeline/scripts/smoke-validate-analysis-doc.sh +0 -161
  466. package/pipeline/scripts/smoke-validator-contradiction.sh +0 -67
  467. package/pipeline/scripts/smoke-validator-gates.sh +0 -164
  468. package/pipeline/scripts/smoke-vercel-deploy-redact.sh +0 -129
  469. package/pipeline/scripts/smoke-verify-by-test.sh +0 -148
  470. package/pipeline/scripts/smoke-wiki-integration.sh +0 -122
  471. package/pipeline/scripts/smoke-work-summary.sh +0 -163
  472. package/pipeline/scripts/smoke-workflow-audit.sh +0 -69
  473. package/pipeline/scripts/smoke-worktree-path-convention.sh +0 -86
  474. package/pipeline/scripts/smoke-wrapper-preservation.sh +0 -68
  475. package/pipeline/scripts/smoke-write-state.sh +0 -115
  476. package/pipeline/scripts/sync-parity-check.sh +0 -135
  477. package/pipeline/scripts/test-gap-rules/android.json +0 -25
  478. package/pipeline/scripts/test-gap-rules/ios.json +0 -29
  479. package/pipeline/scripts/test-gap-rules/node.json +0 -17
  480. package/pipeline/scripts/test-gap-rules/python.json +0 -19
  481. package/pipeline/scripts/validate-schemas.mjs +0 -88
@@ -1,207 +0,0 @@
1
- #!/usr/bin/env node
2
- // lint-mcp-refs.mjs - every mcp__<server>__<tool> reference must be callable.
3
- //
4
- // A host composes an MCP tool name as mcp__<registered-server-name>__<tool>.
5
- // The pipeline had 100 references to `mcp__dev_toolkit__*` while the server is
6
- // registered as `dev-toolkit`, so the real names are `mcp__dev-toolkit__*`.
7
- // Nothing caught it: prose is not executed, and a wrong name inside an
8
- // `allowed-tools:` allowlist silently denies the tool instead of erroring.
9
- //
10
- // Checks (errors - fail the gate):
11
- // 1. the server segment must be a known registered server name
12
- // 2. the known-bad snake_case spellings are called out with their fix
13
- //
14
- // Optional deep check (advisory - never fails):
15
- // 3. when the companion dev-toolkit repo resolves locally (via
16
- // prefs.global.devToolkit.localPath, or the mcpServers registration in
17
- // ~/.claude.json / ~/.claude/settings.json), handshake it over stdio and
18
- // confirm every referenced dev-toolkit tool actually exists in tools/list.
19
- // CI has no local checkout, so an unresolvable repo is a skip, not a fail.
20
- //
21
- // Zero-dependency. Runs inside `npm test` and ci-lite.
22
- //
23
- // Usage: node pipeline/scripts/lint-mcp-refs.mjs [--strict-tools]
24
- // Exit: 0 clean, 1 unknown server segment (or a missing tool with --strict-tools).
25
-
26
- import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
27
- import { homedir } from "node:os";
28
- import { dirname, join, resolve } from "node:path";
29
- import { fileURLToPath } from "node:url";
30
- import { spawnSync } from "node:child_process";
31
-
32
- const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
33
- const strictTools = process.argv.includes("--strict-tools");
34
-
35
- // Servers the pipeline is allowed to reference. The key is the registered
36
- // server name as it appears in an mcpServers config, which is what the host
37
- // interpolates into the tool name.
38
- const KNOWN_SERVERS = {
39
- "dev-toolkit": "companion device/browser toolkit (@mmerterden/dev-toolkit-mcp)",
40
- claude_ai_Figma: "Figma MCP (analysis phase only)",
41
- XcodeBuildMCP: "optional third-party Xcode build server",
42
- };
43
- // Spellings that look right but cannot resolve to a registered server.
44
- const KNOWN_BAD = { dev_toolkit: "dev-toolkit", "claude-ai-Figma": "claude_ai_Figma" };
45
-
46
- const SCAN_DIRS = ["pipeline/commands", "pipeline/skills", "pipeline/multi-agent-refs"];
47
- const SCAN_EXT = /\.(md|sh|mjs|json)$/;
48
- const PRUNE = new Set(["node_modules", ".git", ".worktrees", "Pods", ".build", "DerivedData", ".next"]);
49
-
50
- function walk(dir, out = []) {
51
- let entries;
52
- try {
53
- entries = readdirSync(dir, { withFileTypes: true });
54
- } catch {
55
- return out;
56
- }
57
- for (const e of entries) {
58
- if (PRUNE.has(e.name)) continue;
59
- const p = join(dir, e.name);
60
- if (e.isDirectory()) walk(p, out);
61
- else if (SCAN_EXT.test(e.name)) out.push(p);
62
- }
63
- return out;
64
- }
65
-
66
- const files = SCAN_DIRS.flatMap((d) => walk(join(repoRoot, d)));
67
- const REF = /mcp__([A-Za-z0-9_-]+?)__([a-z0-9_]+)/g;
68
-
69
- const errors = [];
70
- const refs = new Map(); // server -> Map(tool -> Set(file:line))
71
-
72
- for (const file of files) {
73
- const rel = file.slice(repoRoot.length + 1);
74
- const lines = readFileSync(file, "utf8").split("\n");
75
- lines.forEach((line, i) => {
76
- for (const m of line.matchAll(REF)) {
77
- const [, server, tool] = m;
78
- // Prose writes families as mcp__dev-toolkit__ios_* - a wildcard, not a tool.
79
- const next = line[m.index + m[0].length];
80
- if (next === "*" || tool.endsWith("_")) continue;
81
- const where = `${rel}:${i + 1}`;
82
- if (!refs.has(server)) refs.set(server, new Map());
83
- const tools = refs.get(server);
84
- if (!tools.has(tool)) tools.set(tool, new Set());
85
- tools.get(tool).add(where);
86
- }
87
- });
88
- }
89
-
90
- for (const [server, tools] of refs) {
91
- if (server in KNOWN_SERVERS) continue;
92
- const fix = KNOWN_BAD[server];
93
- const sample = [...tools.values()][0].values().next().value;
94
- errors.push(
95
- fix
96
- ? `unknown MCP server segment "${server}" (${tools.size} tool refs, e.g. ${sample}) - the registered server is "${fix}", so the prefix must be mcp__${fix}__`
97
- : `unknown MCP server segment "${server}" (${tools.size} tool refs, e.g. ${sample}) - add it to KNOWN_SERVERS in lint-mcp-refs.mjs if this server is expected, or fix the prefix to match the registered server name`,
98
- );
99
- }
100
-
101
- // ---- optional deep check: do the referenced dev-toolkit tools exist? --------
102
-
103
- function resolveToolkitRepo() {
104
- const prefsPath = join(homedir(), ".claude", "multi-agent-preferences.json");
105
- if (existsSync(prefsPath)) {
106
- try {
107
- const dt = JSON.parse(readFileSync(prefsPath, "utf8"))?.global?.devToolkit;
108
- if (dt && dt.enabled === false) return null;
109
- if (dt?.localPath) {
110
- const p = dt.localPath.replace(/^~|\$HOME/, homedir());
111
- if (existsSync(join(p, "package.json"))) return p;
112
- }
113
- } catch {
114
- /* fall through to registration lookup */
115
- }
116
- }
117
- const candidates = [];
118
- const collect = (obj) => {
119
- for (const [name, cfg] of Object.entries(obj || {})) {
120
- const arg = Array.isArray(cfg?.args) ? cfg.args.find((a) => /\.(mjs|js)$/.test(a)) : null;
121
- if (name.includes("dev") && arg) candidates.push(dirname(resolve(arg)));
122
- }
123
- };
124
- for (const cfgPath of [join(homedir(), ".claude.json"), join(homedir(), ".claude", "settings.json")]) {
125
- if (!existsSync(cfgPath)) continue;
126
- try {
127
- const json = JSON.parse(readFileSync(cfgPath, "utf8"));
128
- collect(json.mcpServers);
129
- for (const proj of Object.values(json.projects || {})) collect(proj.mcpServers);
130
- } catch {
131
- /* ignore unreadable config */
132
- }
133
- }
134
- for (const c of candidates) {
135
- try {
136
- const pkg = JSON.parse(readFileSync(join(c, "package.json"), "utf8"));
137
- if (pkg.dependencies?.["@modelcontextprotocol/sdk"] && statSync(join(c, ".git"))) return c;
138
- } catch {
139
- /* not the toolkit */
140
- }
141
- }
142
- return null;
143
- }
144
-
145
- function listTools(repo) {
146
- const frames =
147
- [
148
- '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"lint-mcp-refs","version":"1"}}}',
149
- '{"jsonrpc":"2.0","method":"notifications/initialized"}',
150
- '{"jsonrpc":"2.0","id":2,"method":"tools/list"}',
151
- ].join("\n") + "\n";
152
- const r = spawnSync(process.execPath, ["index.js"], {
153
- cwd: repo,
154
- input: frames,
155
- encoding: "utf8",
156
- timeout: 20000,
157
- maxBuffer: 32 * 1024 * 1024,
158
- });
159
- if (r.error || !r.stdout) return null;
160
- for (const line of r.stdout.split("\n")) {
161
- if (!line.trim()) continue;
162
- try {
163
- const msg = JSON.parse(line);
164
- if (msg.id === 2 && msg.result?.tools) return msg.result.tools.map((t) => t.name);
165
- } catch {
166
- /* not a frame */
167
- }
168
- }
169
- return null;
170
- }
171
-
172
- const referencedToolkitTools = refs.get("dev-toolkit");
173
- let deep = "skipped (no local dev-toolkit checkout)";
174
- if (referencedToolkitTools) {
175
- const repo = resolveToolkitRepo();
176
- const served = repo ? listTools(repo) : null;
177
- if (!served) {
178
- deep = repo ? `skipped (${repo} did not answer tools/list)` : deep;
179
- } else {
180
- const missing = [...referencedToolkitTools.keys()].filter((t) => !served.includes(t));
181
- if (missing.length === 0) {
182
- deep = `all ${referencedToolkitTools.size} referenced tools exist in the live server (${served.length} served)`;
183
- } else {
184
- const msg = `dev-toolkit tools referenced but not served (${served.length} served): ${missing
185
- .map((t) => `${t} [${[...referencedToolkitTools.get(t)][0]}]`)
186
- .join(", ")}`;
187
- deep = `${missing.length} referenced tool(s) not served`;
188
- if (strictTools) errors.push(msg);
189
- else console.warn(` WARNING - ${msg}`);
190
- }
191
- }
192
- }
193
-
194
- const totalRefs = [...refs.values()].reduce((n, tools) => n + tools.size, 0);
195
- console.log(
196
- `lint-mcp-refs: ${totalRefs} distinct tool references across ${refs.size} server(s) in ${files.length} files`,
197
- );
198
- for (const [server, tools] of refs) {
199
- console.log(` ${server in KNOWN_SERVERS ? "✓" : "✗"} mcp__${server}__* : ${tools.size} tools`);
200
- }
201
- console.log(` tool-existence check: ${deep}`);
202
-
203
- if (errors.length > 0) {
204
- console.error(`lint-mcp-refs: ${errors.length} error(s)`);
205
- for (const e of errors) console.error(" " + e);
206
- process.exit(1);
207
- }
@@ -1,143 +0,0 @@
1
- #!/usr/bin/env node
2
- // Frontmatter linter for every SKILL.md shipped by the pipeline.
3
- //
4
- // Until v10.0.0 the shipped SKILL.md files were counted by smokes but never
5
- // content-checked, so a skill could ship without the frontmatter that
6
- // Claude Code / Copilot CLI need to register it. This gate enforces the
7
- // minimal contract; it is zero-dependency (line-based YAML subset) so it
8
- // runs inside `npm test` and ci-lite without installs.
9
- //
10
- // Contract per SKILL.md (errors - fail the gate):
11
- // - frontmatter block present (--- ... ---) starting at line 1
12
- // - name: required, lowercase kebab-case (underscores tolerated for
13
- // legacy skills already published under a snake_case name)
14
- // - description: required, non-empty, single line, <= 1024 chars
15
- // - user-invocable: when present, must be true or false
16
- // - platform: when present, must be ios | android | common | all
17
- //
18
- // Spec-conformance signals (warnings - never fail the gate):
19
- // - name should match the agent-skills spec pattern
20
- // (lowercase letters/digits/hyphens, <= 64 chars)
21
- // - description should carry a routing/trigger clause ("use when ...")
22
- // so the model can decide when to load the skill
23
- // - a body over ~500 lines with no companion-file reference should be
24
- // split into references/ files loaded on demand
25
-
26
- import { readFileSync } from "node:fs";
27
- import { execSync } from "node:child_process";
28
- import { dirname, join } from "node:path";
29
- import { fileURLToPath } from "node:url";
30
-
31
- const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
32
- // Scope to pipeline/skills only. Slash commands under pipeline/commands also use
33
- // the <name>/SKILL.md layout now, but they are command definitions
34
- // (description + allowed-tools, name derived from the dir), NOT skills, so the
35
- // skill frontmatter contract (required `name:`) does not apply to them.
36
- const files = execSync("find pipeline/skills -name SKILL.md", { cwd: repoRoot, encoding: "utf-8" })
37
- .trim()
38
- .split("\n")
39
- .filter(Boolean)
40
- .sort();
41
-
42
- const errors = [];
43
- const fail = (file, msg) => errors.push(`${file}: ${msg}`);
44
- // Non-fatal quality signals (a terse description routes poorly). Warnings never
45
- // fail the gate; they surface skills whose frontmatter could trigger better.
46
- const warnings = [];
47
- const warn = (file, msg) => warnings.push(`${file}: ${msg}`);
48
-
49
- for (const file of files) {
50
- const raw = readFileSync(join(repoRoot, file), "utf-8");
51
-
52
- if (!raw.startsWith("---\n")) {
53
- fail(file, "missing frontmatter block at line 1");
54
- continue;
55
- }
56
- const end = raw.indexOf("\n---", 4);
57
- if (end === -1) {
58
- fail(file, "frontmatter block never closed");
59
- continue;
60
- }
61
-
62
- const fields = {};
63
- for (const line of raw.slice(4, end).split("\n")) {
64
- const m = line.match(/^([a-zA-Z][a-zA-Z0-9-]*):\s*(.*)$/);
65
- if (m) fields[m[1]] = m[2].replace(/^["']|["']$/g, "").trim();
66
- }
67
-
68
- if (!fields.name) {
69
- fail(file, "missing required field: name");
70
- } else if (!/^[a-z0-9]+([-_][a-z0-9]+)*$/.test(fields.name)) {
71
- fail(file, `name is not lowercase kebab/snake-case: "${fields.name}"`);
72
- } else {
73
- // Spec conformance (warn-only): the agent-skills spec allows lowercase
74
- // letters, digits, and hyphens, max 64 chars. Snake_case passes the
75
- // legacy error check above but is out of spec.
76
- if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(fields.name)) {
77
- warn(file, `name is outside the agent-skills spec pattern (hyphens only): "${fields.name}"`);
78
- }
79
- if (fields.name.length > 64) {
80
- warn(file, `name exceeds the spec's 64-char limit (${fields.name.length})`);
81
- }
82
- }
83
-
84
- if (!("description" in fields)) {
85
- fail(file, "missing required field: description");
86
- } else if (fields.description.length === 0) {
87
- fail(file, "description is empty");
88
- } else if (fields.description.length > 1024) {
89
- fail(file, `description exceeds 1024 chars (${fields.description.length})`);
90
- } else {
91
- // Routing quality: a description of a few words rarely says what the skill
92
- // does AND when to use it, so the model cannot decide to trigger it.
93
- // Skip YAML block scalars (`description: |` / `>`): this line-based parser
94
- // only sees the indicator, not the real multi-line text, so a word count
95
- // would be a false positive.
96
- const desc = fields.description;
97
- const isBlockScalar = /^[|>][+-]?\d*$/.test(desc);
98
- const words = desc.split(/\s+/).filter(Boolean).length;
99
- if (!isBlockScalar && words < 6) {
100
- warn(file, `description is terse (${words} words) - say what it does AND when to use it`);
101
- }
102
- // Routing quality (warn-only): without a trigger clause the model has no
103
- // signal for WHEN to load the skill. Heuristic phrase match; block
104
- // scalars are skipped for the same parser reason as above.
105
- const ROUTING_RE = /\b(use (this|it|when|for|whenever)|when (the|a|an|you|asked|working|building|implementing|writing|reviewing)|triggers?|invoked?( when| for)?|applies when|activated?)\b/i;
106
- if (!isBlockScalar && !ROUTING_RE.test(desc)) {
107
- warn(file, "description has no routing/trigger clause (e.g. \"use when ...\")");
108
- }
109
- }
110
-
111
- // Body size (warn-only): the agent-skills guidance is to keep SKILL.md
112
- // lean and push detail into companion files loaded on demand. A ~500+
113
- // line body that references no companion file loads whole every time.
114
- const body = raw.slice(end + 4);
115
- const bodyLines = body.split("\n").length;
116
- if (bodyLines > 500) {
117
- const referencesCompanion =
118
- /\]\((?!https?:|mailto:|#)[^)]+\)/.test(body) || /`[^`\n]*\/[^`\n]*\.(md|sh|mjs|json|py|txt)`/.test(body);
119
- if (!referencesCompanion) {
120
- warn(file, `body is ${bodyLines} lines with no companion-file reference - consider splitting into references/`);
121
- }
122
- }
123
-
124
- if ("user-invocable" in fields && !["true", "false"].includes(fields["user-invocable"])) {
125
- fail(file, `user-invocable must be true|false, got "${fields["user-invocable"]}"`);
126
- }
127
-
128
- if ("platform" in fields && !["ios", "android", "common", "all"].includes(fields.platform)) {
129
- fail(file, `platform must be ios|android|common|all, got "${fields.platform}"`);
130
- }
131
- }
132
-
133
- if (warnings.length > 0) {
134
- console.warn(`lint-skills: ${warnings.length} warning(s) (non-fatal):`);
135
- for (const w of warnings) console.warn(" " + w);
136
- }
137
-
138
- if (errors.length > 0) {
139
- console.error(`lint-skills: ${errors.length} error(s) across ${files.length} SKILL.md files`);
140
- for (const e of errors) console.error(" " + e);
141
- process.exit(1);
142
- }
143
- console.log(`lint-skills: ${files.length} SKILL.md files OK`);
@@ -1,76 +0,0 @@
1
- #!/usr/bin/env node
2
- // Structured runner for pipeline/scripts/smoke-*.sh.
3
- //
4
- // Replaces the bare `for f in smoke-*.sh; do bash "$f" || exit 1; done`
5
- // loop with per-suite timeouts, timing, and a summary, so a hung smoke
6
- // (network wait, interactive prompt) can never block `npm test` or CI
7
- // indefinitely.
8
- //
9
- // Env:
10
- // SMOKE_TIMEOUT_SECONDS per-suite timeout (default 180)
11
- // SMOKE_NO_BAIL=1 run every suite and summarize instead of
12
- // stopping at the first failure
13
- // Args:
14
- // optional substring filters: `node run-smokes.mjs adapters keychain`
15
- // runs only suites whose filename contains one of the terms.
16
-
17
- import { spawnSync } from "node:child_process";
18
- import { readdirSync } from "node:fs";
19
- import { dirname, join } from "node:path";
20
- import { fileURLToPath } from "node:url";
21
-
22
- const scriptsDir = dirname(fileURLToPath(import.meta.url));
23
- const timeoutSec = Number(process.env.SMOKE_TIMEOUT_SECONDS || 180);
24
- const bail = process.env.SMOKE_NO_BAIL !== "1";
25
- const filters = process.argv.slice(2);
26
-
27
- const suites = readdirSync(scriptsDir)
28
- .filter((f) => f.startsWith("smoke-") && f.endsWith(".sh"))
29
- .filter((f) => filters.length === 0 || filters.some((t) => f.includes(t)))
30
- .sort();
31
-
32
- if (suites.length === 0) {
33
- console.error("run-smokes: no smoke suites matched");
34
- process.exit(1);
35
- }
36
-
37
- const failures = [];
38
- let ran = 0;
39
- const startedAt = Date.now();
40
-
41
- for (const suite of suites) {
42
- ran++;
43
- const t0 = Date.now();
44
- const res = spawnSync("bash", [join(scriptsDir, suite)], {
45
- encoding: "utf-8",
46
- timeout: timeoutSec * 1000,
47
- maxBuffer: 16 * 1024 * 1024,
48
- });
49
- const secs = ((Date.now() - t0) / 1000).toFixed(1);
50
-
51
- const timedOut = res.error && res.error.code === "ETIMEDOUT";
52
- const ok = !timedOut && res.status === 0;
53
-
54
- if (ok) {
55
- console.log(`ok ${suite} (${secs}s)`);
56
- continue;
57
- }
58
-
59
- const reason = timedOut ? `timeout after ${timeoutSec}s` : `exit ${res.status}`;
60
- console.error(`FAIL ${suite} (${reason}, ${secs}s)`);
61
- if (res.stdout) console.error(res.stdout.split("\n").slice(-30).join("\n"));
62
- if (res.stderr) console.error(res.stderr.split("\n").slice(-30).join("\n"));
63
- failures.push(suite);
64
- if (bail) break;
65
- }
66
-
67
- const totalSecs = ((Date.now() - startedAt) / 1000).toFixed(1);
68
- const skipped = suites.length - ran;
69
- console.log(
70
- `run-smokes: ${ran - failures.length}/${suites.length} passed in ${totalSecs}s` +
71
- (skipped > 0 ? ` (${skipped} not run after bail)` : ""),
72
- );
73
- if (failures.length > 0) {
74
- console.error(`run-smokes: failed -> ${failures.join(", ")}`);
75
- process.exit(1);
76
- }
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-add-detail.sh - contract check for the `add-detail` command.
3
- #
4
- # Does NOT hit real Bitbucket / Jira / GitHub. Instead:
5
- # 1. Generates a fake PR diff and body fixture.
6
- # 2. Runs the body-file + jq --rawfile + curl --data-binary pipeline
7
- # against a local `jq` / `python -c` simulator that checks the
8
- # resulting JSON payload round-trips with:
9
- # - real newlines (no literal "\n")
10
- # - no HTML entities (&amp; / &lt; / &quot; / &#39;)
11
- # - required Bitbucket PUT fields present: reviewers, fromRef, toRef, draft
12
- # 3. Returns non-zero if any contract is violated.
13
- #
14
- # Intended as a CI guard so regressions like the "23 reviewers wiped" incident
15
- # cannot land unnoticed.
16
-
17
- set -euo pipefail
18
-
19
- TMP="$(mktemp -d -t multi-agent-smoke-XXXX)" || { echo "FATAL: mktemp failed" >&2; exit 1; }
20
- trap 'rm -rf "$TMP"' EXIT
21
-
22
- PASS=0
23
- FAIL=0
24
-
25
- pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
26
- fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
27
-
28
- need() {
29
- command -v "$1" >/dev/null 2>&1 || {
30
- echo "error: $1 is required" >&2
31
- exit 2
32
- }
33
- }
34
- need jq
35
- need python3
36
-
37
- echo "→ Writing fixture body with newlines, '&' and Turkish chars"
38
- cat > "$TMP/body.md" <<'EOF'
39
- ## Özet
40
-
41
- - Kök neden: UILabel'e `adjustsFontSizeToFitWidth` eklenmemiş
42
- - Çözüm: `minimumScaleFactor = 0.7` ile ölçek desteği
43
- - Etki: İspanyolca & Almanca'da taşma düzeliyor
44
-
45
- ## Test Senaryoları
46
-
47
- | # | Ön koşul | Adımlar | Beklenen |
48
- |---|----------|---------|----------|
49
- | 1 | Dil = ES | Check-in Summary aç | Şehir isimleri sığar |
50
- EOF
51
-
52
- echo "→ Building payload with jq --rawfile"
53
- jq -n \
54
- --rawfile body "$TMP/body.md" \
55
- --arg title 'fix(checkin): Spanish overflow [PROJ-12345]' \
56
- '{
57
- title: $title,
58
- description: $body,
59
- fromRef: { id: "refs/heads/bugfix/PROJ-12345", repository: { slug: "my-app", project: { key: "APP" } } },
60
- toRef: { id: "refs/heads/develop", repository: { slug: "my-app", project: { key: "APP" } } },
61
- reviewers: [{ user: { name: "alice" } }, { user: { name: "bob" } }],
62
- draft: false,
63
- state: "OPEN", open: true, closed: false, locked: false
64
- }' > "$TMP/payload.json"
65
-
66
- echo "→ Contract checks"
67
-
68
- # Contract 1: payload is valid JSON.
69
- if jq -e . "$TMP/payload.json" >/dev/null 2>&1; then
70
- pass "payload is valid JSON"
71
- else
72
- fail "payload is not valid JSON"
73
- fi
74
-
75
- # Contract 2: description field round-trips with real newlines (not literal \n).
76
- DESC="$(jq -r .description "$TMP/payload.json")"
77
- if [[ "$DESC" == *$'\n'* ]]; then
78
- pass "description contains real newlines"
79
- else
80
- fail "description is single-line - newlines were escaped"
81
- fi
82
-
83
- # Contract 3: no literal backslash-n sequence survived.
84
- if grep -q '\\n' <<< "$DESC"; then
85
- fail "literal \\n escaped into description"
86
- else
87
- pass "no literal \\n in description"
88
- fi
89
-
90
- # Contract 4: no HTML entities in title or description.
91
- for field in title description; do
92
- VALUE="$(jq -r --arg f "$field" '.[$f]' "$TMP/payload.json")"
93
- if grep -Eq '&(amp|lt|gt|quot|#39);' <<< "$VALUE"; then
94
- fail "$field contains HTML entities"
95
- else
96
- pass "$field has no HTML entities"
97
- fi
98
- done
99
-
100
- # Contract 5: UTF-8 survives end-to-end (checks 'Ö', 'İ', 'ç').
101
- for glyph in 'Ö' 'İ' 'ç'; do
102
- if grep -q "$glyph" <<< "$DESC"; then
103
- pass "UTF-8 glyph '$glyph' preserved"
104
- else
105
- fail "UTF-8 glyph '$glyph' missing from description"
106
- fi
107
- done
108
-
109
- # Contract 6: Bitbucket PUT contract - all of reviewers/fromRef/toRef/draft present.
110
- for field in reviewers fromRef toRef draft; do
111
- if jq -e "has(\"$field\")" "$TMP/payload.json" >/dev/null; then
112
- pass "payload has .$field"
113
- else
114
- fail "payload missing .$field (Bitbucket will wipe it)"
115
- fi
116
- done
117
-
118
- # Contract 7: reviewers is a non-empty array for this fixture.
119
- LEN="$(jq '.reviewers | length' "$TMP/payload.json")"
120
- if [ "$LEN" -gt 0 ]; then
121
- pass "reviewers array preserved ($LEN entries)"
122
- else
123
- fail "reviewers array is empty - would wipe defaults"
124
- fi
125
-
126
- # Contract 8: fromRef / toRef are distinct (PR to self is rejected by Bitbucket).
127
- FROM="$(jq -r .fromRef.id "$TMP/payload.json")"
128
- TO="$(jq -r .toRef.id "$TMP/payload.json")"
129
- if [ "$FROM" != "$TO" ]; then
130
- pass "fromRef ($FROM) ≠ toRef ($TO)"
131
- else
132
- fail "fromRef == toRef - invalid PR"
133
- fi
134
-
135
- echo
136
- echo "══ add-detail smoke: $PASS passed, $FAIL failed ══"
137
- [ "$FAIL" -eq 0 ]
@@ -1,74 +0,0 @@
1
- #!/usr/bin/env bash
2
- # smoke-agent-guard.sh - behavioral contract for the agent-guard PreToolUse hook.
3
- #
4
- # Verifies the guard blocks (exit 2) AI-attribution commits and force-push to a
5
- # protected branch, allows (exit 0) everything else, fails open on bad input, and
6
- # NEVER executes the inspected command (injection safety).
7
- #
8
- # Runs the guard from the repo copy in a throwaway git repo whose branch we set,
9
- # so the "bare push on a protected branch" path is exercised deterministically.
10
- #
11
- # Exit 0 = all pass, 1 = any failure.
12
-
13
- set -uo pipefail
14
-
15
- ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
16
- GUARD="$ROOT/pipeline/scripts/agent-guard.sh"
17
- command -v python3 >/dev/null 2>&1 || { echo "error: python3 required" >&2; exit 127; }
18
- [ -f "$GUARD" ] || { echo "FAIL: agent-guard.sh missing at $GUARD" >&2; exit 1; }
19
- [ -f "$ROOT/pipeline/scripts/agent-guard.py" ] || { echo "FAIL: agent-guard.py missing" >&2; exit 1; }
20
-
21
- PASS=0; FAIL=0
22
- pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
23
- fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
24
-
25
- # throwaway repo on a protected branch so `git rev-parse` inside the guard = main
26
- WORK="$(mktemp -d)"
27
- trap 'rm -rf "$WORK"' EXIT
28
- # init on main WITH a commit so `git rev-parse --abbrev-ref HEAD` resolves to main
29
- # (an unborn branch reports HEAD, which would not exercise the bare-push path)
30
- ( cd "$WORK" \
31
- && git init -q \
32
- && git symbolic-ref HEAD refs/heads/main \
33
- && git -c user.email=t@t -c user.name=t commit -q --allow-empty -m init ) 2>/dev/null
34
-
35
- J() { python3 -c 'import json,sys; print(json.dumps({"tool_input":{"command":sys.argv[1]}}))' "$1"; }
36
- run() { # label expected-exit command-string
37
- local got
38
- ( cd "$WORK" && printf '%s' "$(J "$3")" | bash "$GUARD" >/dev/null 2>&1 )
39
- got=$?
40
- if [ "$got" = "$2" ]; then pass "[$got] $1"; else fail "expected $2 got $got: $1"; fi
41
- }
42
-
43
- echo "→ blocks (exit 2)"
44
- run "commit Co-Authored-By: Claude" 2 'git commit -m "x
45
-
46
- Co-Authored-By: Claude <noreply@anthropic.com>"'
47
- run "commit robot-emoji" 2 'git commit -m "x
48
-
49
- 🤖 Generated with Claude Code"'
50
- run "push --force origin main" 2 'git push --force origin main'
51
- run "push -f origin develop" 2 'git push -f origin develop'
52
- run "push --force-with-lease master" 2 'git push --force-with-lease origin master'
53
- run "bare push -f on main" 2 'git push -f'
54
-
55
- echo "→ allows (exit 0)"
56
- run "normal commit" 0 'git commit -m "feat: normal"'
57
- run "push no force" 0 'git push origin main'
58
- run "force push feature branch" 0 'git push --force origin feature/DEMO-1'
59
- run "force push tag" 0 'git push -f origin v1.2.3'
60
- run "non-git command" 0 'ls -la /tmp'
61
- run "empty command" 0 ''
62
-
63
- echo "→ fail-open on bad input"
64
- ( cd "$WORK" && printf 'not-json{' | bash "$GUARD" >/dev/null 2>&1 ); [ $? -eq 0 ] && pass "malformed json -> allow" || fail "malformed json blocked"
65
- ( cd "$WORK" && printf '' | bash "$GUARD" >/dev/null 2>&1 ); [ $? -eq 0 ] && pass "empty stdin -> allow" || fail "empty stdin blocked"
66
-
67
- echo "→ injection safety (inspected command must NOT execute)"
68
- SENT="$WORK/sentinel"; : > "$SENT"
69
- ( cd "$WORK" && printf '%s' "$(J "git commit -m \"\$(rm -f '$SENT')\"")" | bash "$GUARD" >/dev/null 2>&1 )
70
- [ -f "$SENT" ] && pass "sentinel survived (no execution)" || fail "sentinel deleted - command executed"
71
-
72
- echo ""
73
- echo "══ agent-guard smoke: $PASS passed, $FAIL failed ══"
74
- [ "$FAIL" -eq 0 ]