@mmerterden/multi-agent-pipeline 8.6.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.
- package/CHANGELOG.md +2623 -0
- package/LICENSE +21 -0
- package/README.md +852 -0
- package/docs/FIGMA_PIPELINE.md +138 -0
- package/docs/GENERICITY-REVIEW.md +277 -0
- package/docs/STABILITY-FIX-PLAN.md +168 -0
- package/docs/adr/0001-three-model-triage.md +81 -0
- package/docs/adr/0002-instruction-driven-flag.md +62 -0
- package/docs/adr/0003-unified-shared-skills.md +55 -0
- package/docs/adr/0004-zero-dependency-philosophy.md +60 -0
- package/docs/adr/0005-lazy-phase-docs.md +68 -0
- package/docs/adr/0006-skills-core-external-split.md +52 -0
- package/docs/adr/0007-multi-tool-adapter-framework.md +110 -0
- package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +98 -0
- package/docs/adr/README.md +33 -0
- package/docs/architecture.md +181 -0
- package/docs/best-practices.md +93 -0
- package/docs/features.md +274 -0
- package/docs/performance.md +116 -0
- package/docs/recovery-guide.md +479 -0
- package/index.js +76 -0
- package/install/_adapters.mjs +69 -0
- package/install/_common.mjs +150 -0
- package/install/_copilot-instructions.mjs +32 -0
- package/install/_dev-only-files.mjs +23 -0
- package/install/_platform-filter.mjs +132 -0
- package/install/_telemetry.mjs +79 -0
- package/install/claude.mjs +332 -0
- package/install/copilot.mjs +254 -0
- package/install/index.mjs +179 -0
- package/install/templates/copilot-instructions.md +319 -0
- package/install.js +24 -0
- package/package.json +78 -0
- package/pipeline/adapters/_base.mjs +288 -0
- package/pipeline/adapters/copilot-chat.mjs +158 -0
- package/pipeline/adapters/cursor.mjs +187 -0
- package/pipeline/agents/android-architect.md +42 -0
- package/pipeline/agents/backend-architect.md +43 -0
- package/pipeline/agents/code-reviewer.md +57 -0
- package/pipeline/agents/dev-critic.md +148 -0
- package/pipeline/agents/explorer.md +34 -0
- package/pipeline/agents/ios-architect.md +41 -0
- package/pipeline/agents/security-auditor.md +98 -0
- package/pipeline/agents/task-clarifier.md +113 -0
- package/pipeline/claude-md-template.md +55 -0
- package/pipeline/commands/archive-guard.md +45 -0
- package/pipeline/commands/deploy.md +54 -0
- package/pipeline/commands/figma-to-swiftui.md +295 -0
- package/pipeline/commands/multi-agent/_account-picker.md +90 -0
- package/pipeline/commands/multi-agent/_dev-context.md +111 -0
- package/pipeline/commands/multi-agent/_input-parser.md +43 -0
- package/pipeline/commands/multi-agent/_repo-picker.md +76 -0
- package/pipeline/commands/multi-agent/autopilot.md +116 -0
- package/pipeline/commands/multi-agent/channels.md +465 -0
- package/pipeline/commands/multi-agent/delete.md +66 -0
- package/pipeline/commands/multi-agent/dev-autopilot.md +120 -0
- package/pipeline/commands/multi-agent/dev-local-autopilot.md +110 -0
- package/pipeline/commands/multi-agent/dev-local.md +105 -0
- package/pipeline/commands/multi-agent/dev.md +246 -0
- package/pipeline/commands/multi-agent/diff-explain.md +68 -0
- package/pipeline/commands/multi-agent/help.md +422 -0
- package/pipeline/commands/multi-agent/issue.md +79 -0
- package/pipeline/commands/multi-agent/jira.md +132 -0
- package/pipeline/commands/multi-agent/kill.md +38 -0
- package/pipeline/commands/multi-agent/language.md +94 -0
- package/pipeline/commands/multi-agent/local-autopilot.md +139 -0
- package/pipeline/commands/multi-agent/local.md +117 -0
- package/pipeline/commands/multi-agent/log.md +25 -0
- package/pipeline/commands/multi-agent/manual-test.md +43 -0
- package/pipeline/commands/multi-agent/purge.md +39 -0
- package/pipeline/commands/multi-agent/refactor.md +188 -0
- package/pipeline/commands/multi-agent/refs/android-guide.md +250 -0
- package/pipeline/commands/multi-agent/refs/audit-guide.md +240 -0
- package/pipeline/commands/multi-agent/refs/backend-guide.md +135 -0
- package/pipeline/commands/multi-agent/refs/channels/confluence.md +153 -0
- package/pipeline/commands/multi-agent/refs/channels/issue-comment.md +141 -0
- package/pipeline/commands/multi-agent/refs/channels/jira.md +127 -0
- package/pipeline/commands/multi-agent/refs/channels/pr-review-actions.md +135 -0
- package/pipeline/commands/multi-agent/refs/channels/pr.md +139 -0
- package/pipeline/commands/multi-agent/refs/channels/wiki.md +66 -0
- package/pipeline/commands/multi-agent/refs/component-dispatch.md +92 -0
- package/pipeline/commands/multi-agent/refs/cross-cli-contract.md +326 -0
- package/pipeline/commands/multi-agent/refs/frontend-guide.md +136 -0
- package/pipeline/commands/multi-agent/refs/issue-jira-triad.md +104 -0
- package/pipeline/commands/multi-agent/refs/keychain.md +80 -0
- package/pipeline/commands/multi-agent/refs/knowledge.md +112 -0
- package/pipeline/commands/multi-agent/refs/multi-repo-integration-build.md +207 -0
- package/pipeline/commands/multi-agent/refs/phases/log-format.md +89 -0
- package/pipeline/commands/multi-agent/refs/phases/modes.md +156 -0
- package/pipeline/commands/multi-agent/refs/phases/operations.md +91 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-0-init.md +481 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-1-analysis.md +264 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-2-planning.md +278 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-3-dev.md +364 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-4-review.md +378 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-5-test.md +129 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-6-commit.md +339 -0
- package/pipeline/commands/multi-agent/refs/phases/phase-7-report.md +361 -0
- package/pipeline/commands/multi-agent/refs/phases.md +187 -0
- package/pipeline/commands/multi-agent/refs/progress-contract.md +155 -0
- package/pipeline/commands/multi-agent/refs/rules.md +189 -0
- package/pipeline/commands/multi-agent/refs/swiftui-guide.md +254 -0
- package/pipeline/commands/multi-agent/refs/tracker-contract.md +256 -0
- package/pipeline/commands/multi-agent/refs/wiki-capture.md +109 -0
- package/pipeline/commands/multi-agent/resume.md +28 -0
- package/pipeline/commands/multi-agent/review.md +228 -0
- package/pipeline/commands/multi-agent/scan.md +74 -0
- package/pipeline/commands/multi-agent/search.md +97 -0
- package/pipeline/commands/multi-agent/setup.md +767 -0
- package/pipeline/commands/multi-agent/stack.md +48 -0
- package/pipeline/commands/multi-agent/status.md +38 -0
- package/pipeline/commands/multi-agent/sync.md +319 -0
- package/pipeline/commands/multi-agent/test.md +39 -0
- package/pipeline/commands/multi-agent/update.md +88 -0
- package/pipeline/commands/multi-agent.md +293 -0
- package/pipeline/commands/security-review.md +6 -0
- package/pipeline/commands/sim-test.md +256 -0
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-1-analysis.json +25 -0
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-2-plan.json +30 -0
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-review.json +20 -0
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-triage.json +15 -0
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/metadata.json +14 -0
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/task.json +12 -0
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-1-analysis.json +29 -0
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-2-plan.json +43 -0
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-review.json +35 -0
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-triage.json +35 -0
- package/pipeline/eval/golden-tasks/02-android-feature-compose/metadata.json +14 -0
- package/pipeline/eval/golden-tasks/02-android-feature-compose/task.json +12 -0
- package/pipeline/eval/golden-tasks/README.md +65 -0
- package/pipeline/eval/triage/01-empty-findings/expected.json +6 -0
- package/pipeline/eval/triage/01-empty-findings/input.json +5 -0
- package/pipeline/eval/triage/01-empty-findings/notes.md +7 -0
- package/pipeline/eval/triage/02-real-blocker/expected.json +15 -0
- package/pipeline/eval/triage/02-real-blocker/input.json +14 -0
- package/pipeline/eval/triage/02-real-blocker/notes.md +7 -0
- package/pipeline/eval/triage/03-out-of-scope-defer/expected.json +18 -0
- package/pipeline/eval/triage/03-out-of-scope-defer/input.json +14 -0
- package/pipeline/eval/triage/03-out-of-scope-defer/notes.md +10 -0
- package/pipeline/eval/triage/04-false-positive-reject/expected.json +18 -0
- package/pipeline/eval/triage/04-false-positive-reject/input.json +14 -0
- package/pipeline/eval/triage/04-false-positive-reject/notes.md +10 -0
- package/pipeline/eval/triage/05-mixed-classification/expected.json +43 -0
- package/pipeline/eval/triage/05-mixed-classification/input.json +38 -0
- package/pipeline/eval/triage/05-mixed-classification/notes.md +17 -0
- package/pipeline/eval/triage/06-severity-mismatch/expected.json +15 -0
- package/pipeline/eval/triage/06-severity-mismatch/input.json +14 -0
- package/pipeline/eval/triage/06-severity-mismatch/notes.md +9 -0
- package/pipeline/eval/triage/07-duplicate-reviewers/expected.json +27 -0
- package/pipeline/eval/triage/07-duplicate-reviewers/input.json +22 -0
- package/pipeline/eval/triage/07-duplicate-reviewers/notes.md +9 -0
- package/pipeline/eval/triage/08-style-misclassified/expected.json +18 -0
- package/pipeline/eval/triage/08-style-misclassified/input.json +14 -0
- package/pipeline/eval/triage/08-style-misclassified/notes.md +9 -0
- package/pipeline/eval/triage/09-cascading-finding/expected.json +23 -0
- package/pipeline/eval/triage/09-cascading-finding/input.json +22 -0
- package/pipeline/eval/triage/09-cascading-finding/notes.md +9 -0
- package/pipeline/eval/triage/10-deferred-crossref/expected.json +18 -0
- package/pipeline/eval/triage/10-deferred-crossref/input.json +14 -0
- package/pipeline/eval/triage/10-deferred-crossref/notes.md +9 -0
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/expected.json +27 -0
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/input.json +22 -0
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/notes.md +14 -0
- package/pipeline/eval/triage/README.md +54 -0
- package/pipeline/lib/account-resolver.sh +204 -0
- package/pipeline/lib/channels-multi-repo.sh +218 -0
- package/pipeline/lib/context-link-extractor.sh +192 -0
- package/pipeline/lib/credential-store-resolver.sh +57 -0
- package/pipeline/lib/credential-store.sh +226 -0
- package/pipeline/lib/fetch-confluence.sh +358 -0
- package/pipeline/lib/fetch-crashlytics.sh +314 -0
- package/pipeline/lib/fetch-fortify.sh +321 -0
- package/pipeline/lib/fetch-swagger.sh +270 -0
- package/pipeline/lib/issue-fetcher.sh +333 -0
- package/pipeline/lib/multi-repo-pipeline.sh +252 -0
- package/pipeline/lib/plan-todos.sh +284 -0
- package/pipeline/lib/post-pr-review.sh +374 -0
- package/pipeline/lib/repo-cache.sh +231 -0
- package/pipeline/lib/review-watch.sh +244 -0
- package/pipeline/lib/shadow-git.sh +222 -0
- package/pipeline/lib/submodule-detector.sh +177 -0
- package/pipeline/lib/vercel-deploy.sh +170 -0
- package/pipeline/preferences-template.json +132 -0
- package/pipeline/rules/app-store-guidelines.md +59 -0
- package/pipeline/rules/code-review.md +27 -0
- package/pipeline/rules/code-style.md +37 -0
- package/pipeline/rules/debugging.md +24 -0
- package/pipeline/rules/figma-pipeline.md +190 -0
- package/pipeline/rules/git-conventions.md +29 -0
- package/pipeline/rules/kotlin-android.md +92 -0
- package/pipeline/rules/performance.md +23 -0
- package/pipeline/rules/security.md +39 -0
- package/pipeline/rules/swiftui-qa.md +32 -0
- package/pipeline/rules/tdd.md +25 -0
- package/pipeline/rules/testing.md +37 -0
- package/pipeline/schemas/agent-state.schema.json +273 -0
- package/pipeline/schemas/analysis-output.schema.json +59 -0
- package/pipeline/schemas/clarify-output.schema.json +74 -0
- package/pipeline/schemas/dev-critic-output.schema.json +104 -0
- package/pipeline/schemas/diff-risk.schema.json +78 -0
- package/pipeline/schemas/figma-project-config.schema.json +372 -0
- package/pipeline/schemas/migrations/README.md +73 -0
- package/pipeline/schemas/migrations/figma-config-1.0.0-to-2.0.0.mjs +112 -0
- package/pipeline/schemas/migrations/prefs-2.0.0-to-2.1.0.mjs +75 -0
- package/pipeline/schemas/migrations/prefs-2.1.0-to-2.2.0.mjs +64 -0
- package/pipeline/schemas/migrations/prefs-2.2.0-to-2.3.0.mjs +36 -0
- package/pipeline/schemas/migrations/state-2.0.0-to-2.1.0.mjs +34 -0
- package/pipeline/schemas/plan-todos.schema.json +62 -0
- package/pipeline/schemas/planning-output.schema.json +57 -0
- package/pipeline/schemas/prefs.schema.json +1137 -0
- package/pipeline/schemas/reviewer-output.schema.json +55 -0
- package/pipeline/schemas/test-gap.schema.json +64 -0
- package/pipeline/schemas/token-budget.json +17 -0
- package/pipeline/schemas/triage-corpus.schema.json +31 -0
- package/pipeline/schemas/triage-output.schema.json +115 -0
- package/pipeline/scripts/.last-figma-sync-plan.json +23 -0
- package/pipeline/scripts/README-figma-smokes.md +34 -0
- package/pipeline/scripts/README.md +104 -0
- package/pipeline/scripts/aggregate-metrics.mjs +310 -0
- package/pipeline/scripts/audit-log-rotate.sh +61 -0
- package/pipeline/scripts/audit-log.sh +69 -0
- package/pipeline/scripts/benchmark-phase-0.sh +128 -0
- package/pipeline/scripts/build-skills-index.mjs +139 -0
- package/pipeline/scripts/classify-plan-safety.mjs +177 -0
- package/pipeline/scripts/cost-table.json +27 -0
- package/pipeline/scripts/diff-explain.mjs +276 -0
- package/pipeline/scripts/diff-risk-score.mjs +328 -0
- package/pipeline/scripts/eval-golden-tasks-live.mjs +294 -0
- package/pipeline/scripts/eval-golden-tasks.mjs +223 -0
- package/pipeline/scripts/eval-triage.mjs +171 -0
- package/pipeline/scripts/figma-placeholder-map.json +191 -0
- package/pipeline/scripts/fixtures/diff-risk-android.diff +40 -0
- package/pipeline/scripts/fixtures/diff-risk-ios.diff +48 -0
- package/pipeline/scripts/fixtures/install-layout.tsv +16 -0
- package/pipeline/scripts/fixtures/test-gap-node.diff +30 -0
- package/pipeline/scripts/fixtures/test-gap-python.diff +32 -0
- package/pipeline/scripts/gen-mode-dispatch.mjs +170 -0
- package/pipeline/scripts/gen-skills-index.mjs +90 -0
- package/pipeline/scripts/github-ssh-setup.sh +103 -0
- package/pipeline/scripts/import-figma-skills.sh +253 -0
- package/pipeline/scripts/keychain-save.sh +74 -0
- package/pipeline/scripts/keychain.py +294 -0
- package/pipeline/scripts/log-metric.sh +98 -0
- package/pipeline/scripts/match-skills.mjs +167 -0
- package/pipeline/scripts/memory-load.sh +46 -0
- package/pipeline/scripts/memory-save.sh +76 -0
- package/pipeline/scripts/migrate-prefs.mjs +390 -0
- package/pipeline/scripts/migrate-state.mjs +215 -0
- package/pipeline/scripts/output-quality-check.sh +125 -0
- package/pipeline/scripts/phase-banner.sh +158 -0
- package/pipeline/scripts/phase-tracker.sh +548 -0
- package/pipeline/scripts/pre-commit-check.sh +69 -0
- package/pipeline/scripts/pre-push-check.sh +77 -0
- package/pipeline/scripts/render-agent-log-cost.sh +149 -0
- package/pipeline/scripts/render-cost-summary.sh +137 -0
- package/pipeline/scripts/render-work-summary.sh +195 -0
- package/pipeline/scripts/repo-map.mjs +367 -0
- package/pipeline/scripts/run-aggregator.mjs +298 -0
- package/pipeline/scripts/scan-skills.sh +332 -0
- package/pipeline/scripts/search-logs.sh +291 -0
- package/pipeline/scripts/sign-skills.sh +67 -0
- package/pipeline/scripts/smoke-adapters.sh +207 -0
- package/pipeline/scripts/smoke-add-detail.sh +137 -0
- package/pipeline/scripts/smoke-agent-log-cost.sh +183 -0
- package/pipeline/scripts/smoke-agent-model-routing.sh +87 -0
- package/pipeline/scripts/smoke-bitbucket-contract.sh +223 -0
- package/pipeline/scripts/smoke-channels-flow.sh +130 -0
- package/pipeline/scripts/smoke-ci-workflows.sh +88 -0
- package/pipeline/scripts/smoke-clarify.sh +148 -0
- package/pipeline/scripts/smoke-commands-skills-parity.sh +87 -0
- package/pipeline/scripts/smoke-compliance-skills.sh +119 -0
- package/pipeline/scripts/smoke-cost-summary.sh +139 -0
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +198 -0
- package/pipeline/scripts/smoke-cross-phase-cohesion.sh +128 -0
- package/pipeline/scripts/smoke-delete-flow.sh +151 -0
- package/pipeline/scripts/smoke-dev-critic.sh +144 -0
- package/pipeline/scripts/smoke-diff-explain.sh +128 -0
- package/pipeline/scripts/smoke-diff-risk.sh +161 -0
- package/pipeline/scripts/smoke-dynamic-skill-loading.sh +160 -0
- package/pipeline/scripts/smoke-eval-live.sh +136 -0
- package/pipeline/scripts/smoke-existing-discovery-gate.sh +71 -0
- package/pipeline/scripts/smoke-figma-android-parity.sh +148 -0
- package/pipeline/scripts/smoke-figma-config-schema.sh +144 -0
- package/pipeline/scripts/smoke-figma-credential-store.sh +105 -0
- package/pipeline/scripts/smoke-figma-cross-cli-inventory.sh +177 -0
- package/pipeline/scripts/smoke-figma-dispatch.sh +123 -0
- package/pipeline/scripts/smoke-figma-skill-import.sh +174 -0
- package/pipeline/scripts/smoke-figma-sync.sh +149 -0
- package/pipeline/scripts/smoke-identity-isolation.sh +70 -0
- package/pipeline/scripts/smoke-install-layout.sh +241 -0
- package/pipeline/scripts/smoke-install-leak-gate.sh +125 -0
- package/pipeline/scripts/smoke-issue-comment-template.sh +86 -0
- package/pipeline/scripts/smoke-issue-jira-triad.sh +120 -0
- package/pipeline/scripts/smoke-keychain.sh +158 -0
- package/pipeline/scripts/smoke-language-axis.sh +109 -0
- package/pipeline/scripts/smoke-lib-scripts.sh +395 -0
- package/pipeline/scripts/smoke-migrate-state.sh +102 -0
- package/pipeline/scripts/smoke-mode-dispatch-drift.sh +158 -0
- package/pipeline/scripts/smoke-multi-repo-integration.sh +116 -0
- package/pipeline/scripts/smoke-multi-repo-worktree.sh +61 -0
- package/pipeline/scripts/smoke-no-token-prompt.sh +69 -0
- package/pipeline/scripts/smoke-pat-audit.sh +107 -0
- package/pipeline/scripts/smoke-per-repo-memory.sh +156 -0
- package/pipeline/scripts/smoke-personal-data.sh +82 -0
- package/pipeline/scripts/smoke-phase-0-multi-repo.sh +170 -0
- package/pipeline/scripts/smoke-phase-6-multi.sh +79 -0
- package/pipeline/scripts/smoke-phase-banner.sh +101 -0
- package/pipeline/scripts/smoke-phase-tracker.sh +255 -0
- package/pipeline/scripts/smoke-phase0-bridge-contract.sh +241 -0
- package/pipeline/scripts/smoke-phase4-triage.sh +142 -0
- package/pipeline/scripts/smoke-plan-approval-gate.sh +71 -0
- package/pipeline/scripts/smoke-plan-safety.sh +139 -0
- package/pipeline/scripts/smoke-plan-todos.sh +193 -0
- package/pipeline/scripts/smoke-pr-review-actions.sh +152 -0
- package/pipeline/scripts/smoke-pre-commit.sh +138 -0
- package/pipeline/scripts/smoke-pref-migration.sh +224 -0
- package/pipeline/scripts/smoke-prefs-language.sh +134 -0
- package/pipeline/scripts/smoke-progress-contract.sh +118 -0
- package/pipeline/scripts/smoke-push-retry.sh +75 -0
- package/pipeline/scripts/smoke-readme-counts.sh +120 -0
- package/pipeline/scripts/smoke-repo-map.sh +300 -0
- package/pipeline/scripts/smoke-review-watch.sh +134 -0
- package/pipeline/scripts/smoke-run-aggregator.sh +216 -0
- package/pipeline/scripts/smoke-schema-validation.sh +173 -0
- package/pipeline/scripts/smoke-search.sh +187 -0
- package/pipeline/scripts/smoke-shadow-git.sh +175 -0
- package/pipeline/scripts/smoke-skill-authoring.sh +142 -0
- package/pipeline/scripts/smoke-skill-language.sh +83 -0
- package/pipeline/scripts/smoke-skill-manifest.sh +138 -0
- package/pipeline/scripts/smoke-skill-scan.sh +198 -0
- package/pipeline/scripts/smoke-stack-swap.sh +132 -0
- package/pipeline/scripts/smoke-subagent-validators.sh +105 -0
- package/pipeline/scripts/smoke-sync-delegation.sh +74 -0
- package/pipeline/scripts/smoke-sync-parity.sh +92 -0
- package/pipeline/scripts/smoke-tasklist-ordering.sh +111 -0
- package/pipeline/scripts/smoke-telemetry.sh +147 -0
- package/pipeline/scripts/smoke-test-gap.sh +183 -0
- package/pipeline/scripts/smoke-token-budget.sh +67 -0
- package/pipeline/scripts/smoke-tracker-contract.sh +129 -0
- package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +65 -0
- package/pipeline/scripts/smoke-triage-memory.sh +174 -0
- package/pipeline/scripts/smoke-url-enrichment.sh +70 -0
- package/pipeline/scripts/smoke-validator-contradiction.sh +67 -0
- package/pipeline/scripts/smoke-vercel-deploy-redact.sh +129 -0
- package/pipeline/scripts/smoke-wiki-integration.sh +146 -0
- package/pipeline/scripts/smoke-work-summary.sh +163 -0
- package/pipeline/scripts/smoke-worktree-path-convention.sh +86 -0
- package/pipeline/scripts/smoke-write-state.sh +115 -0
- package/pipeline/scripts/stack-swap.sh +182 -0
- package/pipeline/scripts/sync-figma-source.sh +228 -0
- package/pipeline/scripts/sync-parity-check.sh +135 -0
- package/pipeline/scripts/test-gap-rules/android.json +25 -0
- package/pipeline/scripts/test-gap-rules/ios.json +29 -0
- package/pipeline/scripts/test-gap-rules/node.json +17 -0
- package/pipeline/scripts/test-gap-rules/python.json +19 -0
- package/pipeline/scripts/test-gap-scan.mjs +343 -0
- package/pipeline/scripts/token-budget-report.mjs +145 -0
- package/pipeline/scripts/triage-memory.mjs +258 -0
- package/pipeline/scripts/ui-tree-dumper.swift +122 -0
- package/pipeline/scripts/uninstall.mjs +331 -0
- package/pipeline/scripts/update-issue-progress.sh +146 -0
- package/pipeline/scripts/validate-analysis.mjs +132 -0
- package/pipeline/scripts/validate-diff-risk.mjs +117 -0
- package/pipeline/scripts/validate-planning.mjs +180 -0
- package/pipeline/scripts/validate-reviewer.mjs +131 -0
- package/pipeline/scripts/validate-schemas.mjs +88 -0
- package/pipeline/scripts/validate-test-gap.mjs +90 -0
- package/pipeline/scripts/validate-triage.mjs +175 -0
- package/pipeline/scripts/verify-skills.sh +126 -0
- package/pipeline/scripts/write-state.mjs +175 -0
- package/pipeline/skills/.skill-manifest.json +779 -0
- package/pipeline/skills/.skills-index.json +1771 -0
- package/pipeline/skills/figma-android/README.md +36 -0
- package/pipeline/skills/figma-android/figma-component-code-connect/SKILL.md +62 -0
- package/pipeline/skills/figma-android/figma-component-implement/SKILL.md +158 -0
- package/pipeline/skills/figma-android/figma-component-test/SKILL.md +120 -0
- package/pipeline/skills/figma-android/figma-component-wiki/SKILL.md +35 -0
- package/pipeline/skills/figma-android/figma-to-component/SKILL.md +124 -0
- package/pipeline/skills/figma-common/README.md +57 -0
- package/pipeline/skills/figma-common/figma-cli-iterate/SKILL.md +277 -0
- package/pipeline/skills/figma-common/figma-cli-iterate-mend/SKILL.md +498 -0
- package/pipeline/skills/figma-common/figma-cli-lean-iterate/SKILL.md +283 -0
- package/pipeline/skills/figma-common/figma-cli-skip/SKILL.md +362 -0
- package/pipeline/skills/figma-common/figma-commit/COMMON_REBASE.md +206 -0
- package/pipeline/skills/figma-common/figma-commit/REVIEW.md +337 -0
- package/pipeline/skills/figma-common/figma-commit/SKILL.md +211 -0
- package/pipeline/skills/figma-common/figma-component-confluence-sync/SKILL.md +218 -0
- package/pipeline/skills/figma-common/figma-component-start/SKILL.md +246 -0
- package/pipeline/skills/figma-common/figma-component-status-update/SKILL.md +73 -0
- package/pipeline/skills/figma-common/figma-fix/SKILL.md +316 -0
- package/pipeline/skills/figma-common/figma-form-integration/SKILL.md +542 -0
- package/pipeline/skills/figma-common/figma-issue/SKILL.md +745 -0
- package/pipeline/skills/figma-common/figma-iterate/SKILL.md +203 -0
- package/pipeline/skills/figma-common/figma-iteration-commit/SKILL.md +1015 -0
- package/pipeline/skills/figma-common/figma-mend/SKILL.md +331 -0
- package/pipeline/skills/figma-common/figma-price-integration/SKILL.md +398 -0
- package/pipeline/skills/figma-common/figma-remote-mcp-auth/SKILL.md +104 -0
- package/pipeline/skills/figma-common/figma-review/SKILL.md +395 -0
- package/pipeline/skills/figma-common/figma-setup/SKILL.md +514 -0
- package/pipeline/skills/figma-common/figma-setup/scripts/fetch-mcp-token.py +592 -0
- package/pipeline/skills/figma-common/figma-skip/SKILL.md +129 -0
- package/pipeline/skills/figma-common/figma-ui-patterns/SKILL.md +104 -0
- package/pipeline/skills/figma-common/figma-utility/SKILL.md +274 -0
- package/pipeline/skills/figma-common/figma-utility/scripts/figma-utility.py +808 -0
- package/pipeline/skills/figma-common/figma-validate/SKILL.md +633 -0
- package/pipeline/skills/figma-common/performance-iteration-commit-all/SKILL.md +711 -0
- package/pipeline/skills/figma-common/performance-review-next/SKILL.md +233 -0
- package/pipeline/skills/figma-common/performance-start/SKILL.md +425 -0
- package/pipeline/skills/figma-common/performance-swiftui/SKILL.md +706 -0
- package/pipeline/skills/figma-common/performance-tour/SKILL.md +418 -0
- package/pipeline/skills/figma-ios/REVIEW_CHECKLIST.md +67 -0
- package/pipeline/skills/figma-ios/figma-component-code-connect/SKILL.md +178 -0
- package/pipeline/skills/figma-ios/figma-component-implement/SKILL.md +184 -0
- package/pipeline/skills/figma-ios/figma-component-test/SKILL.md +219 -0
- package/pipeline/skills/figma-ios/figma-component-wiki/SKILL.md +274 -0
- package/pipeline/skills/figma-ios/figma-to-component/SKILL.md +401 -0
- package/pipeline/skills/figma-ios/figma-to-component/halt-return-protocol.md +57 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-0-init.md +307 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-1-gathering.md +119 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-1.5-existing-discovery.md +174 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2-orchestrator.md +333 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2a-testing-identifiers.md +368 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2b-localization.md +393 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2c-accessibility.md +617 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-2d-analytics.md +352 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3-orchestrator.md +337 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3a-location.md +206 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3b-tokens.md +235 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3c-nested.md +214 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3d-patterns.md +871 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3e-assets.md +156 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3f-utilities.md +175 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3g-property-coverage.md +176 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-3h-variant-config.md +333 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4-orchestrator.md +412 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4a-configuration.md +336 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4b-view.md +695 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4c-documentation.md +332 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4d-preview.md +380 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-4e-modifiers.md +262 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5-orchestrator.md +482 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5a-viewinspector.md +274 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5b-snapshot.md +636 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-5c-unit.md +142 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-6-code-connect.md +547 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7-wiki.md +39 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7a-confluence-generate.md +659 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-7a-wiki-generate.md +580 -0
- package/pipeline/skills/figma-ios/figma-to-component/phases/phase-8-cleanup.md +51 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/accessibility.md +129 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/analytics-events.md +64 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/code-connect.md +531 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/confluence-api.md +89 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/confluence-xhtml.md +155 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/figma-to-swiftui-effects.md +196 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/halt-return-protocol.md +57 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/localization-naming.md +89 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/macros.md +227 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/missing-tokens.md +157 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/orchestrator-discipline.md +90 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/registry.md +116 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/remote-mcp-script.md +153 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/rest-api-script.md +130 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/scripts-inventory.md +218 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/snapshot-testing.md +188 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/subcomponent-graph.md +93 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/testing-identifiers-naming.md +98 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/tools.md +261 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/viewinspector.md +147 -0
- package/pipeline/skills/figma-ios/figma-to-component/reference/wiki-to-confluence-mapping.md +182 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/apply-author-login-map.py +185 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/backfill-status.py +609 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/build-author-registry.py +332 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/bulk-sync-issues.py +261 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/code-connect-data-gather.py +184 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/code-connect-publish.sh +188 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-component-status-upload.py +768 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-component-status.py +191 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-data-gather.py +420 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-page-ids.json +94 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/confluence-publish.py +336 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/figma-subcomponent-graph.py +391 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/figma-update.py +292 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/__init__.py +1 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/issue_sync_propagate.py +93 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/registry_writer.py +299 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_backfill_status.py +343 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_figma_update.py +206 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_figma_update_http.py +149 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_phase_clis.py +281 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_registry_writer.py +332 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_skill_figma_issue.py +176 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_skill_figma_review.py +98 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_update_issue.py +298 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/lib/test_update_issue_gh.py +195 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/phase1-gather.py +1298 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/phase2-finalize.py +228 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/phase3-scripts.py +1089 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/phase4-finalize.py +141 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/phase5-finalize.py +106 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/phase6-finalize.py +162 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/phase7-finalize.py +105 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/register-icons-codeconnect.py +179 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/remote-mcp-fetch.py +260 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/resolve-author-logins.py +260 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/run-uicomponents-tests.sh +86 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/sidebar-generator.py +321 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/update-issue-from-registry.py +1470 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase4.sh +176 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase6.sh +147 -0
- package/pipeline/skills/figma-ios/figma-to-component/scripts/validate-phase7a.py +629 -0
- package/pipeline/skills/shared/README.md +212 -0
- package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +315 -0
- package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +348 -0
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +944 -0
- package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +51 -0
- package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +300 -0
- package/pipeline/skills/shared/core/multi-agent-delete/SKILL.md +63 -0
- package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +64 -0
- package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +56 -0
- package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +36 -0
- package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +42 -0
- package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +66 -0
- package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +292 -0
- package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +35 -0
- package/pipeline/skills/shared/core/multi-agent-jira/SKILL.md +38 -0
- package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +41 -0
- package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +87 -0
- package/pipeline/skills/shared/core/multi-agent-local/SKILL.md +37 -0
- package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +53 -0
- package/pipeline/skills/shared/core/multi-agent-log/SKILL.md +28 -0
- package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +47 -0
- package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +42 -0
- package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +191 -0
- package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +31 -0
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +61 -0
- package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +61 -0
- package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +62 -0
- package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +309 -0
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +55 -0
- package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +41 -0
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +184 -0
- package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +44 -0
- package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +34 -0
- package/pipeline/skills/shared/external/accessibility-compliance-accessibility-audit/SKILL.md +45 -0
- package/pipeline/skills/shared/external/agentflow/SKILL.md +199 -0
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +438 -0
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +584 -0
- package/pipeline/skills/shared/external/android-architecture/SKILL.md +407 -0
- package/pipeline/skills/shared/external/android-jetpack-compose-expert/SKILL.md +153 -0
- package/pipeline/skills/shared/external/android-performance/SKILL.md +736 -0
- package/pipeline/skills/shared/external/android-security/SKILL.md +577 -0
- package/pipeline/skills/shared/external/android_ui_verification/SKILL.md +66 -0
- package/pipeline/skills/shared/external/api-patterns/SKILL.md +85 -0
- package/pipeline/skills/shared/external/api-security-best-practices/SKILL.md +910 -0
- package/pipeline/skills/shared/external/app-clips/SKILL.md +436 -0
- package/pipeline/skills/shared/external/app-intents/SKILL.md +489 -0
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +1076 -0
- package/pipeline/skills/shared/external/app-store-changelog/SKILL.md +75 -0
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +409 -0
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +411 -0
- package/pipeline/skills/shared/external/app-store-review/references/code-signing.md +259 -0
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +90 -0
- package/pipeline/skills/shared/external/app-store-review/references/rejection-patterns.md +152 -0
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +118 -0
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +500 -0
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +425 -0
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +344 -0
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +508 -0
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +285 -0
- package/pipeline/skills/shared/external/architecture/SKILL.md +60 -0
- package/pipeline/skills/shared/external/authentication/SKILL.md +496 -0
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +211 -0
- package/pipeline/skills/shared/external/background-processing/SKILL.md +499 -0
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +390 -0
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +461 -0
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +425 -0
- package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +462 -0
- package/pipeline/skills/shared/external/clean-code/SKILL.md +94 -0
- package/pipeline/skills/shared/external/closed-loop-delivery/SKILL.md +116 -0
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +492 -0
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +461 -0
- package/pipeline/skills/shared/external/compose-components/SKILL.md +441 -0
- package/pipeline/skills/shared/external/compose-navigation/SKILL.md +436 -0
- package/pipeline/skills/shared/external/compose-testing/SKILL.md +527 -0
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +425 -0
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +409 -0
- package/pipeline/skills/shared/external/context-compression/SKILL.md +266 -0
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +491 -0
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +435 -0
- package/pipeline/skills/shared/external/core-motion/SKILL.md +388 -0
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +405 -0
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +495 -0
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +420 -0
- package/pipeline/skills/shared/external/coreml/SKILL.md +458 -0
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +765 -0
- package/pipeline/skills/shared/external/css-modern/SKILL.md +467 -0
- package/pipeline/skills/shared/external/database-patterns/SKILL.md +335 -0
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +422 -0
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +387 -0
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +298 -0
- package/pipeline/skills/shared/external/debugging-strategies/SKILL.md +37 -0
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +477 -0
- package/pipeline/skills/shared/external/docker-expert/SKILL.md +413 -0
- package/pipeline/skills/shared/external/energykit/SKILL.md +460 -0
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +541 -0
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +483 -0
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +326 -0
- package/pipeline/skills/shared/external/fastapi-pro/SKILL.md +190 -0
- package/pipeline/skills/shared/external/firebase/SKILL.md +61 -0
- package/pipeline/skills/shared/external/github-actions-templates/SKILL.md +348 -0
- package/pipeline/skills/shared/external/gradle-kotlin-dsl/SKILL.md +552 -0
- package/pipeline/skills/shared/external/healthkit/SKILL.md +498 -0
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +602 -0
- package/pipeline/skills/shared/external/help-skills/SKILL.md +166 -0
- package/pipeline/skills/shared/external/hig-components-content/SKILL.md +81 -0
- package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +95 -0
- package/pipeline/skills/shared/external/hig-components-status/SKILL.md +82 -0
- package/pipeline/skills/shared/external/hig-components-system/SKILL.md +101 -0
- package/pipeline/skills/shared/external/hig-foundations/SKILL.md +94 -0
- package/pipeline/skills/shared/external/hig-inputs/SKILL.md +110 -0
- package/pipeline/skills/shared/external/hig-patterns/SKILL.md +99 -0
- package/pipeline/skills/shared/external/hig-platforms/SKILL.md +81 -0
- package/pipeline/skills/shared/external/hig-technologies/SKILL.md +125 -0
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +496 -0
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +455 -0
- package/pipeline/skills/shared/external/html-semantic/SKILL.md +301 -0
- package/pipeline/skills/shared/external/humanizer/SKILL.md +118 -0
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +301 -0
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +140 -0
- package/pipeline/skills/shared/external/ios-debugger-agent/SKILL.md +59 -0
- package/pipeline/skills/shared/external/ios-developer/SKILL.md +217 -0
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +418 -0
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +627 -0
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +462 -0
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +441 -0
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +862 -0
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -0
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +563 -0
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +1116 -0
- package/pipeline/skills/shared/external/ios-security/SKILL.md +496 -0
- package/pipeline/skills/shared/external/ios-security/references/app-review-guidelines.md +174 -0
- package/pipeline/skills/shared/external/ios-security/references/cryptokit-advanced.md +297 -0
- package/pipeline/skills/shared/external/ios-security/references/file-storage-patterns.md +354 -0
- package/pipeline/skills/shared/external/ios-security/references/privacy-manifest.md +117 -0
- package/pipeline/skills/shared/external/kotlin-coroutines-expert/SKILL.md +101 -0
- package/pipeline/skills/shared/external/live-activities/SKILL.md +500 -0
- package/pipeline/skills/shared/external/live-activities/references/live-activity-patterns.md +868 -0
- package/pipeline/skills/shared/external/macos-menubar-tuist-app/SKILL.md +109 -0
- package/pipeline/skills/shared/external/macos-spm-app-packaging/SKILL.md +110 -0
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +485 -0
- package/pipeline/skills/shared/external/mapkit-location/references/corelocation-patterns.md +730 -0
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +748 -0
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +479 -0
- package/pipeline/skills/shared/external/monorepo-architect/SKILL.md +64 -0
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +395 -0
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +363 -0
- package/pipeline/skills/shared/external/natural-language/SKILL.md +412 -0
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +311 -0
- package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +418 -0
- package/pipeline/skills/shared/external/nodejs-backend-patterns/SKILL.md +38 -0
- package/pipeline/skills/shared/external/observability-engineer/SKILL.md +235 -0
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +398 -0
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +254 -0
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +387 -0
- package/pipeline/skills/shared/external/pencilkit-drawing/references/paperkit-integration.md +376 -0
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +302 -0
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +446 -0
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +435 -0
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +501 -0
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +701 -0
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +774 -0
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +869 -0
- package/pipeline/skills/shared/external/photos-camera-media/references/photospicker-patterns.md +597 -0
- package/pipeline/skills/shared/external/play-store-review/SKILL.md +350 -0
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +501 -0
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +677 -0
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +745 -0
- package/pipeline/skills/shared/external/python-patterns/SKILL.md +383 -0
- package/pipeline/skills/shared/external/react-best-practices/SKILL.md +290 -0
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +479 -0
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +480 -0
- package/pipeline/skills/shared/external/rest-api-design/SKILL.md +386 -0
- package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +506 -0
- package/pipeline/skills/shared/external/room-database/SKILL.md +564 -0
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +483 -0
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +544 -0
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +485 -0
- package/pipeline/skills/shared/external/storekit/SKILL.md +478 -0
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +58 -0
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +755 -0
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +487 -0
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +895 -0
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +467 -0
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +408 -0
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +80 -0
- package/pipeline/skills/shared/external/swift-concurrency/references/swift-6-2-concurrency.md +233 -0
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +187 -0
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +341 -0
- package/pipeline/skills/shared/external/swift-concurrency-expert/SKILL.md +113 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/SKILL.md +124 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/actors.md +155 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/async-streams.md +67 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/bridging.md +52 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/bug-patterns.md +100 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/cancellation.md +107 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/diagnostics.md +70 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/hotspots.md +47 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/interop.md +129 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/new-features.md +224 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/structured.md +101 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/testing.md +218 -0
- package/pipeline/skills/shared/external/swift-concurrency-pro/references/unstructured.md +61 -0
- package/pipeline/skills/shared/external/swift-language/SKILL.md +498 -0
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +505 -0
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +462 -0
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +504 -0
- package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +97 -0
- package/pipeline/skills/shared/external/swift-testing-pro/references/async-tests.md +252 -0
- package/pipeline/skills/shared/external/swift-testing-pro/references/core-rules.md +52 -0
- package/pipeline/skills/shared/external/swift-testing-pro/references/migrating-from-xctest.md +34 -0
- package/pipeline/skills/shared/external/swift-testing-pro/references/new-features.md +318 -0
- package/pipeline/skills/shared/external/swift-testing-pro/references/writing-better-tests.md +254 -0
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +334 -0
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +504 -0
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +975 -0
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +675 -0
- package/pipeline/skills/shared/external/swiftdata-pro/SKILL.md +102 -0
- package/pipeline/skills/shared/external/swiftdata-pro/references/class-inheritance.md +104 -0
- package/pipeline/skills/shared/external/swiftdata-pro/references/cloudkit.md +10 -0
- package/pipeline/skills/shared/external/swiftdata-pro/references/core-rules.md +20 -0
- package/pipeline/skills/shared/external/swiftdata-pro/references/indexing.md +27 -0
- package/pipeline/skills/shared/external/swiftdata-pro/references/predicates.md +73 -0
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +503 -0
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +821 -0
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +553 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/SKILL.md +102 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/accessibility-patterns.md +215 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-advanced.md +403 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-basics.md +284 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-transitions.md +326 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/charts-accessibility.md +135 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/charts.md +602 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/image-optimization.md +203 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/latest-apis.md +464 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/layout-best-practices.md +266 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/liquid-glass.md +416 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/list-patterns.md +394 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/macos-scenes.md +318 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/macos-views.md +357 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/macos-window-styling.md +303 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/performance-patterns.md +403 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/scroll-patterns.md +293 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/sheet-navigation-patterns.md +363 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/state-management.md +417 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/references/view-structure.md +389 -0
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +450 -0
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +425 -0
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +336 -0
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +97 -0
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +69 -0
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +99 -0
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +147 -0
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +98 -0
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +262 -0
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +207 -0
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +177 -0
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +169 -0
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +178 -0
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +371 -0
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +486 -0
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +1097 -0
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +780 -0
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +696 -0
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +487 -0
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +46 -0
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +29 -0
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +33 -0
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +52 -0
- package/pipeline/skills/shared/external/swiftui-performance-audit/SKILL.md +114 -0
- package/pipeline/skills/shared/external/swiftui-pro/SKILL.md +108 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/accessibility.md +13 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/api.md +39 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/data.md +43 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/design.md +31 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/hygiene.md +9 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/navigation.md +14 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/performance.md +46 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/swift.md +56 -0
- package/pipeline/skills/shared/external/swiftui-pro/references/views.md +35 -0
- package/pipeline/skills/shared/external/swiftui-ui-patterns/SKILL.md +103 -0
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +428 -0
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +534 -0
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +948 -0
- package/pipeline/skills/shared/external/swiftui-view-refactor/SKILL.md +210 -0
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +273 -0
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +151 -0
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +95 -0
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +51 -0
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +111 -0
- package/pipeline/skills/shared/external/tailwind-css/SKILL.md +309 -0
- package/pipeline/skills/shared/external/testing-backend/SKILL.md +393 -0
- package/pipeline/skills/shared/external/tipkit/SKILL.md +494 -0
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +782 -0
- package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +336 -0
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +475 -0
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +736 -0
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +738 -0
- package/pipeline/skills/shared/external/vue-composition/SKILL.md +371 -0
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +410 -0
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +567 -0
- package/pipeline/skills/shared/external/web-accessibility/SKILL.md +373 -0
- package/pipeline/skills/shared/external/web-performance/SKILL.md +345 -0
- package/pipeline/skills/shared/external/web-testing/SKILL.md +385 -0
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +497 -0
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +871 -0
- package/pipeline/skills/skills-index.md +205 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: figma-form-integration
|
|
3
|
+
description: "Form pattern integration for Figma-to-SwiftUI components. Guides FormSection/FormField adoption — when a component embeds form-capable sub-components (Selectbox, Checkbox, Radio, TextboxTextarea, DatepickerSchedule, ButtonsInputStepper) this skill defines how to model them as FormField references inside a nested FormSection, owned by the caller."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
allowed-tools: Read, Glob, Grep
|
|
6
|
+
status: wip-v5
|
|
7
|
+
sourced-from: upstream/figma-form-integration
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# /figma-form-integration — Form Pattern Integration
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
This skill is consumed by other skills (Phase 3D pattern detection, Phase 4A configuration, Phase 4B view implementation) when a **form pattern** is detected in a Figma component. It defines how to model form inputs using the CoreUI `FormField` + `FormSection` system instead of raw `@State`, `Binding`, or ad-hoc value properties.
|
|
15
|
+
|
|
16
|
+
It is also **user-invocable** for vibe-coding / ad-hoc work: whenever you are wiring up a component that embeds form-capable sub-components outside the full figma-to-swiftui pipeline, run `/figma-form-integration` to apply the same rules.
|
|
17
|
+
|
|
18
|
+
This is the forms counterpart of `/figma-price-integration`. Same shape: a protocol-level pattern (`FormSection`) with a default concrete implementation (`FormGroup`), consumed by Phase 3/4 as a cross-cutting integration.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Strict Rules (non-negotiable)
|
|
23
|
+
|
|
24
|
+
1. **Any form input MUST go through a `FormField` subclass.** No raw `Binding<Value>`, no `@State` values, no ad-hoc `isChecked: Bool` / `selectedOption: X` properties on Configuration or View. This applies to:
|
|
25
|
+
- A single embedded atomic control (Checkbox, Radio, Selectbox, TextboxTextarea, DatepickerSchedule).
|
|
26
|
+
- Multiple embedded controls forming a composite form (2+ inputs in one component).
|
|
27
|
+
- Any nested form sub-component detected in Figma.
|
|
28
|
+
If you see any of those cases → `FormField` / `FormSection`, always.
|
|
29
|
+
|
|
30
|
+
2. **Multi-field components MUST expose a nested `FormSection`.** When the component embeds 2+ form-capable sub-components, the Configuration holds a nested `@FormSection @Observable` class conforming to `FormSection`. The View binds the section via `@Bindable` and delegates rendering per field.
|
|
31
|
+
|
|
32
|
+
3. **The caller owns the section / fields. The component does NOT instantiate them.** Configuration carries the `FormSection` (or single `FormField`) reference. The scene view-model constructs the fields with their rules and policy; the component is headless over them.
|
|
33
|
+
|
|
34
|
+
4. **Configuration holds form references, not values.** No `amount: String`, no `selectedOption: Option`, no `isChecked: Bool` next to a form input. If a value travels through the API, it travels through its `FormField`.
|
|
35
|
+
|
|
36
|
+
5. **Section belongs in Configuration, not View — if a Configuration exists.** When the component has a Configuration struct (COMPLEX), the `FormSection` property MUST live on Configuration. Only components with NO Configuration may accept a `FormField` directly as a View init parameter.
|
|
37
|
+
|
|
38
|
+
6. **Static content (labels, placeholders, helper text, toggle captions) stays in Configuration — not on the field.** Fields are pure form state: value, rules, policy, options, loading. Labels and copy are visual/content — they go on Configuration (chainable via `@GenerateChainModifiers`).
|
|
39
|
+
|
|
40
|
+
7. **The nested `FormSection` mirrors the design exactly.** Declare ONLY the fields the component actually renders. Do not add fields the design doesn't use; do not drop fields the design does use. The section's shape is dictated by the design, not by developer convenience or a shared/generic form model.
|
|
41
|
+
|
|
42
|
+
8. **Non-form actions ("Sil", "Detaylar", "Edit") stay as paired closures on the View.** They are NOT fields, NOT Configuration values — they are View dependencies passed via paired modifiers, exactly like any other coexistent action (see Phase 3D §2.3.1).
|
|
43
|
+
|
|
44
|
+
9. **Validation and focus are caller concerns.** The component never exposes an `isValid` property, never owns a `FormFocus`, never calls `validate()` internally. The scene calls `section.validate()` (or `[section].validateAll(focus:)`) and sets `.formFocus(...)` at the scene root.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## When to Invoke This Skill
|
|
49
|
+
|
|
50
|
+
Invoke when ANY of these are detected:
|
|
51
|
+
|
|
52
|
+
1. **Phase 3D — Sub-Component Integration (§2.2):** A nested instance of a form-capable design-system component:
|
|
53
|
+
- `Selectbox` (single-select dropdown)
|
|
54
|
+
- `Checkbox` / `CheckboxButton`
|
|
55
|
+
- `Radio` / `RadioButton`
|
|
56
|
+
- `TextboxTextarea` (text input, single or multi-line)
|
|
57
|
+
- `DatepickerSchedule` (date / date-range input)
|
|
58
|
+
- `ButtonsInputStepper` (numeric +/- counter, e.g. passenger / quantity selectors)
|
|
59
|
+
- Any component whose Figma variants include an input state (empty/filled/error/disabled) with a user-driven value
|
|
60
|
+
2. **Phase 4A — Configuration:** A property group contains form-input fields.
|
|
61
|
+
3. **Phase 4B — View:** The view renders form controls that require user input with validation semantics.
|
|
62
|
+
|
|
63
|
+
**Counting rule (atomic vs composite):**
|
|
64
|
+
- **0 embedded form sub-components** — no form pattern; skip this skill.
|
|
65
|
+
- **1 embedded form sub-component** — atomic form: the Configuration (or View init) takes ONE `*FormField` directly, no `FormSection` wrapper.
|
|
66
|
+
- **2+ embedded form sub-components** — composite form: nested `FormSection` class in Configuration bundling every field.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Architecture
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Scene ViewModel (caller)
|
|
74
|
+
|
|
|
75
|
+
| constructs fields + rules + policy
|
|
76
|
+
v
|
|
77
|
+
ComponentName.Section : FormSection (component-specific, only needed fields)
|
|
78
|
+
| declared with @FormSection @Observable
|
|
79
|
+
| macro synthesizes: state, children
|
|
80
|
+
v
|
|
81
|
+
ComponentNameConfiguration
|
|
82
|
+
| holds `section: ComponentName.Section`
|
|
83
|
+
| plus static content (labels, placeholders, copy)
|
|
84
|
+
v
|
|
85
|
+
ComponentName: View
|
|
86
|
+
| @Bindable var section (plus paired closures for non-form actions)
|
|
87
|
+
v
|
|
88
|
+
Atomic form views (Checkbox, Radio, Selectbox, InputField, DatePicker)
|
|
89
|
+
each takes its child field from section.<fieldName>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Key Files
|
|
93
|
+
|
|
94
|
+
| File | Location | Purpose |
|
|
95
|
+
|------|----------|---------|
|
|
96
|
+
| `FormSection.swift` | `CoreUI/Components/Forms/Foundation/` | Protocol + default aggregate `validate` / `evaluate` / `clear` / `state` semantics |
|
|
97
|
+
| `FormGroup.swift` | `CoreUI/Components/Forms/Foundation/` | Concrete everyday `FormSection` — use for ad-hoc grouping when a named type isn't worth it |
|
|
98
|
+
| `FormField.swift` | `CoreUI/Components/Forms/Foundation/` | Generic base: `value`, `state`, `rules`, `validationPolicy` |
|
|
99
|
+
| `Validatable.swift` | `CoreUI/Components/Forms/Foundation/` | Non-generic protocol; `[any Validatable].validateAll(focus:)` + `leafFields` |
|
|
100
|
+
| `FormFocus.swift` | `CoreUI/Components/Forms/Foundation/` | `.formFocus(focus)` environment, `focus.focusFirstError()` |
|
|
101
|
+
| `CheckboxFormField.swift` etc. | `CoreUI/Components/Forms/FormFields/` | Per-control mini-viewmodels |
|
|
102
|
+
| `FormSection` macro | `UIMacros/FormSection/` | `@FormSection` synthesizes `state` + `children` |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## The Protocol
|
|
107
|
+
|
|
108
|
+
```swift
|
|
109
|
+
public protocol FormSection: Validatable {
|
|
110
|
+
// Inherits from Validatable:
|
|
111
|
+
// var children: [any Validatable] { get }
|
|
112
|
+
// var state: FormState { get set }
|
|
113
|
+
// validate() / evaluate() / clear()
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Default aggregate implementations are provided by a protocol extension: `validate()` runs every child (no short-circuit — all inline errors update), rolls the first error into the section's own `state`; `clear()` resets everything to `.pristine`. Identical semantics to `FormGroup`.
|
|
118
|
+
|
|
119
|
+
### @FormSection macro
|
|
120
|
+
|
|
121
|
+
Attached to an `@Observable` class, synthesizes:
|
|
122
|
+
- `public var state: FormState = .pristine`
|
|
123
|
+
- `public var children: [any Validatable]` — auto-detected from stored properties whose type matches `*FormField`, `*FormSection`, `FormGroup`, or is marked `@FormChild`.
|
|
124
|
+
|
|
125
|
+
Supports `T?`, `[T]`, `[T]?` transparently. Plain data properties (`String`, `URL`, `Int`) are ignored.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## How to Create a Component-Specific Section
|
|
130
|
+
|
|
131
|
+
**Rule: each COMPOSITE form component defines its own nested `.Section` class conforming to `FormSection`.** The nested section exposes ONLY the fields that component accepts — no silent discard.
|
|
132
|
+
|
|
133
|
+
### Step 1: Inventory the Embedded Form Sub-Components
|
|
134
|
+
|
|
135
|
+
From the Figma design, list every input element:
|
|
136
|
+
|
|
137
|
+
| Figma element | FormField subclass | Notes |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| Selectbox (single value) | `PickerFormField<Option>` | `.searchable(options:)` if search enabled; `.async()` if remote |
|
|
140
|
+
| Selectbox (multi select) | `MultiPickerFormField<Option>` | Usually max selection rule |
|
|
141
|
+
| Checkbox / CheckboxButton (single) | `CheckboxFormField` | `MustBeTrueRule` if acceptance |
|
|
142
|
+
| Checkbox group | `CheckboxGroupFormField<Option>` | `minSelections` / `maxSelections` |
|
|
143
|
+
| Radio / RadioButton group | `RadioFormField<Option>` | `RequiredSelectionRule` |
|
|
144
|
+
| TextboxTextarea (single line) | `TextFormField` | Add filters: digits, email regex, max length |
|
|
145
|
+
| TextboxTextarea (multi line) | `TextFormField` (textArea:true) | Same field type, visual variant |
|
|
146
|
+
| DatepickerSchedule (date) | `DatePickerFormField` | `.flightDate()` / `.birthDate()` factories |
|
|
147
|
+
| DatepickerSchedule (range) | `DateRangePickerFormField` | `.roundTrip(minimumNights:maximumNights:)` |
|
|
148
|
+
| ButtonsInputStepper (numeric +/-) | `StepperFormField` | `minValue` / `maxValue` / `step`; helpers `increment()` / `decrement()` / `canIncrement` / `canDecrement` |
|
|
149
|
+
| Toggle (visual switch of Bool, dedicated) | `ToggleFormField` | Use when the design renders a Switch (`TurkishToggle`) and you want a typed-distinct field. No indeterminate state. `MustBeTrueRule()` if acceptance. Factory: `ToggleFormField.disabled(value:)`. |
|
|
150
|
+
| Toggle (visual switch of Bool, unified with checkbox) | `CheckboxFormField` | Use when toggle and checkbox are interchangeable in the same form (atomic view decides Switch vs Box rendering). Has `.indeterminate` state which Toggle never uses. |
|
|
151
|
+
| Phone input (country code + number) | Composite `PhoneFormField` (one field) | Wraps two children internally; see `FormField` composite pattern |
|
|
152
|
+
|
|
153
|
+
### Step 2: Define the Nested Section (COMPOSITE, 2+ fields)
|
|
154
|
+
|
|
155
|
+
**If the component has a Configuration struct (default for COMPLEX components):** Nest a `@FormSection`-annotated class inside the component's namespace, and put the `section` property on Configuration.
|
|
156
|
+
|
|
157
|
+
```swift
|
|
158
|
+
extension PNRContactCard {
|
|
159
|
+
|
|
160
|
+
@FormSection
|
|
161
|
+
@Observable
|
|
162
|
+
public final class Section: FormSection, @unchecked Sendable {
|
|
163
|
+
public let email = TextFormField(
|
|
164
|
+
rules: [RequiredRule(), EmailRule()]
|
|
165
|
+
)
|
|
166
|
+
public let phoneCountry = PickerFormField<CountryCode>.searchable(
|
|
167
|
+
options: CountryCode.all,
|
|
168
|
+
initialValue: .tr,
|
|
169
|
+
rules: [RequiredSelectionRule()]
|
|
170
|
+
)
|
|
171
|
+
public let phoneNumber = TextFormField(
|
|
172
|
+
rules: [RequiredRule(), PhoneRule()],
|
|
173
|
+
filter: .digitsOnly
|
|
174
|
+
)
|
|
175
|
+
public let isPrimary = CheckboxFormField()
|
|
176
|
+
|
|
177
|
+
public init() {} // caller builds with defaults; override factories if needed
|
|
178
|
+
// Macro synthesizes: var state, var children
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
> **`@unchecked Sendable` on the nested `Section`**: nested `Section` classes MUST conform to `@unchecked Sendable` so they can be stored on a `Sendable` Configuration (compiler cannot verify a mutable reference type as Sendable, but @Observable's MainActor scheduling makes it safe in practice). All concrete sections in the codebase use this pattern (see `MilesSmilesMilesMissingMiles.Section`, `AvailabilityFilter.Section`).
|
|
184
|
+
|
|
185
|
+
**If the component has NO Configuration (SIMPLE, 0–1 field):** skip the `Section` and take the `FormField` directly on the View init.
|
|
186
|
+
|
|
187
|
+
```swift
|
|
188
|
+
public struct TermsCheckbox: View {
|
|
189
|
+
@Bindable private var field: CheckboxFormField
|
|
190
|
+
public init(field: CheckboxFormField) { self._field = Bindable(field) }
|
|
191
|
+
// ...
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Step 3: Define the Configuration
|
|
196
|
+
|
|
197
|
+
```swift
|
|
198
|
+
@GenerateChainModifiers
|
|
199
|
+
public struct PNRContactCardConfiguration: Sendable {
|
|
200
|
+
public let section: PNRContactCard.Section // form binding root
|
|
201
|
+
|
|
202
|
+
// Identity / static content
|
|
203
|
+
public let badgeText: String // "PNR Kontakt"
|
|
204
|
+
public let passengerName: String // display-only
|
|
205
|
+
public let avatarURL: URL?
|
|
206
|
+
public let deleteLinkTitle: String? // "Sil" (paired action's label)
|
|
207
|
+
|
|
208
|
+
// Per-field labels / placeholders — static copy, NOT on the field
|
|
209
|
+
public let emailLabel: String // "E-Posta"
|
|
210
|
+
public let emailPlaceholder: String // "E-Postanızı giriniz"
|
|
211
|
+
public let phoneLabel: String // "Telefon Numarası"
|
|
212
|
+
public let toggleLabel: String // "Birincil (PNR Kontakt) yolcusu yap"
|
|
213
|
+
|
|
214
|
+
public init(
|
|
215
|
+
section: PNRContactCard.Section,
|
|
216
|
+
badgeText: String,
|
|
217
|
+
passengerName: String,
|
|
218
|
+
avatarURL: URL? = nil,
|
|
219
|
+
deleteLinkTitle: String? = nil,
|
|
220
|
+
emailLabel: String,
|
|
221
|
+
emailPlaceholder: String,
|
|
222
|
+
phoneLabel: String,
|
|
223
|
+
toggleLabel: String
|
|
224
|
+
) {
|
|
225
|
+
self.section = section
|
|
226
|
+
self.badgeText = badgeText
|
|
227
|
+
self.passengerName = passengerName
|
|
228
|
+
self.avatarURL = avatarURL
|
|
229
|
+
self.deleteLinkTitle = deleteLinkTitle
|
|
230
|
+
self.emailLabel = emailLabel
|
|
231
|
+
self.emailPlaceholder = emailPlaceholder
|
|
232
|
+
self.phoneLabel = phoneLabel
|
|
233
|
+
self.toggleLabel = toggleLabel
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Step 4: Implement the View
|
|
239
|
+
|
|
240
|
+
Bind the section, render each field via its atomic form view, pass paired closures for non-form actions.
|
|
241
|
+
|
|
242
|
+
```swift
|
|
243
|
+
public struct PNRContactCard: View {
|
|
244
|
+
private let configuration: PNRContactCardConfiguration
|
|
245
|
+
private let onDelete: (() -> Void)?
|
|
246
|
+
|
|
247
|
+
@Bindable private var section: Section
|
|
248
|
+
|
|
249
|
+
public init(
|
|
250
|
+
configuration: PNRContactCardConfiguration,
|
|
251
|
+
onDelete: (() -> Void)? = nil
|
|
252
|
+
) {
|
|
253
|
+
self.configuration = configuration
|
|
254
|
+
self.onDelete = onDelete
|
|
255
|
+
self._section = Bindable(configuration.section)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
public var body: some View {
|
|
259
|
+
VStack(alignment: .leading, spacing: .Spacing.m) {
|
|
260
|
+
Badge(configuration.badgeText, style: .success)
|
|
261
|
+
|
|
262
|
+
HStack {
|
|
263
|
+
Avatar(url: configuration.avatarURL)
|
|
264
|
+
Text(configuration.passengerName).font(.bodyBold)
|
|
265
|
+
Spacer()
|
|
266
|
+
if let label = configuration.deleteLinkTitle {
|
|
267
|
+
LinkButton(label) { onDelete?() }
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
InputField(field: section.email)
|
|
272
|
+
.label(configuration.emailLabel)
|
|
273
|
+
.placeholder(configuration.emailPlaceholder)
|
|
274
|
+
.keyboard(.emailAddress)
|
|
275
|
+
|
|
276
|
+
HStack(spacing: .Spacing.s) {
|
|
277
|
+
Selectbox(field: section.phoneCountry).width(96)
|
|
278
|
+
InputField(field: section.phoneNumber)
|
|
279
|
+
.label(configuration.phoneLabel)
|
|
280
|
+
.keyboard(.phonePad)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
HStack {
|
|
284
|
+
Text(configuration.toggleLabel)
|
|
285
|
+
Spacer()
|
|
286
|
+
Toggle(field: section.isPrimary)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
.padding(.Spacing.l)
|
|
290
|
+
.background(Color.Surface.card)
|
|
291
|
+
.cornerRadius(.Radius.l)
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Scene-Level Usage (for vibe-coding reference)
|
|
299
|
+
|
|
300
|
+
```swift
|
|
301
|
+
@Observable
|
|
302
|
+
final class EInvoiceSceneVM {
|
|
303
|
+
let contacts: [PNRContactCard.Section] = [PNRContactCard.Section()]
|
|
304
|
+
let passengerSelection = RadioFormField<Passenger>(
|
|
305
|
+
rules: [RequiredSelectionRule()]
|
|
306
|
+
)
|
|
307
|
+
var focus: FormFocus?
|
|
308
|
+
|
|
309
|
+
var form: FormGroup {
|
|
310
|
+
FormGroup([passengerSelection] + contacts.map { $0 as any Validatable })
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
func submit() {
|
|
314
|
+
guard form.validate() else { focus?.focusFirstError(); return }
|
|
315
|
+
// build payload from field values
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
struct EInvoiceSceneView: View {
|
|
320
|
+
@State private var vm = EInvoiceSceneVM()
|
|
321
|
+
|
|
322
|
+
var body: some View {
|
|
323
|
+
ScrollView {
|
|
324
|
+
VStack(spacing: .Spacing.l) {
|
|
325
|
+
PassengerList(configuration: .init(
|
|
326
|
+
title: "Yolcu Listesi",
|
|
327
|
+
description: "E-Fatura talebinde bulunacağınız yolcuyu seçiniz.",
|
|
328
|
+
selection: vm.passengerSelection
|
|
329
|
+
)) { pax in router.openTicketDetails(pax) }
|
|
330
|
+
|
|
331
|
+
ForEach(vm.contacts) { section in
|
|
332
|
+
PNRContactCard(configuration: .init(
|
|
333
|
+
section: section,
|
|
334
|
+
badgeText: "PNR Kontakt",
|
|
335
|
+
passengerName: section.displayName,
|
|
336
|
+
emailLabel: "E-Posta",
|
|
337
|
+
emailPlaceholder: "E-Postanızı giriniz",
|
|
338
|
+
phoneLabel: "Telefon Numarası",
|
|
339
|
+
toggleLabel: "Birincil (PNR Kontakt) yolcusu yap"
|
|
340
|
+
)) { vm.remove(section) }
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
PrimaryButton("Devam Et") { vm.submit() }
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
.formFocus($vm.focus) // ← scene root
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Integration with Phase 3D
|
|
354
|
+
|
|
355
|
+
When Phase 3D's Sub-Component Integration (§2.2) detects a form-capable instance:
|
|
356
|
+
|
|
357
|
+
### Replace / augment §2.2 Output
|
|
358
|
+
|
|
359
|
+
Instead of treating a Selectbox/Checkbox/Radio/TextboxTextarea/DatepickerSchedule instance as a mini-config struct of its dynamic props, recognize it as a **form input** and emit a `FormField` reference.
|
|
360
|
+
|
|
361
|
+
### Architecture Output (04b_component_architecture.md)
|
|
362
|
+
|
|
363
|
+
In the Sub-Components section:
|
|
364
|
+
|
|
365
|
+
```markdown
|
|
366
|
+
## Sub-Components
|
|
367
|
+
|
|
368
|
+
| Element | Scope | Integration |
|
|
369
|
+
|---------|-------|-------------|
|
|
370
|
+
| Email input (TextboxTextarea) | Required | `FormField` — `email: TextFormField` in nested `Section` |
|
|
371
|
+
| Phone country (Selectbox) | Required | `FormField` — `phoneCountry: PickerFormField<CountryCode>` |
|
|
372
|
+
| Phone number (TextboxTextarea) | Required | `FormField` — `phoneNumber: TextFormField` |
|
|
373
|
+
| Primary toggle (Checkbox) | Required | `FormField` — `isPrimary: CheckboxFormField` (rendered as Switch) |
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
In the Final API Design:
|
|
377
|
+
|
|
378
|
+
```swift
|
|
379
|
+
extension ComponentName {
|
|
380
|
+
@FormSection
|
|
381
|
+
@Observable
|
|
382
|
+
public final class Section: FormSection, @unchecked Sendable {
|
|
383
|
+
public let email: TextFormField
|
|
384
|
+
public let phoneCountry: PickerFormField<CountryCode>
|
|
385
|
+
public let phoneNumber: TextFormField
|
|
386
|
+
public let isPrimary: CheckboxFormField
|
|
387
|
+
public init(...)
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
public struct ComponentNameConfiguration: Sendable {
|
|
392
|
+
public let section: ComponentName.Section
|
|
393
|
+
// + static content (labels, placeholders)
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
> **Configuration imports**: when using `@GenerateChainModifiers` on a Configuration that contains String / `*Title` / label properties, the macro emits `LocalizationStringKey` overloads. Add `import CoreLocalization` to the Configuration file or the build will fail with `cannot find type 'LocalizationStringKey' in scope`.
|
|
398
|
+
|
|
399
|
+
### Property Classification addition
|
|
400
|
+
|
|
401
|
+
| Classification | When | Swift Pattern |
|
|
402
|
+
|---|---|---|
|
|
403
|
+
| Form section (composite) | Component contains 2+ form-capable sub-components | `section: ComponentName.Section` on Configuration |
|
|
404
|
+
| Form field (atomic) | Component contains exactly 1 form-capable sub-component | `field: SomeFormField` on Configuration or View init |
|
|
405
|
+
|
|
406
|
+
### Layer-text + form interaction
|
|
407
|
+
|
|
408
|
+
Dynamic layer text INSIDE a form control (e.g. the placeholder text inside a Selectbox) is still **static copy** from the caller's perspective — it becomes a Configuration string (`placeholder`, `label`), NOT a FormField-value substitute. Form fields own the *value*, not the *copy*.
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Integration with Phase 4A
|
|
413
|
+
|
|
414
|
+
When writing the Configuration struct for a component with form fields:
|
|
415
|
+
|
|
416
|
+
1. Define the nested `Section: FormSection` class in an extension on the component namespace, annotated `@FormSection @Observable`.
|
|
417
|
+
2. Only include the fields identified in Phase 3D analysis — one FormField subclass per form sub-component.
|
|
418
|
+
3. The `section` property on Configuration is non-optional when the form is required, optional when the whole form block is boolean-gated.
|
|
419
|
+
4. Do NOT flatten field values into the Configuration — keep them inside the section.
|
|
420
|
+
5. Static content (labels, placeholders, helper copy, toggle labels) stays in Configuration as `String` / `String?` and gets chainable modifiers via `@GenerateChainModifiers`.
|
|
421
|
+
6. Paired action closures (`onDelete`, `onEdit`, row-level disclosure) stay as View init parameters — NOT in Configuration, NOT on fields.
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Integration with Phase 4B
|
|
426
|
+
|
|
427
|
+
When implementing the View that renders form data:
|
|
428
|
+
|
|
429
|
+
```swift
|
|
430
|
+
public struct ComponentName: View {
|
|
431
|
+
private let configuration: ComponentNameConfiguration
|
|
432
|
+
private let onAction: (() -> Void)?
|
|
433
|
+
|
|
434
|
+
@Bindable private var section: Section
|
|
435
|
+
|
|
436
|
+
public init(
|
|
437
|
+
configuration: ComponentNameConfiguration,
|
|
438
|
+
onAction: (() -> Void)? = nil
|
|
439
|
+
) {
|
|
440
|
+
self.configuration = configuration
|
|
441
|
+
self.onAction = onAction
|
|
442
|
+
self._section = Bindable(configuration.section)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
public var body: some View {
|
|
446
|
+
VStack(...) {
|
|
447
|
+
InputField(field: section.email)
|
|
448
|
+
.label(configuration.emailLabel)
|
|
449
|
+
.placeholder(configuration.emailPlaceholder)
|
|
450
|
+
|
|
451
|
+
Selectbox(field: section.phoneCountry)
|
|
452
|
+
// ... etc
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Rules
|
|
459
|
+
|
|
460
|
+
- **Never** use `@State` for form values. Never wrap `section.<field>.value` in `Binding(get:set:)` — pass the field itself.
|
|
461
|
+
- **Never** call `section.validate()` from inside the View. Validation is a caller concern.
|
|
462
|
+
- **Never** instantiate a `FormField` or `Section` inside the component. They come from the caller via Configuration.
|
|
463
|
+
- **Do** read `section.state` to render section-level banners/errors if the design shows one.
|
|
464
|
+
- **Do** use atomic form views (`InputField(field:)`, `Selectbox(field:)`, `Radio(field:)`, `Checkbox(field:)`, `DatePicker(field:)`) — they handle `field.state` → visual state internally.
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Atomic vs Composite Decision
|
|
469
|
+
|
|
470
|
+
```
|
|
471
|
+
┌────────────────────────────────────────────────────┐
|
|
472
|
+
│ Count form-capable sub-components in the design │
|
|
473
|
+
├────────────────────────────────────────────────────┤
|
|
474
|
+
│ 0 → No form pattern. Skip this skill. │
|
|
475
|
+
│ 1 → Atomic. Use `*FormField` directly on Config │
|
|
476
|
+
│ / View init. No Section wrapper. │
|
|
477
|
+
│ 2+ → Composite. Nested `.Section: FormSection` │
|
|
478
|
+
│ class on Configuration. │
|
|
479
|
+
└────────────────────────────────────────────────────┘
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## When NOT to Use Form Integration
|
|
485
|
+
|
|
486
|
+
- **Pure display components** showing data that is not user-editable — use plain `String` / `Int` / model properties.
|
|
487
|
+
- **Static checkmarks / indicators** that are read-only state (e.g., a green tick in a stepper) — use `Bool` in Configuration, not `CheckboxFormField`.
|
|
488
|
+
- **Radio-like selection that is display only** (e.g., a highlighted selected tab in a segmented control where selection is controlled by the parent, not a form submission) — use an `enum` property, not `RadioFormField`.
|
|
489
|
+
- **Segmented controls that represent navigation / filter state, not form input** — plain `Binding<Enum>` is fine for those; they are not validated or submitted.
|
|
490
|
+
|
|
491
|
+
Rule of thumb: ask "would a ViewModel run `validate()` on this value before submitting?" If no → it's not a form field.
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## FormGroup Everyday Use
|
|
496
|
+
|
|
497
|
+
When you need ad-hoc grouping (not a stable component-owned section), use `FormGroup` directly:
|
|
498
|
+
|
|
499
|
+
```swift
|
|
500
|
+
// In a scene where 3 fields logically belong together but no named type is worth it:
|
|
501
|
+
let personalInfo = FormGroup(firstName, lastName, birthDate)
|
|
502
|
+
|
|
503
|
+
personalInfo.validate()
|
|
504
|
+
personalInfo.leafFields // for FormFocus.fields
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
Prefer a named `FormSection` subclass when the card has a stable identity in the design. Use `FormGroup` only for genuinely ad-hoc scoping.
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## Real-World Scenarios
|
|
512
|
+
|
|
513
|
+
| Scenario | Model |
|
|
514
|
+
|---|---|
|
|
515
|
+
| Card with 1 checkbox (accept terms) | View takes `CheckboxFormField` directly, no Section |
|
|
516
|
+
| PNR contact card (email + phone + primary toggle) | Nested `Section` with 3 fields |
|
|
517
|
+
| Passenger list (single-select radio over passengers) | Caller owns `RadioFormField<Passenger>`, component atomic |
|
|
518
|
+
| Search form with free-text + date range + pax count selectbox | Nested `Section` with 3 fields |
|
|
519
|
+
| E-invoice form (passenger radio + N contact cards) | Scene `FormGroup([passengerRadio] + contacts.map { $0 })` |
|
|
520
|
+
| Password change (old + new + confirm) | Nested `Section` with 3 `TextFormField`s + cross-field `MatchRule` |
|
|
521
|
+
| Toggle inside a card (no other inputs, dedicated) | `ToggleFormField` directly on Configuration (atomic, no Section) — preferred when the design uses `TurkishToggle` |
|
|
522
|
+
| Toggle inside a card (no other inputs, unified) | `CheckboxFormField` directly on Configuration (atomic, no Section) — only when toggle and checkbox are interchangeable in the same form |
|
|
523
|
+
| Passenger picker (N stepper rows + disclosure expansion) | Nested `Section` with N `StepperFormField`s + a plain `displayState` enum property (named to avoid colliding with the `state: FormState` synthesized by `@FormSection`) |
|
|
524
|
+
| Filter panel (1 toggle + N multi-select chip groups) | Nested `Section` with 1 `ToggleFormField` + N `CheckboxGroupFormField<Item>` (one per group). Section conforms to `@unchecked Sendable`. See `AvailabilityFilter` for the canonical example. |
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## Checklist — Before Leaving the Skill
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
[ ] Counted form-capable sub-components in the Figma design
|
|
532
|
+
[ ] Decided atomic (1) vs composite (2+)
|
|
533
|
+
[ ] For composite: defined nested `Section: FormSection` with @FormSection @Observable
|
|
534
|
+
[ ] Section declares ONLY fields the design renders (no extras, no omissions)
|
|
535
|
+
[ ] Configuration carries `section: .Section` (or single field for atomic)
|
|
536
|
+
[ ] Labels / placeholders / toggle captions are Configuration strings, NOT on fields
|
|
537
|
+
[ ] Non-form actions (Sil/Edit/Detaylar) are paired closures on the View
|
|
538
|
+
[ ] View uses @Bindable on the section; never @State for values
|
|
539
|
+
[ ] View never calls validate() or instantiates fields
|
|
540
|
+
[ ] No Binding<Value> anywhere in the component — only field references
|
|
541
|
+
[ ] Scene-level caller builds the section, calls validate() / leafFields / focus
|
|
542
|
+
```
|