@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,609 +0,0 @@
1
- #!/usr/bin/env python3
2
- """backfill-status.py - populate status blocks in existing registry files.
3
-
4
- Walks every JSON in the registry directory and, for each component,
5
- infers the initial `status.ios.*` block from filesystem signals:
6
-
7
- - status.ios.implemented:
8
- True if a Swift source file with the component's iOS name exists
9
- anywhere under the uicomponents Sources tree. When set, version
10
- starts at 1.
11
-
12
- - status.ios.codeConnect:
13
- Mirrors the legacy top-level `codeConnect.ios` field. Only set if
14
- the legacy value was True. Recorded against the current
15
- impl.version - so if impl was just set to 1 in this same run,
16
- codeConnect lands green (against=1), not yellow.
17
-
18
- - status.ios.tested and status.ios.wiki:
19
- NOT backfilled in this pass. These signals live in separate repos
20
- and trees, and the heuristics are fragile. They'll naturally
21
- populate on the next pipeline run of each component.
22
-
23
- - status.android.*:
24
- NOT backfilled. Android source tree and component index are
25
- out-of-scope for tonight. Future enhancement.
26
-
27
- The legacy top-level `codeConnect.{ios,android}` field is left intact.
28
- set_flag's built-in mirror keeps the two representations in sync going
29
- forward, and the backfill never explicitly downgrades anything.
30
-
31
- Usage:
32
- # See what would change - no writes
33
- python3 backfill-status.py \\
34
- --registry-dir /path/to/Shared/Figma/Components \\
35
- --sources-dir /path/to/uicomponents/Sources \\
36
- --dry-run
37
-
38
- # Smoke test on 5 entries
39
- python3 backfill-status.py \\
40
- --registry-dir ... --sources-dir ... \\
41
- --dry-run --limit 5
42
-
43
- # Real backfill (only run after you've reviewed a --dry-run)
44
- python3 backfill-status.py \\
45
- --registry-dir ... --sources-dir ...
46
-
47
- Exit codes:
48
- 0 - Success (full walk completed)
49
- 1 - Error (bad paths, read/write failure)
50
- """
51
-
52
- import argparse
53
- import json
54
- import subprocess
55
- import sys
56
- from collections import Counter
57
- from pathlib import Path
58
- from typing import Dict, List, Optional, Set
59
-
60
- sys.path.insert(0, str(Path(__file__).parent))
61
- from lib.registry_writer import set_flag, set_implemented # noqa: E402
62
-
63
-
64
- def find_repo_root() -> Path:
65
- p = Path.cwd()
66
- while p != p.parent:
67
- if (p / ".git").exists():
68
- return p
69
- p = p.parent
70
- return Path.cwd()
71
-
72
-
73
- def default_registry_dir() -> Path:
74
- return (
75
- find_repo_root()
76
- / "{repos.packagesContainer}"
77
- / "Packages"
78
- / "{project.slug}-common"
79
- / "Shared"
80
- / "Figma"
81
- / "Components"
82
- )
83
-
84
-
85
- def default_sources_dir() -> Path:
86
- return (
87
- find_repo_root()
88
- / "{repos.packagesContainer}"
89
- / "Packages"
90
- / "{project.slug}-components"
91
- / "Sources"
92
- )
93
-
94
-
95
- def default_tests_dir() -> Path:
96
- return (
97
- find_repo_root()
98
- / "{repos.packagesContainer}"
99
- / "Packages"
100
- / "{project.slug}-components"
101
- / "Tests"
102
- )
103
-
104
-
105
- def default_wiki_dir() -> Path:
106
- return (
107
- find_repo_root()
108
- / "{repos.packagesContainer}"
109
- / "Packages"
110
- / "{project.slug}-wiki"
111
- )
112
-
113
-
114
- def default_uicomponents_repo_dir() -> Path:
115
- return (
116
- find_repo_root()
117
- / "{repos.packagesContainer}"
118
- / "Packages"
119
- / "{project.slug}-components"
120
- )
121
-
122
-
123
- # --------------------------------------------------------------------
124
- # Source-tree indexing (separate from backfill for testability)
125
- # --------------------------------------------------------------------
126
-
127
- def build_swift_file_index(sources_dir: Path) -> Dict[str, Path]:
128
- """Walk the Sources tree and return { base_name: first_matching_path }.
129
-
130
- Base name is the filename without the .swift extension.
131
- Only the first match is kept if the same name appears twice
132
- (unlikely in a well-organized source tree).
133
- """
134
- index: Dict[str, Path] = {}
135
- if not sources_dir.exists():
136
- return index
137
-
138
- for swift in sources_dir.rglob("*.swift"):
139
- base = swift.stem
140
- if base not in index:
141
- index[base] = swift
142
- return index
143
-
144
-
145
- # Test-file name suffixes we recognize as "this component has tests".
146
- TEST_SUFFIXES = (
147
- "SnapshotTests",
148
- "Tests",
149
- "XCTests",
150
- "ViewInspectorTests",
151
- "UnitTests",
152
- )
153
-
154
-
155
- def build_test_file_index(tests_dir: Path) -> Dict[str, List[Path]]:
156
- """Walk the Tests tree and return { ComponentName: [test_path, ...] }.
157
-
158
- For each `{ComponentName}{suffix}.swift` we find, strip the suffix
159
- and index under the stripped component name. A component is
160
- considered tested if at least one test file maps to it.
161
- """
162
- index: Dict[str, List[Path]] = {}
163
- if not tests_dir.exists():
164
- return index
165
-
166
- for swift in tests_dir.rglob("*.swift"):
167
- stem = swift.stem
168
- for suffix in TEST_SUFFIXES:
169
- if stem.endswith(suffix) and len(stem) > len(suffix):
170
- comp = stem[: -len(suffix)]
171
- index.setdefault(comp, []).append(swift)
172
- break
173
- return index
174
-
175
-
176
- def build_wiki_index(wiki_dir: Path) -> Dict[str, Path]:
177
- """Walk the wiki tree and return { ComponentName: path_to_md_file }.
178
-
179
- Matches `**/{ComponentName}/{ComponentName}.md` (the canonical
180
- per-component layout used in the uicomponents-wiki submodule).
181
- Also accepts `**/{ComponentName}.md` as a fallback for flat
182
- structures.
183
- """
184
- index: Dict[str, Path] = {}
185
- if not wiki_dir.exists():
186
- return index
187
-
188
- # Prefer per-component directories first
189
- for md in wiki_dir.rglob("*.md"):
190
- stem = md.stem
191
- parent_name = md.parent.name
192
- if parent_name == stem:
193
- # {Component}/{Component}.md - canonical
194
- index.setdefault(stem, md)
195
- elif stem not in index:
196
- # {Component}.md at any depth - fallback
197
- index[stem] = md
198
- return index
199
-
200
-
201
- def detect_primary_author(
202
- source_file: Path,
203
- repo_root: Path,
204
- ) -> Optional[str]:
205
- """Return the git author (most commits on `source_file`) inside `repo_root`.
206
-
207
- Runs `git -C repo_root log --format=%an -- <rel_path>`, counts
208
- unique authors, picks the one with the most commits.
209
-
210
- Returns None if:
211
- - source file doesn't exist
212
- - git command fails
213
- - no commits touch the file
214
- - author name is empty
215
- """
216
- if not source_file.exists():
217
- return None
218
- try:
219
- rel = source_file.relative_to(repo_root)
220
- except ValueError:
221
- rel = source_file
222
- try:
223
- r = subprocess.run(
224
- ["git", "-C", str(repo_root), "log", "--format=%an", "--", str(rel)],
225
- capture_output=True,
226
- text=True,
227
- check=False,
228
- timeout=10,
229
- )
230
- except (subprocess.SubprocessError, FileNotFoundError):
231
- return None
232
- if r.returncode != 0:
233
- return None
234
- lines = [line.strip() for line in r.stdout.splitlines() if line.strip()]
235
- if not lines:
236
- return None
237
- counter = Counter(lines)
238
- author, _ = counter.most_common(1)[0]
239
- return author or None
240
-
241
-
242
- # --------------------------------------------------------------------
243
- # Per-entry decision logic (pure, testable)
244
- # --------------------------------------------------------------------
245
-
246
- def _safe_dict(value) -> dict:
247
- """Return value if it's a dict, otherwise an empty dict.
248
-
249
- Real registry data in the wild contains a small number of legacy
250
- entries where fields like `status` are strings (e.g. "implemented")
251
- or `componentName` is a bare string. This helper lets the decision
252
- logic treat those the same as missing/empty without raising.
253
- """
254
- return value if isinstance(value, dict) else {}
255
-
256
-
257
- def _component_name_ios(raw) -> Optional[str]:
258
- """Handle both shapes: {"ios": "X", "android": "X"} and bare "X"."""
259
- if isinstance(raw, dict):
260
- return raw.get("ios")
261
- if isinstance(raw, str) and raw:
262
- return raw
263
- return None
264
-
265
-
266
- def decide_backfill(
267
- entry: dict,
268
- swift_index: Dict[str, Path],
269
- test_index: Optional[Dict[str, List[Path]]] = None,
270
- wiki_index: Optional[Dict[str, Path]] = None,
271
- ) -> dict:
272
- """Decide what the backfill should do for one registry entry.
273
-
274
- Pure function - no I/O. Returns a dict describing the intended
275
- action per flag, used by both dry-run and real-write paths.
276
-
277
- test_index and wiki_index are optional for backward compat - when
278
- None, tested/wiki detection is skipped and only implemented/cc are
279
- considered (original Step 5 behavior).
280
-
281
- Returned shape (added fields are marked NEW):
282
- {
283
- "node_id": str,
284
- "component_name_ios": Optional[str],
285
- "has_status_block": bool,
286
- "impl_action": ...,
287
- "codeconnect_action": ...,
288
- "tested_action": ..., # NEW - "set" | "skip_*"
289
- "wiki_action": ..., # NEW - "set" | "skip_*"
290
- "swift_path": Optional[str],
291
- "test_paths": List[str], # NEW - 0+ paths that match the component
292
- "wiki_path": Optional[str], # NEW - the detected wiki .md file
293
- }
294
- """
295
- node_id = entry.get("nodeId")
296
- component_name = _component_name_ios(entry.get("componentName"))
297
-
298
- # Legacy shape: `status` was a bare string like "implemented". Leave
299
- # these for manual migration - do not overwrite with the new block.
300
- raw_status = entry.get("status")
301
- if isinstance(raw_status, str):
302
- return {
303
- "node_id": node_id,
304
- "component_name_ios": component_name,
305
- "has_status_block": True,
306
- "impl_action": "skip_legacy_status_string",
307
- "codeconnect_action": "skip_legacy_status_string",
308
- "tested_action": "skip_legacy_status_string",
309
- "wiki_action": "skip_legacy_status_string",
310
- "swift_path": None,
311
- "test_paths": [],
312
- "wiki_path": None,
313
- }
314
-
315
- status_block = _safe_dict(raw_status)
316
- ios_status = _safe_dict(status_block.get("ios"))
317
- implemented_block = _safe_dict(ios_status.get("implemented"))
318
- has_status = bool(implemented_block.get("value"))
319
-
320
- legacy_cc_ios = bool(_safe_dict(entry.get("codeConnect")).get("ios"))
321
- skip = bool(entry.get("skip"))
322
-
323
- result: dict = {
324
- "node_id": node_id,
325
- "component_name_ios": component_name,
326
- "has_status_block": has_status,
327
- "impl_action": None,
328
- "codeconnect_action": None,
329
- "tested_action": None,
330
- "wiki_action": None,
331
- "swift_path": None,
332
- "test_paths": [],
333
- "wiki_path": None,
334
- }
335
-
336
- # Skip entries marked skip=true
337
- if skip:
338
- for k in ("impl_action", "codeconnect_action", "tested_action", "wiki_action"):
339
- result[k] = "skip_marked_skip"
340
- return result
341
-
342
- if not component_name:
343
- for k in ("impl_action", "codeconnect_action", "tested_action", "wiki_action"):
344
- result[k] = "skip_no_name" if k == "impl_action" else "skip_no_impl"
345
- return result
346
-
347
- # tested / wiki can be set independently of impl (they're orthogonal
348
- # signals) but we compute them regardless so the decision dict is
349
- # fully populated for the report.
350
- if test_index is not None:
351
- test_paths = test_index.get(component_name, [])
352
- if test_paths:
353
- result["test_paths"] = [str(p) for p in test_paths]
354
- if wiki_index is not None:
355
- wiki_path = wiki_index.get(component_name)
356
- if wiki_path:
357
- result["wiki_path"] = str(wiki_path)
358
-
359
- # If the new status block already has implemented.value=true, don't
360
- # overwrite the impl/cc flags. tested/wiki can still be added if
361
- # they haven't been populated yet (backfill is additive for those).
362
- if has_status:
363
- result["impl_action"] = "skip_existing_status"
364
- result["codeconnect_action"] = "skip_existing_status"
365
- # Populate swift_path even when skipping impl - author detection
366
- # needs it, and we want to be able to fill in implementedBy for
367
- # components that were backfilled before author detection existed.
368
- swift_path = swift_index.get(component_name) if component_name else None
369
- if swift_path:
370
- result["swift_path"] = str(swift_path)
371
- # tested/wiki: still set them if not already set
372
- tested_set = bool(_safe_dict(ios_status.get("tested")).get("value"))
373
- wiki_set = bool(_safe_dict(ios_status.get("wiki")).get("value"))
374
- if result["test_paths"] and not tested_set:
375
- result["tested_action"] = "set"
376
- else:
377
- result["tested_action"] = "skip_existing_status" if tested_set else "skip_no_tests"
378
- if result["wiki_path"] and not wiki_set:
379
- result["wiki_action"] = "set"
380
- else:
381
- result["wiki_action"] = "skip_existing_status" if wiki_set else "skip_no_wiki"
382
- return result
383
-
384
- # Fresh entry - check swift file for implementation
385
- swift_path = swift_index.get(component_name)
386
- if not swift_path:
387
- result["impl_action"] = "skip_no_swift"
388
- result["codeconnect_action"] = "skip_no_impl"
389
- result["tested_action"] = "skip_no_impl"
390
- result["wiki_action"] = "skip_no_impl"
391
- return result
392
-
393
- result["impl_action"] = "set"
394
- result["swift_path"] = str(swift_path)
395
- result["codeconnect_action"] = "set" if legacy_cc_ios else "skip_legacy_false"
396
- result["tested_action"] = "set" if result["test_paths"] else "skip_no_tests"
397
- result["wiki_action"] = "set" if result["wiki_path"] else "skip_no_wiki"
398
-
399
- return result
400
-
401
-
402
- # --------------------------------------------------------------------
403
- # Backfill execution
404
- # --------------------------------------------------------------------
405
-
406
- def apply_decision(
407
- registry_dir: Path,
408
- decision: dict,
409
- uicomponents_repo: Optional[Path] = None,
410
- ) -> None:
411
- """Execute the decision (skip if action is 'skip_*').
412
-
413
- Writes are atomic per flag - a crash between writes leaves a
414
- partially-backfilled entry, recoverable on re-run. Order:
415
- 1. set_implemented (establishes version=1)
416
- 2. set_implemented_by (author)
417
- 3. set_flag codeConnect (if legacy was true)
418
- 4. set_flag tested (if tests detected)
419
- 5. set_flag wiki (if wiki detected)
420
- """
421
- from lib.registry_writer import set_implemented_by # local to avoid circular
422
-
423
- node_id = decision["node_id"]
424
-
425
- if decision.get("impl_action") == "set":
426
- set_implemented(
427
- registry_dir=registry_dir,
428
- node_id=node_id,
429
- platform="ios",
430
- updater="backfill-status",
431
- source_file=None,
432
- )
433
-
434
- # Author detection - only meaningful when we actually set impl OR
435
- # impl was already set (so the registry entry exists and we just
436
- # want to populate the missing field).
437
- if uicomponents_repo and decision.get("swift_path"):
438
- swift_file = Path(decision["swift_path"])
439
- author = detect_primary_author(swift_file, uicomponents_repo)
440
- if author:
441
- set_implemented_by(
442
- registry_dir=registry_dir,
443
- node_id=node_id,
444
- platform="ios",
445
- author=author,
446
- updater="backfill-status",
447
- )
448
- decision["author"] = author
449
-
450
- if decision.get("codeconnect_action") == "set":
451
- set_flag(
452
- registry_dir=registry_dir,
453
- node_id=node_id,
454
- platform="ios",
455
- flag="codeConnect",
456
- updater="backfill-status",
457
- )
458
-
459
- if decision.get("tested_action") == "set":
460
- set_flag(
461
- registry_dir=registry_dir,
462
- node_id=node_id,
463
- platform="ios",
464
- flag="tested",
465
- updater="backfill-status",
466
- )
467
-
468
- if decision.get("wiki_action") == "set":
469
- set_flag(
470
- registry_dir=registry_dir,
471
- node_id=node_id,
472
- platform="ios",
473
- flag="wiki",
474
- updater="backfill-status",
475
- )
476
-
477
-
478
- def run_backfill(
479
- registry_dir: Path,
480
- sources_dir: Path,
481
- dry_run: bool,
482
- limit: Optional[int] = None,
483
- tests_dir: Optional[Path] = None,
484
- wiki_dir: Optional[Path] = None,
485
- uicomponents_repo: Optional[Path] = None,
486
- ) -> dict:
487
- """Top-level backfill. Returns a summary dict."""
488
- swift_index = build_swift_file_index(sources_dir)
489
- test_index = build_test_file_index(tests_dir) if tests_dir else {}
490
- wiki_index = build_wiki_index(wiki_dir) if wiki_dir else {}
491
-
492
- all_files = sorted(registry_dir.glob("*.json"))
493
- if limit is not None:
494
- all_files = all_files[:limit]
495
-
496
- counts: Dict[str, int] = {}
497
- flag_counts = {
498
- "impl_set": 0,
499
- "tested_set": 0,
500
- "codeconnect_set": 0,
501
- "wiki_set": 0,
502
- "author_set": 0,
503
- }
504
- decisions: List[dict] = []
505
- errors: List[dict] = []
506
-
507
- for path in all_files:
508
- try:
509
- entry = json.loads(path.read_text(encoding="utf-8"))
510
- except (json.JSONDecodeError, OSError) as e:
511
- errors.append({"file": path.name, "error": f"read: {type(e).__name__}: {e}"})
512
- continue
513
-
514
- decision = decide_backfill(entry, swift_index, test_index, wiki_index)
515
- decisions.append(decision)
516
-
517
- key = f"{decision['impl_action']}/{decision['codeconnect_action']}/{decision['tested_action']}/{decision['wiki_action']}"
518
- counts[key] = counts.get(key, 0) + 1
519
-
520
- # per-flag set counts (dry-run accurate)
521
- for flag_name, counter_key in (
522
- ("impl_action", "impl_set"),
523
- ("tested_action", "tested_set"),
524
- ("codeconnect_action", "codeconnect_set"),
525
- ("wiki_action", "wiki_set"),
526
- ):
527
- if decision.get(flag_name) == "set":
528
- flag_counts[counter_key] += 1
529
-
530
- if not dry_run:
531
- try:
532
- apply_decision(registry_dir, decision, uicomponents_repo=uicomponents_repo)
533
- if decision.get("author"):
534
- flag_counts["author_set"] += 1
535
- except (OSError, ValueError) as e:
536
- errors.append({
537
- "file": path.name,
538
- "node_id": decision["node_id"],
539
- "error": f"write: {type(e).__name__}: {e}",
540
- })
541
-
542
- return {
543
- "status": "ok" if not errors else "partial",
544
- "dry_run": dry_run,
545
- "registry_dir": str(registry_dir),
546
- "sources_dir": str(sources_dir),
547
- "tests_dir": str(tests_dir) if tests_dir else None,
548
- "wiki_dir": str(wiki_dir) if wiki_dir else None,
549
- "total_files": len(all_files),
550
- "swift_files_indexed": len(swift_index),
551
- "test_files_indexed": len(test_index),
552
- "wiki_files_indexed": len(wiki_index),
553
- "flag_set_counts": flag_counts,
554
- "action_counts": counts,
555
- "errors": errors,
556
- "sample_decisions": decisions[:5],
557
- }
558
-
559
-
560
- # --------------------------------------------------------------------
561
- # CLI
562
- # --------------------------------------------------------------------
563
-
564
- def main() -> int:
565
- parser = argparse.ArgumentParser(
566
- description="Backfill status blocks in existing registry entries",
567
- )
568
- parser.add_argument("--registry-dir", help="Override registry path")
569
- parser.add_argument("--sources-dir", help="Override uicomponents Sources path")
570
- parser.add_argument("--tests-dir", help="Override uicomponents Tests path")
571
- parser.add_argument("--wiki-dir", help="Override uicomponents-wiki path")
572
- parser.add_argument("--uicomponents-repo", help="Override uicomponents repo root (for git-log author detection)")
573
- parser.add_argument("--skip-authors", action="store_true", help="Skip git log author detection (fast mode)")
574
- parser.add_argument("--dry-run", action="store_true", help="No writes, print summary only")
575
- parser.add_argument("--limit", type=int, help="Process at most N registry files (smoke-test safety)")
576
- args = parser.parse_args()
577
-
578
- registry_dir = Path(args.registry_dir) if args.registry_dir else default_registry_dir()
579
- sources_dir = Path(args.sources_dir) if args.sources_dir else default_sources_dir()
580
- tests_dir = Path(args.tests_dir) if args.tests_dir else default_tests_dir()
581
- wiki_dir = Path(args.wiki_dir) if args.wiki_dir else default_wiki_dir()
582
- uicomponents_repo = None
583
- if not args.skip_authors:
584
- uicomponents_repo = (
585
- Path(args.uicomponents_repo) if args.uicomponents_repo else default_uicomponents_repo_dir()
586
- )
587
-
588
- if not registry_dir.exists():
589
- print(f"ERROR: registry directory does not exist: {registry_dir}", file=sys.stderr)
590
- return 1
591
- if not sources_dir.exists():
592
- print(f"ERROR: sources directory does not exist: {sources_dir}", file=sys.stderr)
593
- return 1
594
-
595
- summary = run_backfill(
596
- registry_dir=registry_dir,
597
- sources_dir=sources_dir,
598
- dry_run=args.dry_run,
599
- limit=args.limit,
600
- tests_dir=tests_dir,
601
- wiki_dir=wiki_dir,
602
- uicomponents_repo=uicomponents_repo,
603
- )
604
- print(json.dumps(summary, indent=2, ensure_ascii=False))
605
- return 0 if summary["status"] == "ok" else 1
606
-
607
-
608
- if __name__ == "__main__":
609
- sys.exit(main())