@mmerterden/multi-agent-pipeline 11.1.0 → 11.3.0

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