@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,577 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: android-security
|
|
3
|
+
description: "Secure Android apps with ProGuard/R8 obfuscation, OkHttp certificate pinning, BiometricPrompt authentication, EncryptedSharedPreferences, Play Integrity API, root detection, secure network communication, and API key protection via local.properties and BuildConfig. Use when implementing security features, auditing app security, handling sensitive data, or preparing for production release."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Android Security
|
|
7
|
+
|
|
8
|
+
Security patterns for Android apps covering data storage, network security,
|
|
9
|
+
authentication, integrity verification, and obfuscation. Targets 2024-2025
|
|
10
|
+
best practices with AndroidX Security, BiometricPrompt, and Play Integrity.
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- [Secure Data Storage](#secure-data-storage)
|
|
15
|
+
- [Biometric Authentication](#biometric-authentication)
|
|
16
|
+
- [Certificate Pinning](#certificate-pinning)
|
|
17
|
+
- [API Key Protection](#api-key-protection)
|
|
18
|
+
- [R8 Obfuscation](#r8-obfuscation)
|
|
19
|
+
- [Play Integrity API](#play-integrity-api)
|
|
20
|
+
- [Root Detection](#root-detection)
|
|
21
|
+
- [Secure Network Communication](#secure-network-communication)
|
|
22
|
+
- [Secure Coding Patterns](#secure-coding-patterns)
|
|
23
|
+
- [Do's and Don'ts](#dos-and-donts)
|
|
24
|
+
- [Troubleshooting](#troubleshooting)
|
|
25
|
+
- [Review Checklist](#review-checklist)
|
|
26
|
+
|
|
27
|
+
## Secure Data Storage
|
|
28
|
+
|
|
29
|
+
### EncryptedSharedPreferences
|
|
30
|
+
|
|
31
|
+
For sensitive key-value data. Uses AES-256 encryption under the hood.
|
|
32
|
+
|
|
33
|
+
```kotlin
|
|
34
|
+
import androidx.security.crypto.EncryptedSharedPreferences
|
|
35
|
+
import androidx.security.crypto.MasterKey
|
|
36
|
+
|
|
37
|
+
class SecureStorage @Inject constructor(
|
|
38
|
+
@ApplicationContext private val context: Context,
|
|
39
|
+
) {
|
|
40
|
+
private val masterKey = MasterKey.Builder(context)
|
|
41
|
+
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
|
42
|
+
.build()
|
|
43
|
+
|
|
44
|
+
private val prefs = EncryptedSharedPreferences.create(
|
|
45
|
+
context,
|
|
46
|
+
"secure_prefs",
|
|
47
|
+
masterKey,
|
|
48
|
+
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
|
49
|
+
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
fun saveToken(token: String) {
|
|
53
|
+
prefs.edit().putString("auth_token", token).apply()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fun getToken(): String? = prefs.getString("auth_token", null)
|
|
57
|
+
|
|
58
|
+
fun clearToken() {
|
|
59
|
+
prefs.edit().remove("auth_token").apply()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fun clearAll() {
|
|
63
|
+
prefs.edit().clear().apply()
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Android Keystore
|
|
69
|
+
|
|
70
|
+
For cryptographic key management. Keys never leave the hardware.
|
|
71
|
+
|
|
72
|
+
```kotlin
|
|
73
|
+
import java.security.KeyStore
|
|
74
|
+
import javax.crypto.Cipher
|
|
75
|
+
import javax.crypto.KeyGenerator
|
|
76
|
+
import javax.crypto.SecretKey
|
|
77
|
+
import javax.crypto.spec.GCMParameterSpec
|
|
78
|
+
import android.security.keystore.KeyGenParameterSpec
|
|
79
|
+
import android.security.keystore.KeyProperties
|
|
80
|
+
|
|
81
|
+
class KeystoreManager {
|
|
82
|
+
|
|
83
|
+
companion object {
|
|
84
|
+
private const val KEYSTORE_PROVIDER = "AndroidKeyStore"
|
|
85
|
+
private const val KEY_ALIAS = "app_encryption_key"
|
|
86
|
+
private const val TRANSFORMATION = "AES/GCM/NoPadding"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private fun getOrCreateKey(): SecretKey {
|
|
90
|
+
val keyStore = KeyStore.getInstance(KEYSTORE_PROVIDER).apply { load(null) }
|
|
91
|
+
|
|
92
|
+
keyStore.getEntry(KEY_ALIAS, null)?.let { entry ->
|
|
93
|
+
return (entry as KeyStore.SecretKeyEntry).secretKey
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
val keyGenerator = KeyGenerator.getInstance(
|
|
97
|
+
KeyProperties.KEY_ALGORITHM_AES,
|
|
98
|
+
KEYSTORE_PROVIDER,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
keyGenerator.init(
|
|
102
|
+
KeyGenParameterSpec.Builder(
|
|
103
|
+
KEY_ALIAS,
|
|
104
|
+
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT,
|
|
105
|
+
)
|
|
106
|
+
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
|
|
107
|
+
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
|
108
|
+
.setKeySize(256)
|
|
109
|
+
.setUserAuthenticationRequired(false)
|
|
110
|
+
.build()
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
return keyGenerator.generateKey()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
fun encrypt(data: ByteArray): Pair<ByteArray, ByteArray> {
|
|
117
|
+
val cipher = Cipher.getInstance(TRANSFORMATION)
|
|
118
|
+
cipher.init(Cipher.ENCRYPT_MODE, getOrCreateKey())
|
|
119
|
+
val encrypted = cipher.doFinal(data)
|
|
120
|
+
return Pair(cipher.iv, encrypted)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
fun decrypt(iv: ByteArray, encryptedData: ByteArray): ByteArray {
|
|
124
|
+
val cipher = Cipher.getInstance(TRANSFORMATION)
|
|
125
|
+
val spec = GCMParameterSpec(128, iv)
|
|
126
|
+
cipher.init(Cipher.DECRYPT_MODE, getOrCreateKey(), spec)
|
|
127
|
+
return cipher.doFinal(encryptedData)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### What Goes Where
|
|
133
|
+
|
|
134
|
+
| Data Type | Storage | Why |
|
|
135
|
+
|-----------|---------|-----|
|
|
136
|
+
| Auth tokens | EncryptedSharedPreferences | Encrypted at rest, simple API |
|
|
137
|
+
| Passwords | Android Keystore + encryption | Hardware-backed security |
|
|
138
|
+
| API keys | BuildConfig (build-time injection) | Not in source; obfuscated by R8 |
|
|
139
|
+
| User preferences (non-sensitive) | SharedPreferences / DataStore | No encryption needed |
|
|
140
|
+
| Large sensitive files | Encrypted file + Keystore key | AES encryption with hardware key |
|
|
141
|
+
|
|
142
|
+
## Biometric Authentication
|
|
143
|
+
|
|
144
|
+
### BiometricPrompt Setup
|
|
145
|
+
|
|
146
|
+
```kotlin
|
|
147
|
+
class BiometricAuthenticator @Inject constructor() {
|
|
148
|
+
|
|
149
|
+
fun authenticate(
|
|
150
|
+
activity: FragmentActivity,
|
|
151
|
+
title: String = "Authenticate",
|
|
152
|
+
subtitle: String = "Verify your identity",
|
|
153
|
+
onSuccess: () -> Unit,
|
|
154
|
+
onError: (String) -> Unit,
|
|
155
|
+
) {
|
|
156
|
+
val biometricManager = BiometricManager.from(activity)
|
|
157
|
+
val canAuthenticate = biometricManager.canAuthenticate(
|
|
158
|
+
BiometricManager.Authenticators.BIOMETRIC_STRONG or
|
|
159
|
+
BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
if (canAuthenticate != BiometricManager.BIOMETRIC_SUCCESS) {
|
|
163
|
+
onError(mapBiometricError(canAuthenticate))
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
val promptInfo = BiometricPrompt.PromptInfo.Builder()
|
|
168
|
+
.setTitle(title)
|
|
169
|
+
.setSubtitle(subtitle)
|
|
170
|
+
.setAllowedAuthenticators(
|
|
171
|
+
BiometricManager.Authenticators.BIOMETRIC_STRONG or
|
|
172
|
+
BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
|
173
|
+
)
|
|
174
|
+
.build()
|
|
175
|
+
|
|
176
|
+
val callback = object : BiometricPrompt.AuthenticationCallback() {
|
|
177
|
+
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
|
178
|
+
onSuccess()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
|
182
|
+
onError(errString.toString())
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
override fun onAuthenticationFailed() {
|
|
186
|
+
// Called on failed attempt but user can retry
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
val prompt = BiometricPrompt(activity, callback)
|
|
191
|
+
prompt.authenticate(promptInfo)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private fun mapBiometricError(code: Int): String = when (code) {
|
|
195
|
+
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> "No biometric hardware"
|
|
196
|
+
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> "Biometric hardware unavailable"
|
|
197
|
+
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> "No biometrics enrolled"
|
|
198
|
+
else -> "Biometric authentication unavailable"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Biometric + Keystore (Crypto-Based Auth)
|
|
204
|
+
|
|
205
|
+
```kotlin
|
|
206
|
+
fun authenticateWithCrypto(
|
|
207
|
+
activity: FragmentActivity,
|
|
208
|
+
onSuccess: (Cipher) -> Unit,
|
|
209
|
+
) {
|
|
210
|
+
val key = getOrCreateBiometricKey()
|
|
211
|
+
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
|
|
212
|
+
cipher.init(Cipher.ENCRYPT_MODE, key)
|
|
213
|
+
|
|
214
|
+
val cryptoObject = BiometricPrompt.CryptoObject(cipher)
|
|
215
|
+
|
|
216
|
+
val prompt = BiometricPrompt(activity, object : BiometricPrompt.AuthenticationCallback() {
|
|
217
|
+
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
|
218
|
+
result.cryptoObject?.cipher?.let(onSuccess)
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
prompt.authenticate(promptInfo, cryptoObject)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private fun getOrCreateBiometricKey(): SecretKey {
|
|
226
|
+
val keyGenerator = KeyGenerator.getInstance("AES", "AndroidKeyStore")
|
|
227
|
+
keyGenerator.init(
|
|
228
|
+
KeyGenParameterSpec.Builder("biometric_key",
|
|
229
|
+
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
|
|
230
|
+
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
|
|
231
|
+
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
|
232
|
+
.setUserAuthenticationRequired(true)
|
|
233
|
+
.setInvalidatedByBiometricEnrollment(true)
|
|
234
|
+
.build()
|
|
235
|
+
)
|
|
236
|
+
return keyGenerator.generateKey()
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Certificate Pinning
|
|
241
|
+
|
|
242
|
+
### OkHttp CertificatePinner
|
|
243
|
+
|
|
244
|
+
```kotlin
|
|
245
|
+
val certificatePinner = CertificatePinner.Builder()
|
|
246
|
+
.add("api.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") // Primary
|
|
247
|
+
.add("api.example.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=") // Backup
|
|
248
|
+
.build()
|
|
249
|
+
|
|
250
|
+
val client = OkHttpClient.Builder()
|
|
251
|
+
.certificatePinner(certificatePinner)
|
|
252
|
+
.build()
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Generating Pin Hashes
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# From a domain
|
|
259
|
+
openssl s_client -connect api.example.com:443 -servername api.example.com \
|
|
260
|
+
| openssl x509 -pubkey -noout \
|
|
261
|
+
| openssl pkey -pubin -outform der \
|
|
262
|
+
| openssl dgst -sha256 -binary \
|
|
263
|
+
| openssl enc -base64
|
|
264
|
+
|
|
265
|
+
# From a certificate file
|
|
266
|
+
openssl x509 -in cert.pem -pubkey -noout \
|
|
267
|
+
| openssl pkey -pubin -outform der \
|
|
268
|
+
| openssl dgst -sha256 -binary \
|
|
269
|
+
| openssl enc -base64
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Network Security Config (XML-based)
|
|
273
|
+
|
|
274
|
+
```xml
|
|
275
|
+
<!-- res/xml/network_security_config.xml -->
|
|
276
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
277
|
+
<network-security-config>
|
|
278
|
+
<domain-config cleartextTrafficPermitted="false">
|
|
279
|
+
<domain includeSubdomains="true">api.example.com</domain>
|
|
280
|
+
<pin-set expiration="2026-01-01">
|
|
281
|
+
<pin digest="SHA-256">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</pin>
|
|
282
|
+
<pin digest="SHA-256">BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=</pin>
|
|
283
|
+
</pin-set>
|
|
284
|
+
</domain-config>
|
|
285
|
+
|
|
286
|
+
<!-- Block cleartext for all domains -->
|
|
287
|
+
<base-config cleartextTrafficPermitted="false" />
|
|
288
|
+
</network-security-config>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
```xml
|
|
292
|
+
<!-- AndroidManifest.xml -->
|
|
293
|
+
<application android:networkSecurityConfig="@xml/network_security_config">
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## API Key Protection
|
|
297
|
+
|
|
298
|
+
### local.properties (Gitignored)
|
|
299
|
+
|
|
300
|
+
```properties
|
|
301
|
+
# local.properties -- NEVER commit this file
|
|
302
|
+
MAPS_API_KEY=AIzaSyB...
|
|
303
|
+
BASE_URL=https://api.example.com/
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Build-Time Injection
|
|
307
|
+
|
|
308
|
+
```kotlin
|
|
309
|
+
// build.gradle.kts
|
|
310
|
+
import java.util.Properties
|
|
311
|
+
|
|
312
|
+
val localProperties = Properties().apply {
|
|
313
|
+
val file = rootProject.file("local.properties")
|
|
314
|
+
if (file.exists()) load(file.inputStream())
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
android {
|
|
318
|
+
defaultConfig {
|
|
319
|
+
buildConfigField("String", "MAPS_API_KEY",
|
|
320
|
+
"\"${localProperties["MAPS_API_KEY"] ?: ""}\"")
|
|
321
|
+
buildConfigField("String", "BASE_URL",
|
|
322
|
+
"\"${localProperties["BASE_URL"] ?: "https://api.example.com/"}\"")
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Usage in Code
|
|
328
|
+
|
|
329
|
+
```kotlin
|
|
330
|
+
// Access via BuildConfig -- obfuscated by R8 in release builds
|
|
331
|
+
val apiKey = BuildConfig.MAPS_API_KEY
|
|
332
|
+
val baseUrl = BuildConfig.BASE_URL
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Manifest Placeholder
|
|
336
|
+
|
|
337
|
+
```kotlin
|
|
338
|
+
android {
|
|
339
|
+
defaultConfig {
|
|
340
|
+
manifestPlaceholders["MAPS_API_KEY"] = localProperties["MAPS_API_KEY"] ?: ""
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
```xml
|
|
346
|
+
<meta-data
|
|
347
|
+
android:name="com.google.android.geo.API_KEY"
|
|
348
|
+
android:value="${MAPS_API_KEY}" />
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## R8 Obfuscation
|
|
352
|
+
|
|
353
|
+
R8 is enabled automatically when `isMinifyEnabled = true`. It performs:
|
|
354
|
+
- Code shrinking (removes unused code)
|
|
355
|
+
- Resource shrinking (removes unused resources)
|
|
356
|
+
- Obfuscation (renames classes/methods)
|
|
357
|
+
- Optimization (inlining, dead code elimination)
|
|
358
|
+
|
|
359
|
+
### Mapping File
|
|
360
|
+
|
|
361
|
+
R8 generates `mapping.txt` for deobfuscating crash reports:
|
|
362
|
+
|
|
363
|
+
```kotlin
|
|
364
|
+
android {
|
|
365
|
+
buildTypes {
|
|
366
|
+
release {
|
|
367
|
+
isMinifyEnabled = true
|
|
368
|
+
isShrinkResources = true
|
|
369
|
+
proguardFiles(
|
|
370
|
+
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
371
|
+
"proguard-rules.pro",
|
|
372
|
+
)
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Upload `mapping.txt` to Google Play Console and Firebase Crashlytics for
|
|
379
|
+
readable stack traces.
|
|
380
|
+
|
|
381
|
+
## Play Integrity API
|
|
382
|
+
|
|
383
|
+
Verify that API requests come from a genuine app on a genuine device.
|
|
384
|
+
|
|
385
|
+
```kotlin
|
|
386
|
+
class IntegrityVerifier @Inject constructor(
|
|
387
|
+
@ApplicationContext private val context: Context,
|
|
388
|
+
) {
|
|
389
|
+
suspend fun getIntegrityToken(nonce: String): String? {
|
|
390
|
+
return try {
|
|
391
|
+
val integrityManager = IntegrityManagerFactory.create(context)
|
|
392
|
+
|
|
393
|
+
val request = IntegrityTokenRequest.builder()
|
|
394
|
+
.setNonce(nonce)
|
|
395
|
+
.build()
|
|
396
|
+
|
|
397
|
+
val response = integrityManager
|
|
398
|
+
.requestIntegrityToken(request)
|
|
399
|
+
.await()
|
|
400
|
+
|
|
401
|
+
response.token()
|
|
402
|
+
} catch (e: Exception) {
|
|
403
|
+
null
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Send the token to your server for verification. Never verify integrity tokens
|
|
410
|
+
on the client -- the server must decode and validate them via the Play Integrity
|
|
411
|
+
API.
|
|
412
|
+
|
|
413
|
+
## Root Detection
|
|
414
|
+
|
|
415
|
+
Root detection is defense-in-depth. Determined attackers can bypass it, but it
|
|
416
|
+
raises the bar.
|
|
417
|
+
|
|
418
|
+
```kotlin
|
|
419
|
+
object RootDetector {
|
|
420
|
+
|
|
421
|
+
fun isDeviceRooted(): Boolean =
|
|
422
|
+
checkRootBinaries() || checkSuExists() || checkRootApps()
|
|
423
|
+
|
|
424
|
+
private fun checkRootBinaries(): Boolean {
|
|
425
|
+
val paths = listOf(
|
|
426
|
+
"/system/bin/su",
|
|
427
|
+
"/system/xbin/su",
|
|
428
|
+
"/sbin/su",
|
|
429
|
+
"/system/app/Superuser.apk",
|
|
430
|
+
"/system/app/SuperSU.apk",
|
|
431
|
+
)
|
|
432
|
+
return paths.any { File(it).exists() }
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
private fun checkSuExists(): Boolean = try {
|
|
436
|
+
Runtime.getRuntime().exec("which su").inputStream.bufferedReader().readLine() != null
|
|
437
|
+
} catch (e: Exception) {
|
|
438
|
+
false
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
private fun checkRootApps(): Boolean {
|
|
442
|
+
val rootPackages = listOf(
|
|
443
|
+
"com.topjohnwu.magisk",
|
|
444
|
+
"eu.chainfire.supersu",
|
|
445
|
+
"com.koushikdutta.superuser",
|
|
446
|
+
)
|
|
447
|
+
// Check if any are installed (requires QUERY_ALL_PACKAGES or specific queries)
|
|
448
|
+
return false // Simplified -- use PackageManager in production
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
Use root detection as one signal among many. Combine with Play Integrity for
|
|
454
|
+
stronger guarantees.
|
|
455
|
+
|
|
456
|
+
## Secure Network Communication
|
|
457
|
+
|
|
458
|
+
### Enforce HTTPS
|
|
459
|
+
|
|
460
|
+
```xml
|
|
461
|
+
<!-- network_security_config.xml -->
|
|
462
|
+
<network-security-config>
|
|
463
|
+
<base-config cleartextTrafficPermitted="false" />
|
|
464
|
+
</network-security-config>
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Debug-Only Cleartext (for local development)
|
|
468
|
+
|
|
469
|
+
```xml
|
|
470
|
+
<network-security-config>
|
|
471
|
+
<base-config cleartextTrafficPermitted="false" />
|
|
472
|
+
<domain-config cleartextTrafficPermitted="true">
|
|
473
|
+
<domain includeSubdomains="false">10.0.2.2</domain>
|
|
474
|
+
<domain includeSubdomains="false">localhost</domain>
|
|
475
|
+
</domain-config>
|
|
476
|
+
</network-security-config>
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### TLS Configuration
|
|
480
|
+
|
|
481
|
+
```kotlin
|
|
482
|
+
val spec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
|
483
|
+
.tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3)
|
|
484
|
+
.build()
|
|
485
|
+
|
|
486
|
+
val client = OkHttpClient.Builder()
|
|
487
|
+
.connectionSpecs(listOf(spec))
|
|
488
|
+
.build()
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## Secure Coding Patterns
|
|
492
|
+
|
|
493
|
+
### Never Log Sensitive Data
|
|
494
|
+
|
|
495
|
+
```kotlin
|
|
496
|
+
// WRONG
|
|
497
|
+
Log.d("Auth", "Token: $token")
|
|
498
|
+
Log.d("Payment", "Card: $cardNumber")
|
|
499
|
+
|
|
500
|
+
// CORRECT
|
|
501
|
+
Log.d("Auth", "Token refresh successful")
|
|
502
|
+
Log.d("Payment", "Payment processed")
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Input Validation
|
|
506
|
+
|
|
507
|
+
```kotlin
|
|
508
|
+
fun validateDeepLink(uri: Uri): Boolean {
|
|
509
|
+
val allowedHosts = setOf("example.com", "www.example.com")
|
|
510
|
+
val allowedSchemes = setOf("https")
|
|
511
|
+
|
|
512
|
+
return uri.scheme in allowedSchemes &&
|
|
513
|
+
uri.host in allowedHosts &&
|
|
514
|
+
!uri.path.orEmpty().contains("..")
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Secure WebView
|
|
519
|
+
|
|
520
|
+
```kotlin
|
|
521
|
+
webView.settings.apply {
|
|
522
|
+
javaScriptEnabled = false // Enable ONLY if required
|
|
523
|
+
allowFileAccess = false
|
|
524
|
+
allowContentAccess = false
|
|
525
|
+
domStorageEnabled = false
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
## Do's and Don'ts
|
|
530
|
+
|
|
531
|
+
### Do's
|
|
532
|
+
- Use EncryptedSharedPreferences for sensitive key-value data
|
|
533
|
+
- Use Android Keystore for cryptographic keys
|
|
534
|
+
- Enable R8 with `isMinifyEnabled = true` for release builds
|
|
535
|
+
- Upload `mapping.txt` to Play Console and Crashlytics
|
|
536
|
+
- Use Network Security Config to enforce HTTPS
|
|
537
|
+
- Include at least two certificate pins (primary + backup)
|
|
538
|
+
- Verify Play Integrity tokens server-side only
|
|
539
|
+
- Use BiometricPrompt with BIOMETRIC_STRONG for high-security flows
|
|
540
|
+
|
|
541
|
+
### Don'ts
|
|
542
|
+
- Do not store secrets in SharedPreferences (use EncryptedSharedPreferences)
|
|
543
|
+
- Do not hardcode API keys in Kotlin/Java source files
|
|
544
|
+
- Do not commit `local.properties` or keystore files to version control
|
|
545
|
+
- Do not log tokens, passwords, or card numbers
|
|
546
|
+
- Do not verify integrity tokens on the client
|
|
547
|
+
- Do not trust root detection as the sole security measure
|
|
548
|
+
- Do not enable JavaScript in WebView unless absolutely necessary
|
|
549
|
+
- Do not use `cleartextTrafficPermitted="true"` in production
|
|
550
|
+
|
|
551
|
+
## Troubleshooting
|
|
552
|
+
|
|
553
|
+
| Problem | Cause | Fix |
|
|
554
|
+
|---------|-------|-----|
|
|
555
|
+
| `KeyPermanentlyInvalidatedException` | Biometric enrollment changed | Delete and recreate the Keystore key |
|
|
556
|
+
| EncryptedSharedPreferences crash on upgrade | MasterKey corrupted | Handle exception, recreate storage, re-authenticate user |
|
|
557
|
+
| Certificate pinning fails after cert rotation | Pin hash mismatch | Update pins; always maintain a backup pin |
|
|
558
|
+
| R8 strips serialization classes | Missing keep rules | Add `-keep` rules for `@Serializable` classes |
|
|
559
|
+
| Play Integrity token is null | Missing Play Core dependency or not on Play device | Check `com.google.android.play:integrity` dependency |
|
|
560
|
+
| Cleartext traffic blocked | Network Security Config enforcing HTTPS | Use HTTPS or add debug-only exception for local dev |
|
|
561
|
+
| BiometricPrompt not showing | Wrong authenticator type or no enrollment | Check `canAuthenticate()` before prompting |
|
|
562
|
+
| Keystore key inaccessible after OS update | Keystore compatibility issue | Wrap in try/catch; recreate key if needed |
|
|
563
|
+
|
|
564
|
+
## Review Checklist
|
|
565
|
+
|
|
566
|
+
- [ ] Sensitive data in EncryptedSharedPreferences or Keystore, not plain SharedPreferences
|
|
567
|
+
- [ ] No hardcoded API keys or secrets in source files
|
|
568
|
+
- [ ] `local.properties` is in `.gitignore`
|
|
569
|
+
- [ ] R8 enabled with `isMinifyEnabled = true` for release
|
|
570
|
+
- [ ] `mapping.txt` uploaded to Play Console and Crashlytics
|
|
571
|
+
- [ ] Network Security Config enforces HTTPS (`cleartextTrafficPermitted="false"`)
|
|
572
|
+
- [ ] Certificate pinning with primary + backup pins
|
|
573
|
+
- [ ] BiometricPrompt uses `BIOMETRIC_STRONG` for sensitive operations
|
|
574
|
+
- [ ] No sensitive data in logs
|
|
575
|
+
- [ ] Play Integrity tokens verified server-side
|
|
576
|
+
- [ ] WebView has minimal permissions (JavaScript disabled by default)
|
|
577
|
+
- [ ] Input and deep link URLs validated before processing
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: android_ui_verification
|
|
3
|
+
description: Automated end-to-end UI testing and verification on an Android Emulator using ADB.
|
|
4
|
+
risk: safe
|
|
5
|
+
source: community
|
|
6
|
+
date_added: "2026-02-28"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Android UI Verification Skill
|
|
10
|
+
|
|
11
|
+
This skill provides a systematic approach to testing React Native applications on an Android emulator using ADB commands. It allows for autonomous interaction, state verification, and visual regression checking.
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
- Verifying UI changes in React Native or Native Android apps.
|
|
15
|
+
- Autonomous debugging of layout issues or interaction bugs.
|
|
16
|
+
- Ensuring feature functionality when manual testing is too slow.
|
|
17
|
+
- Capturing automated screenshots for PR documentation.
|
|
18
|
+
|
|
19
|
+
## 🛠Prerequisites
|
|
20
|
+
- Android Emulator running.
|
|
21
|
+
- `adb` installed and in PATH.
|
|
22
|
+
- Application in debug mode for logcat access.
|
|
23
|
+
|
|
24
|
+
## 🚀 Workflow
|
|
25
|
+
|
|
26
|
+
### 1. Device Calibration
|
|
27
|
+
Before interacting, always verify the screen resolution to ensure tap coordinates are accurate.
|
|
28
|
+
```bash
|
|
29
|
+
adb shell wm size
|
|
30
|
+
```
|
|
31
|
+
*Note: Layouts are often scaled. Use the physical size returned as the base for coordinate calculations.*
|
|
32
|
+
|
|
33
|
+
### 2. UI Inspection (State Discovery)
|
|
34
|
+
Use the `uiautomator` dump to find the exact bounds of UI elements (buttons, inputs).
|
|
35
|
+
```bash
|
|
36
|
+
adb shell uiautomator dump /sdcard/view.xml && adb pull /sdcard/view.xml ./artifacts/view.xml
|
|
37
|
+
```
|
|
38
|
+
Search the `view.xml` for `text`, `content-desc`, or `resource-id`. The `bounds` attribute `[x1,y1][x2,y2]` defines the clickable area.
|
|
39
|
+
|
|
40
|
+
### 3. Interaction Commands
|
|
41
|
+
- **Tap**: `adb shell input tap <x> <y>` (Use the center of the element bounds).
|
|
42
|
+
- **Swipe**: `adb shell input swipe <x1> <y1> <x2> <y2> <duration_ms>` (Used for scrolling).
|
|
43
|
+
- **Text Input**: `adb shell input text "<message>"` (Note: Limited support for special characters).
|
|
44
|
+
- **Key Events**: `adb shell input keyevent <code_id>` (e.g., 66 for Enter).
|
|
45
|
+
|
|
46
|
+
### 4. Verification & Reporting
|
|
47
|
+
#### Visual Verification
|
|
48
|
+
Capture a screenshot after interaction to confirm UI changes.
|
|
49
|
+
```bash
|
|
50
|
+
adb shell screencap -p /sdcard/screen.png && adb pull /sdcard/screen.png ./artifacts/test_result.png
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Analytical Verification
|
|
54
|
+
Monitor the JS console logs in real-time to detect errors or log successes.
|
|
55
|
+
```bash
|
|
56
|
+
adb logcat -d | grep "ReactNativeJS" | tail -n 20
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Cleanup
|
|
60
|
+
Always store generated files in the `artifacts/` folder to satisfy project organization rules.
|
|
61
|
+
|
|
62
|
+
## 💡 Best Practices
|
|
63
|
+
- **Wait for Animations**: Always add a short sleep (e.g., 1-2s) between interaction and verification.
|
|
64
|
+
- **Center Taps**: Calculate the arithmetic mean of `[x1,y1][x2,y2]` for the most reliable tap target.
|
|
65
|
+
- **Log Markers**: Use distinct log messages in the code (e.g., `✅ Action Successful`) to make `grep` verification easy.
|
|
66
|
+
- **Fail Fast**: If a `uiautomator dump` fails or doesn't find the expected text, stop and troubleshoot rather than blind-tapping.
|