@mmerterden/multi-agent-pipeline 11.1.0 → 11.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/CHANGELOG.md +58 -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/_common.mjs +9 -1
  7. package/install/_dev-only-files.mjs +0 -6
  8. package/install/claude.mjs +45 -18
  9. package/install/copilot.mjs +16 -14
  10. package/install/templates/copilot-instructions.md +3 -3
  11. package/package.json +1 -1
  12. package/pipeline/commands/{multi-agent.md → multi-agent/SKILL.md} +39 -39
  13. package/pipeline/commands/multi-agent/{analysis.md → analysis/SKILL.md} +18 -18
  14. package/pipeline/commands/multi-agent/{analysis-resolve.md → analysis-resolve/SKILL.md} +4 -4
  15. package/pipeline/commands/multi-agent/{autopilot.md → autopilot/SKILL.md} +4 -4
  16. package/pipeline/commands/multi-agent/{build-optimize.md → build-optimize/SKILL.md} +1 -1
  17. package/pipeline/commands/multi-agent/{channels.md → channels/SKILL.md} +12 -12
  18. package/pipeline/commands/multi-agent/{dev.md → dev/SKILL.md} +4 -4
  19. package/pipeline/commands/multi-agent/{dev-autopilot.md → dev-autopilot/SKILL.md} +4 -4
  20. package/pipeline/commands/multi-agent/{dev-local.md → dev-local/SKILL.md} +5 -5
  21. package/pipeline/commands/multi-agent/{dev-local-autopilot.md → dev-local-autopilot/SKILL.md} +4 -4
  22. package/pipeline/commands/multi-agent/{finish.md → finish/SKILL.md} +6 -6
  23. package/pipeline/commands/multi-agent/{generate.md → generate/SKILL.md} +3 -3
  24. package/pipeline/commands/multi-agent/{help.md → help/SKILL.md} +4 -4
  25. package/pipeline/commands/multi-agent/{local.md → local/SKILL.md} +5 -5
  26. package/pipeline/commands/multi-agent/{local-autopilot.md → local-autopilot/SKILL.md} +5 -5
  27. package/pipeline/commands/multi-agent/{manual-test.md → manual-test/SKILL.md} +1 -1
  28. package/pipeline/commands/multi-agent/refactor/SKILL.md +257 -0
  29. package/pipeline/commands/multi-agent/{resume.md → resume/SKILL.md} +1 -1
  30. package/pipeline/commands/multi-agent/{review.md → review/SKILL.md} +5 -5
  31. package/pipeline/commands/multi-agent/{setup.md → setup/SKILL.md} +1 -1
  32. package/pipeline/commands/multi-agent/{sync.md → sync/SKILL.md} +20 -58
  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-stack-plugins.mjs +1 -1
  66. package/pipeline/scripts/fixtures/install-layout.tsv +6 -5
  67. package/pipeline/scripts/gen-mode-dispatch.mjs +3 -3
  68. package/pipeline/scripts/phase-banner.sh +2 -2
  69. package/pipeline/scripts/review-scope.mjs +94 -0
  70. package/pipeline/scripts/scan-agent-config.sh +2 -2
  71. package/pipeline/scripts/smoke-agent-log-cost.sh +1 -1
  72. package/pipeline/scripts/smoke-agent-model-routing.sh +4 -4
  73. package/pipeline/scripts/smoke-autopilot-circuit-breaker.sh +2 -2
  74. package/pipeline/scripts/smoke-channels-approval-gate.sh +2 -2
  75. package/pipeline/scripts/smoke-channels-flow.sh +5 -5
  76. package/pipeline/scripts/smoke-clarify.sh +1 -1
  77. package/pipeline/scripts/smoke-commands-skills-parity.sh +3 -3
  78. package/pipeline/scripts/smoke-community-gates.sh +1 -1
  79. package/pipeline/scripts/smoke-compliance-skills.sh +2 -2
  80. package/pipeline/scripts/smoke-cost-summary.sh +1 -1
  81. package/pipeline/scripts/smoke-cross-cli-behavior.sh +17 -43
  82. package/pipeline/scripts/smoke-cross-phase-cohesion.sh +1 -1
  83. package/pipeline/scripts/smoke-dev-critic.sh +1 -1
  84. package/pipeline/scripts/smoke-diff-explain.sh +1 -1
  85. package/pipeline/scripts/smoke-diff-risk.sh +1 -1
  86. package/pipeline/scripts/smoke-evidence-gate.sh +1 -1
  87. package/pipeline/scripts/smoke-figma-dispatch.sh +46 -57
  88. package/pipeline/scripts/smoke-gate-hooks.sh +1 -1
  89. package/pipeline/scripts/smoke-generate-issue.sh +8 -8
  90. package/pipeline/scripts/smoke-handoff-contract.sh +3 -3
  91. package/pipeline/scripts/smoke-identity-isolation.sh +2 -2
  92. package/pipeline/scripts/smoke-intent-guard.sh +1 -1
  93. package/pipeline/scripts/smoke-issue-comment-template.sh +2 -2
  94. package/pipeline/scripts/smoke-issue-jira-triad.sh +4 -4
  95. package/pipeline/scripts/smoke-language-axis.sh +6 -6
  96. package/pipeline/scripts/smoke-learnings-ledger.sh +3 -3
  97. package/pipeline/scripts/smoke-mode-dispatch-drift.sh +16 -16
  98. package/pipeline/scripts/smoke-model-fallback.sh +3 -3
  99. package/pipeline/scripts/smoke-multi-repo-integration.sh +2 -2
  100. package/pipeline/scripts/smoke-multi-repo-worktree.sh +1 -1
  101. package/pipeline/scripts/smoke-no-token-prompt.sh +5 -5
  102. package/pipeline/scripts/smoke-phase-0-multi-repo.sh +1 -1
  103. package/pipeline/scripts/smoke-phase-6-multi.sh +1 -1
  104. package/pipeline/scripts/smoke-phase4-gates.sh +45 -0
  105. package/pipeline/scripts/smoke-plan-approval-gate.sh +5 -5
  106. package/pipeline/scripts/smoke-plan-todos.sh +3 -3
  107. package/pipeline/scripts/smoke-pr-review-actions.sh +3 -3
  108. package/pipeline/scripts/smoke-prefs-language.sh +1 -1
  109. package/pipeline/scripts/smoke-progress-contract.sh +2 -2
  110. package/pipeline/scripts/smoke-push-retry.sh +1 -1
  111. package/pipeline/scripts/smoke-repo-map.sh +2 -2
  112. package/pipeline/scripts/smoke-shadow-git.sh +1 -1
  113. package/pipeline/scripts/smoke-skill-authoring.sh +4 -9
  114. package/pipeline/scripts/smoke-tasklist-ordering.sh +10 -10
  115. package/pipeline/scripts/smoke-test-gap.sh +1 -1
  116. package/pipeline/scripts/smoke-token-budget.sh +1 -1
  117. package/pipeline/scripts/smoke-token-preflight.sh +2 -2
  118. package/pipeline/scripts/smoke-tracker-contract.sh +13 -13
  119. package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +5 -5
  120. package/pipeline/scripts/smoke-triage-memory.sh +2 -2
  121. package/pipeline/scripts/smoke-update-check.sh +1 -1
  122. package/pipeline/scripts/smoke-url-enrichment.sh +2 -2
  123. package/pipeline/scripts/smoke-validator-gates.sh +1 -1
  124. package/pipeline/scripts/smoke-verify-by-test.sh +3 -3
  125. package/pipeline/scripts/smoke-wiki-integration.sh +9 -33
  126. package/pipeline/scripts/smoke-work-summary.sh +1 -1
  127. package/pipeline/scripts/smoke-worktree-path-convention.sh +4 -4
  128. package/pipeline/scripts/test-integrity-gate.mjs +83 -0
  129. package/pipeline/scripts/uninstall.mjs +2 -2
  130. package/pipeline/skills/.skill-manifest.json +40 -160
  131. package/pipeline/skills/.skills-index.json +21 -372
  132. package/pipeline/skills/shared/README.md +1 -1
  133. package/pipeline/skills/shared/core/multi-agent/SKILL.md +1 -1
  134. package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +2 -2
  135. package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +3 -3
  136. package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +1 -1
  137. package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +1 -1
  138. package/pipeline/skills/shared/core/multi-agent-finish/SKILL.md +1 -1
  139. package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +1 -1
  140. package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +116 -51
  141. package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +8 -30
  142. package/pipeline/skills/shared/external/backlog/BACKLOG.md +32 -0
  143. package/pipeline/skills/shared/external/backlog/SKILL.md +49 -0
  144. package/pipeline/skills/shared/external/compose-components/SKILL.md +14 -14
  145. package/pipeline/skills/shared/external/skill-creator/SKILL.md +48 -0
  146. package/pipeline/skills/shared/external/skill-creator/audit.md +59 -0
  147. package/pipeline/skills/shared/external/skill-creator/checklist.md +32 -0
  148. package/pipeline/skills/shared/external/skill-creator/examples.md +65 -0
  149. package/pipeline/skills/shared/external/skill-creator/label-check.md +43 -0
  150. package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +83 -0
  151. package/pipeline/skills/shared/external/skill-creator/template.md +67 -0
  152. package/pipeline/skills/skills-index.md +4 -43
  153. package/pipeline/commands/multi-agent/refactor.md +0 -188
  154. package/pipeline/commands/multi-agent/refs/component-dispatch.md +0 -92
  155. package/pipeline/scripts/smoke-existing-discovery-gate.sh +0 -71
  156. package/pipeline/scripts/smoke-figma-android-parity.sh +0 -148
  157. package/pipeline/scripts/smoke-figma-credential-store.sh +0 -105
  158. package/pipeline/scripts/smoke-figma-cross-cli-inventory.sh +0 -177
  159. package/pipeline/scripts/smoke-figma-sync.sh +0 -149
  160. package/pipeline/scripts/smoke-sync-delegation.sh +0 -74
  161. package/pipeline/skills/figma-android/README.md +0 -38
  162. package/pipeline/skills/figma-android/figma-component-code-connect/SKILL.md +0 -62
  163. package/pipeline/skills/figma-android/figma-component-implement/SKILL.md +0 -158
  164. package/pipeline/skills/figma-android/figma-component-test/SKILL.md +0 -120
  165. package/pipeline/skills/figma-android/figma-component-wiki/SKILL.md +0 -35
  166. package/pipeline/skills/figma-android/figma-to-component/SKILL.md +0 -124
  167. package/pipeline/skills/figma-common/README.md +0 -64
  168. package/pipeline/skills/figma-common/figma-bottom-sheets/SKILL.md +0 -152
  169. package/pipeline/skills/figma-common/figma-cli-iterate/SKILL.md +0 -282
  170. package/pipeline/skills/figma-common/figma-cli-iterate-mend/SKILL.md +0 -503
  171. package/pipeline/skills/figma-common/figma-cli-lean-iterate/SKILL.md +0 -288
  172. package/pipeline/skills/figma-common/figma-cli-skip/SKILL.md +0 -362
  173. package/pipeline/skills/figma-common/figma-commit/COMMON_REBASE.md +0 -206
  174. package/pipeline/skills/figma-common/figma-commit/REVIEW.md +0 -337
  175. package/pipeline/skills/figma-common/figma-commit/SKILL.md +0 -216
  176. package/pipeline/skills/figma-common/figma-component-confluence-sync/SKILL.md +0 -223
  177. package/pipeline/skills/figma-common/figma-component-start/SKILL.md +0 -251
  178. package/pipeline/skills/figma-common/figma-component-status-update/SKILL.md +0 -78
  179. package/pipeline/skills/figma-common/figma-evolve-component/SKILL.md +0 -61
  180. package/pipeline/skills/figma-common/figma-fix/SKILL.md +0 -321
  181. package/pipeline/skills/figma-common/figma-form-integration/SKILL.md +0 -542
  182. package/pipeline/skills/figma-common/figma-issue/SKILL.md +0 -750
  183. package/pipeline/skills/figma-common/figma-iterate/SKILL.md +0 -208
  184. package/pipeline/skills/figma-common/figma-iteration-commit/SKILL.md +0 -1020
  185. package/pipeline/skills/figma-common/figma-mend/SKILL.md +0 -331
  186. package/pipeline/skills/figma-common/figma-navigation/SKILL.md +0 -156
  187. package/pipeline/skills/figma-common/figma-overlays/SKILL.md +0 -142
  188. package/pipeline/skills/figma-common/figma-price-integration/SKILL.md +0 -398
  189. package/pipeline/skills/figma-common/figma-remote-mcp-auth/SKILL.md +0 -104
  190. package/pipeline/skills/figma-common/figma-review/SKILL.md +0 -400
  191. package/pipeline/skills/figma-common/figma-setup/SKILL.md +0 -514
  192. package/pipeline/skills/figma-common/figma-setup/scripts/fetch-mcp-token.py +0 -592
  193. package/pipeline/skills/figma-common/figma-skip/SKILL.md +0 -129
  194. package/pipeline/skills/figma-common/figma-ui-patterns/SKILL.md +0 -105
  195. package/pipeline/skills/figma-common/figma-ui-patterns/patterns/animated-gradient-border.md +0 -116
  196. package/pipeline/skills/figma-common/figma-utility/SKILL.md +0 -274
  197. package/pipeline/skills/figma-common/figma-utility/scripts/figma-utility.py +0 -808
  198. package/pipeline/skills/figma-common/figma-validate/SKILL.md +0 -633
  199. package/pipeline/skills/figma-common/performance-iteration-commit-all/SKILL.md +0 -716
  200. package/pipeline/skills/figma-common/performance-review-next/SKILL.md +0 -238
  201. package/pipeline/skills/figma-common/performance-start/SKILL.md +0 -430
  202. package/pipeline/skills/figma-common/performance-swiftui/SKILL.md +0 -706
  203. package/pipeline/skills/figma-common/performance-tour/SKILL.md +0 -423
  204. package/pipeline/skills/figma-ios/REVIEW_CHECKLIST.md +0 -67
  205. package/pipeline/skills/figma-ios/figma-component-code-connect/SKILL.md +0 -178
  206. package/pipeline/skills/figma-ios/figma-component-implement/SKILL.md +0 -184
  207. package/pipeline/skills/figma-ios/figma-component-test/SKILL.md +0 -219
  208. package/pipeline/skills/figma-ios/figma-component-wiki/SKILL.md +0 -274
  209. package/pipeline/skills/figma-ios/figma-to-component/SKILL.md +0 -416
  210. package/pipeline/skills/figma-ios/figma-to-component/halt-return-protocol.md +0 -57
  211. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-0-init.md +0 -307
  212. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-1-gathering.md +0 -119
  213. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-1.5-existing-discovery.md +0 -174
  214. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2-orchestrator.md +0 -333
  215. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2a-testing-identifiers.md +0 -368
  216. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2b-localization.md +0 -393
  217. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2c-accessibility.md +0 -617
  218. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2d-analytics.md +0 -352
  219. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3-orchestrator.md +0 -337
  220. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3a-location.md +0 -206
  221. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3b-tokens.md +0 -235
  222. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3c-nested.md +0 -214
  223. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3d-patterns.md +0 -902
  224. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3e-assets.md +0 -156
  225. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3f-utilities.md +0 -175
  226. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3g-property-coverage.md +0 -176
  227. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3h-variant-config.md +0 -333
  228. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4-orchestrator.md +0 -412
  229. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4a-configuration.md +0 -336
  230. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4b-view.md +0 -705
  231. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4c-documentation.md +0 -332
  232. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4d-preview.md +0 -380
  233. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4e-modifiers.md +0 -262
  234. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5-orchestrator.md +0 -482
  235. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5a-viewinspector.md +0 -274
  236. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5b-snapshot.md +0 -636
  237. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5c-unit.md +0 -142
  238. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-6-code-connect.md +0 -547
  239. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7-wiki.md +0 -39
  240. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7a-confluence-generate.md +0 -659
  241. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7a-wiki-generate.md +0 -580
  242. package/pipeline/skills/figma-ios/figma-to-component/phases/phase-8-cleanup.md +0 -51
  243. package/pipeline/skills/figma-ios/figma-to-component/reference/accessibility.md +0 -183
  244. package/pipeline/skills/figma-ios/figma-to-component/reference/analytics-events.md +0 -64
  245. package/pipeline/skills/figma-ios/figma-to-component/reference/code-connect.md +0 -531
  246. package/pipeline/skills/figma-ios/figma-to-component/reference/confluence-api.md +0 -89
  247. package/pipeline/skills/figma-ios/figma-to-component/reference/confluence-xhtml.md +0 -155
  248. package/pipeline/skills/figma-ios/figma-to-component/reference/figma-to-swiftui-effects.md +0 -196
  249. package/pipeline/skills/figma-ios/figma-to-component/reference/halt-return-protocol.md +0 -57
  250. package/pipeline/skills/figma-ios/figma-to-component/reference/localization-naming.md +0 -89
  251. package/pipeline/skills/figma-ios/figma-to-component/reference/macros.md +0 -227
  252. package/pipeline/skills/figma-ios/figma-to-component/reference/missing-tokens.md +0 -157
  253. package/pipeline/skills/figma-ios/figma-to-component/reference/orchestrator-discipline.md +0 -90
  254. package/pipeline/skills/figma-ios/figma-to-component/reference/registry.md +0 -116
  255. package/pipeline/skills/figma-ios/figma-to-component/reference/remote-mcp-script.md +0 -153
  256. package/pipeline/skills/figma-ios/figma-to-component/reference/rest-api-script.md +0 -130
  257. package/pipeline/skills/figma-ios/figma-to-component/reference/scripts-inventory.md +0 -218
  258. package/pipeline/skills/figma-ios/figma-to-component/reference/snapshot-testing.md +0 -188
  259. package/pipeline/skills/figma-ios/figma-to-component/reference/subcomponent-graph.md +0 -93
  260. package/pipeline/skills/figma-ios/figma-to-component/reference/testing-identifiers-naming.md +0 -98
  261. package/pipeline/skills/figma-ios/figma-to-component/reference/tools.md +0 -261
  262. package/pipeline/skills/figma-ios/figma-to-component/reference/viewinspector.md +0 -147
  263. package/pipeline/skills/figma-ios/figma-to-component/reference/wiki-to-confluence-mapping.md +0 -182
  264. package/pipeline/skills/figma-ios/figma-to-component/scripts/apply-author-login-map.py +0 -185
  265. package/pipeline/skills/figma-ios/figma-to-component/scripts/backfill-status.py +0 -609
  266. package/pipeline/skills/figma-ios/figma-to-component/scripts/build-author-registry.py +0 -332
  267. package/pipeline/skills/figma-ios/figma-to-component/scripts/bulk-sync-issues.py +0 -261
  268. package/pipeline/skills/figma-ios/figma-to-component/scripts/code-connect-data-gather.py +0 -184
  269. package/pipeline/skills/figma-ios/figma-to-component/scripts/code-connect-publish.sh +0 -188
  270. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-component-status-upload.py +0 -768
  271. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-component-status.py +0 -191
  272. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-data-gather.py +0 -420
  273. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-page-ids.example.json +0 -9
  274. package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-publish.py +0 -336
  275. package/pipeline/skills/figma-ios/figma-to-component/scripts/figma-subcomponent-graph.py +0 -391
  276. package/pipeline/skills/figma-ios/figma-to-component/scripts/figma-update.py +0 -292
  277. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/__init__.py +0 -1
  278. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/issue_sync_propagate.py +0 -93
  279. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/registry_writer.py +0 -299
  280. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_backfill_status.py +0 -343
  281. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_figma_update.py +0 -206
  282. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_figma_update_http.py +0 -149
  283. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_phase_clis.py +0 -281
  284. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_registry_writer.py +0 -332
  285. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_skill_figma_issue.py +0 -176
  286. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_skill_figma_review.py +0 -98
  287. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_update_issue.py +0 -298
  288. package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_update_issue_gh.py +0 -195
  289. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase1-gather.py +0 -1298
  290. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase2-finalize.py +0 -228
  291. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase3-scripts.py +0 -1089
  292. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase4-finalize.py +0 -141
  293. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase5-finalize.py +0 -106
  294. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase6-finalize.py +0 -162
  295. package/pipeline/skills/figma-ios/figma-to-component/scripts/phase7-finalize.py +0 -105
  296. package/pipeline/skills/figma-ios/figma-to-component/scripts/register-icons-codeconnect.py +0 -179
  297. package/pipeline/skills/figma-ios/figma-to-component/scripts/remote-mcp-fetch.py +0 -260
  298. package/pipeline/skills/figma-ios/figma-to-component/scripts/resolve-author-logins.py +0 -260
  299. package/pipeline/skills/figma-ios/figma-to-component/scripts/run-uicomponents-tests.sh +0 -86
  300. package/pipeline/skills/figma-ios/figma-to-component/scripts/sidebar-generator.py +0 -321
  301. package/pipeline/skills/figma-ios/figma-to-component/scripts/update-issue-from-registry.py +0 -1470
  302. package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase4.sh +0 -176
  303. package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase6.sh +0 -147
  304. package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase7a.py +0 -629
  305. /package/pipeline/commands/multi-agent/{delete.md → delete/SKILL.md} +0 -0
  306. /package/pipeline/commands/multi-agent/{diff-explain.md → diff-explain/SKILL.md} +0 -0
  307. /package/pipeline/commands/multi-agent/{garbage-collect.md → garbage-collect/SKILL.md} +0 -0
  308. /package/pipeline/commands/multi-agent/{issue.md → issue/SKILL.md} +0 -0
  309. /package/pipeline/commands/multi-agent/{jira.md → jira/SKILL.md} +0 -0
  310. /package/pipeline/commands/multi-agent/{kill.md → kill/SKILL.md} +0 -0
  311. /package/pipeline/commands/multi-agent/{language.md → language/SKILL.md} +0 -0
  312. /package/pipeline/commands/multi-agent/{log.md → log/SKILL.md} +0 -0
  313. /package/pipeline/commands/multi-agent/{prune-logs.md → prune-logs/SKILL.md} +0 -0
  314. /package/pipeline/commands/multi-agent/{purge.md → purge/SKILL.md} +0 -0
  315. /package/pipeline/commands/multi-agent/{scan.md → scan/SKILL.md} +0 -0
  316. /package/pipeline/commands/multi-agent/{search.md → search/SKILL.md} +0 -0
  317. /package/pipeline/commands/multi-agent/{stack.md → stack/SKILL.md} +0 -0
  318. /package/pipeline/commands/multi-agent/{status.md → status/SKILL.md} +0 -0
  319. /package/pipeline/commands/multi-agent/{test.md → test/SKILL.md} +0 -0
  320. /package/pipeline/commands/multi-agent/{update.md → update/SKILL.md} +0 -0
  321. /package/pipeline/{commands/multi-agent → multi-agent-refs}/_input-parser.md +0 -0
  322. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/analysis-template.md +0 -0
  323. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/audit-guide.md +0 -0
  324. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/backend-guide.md +0 -0
  325. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/confluence.md +0 -0
  326. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/issue-comment.md +0 -0
  327. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/pr-review-actions.md +0 -0
  328. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/channels/pr.md +0 -0
  329. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/conventions-defaults.md +0 -0
  330. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/autopilot-circuit-breaker.md +0 -0
  331. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/dev-critic.md +0 -0
  332. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/external-context-injection.md +0 -0
  333. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/model-fallback.md +0 -0
  334. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/plan-todos.md +0 -0
  335. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/prior-fix-detection.md +0 -0
  336. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/repo-map.md +0 -0
  337. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/features/shadow-git.md +0 -0
  338. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/frontend-guide.md +0 -0
  339. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/knowledge.md +0 -0
  340. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/multi-repo-integration-build.md +0 -0
  341. /package/pipeline/{commands/multi-agent/refs → multi-agent-refs}/picker-contract.md +0 -0
  342. /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())