@mmerterden/multi-agent-pipeline 11.2.0 → 11.3.1

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 (335) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +2 -2
  3. package/docs/FIGMA_PIPELINE.md +12 -25
  4. package/docs/architecture.md +3 -5
  5. package/docs/features.md +8 -8
  6. package/install/_dev-only-files.mjs +0 -6
  7. package/install/claude.mjs +39 -17
  8. package/install/copilot.mjs +22 -16
  9. package/install/templates/copilot-instructions.md +3 -3
  10. package/package.json +1 -1
  11. package/pipeline/commands/{multi-agent.md → multi-agent/SKILL.md} +39 -39
  12. package/pipeline/commands/multi-agent/{analysis.md → analysis/SKILL.md} +18 -18
  13. package/pipeline/commands/multi-agent/{analysis-resolve.md → analysis-resolve/SKILL.md} +4 -4
  14. package/pipeline/commands/multi-agent/{autopilot.md → autopilot/SKILL.md} +4 -4
  15. package/pipeline/commands/multi-agent/{build-optimize.md → build-optimize/SKILL.md} +1 -1
  16. package/pipeline/commands/multi-agent/{channels.md → channels/SKILL.md} +12 -12
  17. package/pipeline/commands/multi-agent/{dev.md → dev/SKILL.md} +4 -4
  18. package/pipeline/commands/multi-agent/{dev-autopilot.md → dev-autopilot/SKILL.md} +4 -4
  19. package/pipeline/commands/multi-agent/{dev-local.md → dev-local/SKILL.md} +5 -5
  20. package/pipeline/commands/multi-agent/{dev-local-autopilot.md → dev-local-autopilot/SKILL.md} +4 -4
  21. package/pipeline/commands/multi-agent/{finish.md → finish/SKILL.md} +6 -6
  22. package/pipeline/commands/multi-agent/{generate.md → generate/SKILL.md} +3 -3
  23. package/pipeline/commands/multi-agent/{help.md → help/SKILL.md} +4 -4
  24. package/pipeline/commands/multi-agent/{local.md → local/SKILL.md} +5 -5
  25. package/pipeline/commands/multi-agent/{local-autopilot.md → local-autopilot/SKILL.md} +5 -5
  26. package/pipeline/commands/multi-agent/{manual-test.md → manual-test/SKILL.md} +1 -1
  27. package/pipeline/commands/multi-agent/refactor/SKILL.md +257 -0
  28. package/pipeline/commands/multi-agent/{resume.md → resume/SKILL.md} +1 -1
  29. package/pipeline/commands/multi-agent/{review.md → review/SKILL.md} +5 -5
  30. package/pipeline/commands/multi-agent/{setup.md → setup/SKILL.md} +1 -1
  31. package/pipeline/commands/multi-agent/{sync.md → sync/SKILL.md} +20 -58
  32. package/pipeline/lib/credential-store.sh +8 -4
  33. package/pipeline/{commands/multi-agent → multi-agent-refs}/_account-picker.md +2 -2
  34. package/pipeline/{commands/multi-agent → multi-agent-refs}/_dev-context.md +2 -2
  35. package/pipeline/{commands/multi-agent → multi-agent-refs}/_repo-picker.md +2 -2
  36. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/android-guide.md +1 -1
  37. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/jira.md +1 -1
  38. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/wiki.md +7 -7
  39. package/pipeline/multi-agent-refs/component-dispatch.md +92 -0
  40. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/cross-cli-contract.md +10 -77
  41. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/verify-by-test.md +1 -1
  42. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/generate-issue.md +2 -2
  43. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/issue-jira-triad.md +1 -1
  44. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/keychain.md +1 -1
  45. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/log-format.md +1 -1
  46. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/modes.md +2 -2
  47. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/operations.md +1 -1
  48. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/phase-0-init.md +10 -10
  49. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/phase-1-analysis.md +6 -6
  50. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/phase-2-planning.md +3 -3
  51. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/phase-3-dev.md +10 -10
  52. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/phase-4-review.md +8 -8
  53. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/phase-5-test.md +3 -3
  54. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/phase-6-commit.md +4 -4
  55. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases/phase-7-report.md +6 -6
  56. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/phases.md +12 -12
  57. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/progress-contract.md +4 -4
  58. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/swiftui-guide.md +1 -1
  59. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/tracker-contract.md +3 -3
  60. package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/wiki-capture.md +4 -4
  61. package/pipeline/preferences-template.json +17 -1
  62. package/pipeline/rules/figma-pipeline.md +2 -2
  63. package/pipeline/schemas/prefs.schema.json +0 -34
  64. package/pipeline/scripts/README.md +1 -3
  65. package/pipeline/scripts/build-skills-index.mjs +3 -6
  66. package/pipeline/scripts/eval-mine-corpus.mjs +187 -0
  67. package/pipeline/scripts/fixtures/install-layout.tsv +6 -5
  68. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -3
  69. package/pipeline/scripts/lint-skills.mjs +26 -1
  70. package/pipeline/scripts/phase-banner.sh +2 -2
  71. package/pipeline/scripts/review-scope.mjs +94 -0
  72. package/pipeline/scripts/scan-agent-config.sh +2 -2
  73. package/pipeline/scripts/smoke-agent-log-cost.sh +1 -1
  74. package/pipeline/scripts/smoke-agent-model-routing.sh +4 -4
  75. package/pipeline/scripts/smoke-autopilot-circuit-breaker.sh +2 -2
  76. package/pipeline/scripts/smoke-channels-approval-gate.sh +2 -2
  77. package/pipeline/scripts/smoke-channels-flow.sh +5 -5
  78. package/pipeline/scripts/smoke-clarify.sh +1 -1
  79. package/pipeline/scripts/smoke-commands-skills-parity.sh +3 -3
  80. package/pipeline/scripts/smoke-community-gates.sh +1 -1
  81. package/pipeline/scripts/smoke-compliance-skills.sh +2 -2
  82. package/pipeline/scripts/smoke-cost-summary.sh +1 -1
  83. package/pipeline/scripts/smoke-cross-cli-behavior.sh +17 -43
  84. package/pipeline/scripts/smoke-cross-phase-cohesion.sh +1 -1
  85. package/pipeline/scripts/smoke-dev-critic.sh +1 -1
  86. package/pipeline/scripts/smoke-diff-explain.sh +1 -1
  87. package/pipeline/scripts/smoke-diff-risk.sh +1 -1
  88. package/pipeline/scripts/smoke-evidence-gate.sh +1 -1
  89. package/pipeline/scripts/smoke-figma-dispatch.sh +46 -57
  90. package/pipeline/scripts/smoke-gate-hooks.sh +1 -1
  91. package/pipeline/scripts/smoke-generate-issue.sh +8 -8
  92. package/pipeline/scripts/smoke-handoff-contract.sh +3 -3
  93. package/pipeline/scripts/smoke-identity-isolation.sh +2 -2
  94. package/pipeline/scripts/smoke-intent-guard.sh +1 -1
  95. package/pipeline/scripts/smoke-issue-comment-template.sh +2 -2
  96. package/pipeline/scripts/smoke-issue-jira-triad.sh +4 -4
  97. package/pipeline/scripts/smoke-language-axis.sh +6 -6
  98. package/pipeline/scripts/smoke-learnings-ledger.sh +3 -3
  99. package/pipeline/scripts/smoke-mode-dispatch-drift.sh +16 -16
  100. package/pipeline/scripts/smoke-model-fallback.sh +3 -3
  101. package/pipeline/scripts/smoke-multi-repo-integration.sh +2 -2
  102. package/pipeline/scripts/smoke-multi-repo-worktree.sh +1 -1
  103. package/pipeline/scripts/smoke-no-token-prompt.sh +5 -5
  104. package/pipeline/scripts/smoke-phase-0-multi-repo.sh +1 -1
  105. package/pipeline/scripts/smoke-phase-6-multi.sh +1 -1
  106. package/pipeline/scripts/smoke-phase4-gates.sh +45 -0
  107. package/pipeline/scripts/smoke-plan-approval-gate.sh +5 -5
  108. package/pipeline/scripts/smoke-plan-todos.sh +3 -3
  109. package/pipeline/scripts/smoke-pr-review-actions.sh +3 -3
  110. package/pipeline/scripts/smoke-prefs-language.sh +1 -1
  111. package/pipeline/scripts/smoke-progress-contract.sh +2 -2
  112. package/pipeline/scripts/smoke-push-retry.sh +1 -1
  113. package/pipeline/scripts/smoke-repo-map.sh +2 -2
  114. package/pipeline/scripts/smoke-shadow-git.sh +1 -1
  115. package/pipeline/scripts/smoke-skill-authoring.sh +4 -9
  116. package/pipeline/scripts/smoke-tasklist-ordering.sh +10 -10
  117. package/pipeline/scripts/smoke-test-gap.sh +1 -1
  118. package/pipeline/scripts/smoke-token-budget.sh +1 -1
  119. package/pipeline/scripts/smoke-token-preflight.sh +2 -2
  120. package/pipeline/scripts/smoke-tracker-contract.sh +13 -13
  121. package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +5 -5
  122. package/pipeline/scripts/smoke-triage-memory.sh +2 -2
  123. package/pipeline/scripts/smoke-update-check.sh +1 -1
  124. package/pipeline/scripts/smoke-url-enrichment.sh +2 -2
  125. package/pipeline/scripts/smoke-validator-gates.sh +1 -1
  126. package/pipeline/scripts/smoke-verify-by-test.sh +3 -3
  127. package/pipeline/scripts/smoke-wiki-integration.sh +9 -33
  128. package/pipeline/scripts/smoke-work-summary.sh +1 -1
  129. package/pipeline/scripts/smoke-worktree-path-convention.sh +4 -4
  130. package/pipeline/scripts/test-integrity-gate.mjs +83 -0
  131. package/pipeline/scripts/uninstall.mjs +17 -6
  132. package/pipeline/skills/.skill-manifest.json +40 -160
  133. package/pipeline/skills/.skills-index.json +3 -373
  134. package/pipeline/skills/shared/README.md +1 -1
  135. package/pipeline/skills/shared/core/multi-agent/SKILL.md +1 -1
  136. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +2 -2
  137. package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +3 -3
  138. package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +1 -1
  139. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +1 -1
  140. package/pipeline/skills/shared/core/multi-agent-finish/SKILL.md +1 -1
  141. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +1 -1
  142. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +116 -51
  143. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +8 -30
  144. package/pipeline/skills/shared/external/compose-components/SKILL.md +14 -14
  145. package/pipeline/skills/skills-index.md +3 -44
  146. package/pipeline/commands/multi-agent/refactor.md +0 -188
  147. package/pipeline/commands/multi-agent/refs/component-dispatch.md +0 -92
  148. package/pipeline/scripts/smoke-existing-discovery-gate.sh +0 -71
  149. package/pipeline/scripts/smoke-figma-android-parity.sh +0 -148
  150. package/pipeline/scripts/smoke-figma-credential-store.sh +0 -105
  151. package/pipeline/scripts/smoke-figma-cross-cli-inventory.sh +0 -177
  152. package/pipeline/scripts/smoke-figma-sync.sh +0 -149
  153. package/pipeline/scripts/smoke-sync-delegation.sh +0 -74
  154. package/pipeline/skills/figma-android/README.md +0 -38
  155. package/pipeline/skills/figma-android/figma-component-code-connect/SKILL.md +0 -62
  156. package/pipeline/skills/figma-android/figma-component-implement/SKILL.md +0 -158
  157. package/pipeline/skills/figma-android/figma-component-test/SKILL.md +0 -120
  158. package/pipeline/skills/figma-android/figma-component-wiki/SKILL.md +0 -35
  159. package/pipeline/skills/figma-android/figma-to-component/SKILL.md +0 -124
  160. package/pipeline/skills/figma-common/README.md +0 -64
  161. package/pipeline/skills/figma-common/figma-bottom-sheets/SKILL.md +0 -152
  162. package/pipeline/skills/figma-common/figma-cli-iterate/SKILL.md +0 -282
  163. package/pipeline/skills/figma-common/figma-cli-iterate-mend/SKILL.md +0 -503
  164. package/pipeline/skills/figma-common/figma-cli-lean-iterate/SKILL.md +0 -288
  165. package/pipeline/skills/figma-common/figma-cli-skip/SKILL.md +0 -362
  166. package/pipeline/skills/figma-common/figma-commit/COMMON_REBASE.md +0 -206
  167. package/pipeline/skills/figma-common/figma-commit/REVIEW.md +0 -337
  168. package/pipeline/skills/figma-common/figma-commit/SKILL.md +0 -216
  169. package/pipeline/skills/figma-common/figma-component-confluence-sync/SKILL.md +0 -223
  170. package/pipeline/skills/figma-common/figma-component-start/SKILL.md +0 -251
  171. package/pipeline/skills/figma-common/figma-component-status-update/SKILL.md +0 -78
  172. package/pipeline/skills/figma-common/figma-evolve-component/SKILL.md +0 -61
  173. package/pipeline/skills/figma-common/figma-fix/SKILL.md +0 -321
  174. package/pipeline/skills/figma-common/figma-form-integration/SKILL.md +0 -542
  175. package/pipeline/skills/figma-common/figma-issue/SKILL.md +0 -750
  176. package/pipeline/skills/figma-common/figma-iterate/SKILL.md +0 -208
  177. package/pipeline/skills/figma-common/figma-iteration-commit/SKILL.md +0 -1020
  178. package/pipeline/skills/figma-common/figma-mend/SKILL.md +0 -331
  179. package/pipeline/skills/figma-common/figma-navigation/SKILL.md +0 -156
  180. package/pipeline/skills/figma-common/figma-overlays/SKILL.md +0 -142
  181. package/pipeline/skills/figma-common/figma-price-integration/SKILL.md +0 -398
  182. package/pipeline/skills/figma-common/figma-remote-mcp-auth/SKILL.md +0 -104
  183. package/pipeline/skills/figma-common/figma-review/SKILL.md +0 -400
  184. package/pipeline/skills/figma-common/figma-setup/SKILL.md +0 -514
  185. package/pipeline/skills/figma-common/figma-setup/scripts/fetch-mcp-token.py +0 -592
  186. package/pipeline/skills/figma-common/figma-skip/SKILL.md +0 -129
  187. package/pipeline/skills/figma-common/figma-ui-patterns/SKILL.md +0 -105
  188. package/pipeline/skills/figma-common/figma-ui-patterns/patterns/animated-gradient-border.md +0 -116
  189. package/pipeline/skills/figma-common/figma-utility/SKILL.md +0 -274
  190. package/pipeline/skills/figma-common/figma-utility/scripts/figma-utility.py +0 -808
  191. package/pipeline/skills/figma-common/figma-validate/SKILL.md +0 -633
  192. package/pipeline/skills/figma-common/performance-iteration-commit-all/SKILL.md +0 -716
  193. package/pipeline/skills/figma-common/performance-review-next/SKILL.md +0 -238
  194. package/pipeline/skills/figma-common/performance-start/SKILL.md +0 -430
  195. package/pipeline/skills/figma-common/performance-swiftui/SKILL.md +0 -706
  196. package/pipeline/skills/figma-common/performance-tour/SKILL.md +0 -423
  197. package/pipeline/skills/figma-ios/REVIEW_CHECKLIST.md +0 -67
  198. package/pipeline/skills/figma-ios/figma-component-code-connect/SKILL.md +0 -178
  199. package/pipeline/skills/figma-ios/figma-component-implement/SKILL.md +0 -184
  200. package/pipeline/skills/figma-ios/figma-component-test/SKILL.md +0 -219
  201. package/pipeline/skills/figma-ios/figma-component-wiki/SKILL.md +0 -274
  202. package/pipeline/skills/figma-ios/figma-to-component/SKILL.md +0 -416
  203. package/pipeline/skills/figma-ios/figma-to-component/halt-return-protocol.md +0 -57
  204. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-0-init.md +0 -307
  205. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-1-gathering.md +0 -119
  206. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-1.5-existing-discovery.md +0 -174
  207. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2-orchestrator.md +0 -333
  208. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2a-testing-identifiers.md +0 -368
  209. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2b-localization.md +0 -393
  210. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2c-accessibility.md +0 -617
  211. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2d-analytics.md +0 -352
  212. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3-orchestrator.md +0 -337
  213. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3a-location.md +0 -206
  214. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3b-tokens.md +0 -235
  215. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3c-nested.md +0 -214
  216. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3d-patterns.md +0 -902
  217. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3e-assets.md +0 -156
  218. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3f-utilities.md +0 -175
  219. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3g-property-coverage.md +0 -176
  220. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3h-variant-config.md +0 -333
  221. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4-orchestrator.md +0 -412
  222. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4a-configuration.md +0 -336
  223. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4b-view.md +0 -705
  224. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4c-documentation.md +0 -332
  225. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4d-preview.md +0 -380
  226. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4e-modifiers.md +0 -262
  227. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5-orchestrator.md +0 -482
  228. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5a-viewinspector.md +0 -274
  229. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5b-snapshot.md +0 -636
  230. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5c-unit.md +0 -142
  231. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-6-code-connect.md +0 -547
  232. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7-wiki.md +0 -39
  233. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7a-confluence-generate.md +0 -659
  234. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7a-wiki-generate.md +0 -580
  235. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-8-cleanup.md +0 -51
  236. package/pipeline/skills/figma-ios/figma-to-component/reference/accessibility.md +0 -183
  237. package/pipeline/skills/figma-ios/figma-to-component/reference/analytics-events.md +0 -64
  238. package/pipeline/skills/figma-ios/figma-to-component/reference/code-connect.md +0 -531
  239. package/pipeline/skills/figma-ios/figma-to-component/reference/confluence-api.md +0 -89
  240. package/pipeline/skills/figma-ios/figma-to-component/reference/confluence-xhtml.md +0 -155
  241. package/pipeline/skills/figma-ios/figma-to-component/reference/figma-to-swiftui-effects.md +0 -196
  242. package/pipeline/skills/figma-ios/figma-to-component/reference/halt-return-protocol.md +0 -57
  243. package/pipeline/skills/figma-ios/figma-to-component/reference/localization-naming.md +0 -89
  244. package/pipeline/skills/figma-ios/figma-to-component/reference/macros.md +0 -227
  245. package/pipeline/skills/figma-ios/figma-to-component/reference/missing-tokens.md +0 -157
  246. package/pipeline/skills/figma-ios/figma-to-component/reference/orchestrator-discipline.md +0 -90
  247. package/pipeline/skills/figma-ios/figma-to-component/reference/registry.md +0 -116
  248. package/pipeline/skills/figma-ios/figma-to-component/reference/remote-mcp-script.md +0 -153
  249. package/pipeline/skills/figma-ios/figma-to-component/reference/rest-api-script.md +0 -130
  250. package/pipeline/skills/figma-ios/figma-to-component/reference/scripts-inventory.md +0 -218
  251. package/pipeline/skills/figma-ios/figma-to-component/reference/snapshot-testing.md +0 -188
  252. package/pipeline/skills/figma-ios/figma-to-component/reference/subcomponent-graph.md +0 -93
  253. package/pipeline/skills/figma-ios/figma-to-component/reference/testing-identifiers-naming.md +0 -98
  254. package/pipeline/skills/figma-ios/figma-to-component/reference/tools.md +0 -261
  255. package/pipeline/skills/figma-ios/figma-to-component/reference/viewinspector.md +0 -147
  256. package/pipeline/skills/figma-ios/figma-to-component/reference/wiki-to-confluence-mapping.md +0 -182
  257. package/pipeline/skills/figma-ios/figma-to-component/scripts/apply-author-login-map.py +0 -185
  258. package/pipeline/skills/figma-ios/figma-to-component/scripts/backfill-status.py +0 -609
  259. package/pipeline/skills/figma-ios/figma-to-component/scripts/build-author-registry.py +0 -332
  260. package/pipeline/skills/figma-ios/figma-to-component/scripts/bulk-sync-issues.py +0 -261
  261. package/pipeline/skills/figma-ios/figma-to-component/scripts/code-connect-data-gather.py +0 -184
  262. package/pipeline/skills/figma-ios/figma-to-component/scripts/code-connect-publish.sh +0 -188
  263. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-component-status-upload.py +0 -768
  264. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-component-status.py +0 -191
  265. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-data-gather.py +0 -420
  266. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-page-ids.example.json +0 -9
  267. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-publish.py +0 -336
  268. package/pipeline/skills/figma-ios/figma-to-component/scripts/figma-subcomponent-graph.py +0 -391
  269. package/pipeline/skills/figma-ios/figma-to-component/scripts/figma-update.py +0 -292
  270. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/__init__.py +0 -1
  271. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/issue_sync_propagate.py +0 -93
  272. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/registry_writer.py +0 -299
  273. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_backfill_status.py +0 -343
  274. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_figma_update.py +0 -206
  275. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_figma_update_http.py +0 -149
  276. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_phase_clis.py +0 -281
  277. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_registry_writer.py +0 -332
  278. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_skill_figma_issue.py +0 -176
  279. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_skill_figma_review.py +0 -98
  280. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_update_issue.py +0 -298
  281. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_update_issue_gh.py +0 -195
  282. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase1-gather.py +0 -1298
  283. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase2-finalize.py +0 -228
  284. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase3-scripts.py +0 -1089
  285. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase4-finalize.py +0 -141
  286. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase5-finalize.py +0 -106
  287. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase6-finalize.py +0 -162
  288. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase7-finalize.py +0 -105
  289. package/pipeline/skills/figma-ios/figma-to-component/scripts/register-icons-codeconnect.py +0 -179
  290. package/pipeline/skills/figma-ios/figma-to-component/scripts/remote-mcp-fetch.py +0 -260
  291. package/pipeline/skills/figma-ios/figma-to-component/scripts/resolve-author-logins.py +0 -260
  292. package/pipeline/skills/figma-ios/figma-to-component/scripts/run-uicomponents-tests.sh +0 -86
  293. package/pipeline/skills/figma-ios/figma-to-component/scripts/sidebar-generator.py +0 -321
  294. package/pipeline/skills/figma-ios/figma-to-component/scripts/update-issue-from-registry.py +0 -1470
  295. package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase4.sh +0 -176
  296. package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase6.sh +0 -147
  297. package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase7a.py +0 -629
  298. /package/pipeline/commands/multi-agent/{delete.md → delete/SKILL.md} +0 -0
  299. /package/pipeline/commands/multi-agent/{diff-explain.md → diff-explain/SKILL.md} +0 -0
  300. /package/pipeline/commands/multi-agent/{garbage-collect.md → garbage-collect/SKILL.md} +0 -0
  301. /package/pipeline/commands/multi-agent/{issue.md → issue/SKILL.md} +0 -0
  302. /package/pipeline/commands/multi-agent/{jira.md → jira/SKILL.md} +0 -0
  303. /package/pipeline/commands/multi-agent/{kill.md → kill/SKILL.md} +0 -0
  304. /package/pipeline/commands/multi-agent/{language.md → language/SKILL.md} +0 -0
  305. /package/pipeline/commands/multi-agent/{log.md → log/SKILL.md} +0 -0
  306. /package/pipeline/commands/multi-agent/{prune-logs.md → prune-logs/SKILL.md} +0 -0
  307. /package/pipeline/commands/multi-agent/{purge.md → purge/SKILL.md} +0 -0
  308. /package/pipeline/commands/multi-agent/{scan.md → scan/SKILL.md} +0 -0
  309. /package/pipeline/commands/multi-agent/{search.md → search/SKILL.md} +0 -0
  310. /package/pipeline/commands/multi-agent/{stack.md → stack/SKILL.md} +0 -0
  311. /package/pipeline/commands/multi-agent/{status.md → status/SKILL.md} +0 -0
  312. /package/pipeline/commands/multi-agent/{test.md → test/SKILL.md} +0 -0
  313. /package/pipeline/commands/multi-agent/{update.md → update/SKILL.md} +0 -0
  314. /package/pipeline/{commands/multi-agent → multi-agent-refs}/_input-parser.md +0 -0
  315. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/analysis-template.md +0 -0
  316. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/audit-guide.md +0 -0
  317. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/backend-guide.md +0 -0
  318. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/confluence.md +0 -0
  319. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/issue-comment.md +0 -0
  320. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/pr-review-actions.md +0 -0
  321. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/pr.md +0 -0
  322. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/conventions-defaults.md +0 -0
  323. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/autopilot-circuit-breaker.md +0 -0
  324. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/dev-critic.md +0 -0
  325. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/external-context-injection.md +0 -0
  326. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/model-fallback.md +0 -0
  327. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/plan-todos.md +0 -0
  328. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/prior-fix-detection.md +0 -0
  329. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/repo-map.md +0 -0
  330. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/shadow-git.md +0 -0
  331. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/frontend-guide.md +0 -0
  332. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/knowledge.md +0 -0
  333. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/multi-repo-integration-build.md +0 -0
  334. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/picker-contract.md +0 -0
  335. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/rules.md +0 -0
