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