@mmerterden/multi-agent-pipeline 11.2.0 → 11.3.1

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