@@ -1,332 +0,0 @@
1
- #!/usr/bin/env python3
2
- """build-author-registry.py - walk registry components, git-blame each
3
- swift file, build a reviewable author registry before ANY issue touch.
4
-
5
- For every registry entry that has a swift file under Sources/, runs
6
- `git blame --line-porcelain` and counts the number of lines attributed
7
- to each author. Outputs two artifacts:
8
-
9
- temp/authors-registry.json
10
- {
11
- "meta": { "generated_at": "...", "component_count": N, "distinct_authors": N },
12
- "authors": {
13
- "<author-name>": {
14
- "lines_total": int,
15
- "components": [<componentName>, ...],
16
- "looks_like_github_login": bool # heuristic
17
- },
18
- ...
19
- },
20
- "per_component": {
21
- "<node_id>": {
22
- "componentName": str,
23
- "swift_file": str,
24
- "primary_author": str,
25
- "primary_lines": int,
26
- "all_authors": [
27
- { "name": str, "lines": int },
28
- ...
29
- ]
30
- },
31
- ...
32
- }
33
- }
34
-
35
- temp/authors-needing-mapping.json
36
- Just the authors whose display name doesn't look like a GitHub
37
- login (has spaces, too long, etc). Provided for the human
38
- reviewer to add a mapping to real GitHub usernames later.
39
-
40
- No writes to component registry JSONs, no writes to GitHub. This is a
41
- pure observation pass that produces two files in temp/ for review.
42
-
43
- Usage:
44
- python3 build-author-registry.py \\
45
- [--registry-dir /path] \\
46
- [--uicomponents-repo /path] \\
47
- [--limit N]
48
-
49
- Exit codes:
50
- 0 - success (even with some per-component errors)
51
- 1 - setup error (bad paths)
52
- """
53
-
54
- import argparse
55
- import json
56
- import re
57
- import subprocess
58
- import sys
59
- from collections import Counter
60
- from datetime import datetime, timezone
61
- from pathlib import Path
62
- from typing import Dict, List, Optional
63
-
64
-
65
- def find_repo_root() -> Path:
66
- p = Path.cwd()
67
- while p != p.parent:
68
- if (p / ".git").exists():
69
- return p
70
- p = p.parent
71
- return Path.cwd()
72
-
73
-
74
- def default_registry_dir() -> Path:
75
- return (
76
- find_repo_root()
77
- / "{repos.packagesContainer}"
78
- / "Packages"
79
- / "{project.slug}-common"
80
- / "Shared"
81
- / "Figma"
82
- / "Components"
83
- )
84
-
85
-
86
- def default_uicomponents_repo() -> Path:
87
- return (
88
- find_repo_root()
89
- / "{repos.packagesContainer}"
90
- / "Packages"
91
- / "{project.slug}-components"
92
- )
93
-
94
-
95
- def default_temp_dir() -> Path:
96
- return find_repo_root() / "temp"
97
-
98
-
99
- # --------------------------------------------------------------------
100
- # Heuristic - does a git author name look like a GitHub login?
101
- # --------------------------------------------------------------------
102
-
103
- _GH_LOGIN_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9\-_]{0,38}$")
104
-
105
-
106
- def looks_like_github_login(name: str) -> bool:
107
- if not isinstance(name, str):
108
- return False
109
- return bool(_GH_LOGIN_RE.match(name))
110
-
111
-
112
- # --------------------------------------------------------------------
113
- # git blame parsing
114
- # --------------------------------------------------------------------
115
-
116
- def git_blame_line_counts(source_file: Path, repo_root: Path) -> Counter:
117
- """Return {author_name: line_count} for one file via git blame.
118
-
119
- Uses --line-porcelain for stable parsing. Returns an empty Counter
120
- if the file is missing, git fails, or the blame output is empty.
121
- """
122
- if not source_file.exists():
123
- return Counter()
124
- try:
125
- rel = source_file.relative_to(repo_root)
126
- except ValueError:
127
- rel = source_file
128
- try:
129
- r = subprocess.run(
130
- ["git", "-C", str(repo_root), "blame", "--line-porcelain", "--", str(rel)],
131
- capture_output=True,
132
- text=True,
133
- check=False,
134
- timeout=30,
135
- )
136
- except (subprocess.SubprocessError, FileNotFoundError):
137
- return Counter()
138
- if r.returncode != 0:
139
- return Counter()
140
-
141
- counts: Counter = Counter()
142
- for line in r.stdout.splitlines():
143
- if line.startswith("author "):
144
- author = line[len("author "):].strip()
145
- if author:
146
- counts[author] += 1
147
- return counts
148
-
149
-
150
- # --------------------------------------------------------------------
151
- # Component discovery
152
- # --------------------------------------------------------------------
153
-
154
- def build_swift_file_index(sources_dir: Path) -> Dict[str, Path]:
155
- """Walk Sources/, return { base_name: first_matching_path }."""
156
- index: Dict[str, Path] = {}
157
- if not sources_dir.exists():
158
- return index
159
- for swift in sources_dir.rglob("*.swift"):
160
- base = swift.stem
161
- if base not in index:
162
- index[base] = swift
163
- return index
164
-
165
-
166
- def component_name_ios(raw) -> Optional[str]:
167
- if isinstance(raw, dict):
168
- return raw.get("ios")
169
- if isinstance(raw, str) and raw:
170
- return raw
171
- return None
172
-
173
-
174
- # --------------------------------------------------------------------
175
- # Main pass
176
- # --------------------------------------------------------------------
177
-
178
- def build(
179
- registry_dir: Path,
180
- uicomponents_repo: Path,
181
- limit: Optional[int] = None,
182
- ) -> dict:
183
- sources_dir = uicomponents_repo / "Sources"
184
- swift_index = build_swift_file_index(sources_dir)
185
-
186
- registry_files = sorted(registry_dir.glob("*.json"))
187
- if limit is not None:
188
- registry_files = registry_files[:limit]
189
-
190
- per_component: Dict[str, dict] = {}
191
- authors_global: Dict[str, dict] = {}
192
- skipped_no_swift: List[str] = []
193
- errors: List[dict] = []
194
-
195
- for idx, path in enumerate(registry_files, 1):
196
- try:
197
- entry = json.loads(path.read_text(encoding="utf-8"))
198
- except (json.JSONDecodeError, OSError) as e:
199
- errors.append({"file": path.name, "error": str(e)})
200
- continue
201
-
202
- node_id = entry.get("nodeId") or path.stem.replace("-", ":")
203
- if entry.get("skip"):
204
- continue
205
-
206
- cn = component_name_ios(entry.get("componentName"))
207
- if not cn:
208
- continue
209
-
210
- swift_path = swift_index.get(cn)
211
- if not swift_path:
212
- skipped_no_swift.append(node_id)
213
- continue
214
-
215
- line_counts = git_blame_line_counts(swift_path, uicomponents_repo)
216
- if not line_counts:
217
- continue
218
-
219
- # Sort by line count desc
220
- all_authors_sorted = sorted(line_counts.items(), key=lambda kv: -kv[1])
221
- primary_name, primary_lines = all_authors_sorted[0]
222
-
223
- per_component[node_id] = {
224
- "componentName": cn,
225
- "swift_file": str(swift_path.relative_to(uicomponents_repo)),
226
- "primary_author": primary_name,
227
- "primary_lines": primary_lines,
228
- "all_authors": [
229
- {"name": name, "lines": lines}
230
- for name, lines in all_authors_sorted
231
- ],
232
- }
233
-
234
- for name, lines in line_counts.items():
235
- record = authors_global.setdefault(name, {
236
- "lines_total": 0,
237
- "components": [],
238
- "looks_like_github_login": looks_like_github_login(name),
239
- })
240
- record["lines_total"] += lines
241
- if cn not in record["components"]:
242
- record["components"].append(cn)
243
-
244
- if idx % 25 == 0:
245
- print(f" processed {idx}/{len(registry_files)} ...", file=sys.stderr)
246
-
247
- return {
248
- "meta": {
249
- "generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
250
- "component_count": len(per_component),
251
- "distinct_authors": len(authors_global),
252
- "skipped_no_swift": len(skipped_no_swift),
253
- "read_errors": len(errors),
254
- },
255
- "authors": authors_global,
256
- "per_component": per_component,
257
- "errors": errors,
258
- }
259
-
260
-
261
- def main() -> int:
262
- parser = argparse.ArgumentParser(
263
- description="Build a reviewable author registry via git blame",
264
- )
265
- parser.add_argument("--registry-dir")
266
- parser.add_argument("--uicomponents-repo")
267
- parser.add_argument("--temp-dir")
268
- parser.add_argument("--limit", type=int, help="Process at most N components (smoke-test)")
269
- args = parser.parse_args()
270
-
271
- registry_dir = Path(args.registry_dir) if args.registry_dir else default_registry_dir()
272
- uicomponents_repo = Path(args.uicomponents_repo) if args.uicomponents_repo else default_uicomponents_repo()
273
- temp_dir = Path(args.temp_dir) if args.temp_dir else default_temp_dir()
274
-
275
- if not registry_dir.exists():
276
- print(f"ERROR: registry directory does not exist: {registry_dir}", file=sys.stderr)
277
- return 1
278
- if not uicomponents_repo.exists():
279
- print(f"ERROR: uicomponents repo does not exist: {uicomponents_repo}", file=sys.stderr)
280
- return 1
281
-
282
- temp_dir.mkdir(parents=True, exist_ok=True)
283
-
284
- result = build(registry_dir=registry_dir, uicomponents_repo=uicomponents_repo, limit=args.limit)
285
-
286
- registry_file = temp_dir / "authors-registry.json"
287
- registry_file.write_text(
288
- json.dumps(result, indent=2, ensure_ascii=False) + "\n",
289
- encoding="utf-8",
290
- )
291
-
292
- # Second artifact: just the authors needing mapping
293
- needing = {
294
- name: info
295
- for name, info in result["authors"].items()
296
- if not info.get("looks_like_github_login")
297
- }
298
- # Sort by lines_total desc for reviewer convenience
299
- needing_sorted = dict(
300
- sorted(needing.items(), key=lambda kv: -kv[1]["lines_total"])
301
- )
302
- mapping_file = temp_dir / "authors-needing-mapping.json"
303
- mapping_file.write_text(
304
- json.dumps({
305
- "meta": result["meta"],
306
- "authors": needing_sorted,
307
- "suggestions": (
308
- "Each author above has a display name that doesn't look "
309
- "like a GitHub login (contains spaces or exceeds login "
310
- "length). Add a mapping here before running issue sync:\n"
311
- " {display_name} → {github_login}"
312
- ),
313
- }, indent=2, ensure_ascii=False) + "\n",
314
- encoding="utf-8",
315
- )
316
-
317
- summary = {
318
- "status": "ok",
319
- "registry_file": str(registry_file),
320
- "mapping_file": str(mapping_file),
321
- "meta": result["meta"],
322
- "top_authors_by_lines": [
323
- {"name": n, "lines": info["lines_total"], "components": len(info["components"]), "login_like": info["looks_like_github_login"]}
324
- for n, info in sorted(result["authors"].items(), key=lambda kv: -kv[1]["lines_total"])[:15]
325
- ],
326
- }
327
- print(json.dumps(summary, indent=2, ensure_ascii=False))
328
- return 0
329
-
330
-
331
- if __name__ == "__main__":
332
- sys.exit(main())
@@ -1,261 +0,0 @@
1
- #!/usr/bin/env python3
2
- """bulk-sync-issues.py - sync every backfilled component's GitHub issue.
3
-
4
- Walks the component registry, picks every entry where
5
- `status.ios.implemented.value == true`, and invokes
6
- `update-issue-from-registry.py` for each node-id.
7
-
8
- By default runs with `--no-comment` so a 268-node bulk migration
9
- doesn't spam 268 notifications to reviewers. Pass `--with-comment`
10
- to override.
11
-
12
- Usage:
13
- # Dry-run - no gh calls, just print what would happen
14
- python3 bulk-sync-issues.py --dry-run
15
-
16
- # Real run on first 5 (smoke test)
17
- python3 bulk-sync-issues.py --limit 5
18
-
19
- # Full bulk migration (labels only, no comments)
20
- python3 bulk-sync-issues.py
21
-
22
- # Full bulk with sync comments
23
- python3 bulk-sync-issues.py --with-comment
24
-
25
- Exit codes:
26
- 0 - success (maybe with some per-node failures logged)
27
- 1 - setup error (bad path, missing dependency)
28
- """
29
-
30
- import argparse
31
- import json
32
- import subprocess
33
- import sys
34
- from pathlib import Path
35
- from typing import List
36
-
37
- SCRIPTS_DIR = Path(__file__).parent
38
- UPDATER = SCRIPTS_DIR / "update-issue-from-registry.py"
39
-
40
-
41
- def find_repo_root() -> Path:
42
- p = Path.cwd()
43
- while p != p.parent:
44
- if (p / ".git").exists():
45
- return p
46
- p = p.parent
47
- return Path.cwd()
48
-
49
-
50
- def default_registry_dir() -> Path:
51
- return (
52
- find_repo_root()
53
- / "{repos.packagesContainer}"
54
- / "Packages"
55
- / "{project.slug}-common"
56
- / "Shared"
57
- / "Figma"
58
- / "Components"
59
- )
60
-
61
-
62
- def _is_icon(data: dict) -> bool:
63
- cn = data.get("componentName")
64
- if isinstance(cn, dict):
65
- ios_name = cn.get("ios") or ""
66
- android_name = cn.get("android") or ""
67
- elif isinstance(cn, str):
68
- ios_name = cn
69
- android_name = ""
70
- else:
71
- return False
72
- if isinstance(ios_name, str) and ios_name.startswith("Image."):
73
- return True
74
- if isinstance(android_name, str) and android_name.startswith("Images."):
75
- return True
76
- return False
77
-
78
-
79
- def collect_backfilled_nodes(registry_dir: Path, platform: str) -> List[str]:
80
- """Return every node-id whose status.<platform>.implemented.value is true.
81
-
82
- Excludes:
83
- - entries with skip:true
84
- - icon entries (componentName starts with Image. or Images.)
85
- """
86
- result: List[str] = []
87
- for path in sorted(registry_dir.glob("*.json")):
88
- try:
89
- data = json.loads(path.read_text(encoding="utf-8"))
90
- except (json.JSONDecodeError, OSError):
91
- continue
92
- if data.get("skip"):
93
- continue
94
- if _is_icon(data):
95
- continue
96
- status = data.get("status")
97
- if not isinstance(status, dict):
98
- continue
99
- ps = status.get(platform, {})
100
- if not isinstance(ps, dict):
101
- continue
102
- impl = ps.get("implemented", {})
103
- if isinstance(impl, dict) and impl.get("value"):
104
- node_id = data.get("nodeId")
105
- if node_id:
106
- result.append(node_id)
107
- return result
108
-
109
-
110
- def run_updater_for_node(
111
- node_id: str,
112
- platform: str,
113
- repo: str,
114
- registry_dir: Path,
115
- dry_run: bool,
116
- team_label: str = "team:core",
117
- ) -> dict:
118
- """Invoke update-issue-from-registry.py for one node-id. Return parsed JSON."""
119
- args = [
120
- "python3", str(UPDATER),
121
- "--node-id", node_id,
122
- "--platform", platform,
123
- "--registry-dir", str(registry_dir),
124
- "--repo", repo,
125
- "--team-label", team_label,
126
- ]
127
- if dry_run:
128
- args.append("--dry-run")
129
-
130
- r = subprocess.run(args, capture_output=True, text=True, check=False)
131
- if r.returncode != 0:
132
- return {
133
- "node_id": node_id,
134
- "status": "error",
135
- "stderr": r.stderr.strip(),
136
- "stdout": r.stdout.strip(),
137
- }
138
- try:
139
- out = json.loads(r.stdout)
140
- out["node_id"] = node_id
141
- return out
142
- except json.JSONDecodeError:
143
- return {
144
- "node_id": node_id,
145
- "status": "error",
146
- "stderr": "could not parse updater output",
147
- "stdout": r.stdout,
148
- }
149
-
150
-
151
- def classify(result: dict) -> str:
152
- """Bucket the per-node result into a summary category."""
153
- if result.get("status") == "error":
154
- return "error"
155
- action = result.get("action")
156
- if action == "synced":
157
- return "synced"
158
- if action == "created":
159
- return "created"
160
- if action == "skip_marked_skip":
161
- return "skip_marked_skip"
162
- if action == "skip_icon":
163
- return "skip_icon"
164
- if result.get("dry_run"):
165
- return "dry_run"
166
- return "other"
167
-
168
-
169
- def main() -> int:
170
- parser = argparse.ArgumentParser(
171
- description="Bulk-sync GitHub issues from the backfilled registry",
172
- )
173
- parser.add_argument("--registry-dir", help="Override registry directory path")
174
- parser.add_argument("--platform", default="ios", choices=["ios", "android"])
175
- parser.add_argument(
176
- "--repo",
177
- default="{github.componentsRepo}",
178
- )
179
- parser.add_argument("--dry-run", action="store_true")
180
- parser.add_argument("--limit", type=int, help="Process at most N nodes")
181
- parser.add_argument(
182
- "--team-label",
183
- default="team:core",
184
- help="Team label to apply when creating missing issues (default: team:core)",
185
- )
186
- parser.add_argument(
187
- "--log-file",
188
- help="Write per-node JSON results to this file",
189
- )
190
- args = parser.parse_args()
191
-
192
- registry_dir = Path(args.registry_dir) if args.registry_dir else default_registry_dir()
193
- if not registry_dir.exists():
194
- print(f"ERROR: registry directory does not exist: {registry_dir}", file=sys.stderr)
195
- return 1
196
- if not UPDATER.exists():
197
- print(f"ERROR: updater script missing: {UPDATER}", file=sys.stderr)
198
- return 1
199
-
200
- nodes = collect_backfilled_nodes(registry_dir, args.platform)
201
- if args.limit is not None:
202
- nodes = nodes[: args.limit]
203
-
204
- print(f"Processing {len(nodes)} backfilled nodes (dry_run={args.dry_run})...",
205
- file=sys.stderr)
206
-
207
- results: List[dict] = []
208
- counts = {
209
- "synced": 0,
210
- "created": 0,
211
- "skip_marked_skip": 0,
212
- "skip_icon": 0,
213
- "dry_run": 0,
214
- "error": 0,
215
- "other": 0,
216
- }
217
-
218
- for i, node_id in enumerate(nodes, 1):
219
- result = run_updater_for_node(
220
- node_id=node_id,
221
- platform=args.platform,
222
- repo=args.repo,
223
- registry_dir=registry_dir,
224
- dry_run=args.dry_run,
225
- team_label=args.team_label,
226
- )
227
- bucket = classify(result)
228
- counts[bucket] = counts.get(bucket, 0) + 1
229
- results.append(result)
230
-
231
- if i % 25 == 0 or i == len(nodes):
232
- print(
233
- f" [{i}/{len(nodes)}] synced={counts['synced']} "
234
- f"created={counts['created']} "
235
- f"skip={counts['skip_marked_skip']} "
236
- f"dry_run={counts['dry_run']} "
237
- f"errors={counts['error']}",
238
- file=sys.stderr,
239
- )
240
-
241
- summary = {
242
- "status": "ok" if counts["error"] == 0 else "partial",
243
- "dry_run": args.dry_run,
244
- "total": len(nodes),
245
- "counts": counts,
246
- "errors": [r for r in results if r.get("status") == "error"][:10],
247
- }
248
- print(json.dumps(summary, indent=2, ensure_ascii=False))
249
-
250
- if args.log_file:
251
- Path(args.log_file).write_text(
252
- json.dumps(results, indent=2, ensure_ascii=False),
253
- encoding="utf-8",
254
- )
255
- print(f"\nPer-node results written to {args.log_file}", file=sys.stderr)
256
-
257
- return 0
258
-
259
-
260
- if __name__ == "__main__":
261
- sys.exit(main())