@1aboveio/skills 0.0.0-stage → 1.0.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/README.md +30 -2
- package/bin/cli.mjs +14 -0
- package/bin/select-core.mjs +172 -0
- package/package.json +146 -4
- package/skills/app-dev/airflow/LICENSE +3 -0
- package/skills/app-dev/airflow/SKILL.md +199 -0
- package/skills/app-dev/airflow/release-check.mjs +93 -0
- package/skills/app-dev/android-foundation/LICENSE +3 -0
- package/skills/app-dev/android-foundation/SKILL.md +192 -0
- package/skills/app-dev/android-foundation/assets/android-ci-job.yml +217 -0
- package/skills/app-dev/android-foundation/references/ci.md +87 -0
- package/skills/app-dev/android-foundation/references/gotchas.md +221 -0
- package/skills/app-dev/android-foundation/references/setup.md +164 -0
- package/skills/app-dev/android-foundation/release-check.mjs +93 -0
- package/skills/app-dev/android-foundation/scripts/device-run.sh +176 -0
- package/skills/app-dev/android-foundation/scripts/device-run.test.mjs +172 -0
- package/skills/app-dev/app-debug/LICENSE +3 -0
- package/skills/app-dev/app-debug/SKILL.md +110 -0
- package/skills/app-dev/app-debug/references/common-errors.md +128 -0
- package/skills/app-dev/app-debug/release-check.mjs +93 -0
- package/skills/app-dev/better-auth/LICENSE +3 -0
- package/skills/app-dev/better-auth/SKILL.md +598 -0
- package/skills/app-dev/better-auth/references/feishu-api.md +270 -0
- package/skills/app-dev/better-auth/release-check.mjs +93 -0
- package/skills/app-dev/data-catalog/LICENSE +3 -0
- package/skills/app-dev/data-catalog/SKILL.md +204 -0
- package/skills/app-dev/data-catalog/agents/openai.yaml +3 -0
- package/skills/app-dev/data-catalog/references/data-catalog-conventions.md +75 -0
- package/skills/app-dev/data-catalog/references/field-definitions.md +116 -0
- package/skills/app-dev/data-catalog/references/format.md +121 -0
- package/skills/app-dev/data-catalog/release-check.mjs +93 -0
- package/skills/app-dev/data-catalog/scripts/data-catalog.test.mjs +36 -0
- package/skills/app-dev/data-catalog/scripts/data_catalog.py +1392 -0
- package/skills/app-dev/data-catalog/scripts/persist-conventions-core.mjs +117 -0
- package/skills/app-dev/data-catalog/scripts/persist-conventions.mjs +17 -0
- package/skills/app-dev/data-catalog/scripts/test_data_catalog.py +571 -0
- package/skills/app-dev/ios-foundation/LICENSE +3 -0
- package/skills/app-dev/ios-foundation/SKILL.md +184 -0
- package/skills/app-dev/ios-foundation/references/setup.md +243 -0
- package/skills/app-dev/ios-foundation/release-check.mjs +93 -0
- package/skills/app-dev/monorepo/LICENSE +3 -0
- package/skills/app-dev/monorepo/SKILL.md +462 -0
- package/skills/app-dev/monorepo/release-check.mjs +93 -0
- package/skills/app-dev/nextjs-fullstack/LICENSE +3 -0
- package/skills/app-dev/nextjs-fullstack/SKILL.md +211 -0
- package/skills/app-dev/nextjs-fullstack/conventions.md +318 -0
- package/skills/app-dev/nextjs-fullstack/frontend-conventions.md +61 -0
- package/skills/app-dev/nextjs-fullstack/nextjs16.md +287 -0
- package/skills/app-dev/nextjs-fullstack/release-check.mjs +93 -0
- package/skills/app-dev/nextjs-fullstack/server-actions.md +409 -0
- package/skills/app-dev/prisma-setup/LICENSE +3 -0
- package/skills/app-dev/prisma-setup/SKILL.md +181 -0
- package/skills/app-dev/prisma-setup/nextjs.md +258 -0
- package/skills/app-dev/prisma-setup/release-check.mjs +93 -0
- package/skills/app-dev/prisma-setup/turborepo.md +301 -0
- package/skills/app-dev/pyspark/LICENSE +3 -0
- package/skills/app-dev/pyspark/SKILL.md +127 -0
- package/skills/app-dev/pyspark/assets/templates/etl.py +748 -0
- package/skills/app-dev/pyspark/assets/templates/utils/__init__.py +1 -0
- package/skills/app-dev/pyspark/assets/templates/utils/hudi_metadata.py +14 -0
- package/skills/app-dev/pyspark/references/diagnosis-and-profiling.md +169 -0
- package/skills/app-dev/pyspark/references/etl-contract.md +129 -0
- package/skills/app-dev/pyspark/references/production-validation.md +131 -0
- package/skills/app-dev/pyspark/references/reconciliation.md +38 -0
- package/skills/app-dev/pyspark/references/transformation-design.md +190 -0
- package/skills/app-dev/pyspark/references/velocity-feature-calculation.md +193 -0
- package/skills/app-dev/pyspark/release-check.mjs +93 -0
- package/skills/app-dev/pyspark/scripts/spark_eventlog_summary.py +223 -0
- package/skills/app-dev/python-backend/LICENSE +3 -0
- package/skills/app-dev/python-backend/SKILL.md +325 -0
- package/skills/app-dev/python-backend/assets/uv-install.sh +48 -0
- package/skills/app-dev/python-backend/references/uv-installs.md +83 -0
- package/skills/app-dev/python-backend/release-check.mjs +93 -0
- package/skills/app-dev/shadcn/LICENSE +3 -0
- package/skills/app-dev/shadcn/SKILL.md +120 -0
- package/skills/app-dev/shadcn/assets/shadcn-small.png +0 -0
- package/skills/app-dev/shadcn/assets/shadcn.png +0 -0
- package/skills/app-dev/shadcn/cli.md +411 -0
- package/skills/app-dev/shadcn/customization.md +224 -0
- package/skills/app-dev/shadcn/mcp.md +101 -0
- package/skills/app-dev/shadcn/release-check.mjs +93 -0
- package/skills/app-dev/shadcn/rules/base-vs-radix.md +323 -0
- package/skills/app-dev/shadcn/rules/component-selection.md +67 -0
- package/skills/app-dev/shadcn/rules/composition.md +195 -0
- package/skills/app-dev/shadcn/rules/data-table.md +201 -0
- package/skills/app-dev/shadcn/rules/forms.md +255 -0
- package/skills/app-dev/shadcn/rules/icons.md +103 -0
- package/skills/app-dev/shadcn/rules/styling.md +167 -0
- package/skills/app-dev/zod-v4/LICENSE +3 -0
- package/skills/app-dev/zod-v4/SKILL.md +286 -0
- package/skills/app-dev/zod-v4/release-check.mjs +93 -0
- package/skills/cicd/cloud-build/LICENSE +3 -0
- package/skills/cicd/cloud-build/SKILL.md +707 -0
- package/skills/cicd/cloud-build/release-check.mjs +93 -0
- package/skills/cicd/cloud-debug/LICENSE +3 -0
- package/skills/cicd/cloud-debug/SKILL.md +315 -0
- package/skills/cicd/cloud-debug/references/build-failures.md +238 -0
- package/skills/cicd/cloud-debug/references/deploy-failures.md +376 -0
- package/skills/cicd/cloud-debug/references/pipeline-failures.md +378 -0
- package/skills/cicd/cloud-debug/release-check.mjs +93 -0
- package/skills/cicd/cloud-deploy/LICENSE +3 -0
- package/skills/cicd/cloud-deploy/SKILL.md +230 -0
- package/skills/cicd/cloud-deploy/references/config-templates.md +257 -0
- package/skills/cicd/cloud-deploy/release-check.mjs +93 -0
- package/skills/cicd/docker/LICENSE +3 -0
- package/skills/cicd/docker/SKILL.md +151 -0
- package/skills/cicd/docker/release-check.mjs +93 -0
- package/skills/cicd/github-actions/LICENSE +3 -0
- package/skills/cicd/github-actions/SKILL.md +111 -0
- package/skills/cicd/github-actions/references/audit-profile-optimize.md +150 -0
- package/skills/cicd/github-actions/references/ci-case-studies.md +141 -0
- package/skills/cicd/github-actions/references/conditional-ci.md +214 -0
- package/skills/cicd/github-actions/references/debugging.md +13 -0
- package/skills/cicd/github-actions/references/pipeline.md +87 -0
- package/skills/cicd/github-actions/references/post-deploy-and-publishing.md +33 -0
- package/skills/cicd/github-actions/references/runners.md +253 -0
- package/skills/cicd/github-actions/references/security.md +29 -0
- package/skills/cicd/github-actions/references/speed-and-audit.md +115 -0
- package/skills/cicd/github-actions/references/two-pass-reading.md +92 -0
- package/skills/cicd/github-actions/release-check.mjs +93 -0
- package/skills/cicd/github-actions/scripts/ci-run-audit-core.mjs +612 -0
- package/skills/cicd/github-actions/scripts/ci-run-audit.mjs +4 -0
- package/skills/cicd/github-actions/scripts/ci-run-audit.test.mjs +637 -0
- package/skills/cicd/github-flow/LICENSE +3 -0
- package/skills/cicd/github-flow/SKILL.md +123 -0
- package/skills/cicd/github-flow/references/ci-conventions.md +14 -0
- package/skills/cicd/github-flow/release-check.mjs +93 -0
- package/skills/cicd/github-flow/scripts/flow-core.mjs +105 -0
- package/skills/cicd/github-flow/scripts/flow.mjs +81 -0
- package/skills/cicd/github-flow/scripts/flow.test.mjs +114 -0
- package/skills/cicd/github-flow/scripts/persist-conventions-core.mjs +117 -0
- package/skills/cicd/github-flow/scripts/persist-conventions.mjs +49 -0
- package/skills/cicd/github-flow/scripts/persist-conventions.test.mjs +108 -0
- package/skills/cicd/google-cloud/LICENSE +3 -0
- package/skills/cicd/google-cloud/SKILL.md +119 -0
- package/skills/cicd/google-cloud/references/gcs.md +469 -0
- package/skills/cicd/google-cloud/references/iam.md +451 -0
- package/skills/cicd/google-cloud/references/project.md +349 -0
- package/skills/cicd/google-cloud/references/secrets.md +336 -0
- package/skills/cicd/google-cloud/references/vpc.md +312 -0
- package/skills/cicd/google-cloud/release-check.mjs +93 -0
- package/skills/cicd/google-cloud/scripts/create-sa.sh +36 -0
- package/skills/cicd/google-cloud/scripts/gcp-config.sh +31 -0
- package/skills/cicd/google-cloud/scripts/grant-iap.sh +41 -0
- package/skills/cicd/google-cloud/scripts/setup-secrets.sh +48 -0
- package/skills/cicd/mergify/LICENSE +3 -0
- package/skills/cicd/mergify/SKILL.md +102 -0
- package/skills/cicd/mergify/assets/templates/mergify.yml +215 -0
- package/skills/cicd/mergify/assets/templates/ruleset.json +46 -0
- package/skills/cicd/mergify/references/branch-protection.md +282 -0
- package/skills/cicd/mergify/references/configuration.md +274 -0
- package/skills/cicd/mergify/references/diagnosis.md +109 -0
- package/skills/cicd/mergify/references/stacks.md +84 -0
- package/skills/cicd/mergify/references/traps.md +119 -0
- package/skills/cicd/mergify/references/watch-contract.md +274 -0
- package/skills/cicd/mergify/release-check.mjs +93 -0
- package/skills/cicd/mergify/scripts/audit-core.mjs +208 -0
- package/skills/cicd/mergify/scripts/audit.mjs +4 -0
- package/skills/cicd/mergify/scripts/audit.test.mjs +201 -0
- package/skills/cicd/mergify/scripts/entrypoints.test.mjs +106 -0
- package/skills/cicd/mergify/scripts/pr-620-mergify-comments.fixture.json +30 -0
- package/skills/cicd/mergify/scripts/stack-push-core.mjs +258 -0
- package/skills/cicd/mergify/scripts/stack-push.mjs +4 -0
- package/skills/cicd/mergify/scripts/stack-push.test.mjs +233 -0
- package/skills/cicd/mergify/scripts/watch-pr-delivery-core.mjs +1065 -0
- package/skills/cicd/mergify/scripts/watch-pr-delivery.mjs +4 -0
- package/skills/cicd/mergify/scripts/watch-pr-delivery.test.mjs +1826 -0
- package/skills/cicd/podman/LICENSE +3 -0
- package/skills/cicd/podman/SKILL.md +71 -0
- package/skills/cicd/podman/agents/openai.yaml +4 -0
- package/skills/cicd/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
- package/skills/cicd/podman/assets/templates/podman-service-override.conf +3 -0
- package/skills/cicd/podman/references/compose-compatibility.md +70 -0
- package/skills/cicd/podman/references/networking-and-ports.md +74 -0
- package/skills/cicd/podman/references/rootless-services-and-sockets.md +156 -0
- package/skills/cicd/podman/references/troubleshooting.md +98 -0
- package/skills/cicd/podman/release-check.mjs +93 -0
- package/skills/content/article-review/LICENSE +3 -0
- package/skills/content/article-review/SKILL.md +66 -0
- package/skills/content/article-review/references/report-format.md +68 -0
- package/skills/content/article-review/references/template-guide.md +79 -0
- package/skills/content/article-review/references/template-wechat-payments.md +125 -0
- package/skills/content/article-review/release-check.mjs +93 -0
- package/skills/content/article-to-image/LICENSE +3 -0
- package/skills/content/article-to-image/SKILL.md +91 -0
- package/skills/content/article-to-image/references/formats.md +53 -0
- package/skills/content/article-to-image/release-check.mjs +93 -0
- package/skills/content/flowchart-svg/LICENSE +3 -0
- package/skills/content/flowchart-svg/SKILL.md +43 -0
- package/skills/content/flowchart-svg/release-check.mjs +93 -0
- package/skills/content/flowchart-svg/scripts/export_png.sh +8 -0
- package/skills/content/image-gen/LICENSE +3 -0
- package/skills/content/image-gen/SKILL.md +192 -0
- package/skills/content/image-gen/release-check.mjs +93 -0
- package/skills/content/image-gen/scripts/credentials.mjs +217 -0
- package/skills/content/image-gen/scripts/credentials.test.mjs +212 -0
- package/skills/content/image-gen/scripts/generate.mjs +240 -0
- package/skills/content/image-gen/scripts/options.mjs +293 -0
- package/skills/content/image-gen/scripts/options.test.mjs +245 -0
- package/skills/content/mermaid/LICENSE +3 -0
- package/skills/content/mermaid/SKILL.md +635 -0
- package/skills/content/mermaid/release-check.mjs +93 -0
- package/skills/content/wechat-article-writer/LICENSE +3 -0
- package/skills/content/wechat-article-writer/SKILL.md +92 -0
- package/skills/content/wechat-article-writer/references/style-selector.md +133 -0
- package/skills/content/wechat-article-writer/references/writing-rules.md +152 -0
- package/skills/content/wechat-article-writer/release-check.mjs +93 -0
- package/skills/content/wechat-article-writer/templates/wechat-comparison.md +52 -0
- package/skills/content/wechat-article-writer/templates/wechat-howto.md +51 -0
- package/skills/content/wechat-article-writer/templates/wechat-insight.md +50 -0
- package/skills/content/wechat-article-writer/templates/wechat-pitfall.md +52 -0
- package/skills/content/wechat-publisher/LICENSE +3 -0
- package/skills/content/wechat-publisher/SKILL.md +171 -0
- package/skills/content/wechat-publisher/references/api.md +105 -0
- package/skills/content/wechat-publisher/references/layout-rules.md +57 -0
- package/skills/content/wechat-publisher/references/wechat-safe-template.html +86 -0
- package/skills/content/wechat-publisher/release-check.mjs +93 -0
- package/skills/content/wechat-publisher/scripts/md_to_wechat_html.py +194 -0
- package/skills/content/wechat-publisher/scripts/publish.py +239 -0
- package/skills/content/wechat-search/LICENSE +3 -0
- package/skills/content/wechat-search/SKILL.md +211 -0
- package/skills/content/wechat-search/release-check.mjs +93 -0
- package/skills/content/wechat-search/scripts/start-chrome.sh +83 -0
- package/skills/content/xai-search/LICENSE +3 -0
- package/skills/content/xai-search/SKILL.md +79 -0
- package/skills/content/xai-search/release-check.mjs +93 -0
- package/skills/content/xai-search/scripts/xai_search.sh +187 -0
- package/skills/content/xai-search/tests/smoke_test.sh +36 -0
- package/skills/core/distill-writing/LICENSE +3 -0
- package/skills/core/distill-writing/SKILL.md +74 -0
- package/skills/core/distill-writing/references/extraction.md +95 -0
- package/skills/core/distill-writing/references/updating.md +46 -0
- package/skills/core/distill-writing/release-check.mjs +93 -0
- package/skills/core/doc-to-md/LICENSE +3 -0
- package/skills/core/doc-to-md/SKILL.md +78 -0
- package/skills/core/doc-to-md/release-check.mjs +93 -0
- package/skills/core/doc-to-md/scripts/convert.py +157 -0
- package/skills/core/editorial-review/LICENSE +3 -0
- package/skills/core/editorial-review/SKILL.md +79 -0
- package/skills/core/editorial-review/references/checklist.md +94 -0
- package/skills/core/editorial-review/release-check.mjs +93 -0
- package/skills/core/house-style/LICENSE +3 -0
- package/skills/core/house-style/SKILL.md +33 -0
- package/skills/core/house-style/references/defaults.md +66 -0
- package/skills/core/house-style/references/rules.md +267 -0
- package/skills/core/house-style/references/sources.md +27 -0
- package/skills/core/house-style/references/style-en.md +131 -0
- package/skills/core/house-style/references/style-zh.md +141 -0
- package/skills/core/house-style/references/terminology-zh.md +223 -0
- package/skills/core/house-style/release-check.mjs +93 -0
- package/skills/core/house-style/templates/brd.md +103 -0
- package/skills/core/house-style/templates/commercial-proposal.md +93 -0
- package/skills/core/house-style/templates/compliance-policy.md +109 -0
- package/skills/core/house-style/templates/gap-analysis.md +105 -0
- package/skills/core/house-style/templates/general.md +63 -0
- package/skills/core/house-style/templates/integration-guide.md +98 -0
- package/skills/core/house-style/templates/prd.md +81 -0
- package/skills/core/house-style/templates/risk-operations-procedure.md +94 -0
- package/skills/core/house-style/templates/technical-spec.md +96 -0
- package/skills/core/polish-cn/LICENSE +3 -0
- package/skills/core/polish-cn/SKILL.md +102 -0
- package/skills/core/polish-cn/references/brief.md +93 -0
- package/skills/core/polish-cn/references/models.md +76 -0
- package/skills/core/polish-cn/release-check.mjs +93 -0
- package/skills/core/polish-cn/scripts/polish-cn.test.mjs +244 -0
- package/skills/core/polish-cn/scripts/polish_blocks.py +489 -0
- package/skills/core/reg-parser/LICENSE +3 -0
- package/skills/core/reg-parser/SKILL.md +212 -0
- package/skills/core/reg-parser/references/checklist-schema.md +223 -0
- package/skills/core/reg-parser/references/checklists/hk-amlo-checklist.json +1306 -0
- package/skills/core/reg-parser/references/checklists/hk-amlo-checklist.md +469 -0
- package/skills/core/reg-parser/references/checklists/hk-fi-corporate-onboarding-cdd-checklist.json +634 -0
- package/skills/core/reg-parser/references/checklists/hk-fi-corporate-onboarding-cdd-checklist.md +233 -0
- package/skills/core/reg-parser/references/checklists/hk-mso-guideline-checklist.json +2194 -0
- package/skills/core/reg-parser/references/checklists/hk-mso-guideline-checklist.md +771 -0
- package/skills/core/reg-parser/references/checklists/kyc-aml-checklist.md +258 -0
- package/skills/core/reg-parser/references/checklists/visa-vars-checklist.md +1058 -0
- package/skills/core/reg-parser/references/mandates/hk-amlo-cap615.md +389 -0
- package/skills/core/reg-parser/references/mandates/visa-vars.md +205 -0
- package/skills/core/reg-parser/release-check.mjs +93 -0
- package/skills/core/reg-parser/scripts/compare_checklist.py +230 -0
- package/skills/core/reg-parser/scripts/dump_checklist.py +361 -0
- package/skills/core/reg-parser/scripts/preprocess-mandate.sh +187 -0
- package/skills/core/reg-parser/scripts/reg-parser.test.mjs +165 -0
- package/skills/core/reg-parser/scripts/test_quarantine.sh +105 -0
- package/skills/core/reg-parser/scripts/validate_checklist.py +563 -0
- package/skills/core/reg-parser/scripts/validate_mandate.py +273 -0
- package/skills/core/terminology/LICENSE +3 -0
- package/skills/core/terminology/SKILL.md +62 -0
- package/skills/core/terminology/references/format.md +50 -0
- package/skills/core/terminology/references/init.md +32 -0
- package/skills/core/terminology/release-check.mjs +93 -0
- package/skills/core/write-doc/LICENSE +3 -0
- package/skills/core/write-doc/SKILL.md +141 -0
- package/skills/core/write-doc/references/bilingual.md +60 -0
- package/skills/core/write-doc/release-check.mjs +93 -0
- package/skills/engineering/better-review/LICENSE +3 -0
- package/skills/engineering/better-review/SKILL.md +249 -0
- package/skills/engineering/better-review/agents/openai.yaml +9 -0
- package/skills/engineering/better-review/references/domain-hazards.md +53 -0
- package/skills/engineering/better-review/references/passes.md +147 -0
- package/skills/engineering/better-review/references/result.md +151 -0
- package/skills/engineering/better-review/release-check.mjs +93 -0
- package/skills/engineering/better-review/scripts/pr-context.mjs +212 -0
- package/skills/engineering/better-review/scripts/pr-context.test.mjs +168 -0
- package/skills/engineering/better-review/scripts/rereview-scope.mjs +503 -0
- package/skills/engineering/better-review/scripts/rereview-scope.test.mjs +587 -0
- package/skills/engineering/better-review/scripts/scan-diff.mjs +365 -0
- package/skills/engineering/better-review/scripts/scan-diff.test.mjs +414 -0
- package/skills/engineering/better-review/scripts/vendor-sync.test.mjs +96 -0
- package/skills/engineering/e2e-test/LICENSE +3 -0
- package/skills/engineering/e2e-test/SKILL.md +98 -0
- package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +24 -0
- package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
- package/skills/engineering/e2e-test/references/authoring/playwright-config.md +73 -0
- package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +144 -0
- package/skills/engineering/e2e-test/references/ci-integration.md +25 -0
- package/skills/engineering/e2e-test/references/ci-playwright-container.md +290 -0
- package/skills/engineering/e2e-test/references/presentation-sweep.md +104 -0
- package/skills/engineering/e2e-test/references/reviewing.md +41 -0
- package/skills/engineering/e2e-test/references/route-manifest.md +51 -0
- package/skills/engineering/e2e-test/release-check.mjs +93 -0
- package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
- package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
- package/skills/engineering/e2e-test/scripts/presentation-checks.test.mjs +106 -0
- package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
- package/skills/engineering/e2e-test/scripts/presentation-perceivability.test.mjs +117 -0
- package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
- package/skills/engineering/e2e-test/scripts/presentation-reachability.test.mjs +69 -0
- package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
- package/skills/engineering/e2e-test/scripts/presentation-render-health.test.mjs +98 -0
- package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +147 -0
- package/skills/engineering/e2e-test/scripts/presentation-sweep.test.mjs +71 -0
- package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
- package/skills/engineering/e2e-test/scripts/presentation-temporal.test.mjs +59 -0
- package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +82 -0
- package/skills/engineering/e2e-test/scripts/project-route-manifest.test.mjs +76 -0
- package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
- package/skills/engineering/engineering-runtime/LICENSE +3 -0
- package/skills/engineering/engineering-runtime/SKILL.md +11 -0
- package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
- package/skills/engineering/engineering-runtime/coherence/workflow.json +597 -0
- package/skills/engineering/engineering-runtime/engineering-runtime.test.mjs +68 -0
- package/skills/engineering/engineering-runtime/release-check.mjs +93 -0
- package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
- package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
- package/skills/engineering/engineering-runtime/scripts/invocation-policy.mjs +187 -0
- package/skills/engineering/engineering-runtime/scripts/invocation-policy.test.mjs +95 -0
- package/skills/engineering/engineering-runtime/scripts/main-module.mjs +79 -0
- package/skills/engineering/engineering-runtime/scripts/main-module.test.mjs +288 -0
- package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
- package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
- package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
- package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
- package/skills/engineering/engineering-runtime/scripts/required-check-plan.test.mjs +96 -0
- package/skills/engineering/engineering-runtime/scripts/review-completion.mjs +56 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +595 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +189 -0
- package/skills/engineering/engineering-runtime/scripts/yaml-mapping.mjs +18 -0
- package/skills/engineering/ensure-coverage/LICENSE +3 -0
- package/skills/engineering/ensure-coverage/SKILL.md +129 -0
- package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +92 -0
- package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +85 -0
- package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
- package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
- package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
- package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +19 -0
- package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
- package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +57 -0
- package/skills/engineering/ensure-coverage/references/depth/test-smells.md +39 -0
- package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +44 -0
- package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +110 -0
- package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +35 -0
- package/skills/engineering/ensure-coverage/references/presentation/axis.md +64 -0
- package/skills/engineering/ensure-coverage/references/process/audit-mode.md +27 -0
- package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
- package/skills/engineering/ensure-coverage/references/process/test-strategy.md +56 -0
- package/skills/engineering/ensure-coverage/release-check.mjs +93 -0
- package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +67 -0
- package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +140 -0
- package/skills/engineering/ensure-coverage/scripts/README.md +99 -0
- package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +182 -0
- package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.test.mjs +96 -0
- package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +105 -0
- package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.test.mjs +47 -0
- package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +137 -0
- package/skills/engineering/ensure-coverage/scripts/ci-audit.test.mjs +86 -0
- package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +674 -0
- package/skills/engineering/ensure-coverage/scripts/coverage-ledger.test.mjs +447 -0
- package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
- package/skills/engineering/ensure-coverage/scripts/design-parity.test.mjs +552 -0
- package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +282 -0
- package/skills/engineering/ensure-coverage/scripts/lint-tests.test.mjs +289 -0
- package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
- package/skills/engineering/ensure-coverage/scripts/mock-policy-config.test.mjs +119 -0
- package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
- package/skills/engineering/golden-path/LICENSE +3 -0
- package/skills/engineering/golden-path/SKILL.md +230 -0
- package/skills/engineering/golden-path/agents/openai.yaml +3 -0
- package/skills/engineering/golden-path/assets/golden-paths.example.json +57 -0
- package/skills/engineering/golden-path/references/contract.md +239 -0
- package/skills/engineering/golden-path/references/migration.md +111 -0
- package/skills/engineering/golden-path/release-check.mjs +93 -0
- package/skills/engineering/golden-path/scripts/golden-path-core.mjs +1779 -0
- package/skills/engineering/golden-path/scripts/golden-path.mjs +6 -0
- package/skills/engineering/golden-path/scripts/golden-path.test.mjs +1457 -0
- package/skills/engineering/harness-runtime/LICENSE +3 -0
- package/skills/engineering/harness-runtime/SKILL.md +19 -0
- package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
- package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
- package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
- package/skills/engineering/harness-runtime/contracts.md +15 -0
- package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
- package/skills/engineering/harness-runtime/discover-models.test.mjs +363 -0
- package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
- package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
- package/skills/engineering/harness-runtime/harness-runtime.test.mjs +967 -0
- package/skills/engineering/harness-runtime/index.mjs +767 -0
- package/skills/engineering/harness-runtime/model-catalog-seed.test.mjs +829 -0
- package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
- package/skills/engineering/harness-runtime/model-catalog.test.mjs +366 -0
- package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
- package/skills/engineering/harness-runtime/references/model-catalog-seed.json +408 -0
- package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
- package/skills/engineering/harness-runtime/release-check.mjs +93 -0
- package/skills/engineering/resolve-issues/LICENSE +3 -0
- package/skills/engineering/resolve-issues/SKILL.md +250 -0
- package/skills/engineering/resolve-issues/agents/openai.yaml +9 -0
- package/skills/engineering/resolve-issues/plugin-hooks.json +17 -0
- package/skills/engineering/resolve-issues/references/canary.md +28 -0
- package/skills/engineering/resolve-issues/references/ci.md +105 -0
- package/skills/engineering/resolve-issues/references/done.md +25 -0
- package/skills/engineering/resolve-issues/references/dropbox.md +90 -0
- package/skills/engineering/resolve-issues/references/expire.md +318 -0
- package/skills/engineering/resolve-issues/references/exploration.md +202 -0
- package/skills/engineering/resolve-issues/references/implementation.md +303 -0
- package/skills/engineering/resolve-issues/references/preflight.md +445 -0
- package/skills/engineering/resolve-issues/references/review.md +228 -0
- package/skills/engineering/resolve-issues/references/shared-modules.md +44 -0
- package/skills/engineering/resolve-issues/references/task-plan.md +264 -0
- package/skills/engineering/resolve-issues/release-check.mjs +93 -0
- package/skills/engineering/resolve-issues/scripts/cleanup-runs.mjs +364 -0
- package/skills/engineering/resolve-issues/scripts/cleanup-runs.test.mjs +280 -0
- package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
- package/skills/engineering/resolve-issues/scripts/dropbox.mjs +473 -0
- package/skills/engineering/resolve-issues/scripts/dropbox.test.mjs +346 -0
- package/skills/engineering/resolve-issues/scripts/findings-reuse.mjs +98 -0
- package/skills/engineering/resolve-issues/scripts/findings-reuse.test.mjs +88 -0
- package/skills/engineering/resolve-issues/scripts/github-reviews.mjs +384 -0
- package/skills/engineering/resolve-issues/scripts/github-reviews.test.mjs +264 -0
- package/skills/engineering/resolve-issues/scripts/install-hooks.mjs +135 -0
- package/skills/engineering/resolve-issues/scripts/install-hooks.test.mjs +79 -0
- package/skills/engineering/resolve-issues/scripts/issue-tree.mjs +162 -0
- package/skills/engineering/resolve-issues/scripts/issue-tree.test.mjs +107 -0
- package/skills/engineering/resolve-issues/scripts/manual-invocation.test.mjs +14 -0
- package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
- package/skills/engineering/resolve-issues/scripts/next-actions-capacity.test.mjs +149 -0
- package/skills/engineering/resolve-issues/scripts/next-actions.mjs +856 -0
- package/skills/engineering/resolve-issues/scripts/next-actions.test.mjs +915 -0
- package/skills/engineering/resolve-issues/scripts/plan-sync.mjs +269 -0
- package/skills/engineering/resolve-issues/scripts/plan-sync.test.mjs +156 -0
- package/skills/engineering/resolve-issues/scripts/preflight-models.mjs +736 -0
- package/skills/engineering/resolve-issues/scripts/preflight-models.test.mjs +448 -0
- package/skills/engineering/resolve-issues/scripts/ready-check.mjs +185 -0
- package/skills/engineering/resolve-issues/scripts/ready-check.test.mjs +217 -0
- package/skills/engineering/resolve-issues/scripts/rehydrate.mjs +98 -0
- package/skills/engineering/resolve-issues/scripts/rehydrate.test.mjs +91 -0
- package/skills/engineering/resolve-issues/scripts/review-verdict.mjs +509 -0
- package/skills/engineering/resolve-issues/scripts/review-verdict.test.mjs +1060 -0
- package/skills/engineering/resolve-issues/scripts/size-check.mjs +492 -0
- package/skills/engineering/resolve-issues/scripts/size-check.test.mjs +458 -0
- package/skills/engineering/resolve-release/LICENSE +3 -0
- package/skills/engineering/resolve-release/SKILL.md +215 -0
- package/skills/engineering/resolve-release/agents/openai.yaml +8 -0
- package/skills/engineering/resolve-release/flows/cloud-run-canary.md +13 -0
- package/skills/engineering/resolve-release/flows/cloud-run.md +7 -0
- package/skills/engineering/resolve-release/flows/root-tag-npm.md +13 -0
- package/skills/engineering/resolve-release/flows/workspace-npm.md +22 -0
- package/skills/engineering/resolve-release/references/canary.md +51 -0
- package/skills/engineering/resolve-release/references/candidate.md +41 -0
- package/skills/engineering/resolve-release/references/cut.md +131 -0
- package/skills/engineering/resolve-release/references/dark-launch.md +66 -0
- package/skills/engineering/resolve-release/references/flows.md +150 -0
- package/skills/engineering/resolve-release/references/preflight.md +154 -0
- package/skills/engineering/resolve-release/references/prepared-metadata.md +260 -0
- package/skills/engineering/resolve-release/references/promotion.md +82 -0
- package/skills/engineering/resolve-release/references/publish.md +232 -0
- package/skills/engineering/resolve-release/references/workspace-npm.md +103 -0
- package/skills/engineering/resolve-release/release-check.mjs +93 -0
- package/skills/engineering/resolve-release/scripts/apply.mjs +212 -0
- package/skills/engineering/resolve-release/scripts/apply.test.mjs +99 -0
- package/skills/engineering/resolve-release/scripts/dark-flags.mjs +134 -0
- package/skills/engineering/resolve-release/scripts/dark-flags.test.mjs +100 -0
- package/skills/engineering/resolve-release/scripts/flow.mjs +500 -0
- package/skills/engineering/resolve-release/scripts/flow.test.mjs +340 -0
- package/skills/engineering/resolve-release/scripts/green-head.mjs +231 -0
- package/skills/engineering/resolve-release/scripts/green-head.test.mjs +101 -0
- package/skills/engineering/resolve-release/scripts/npm-version-absence.mjs +138 -0
- package/skills/engineering/resolve-release/scripts/npm-version-absence.test.mjs +426 -0
- package/skills/engineering/resolve-release/scripts/plan-npm.test.mjs +659 -0
- package/skills/engineering/resolve-release/scripts/plan-toml-boundary.test.mjs +317 -0
- package/skills/engineering/resolve-release/scripts/plan-uv.test.mjs +291 -0
- package/skills/engineering/resolve-release/scripts/plan.mjs +806 -0
- package/skills/engineering/resolve-release/scripts/plan.test.mjs +428 -0
- package/skills/engineering/rush-issues/LICENSE +3 -0
- package/skills/engineering/rush-issues/SKILL.md +58 -0
- package/skills/engineering/rush-issues/agents/openai.yaml +8 -0
- package/skills/engineering/rush-issues/rehydrate.mjs +10 -0
- package/skills/engineering/rush-issues/release-check.mjs +93 -0
- package/skills/engineering/rush-release/LICENSE +3 -0
- package/skills/engineering/rush-release/SKILL.md +35 -0
- package/skills/engineering/rush-release/agents/openai.yaml +8 -0
- package/skills/engineering/rush-release/release-check.mjs +93 -0
- package/skills/engineering/test-quality/LICENSE +3 -0
- package/skills/engineering/test-quality/SKILL.md +79 -0
- package/skills/engineering/test-quality/references/audit.md +80 -0
- package/skills/engineering/test-quality/references/lint.md +24 -0
- package/skills/engineering/test-quality/references/principles.md +143 -0
- package/skills/engineering/test-quality/references/testing-conventions.md +9 -0
- package/skills/engineering/test-quality/release-check.mjs +93 -0
- package/skills/engineering/test-quality/scripts/lint-tests.mjs +574 -0
- package/skills/engineering/test-quality/scripts/lint-tests.test.mjs +591 -0
- package/skills/engineering/test-quality/scripts/mock-policy-config.mjs +176 -0
- package/skills/engineering/test-quality/scripts/mock-policy-config.test.mjs +119 -0
- package/skills/engineering/test-quality/scripts/persist-conventions-core.mjs +117 -0
- package/skills/engineering/test-quality/scripts/persist-conventions.mjs +17 -0
- package/skills/engineering/test-quality/scripts/persist-conventions.test.mjs +104 -0
- package/skills/risk-compliance/compliance-audit/LICENSE +3 -0
- package/skills/risk-compliance/compliance-audit/SKILL.md +439 -0
- package/skills/risk-compliance/compliance-audit/references/findings-schema.md +293 -0
- package/skills/risk-compliance/compliance-audit/references/normalization-rules.md +45 -0
- package/skills/risk-compliance/compliance-audit/references/vars-checklist.md +1068 -0
- package/skills/risk-compliance/compliance-audit/references/vars-findings-schema.md +398 -0
- package/skills/risk-compliance/compliance-audit/release-check.mjs +93 -0
- package/skills/risk-compliance/compliance-audit/scripts/compliance-audit.test.mjs +14 -0
- package/skills/risk-compliance/compliance-audit/scripts/export_tracker_xlsx.py +221 -0
- package/skills/risk-compliance/compliance-audit/scripts/reconcile_tracker.py +458 -0
- package/skills/risk-compliance/compliance-audit/scripts/test_export_tracker_xlsx.py +97 -0
- package/skills/risk-compliance/compliance-audit/scripts/test_validate_tracker.py +157 -0
- package/skills/risk-compliance/compliance-audit/scripts/validate_tracker.py +829 -0
- package/skills/risk-compliance/contract-compare/LICENSE +3 -0
- package/skills/risk-compliance/contract-compare/SKILL.md +199 -0
- package/skills/risk-compliance/contract-compare/references/comparison-dimensions.md +209 -0
- package/skills/risk-compliance/contract-compare/release-check.mjs +93 -0
- package/skills/risk-compliance/contract-review/LICENSE +3 -0
- package/skills/risk-compliance/contract-review/SKILL.md +240 -0
- package/skills/risk-compliance/contract-review/references/review-criteria.md +223 -0
- package/skills/risk-compliance/contract-review/release-check.mjs +93 -0
- package/skills/risk-compliance/doc-authenticity/LICENSE +3 -0
- package/skills/risk-compliance/doc-authenticity/SKILL.md +160 -0
- package/skills/risk-compliance/doc-authenticity/agents/openai.yaml +8 -0
- package/skills/risk-compliance/doc-authenticity/manual-invocation.test.mjs +12 -0
- package/skills/risk-compliance/doc-authenticity/references/agreement.md +66 -0
- package/skills/risk-compliance/doc-authenticity/references/bank-statement.md +150 -0
- package/skills/risk-compliance/doc-authenticity/references/forensic-signals.md +157 -0
- package/skills/risk-compliance/doc-authenticity/references/image-signals.md +114 -0
- package/skills/risk-compliance/doc-authenticity/references/invoice.md +66 -0
- package/skills/risk-compliance/doc-authenticity/references/issuer-profiles.md +86 -0
- package/skills/risk-compliance/doc-authenticity/references/verdict-and-report.md +95 -0
- package/skills/risk-compliance/doc-authenticity/references/verdict.schema.json +81 -0
- package/skills/risk-compliance/doc-authenticity/release-check.mjs +93 -0
- package/skills/risk-compliance/doc-authenticity/scripts/image_forensics.py +294 -0
- package/skills/risk-compliance/doc-authenticity/scripts/pdf_forensics.py +401 -0
- package/skills/risk-compliance/doc-authenticity/scripts/validate_codes.py +224 -0
- package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.py +308 -0
- package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.test.mjs +212 -0
- package/skills/risk-compliance/fraud-analysis/LICENSE +3 -0
- package/skills/risk-compliance/fraud-analysis/SKILL.md +114 -0
- package/skills/risk-compliance/fraud-analysis/references/archetypes/authorized-payment-scam.md +41 -0
- package/skills/risk-compliance/fraud-analysis/references/archetypes/first-party-fraud.md +44 -0
- package/skills/risk-compliance/fraud-analysis/references/archetypes/third-party-fraud.md +27 -0
- package/skills/risk-compliance/fraud-analysis/references/contexts/bank-transfer.md +24 -0
- package/skills/risk-compliance/fraud-analysis/references/contexts/card-payment.md +30 -0
- package/skills/risk-compliance/fraud-analysis/references/contexts/payment-collection.md +20 -0
- package/skills/risk-compliance/fraud-analysis/references/contexts/payout.md +20 -0
- package/skills/risk-compliance/fraud-analysis/references/feature-engineering.md +158 -0
- package/skills/risk-compliance/fraud-analysis/references/mechanisms/account-takeover.md +36 -0
- package/skills/risk-compliance/fraud-analysis/references/report-rationale.md +45 -0
- package/skills/risk-compliance/fraud-analysis/references/report-template.md +190 -0
- package/skills/risk-compliance/fraud-analysis/references/review-checklist.md +175 -0
- package/skills/risk-compliance/fraud-analysis/references/taxonomy.md +79 -0
- package/skills/risk-compliance/fraud-analysis/references/terminology.md +108 -0
- package/skills/risk-compliance/fraud-analysis/references/workflow.md +175 -0
- package/skills/risk-compliance/fraud-analysis/release-check.mjs +93 -0
- package/skills/risk-compliance/payment-analysis/LICENSE +3 -0
- package/skills/risk-compliance/payment-analysis/SKILL.md +180 -0
- package/skills/risk-compliance/payment-analysis/references/auth-rate-actions.md +30 -0
- package/skills/risk-compliance/payment-analysis/references/chargebacks.md +208 -0
- package/skills/risk-compliance/payment-analysis/references/chinese-polish.md +51 -0
- package/skills/risk-compliance/payment-analysis/references/event-layers.md +127 -0
- package/skills/risk-compliance/payment-analysis/references/fx.md +59 -0
- package/skills/risk-compliance/payment-analysis/references/journey.md +79 -0
- package/skills/risk-compliance/payment-analysis/references/metrics.md +67 -0
- package/skills/risk-compliance/payment-analysis/references/report-template.md +119 -0
- package/skills/risk-compliance/payment-analysis/references/terminology.md +95 -0
- package/skills/risk-compliance/payment-analysis/references/visualization.md +56 -0
- package/skills/risk-compliance/payment-analysis/release-check.mjs +93 -0
- package/skills/risk-compliance/report-writing/LICENSE +3 -0
- package/skills/risk-compliance/report-writing/SKILL.md +220 -0
- package/skills/risk-compliance/report-writing/references/audit-report-template.md +121 -0
- package/skills/risk-compliance/report-writing/references/external-assessment-template.md +167 -0
- package/skills/risk-compliance/report-writing/references/management-report-template.md +145 -0
- package/skills/risk-compliance/report-writing/references/vars-report-template.md +224 -0
- package/skills/risk-compliance/report-writing/release-check.mjs +93 -0
- package/skills/risk-compliance/similar-domain/LICENSE +3 -0
- package/skills/risk-compliance/similar-domain/SKILL.md +203 -0
- package/skills/risk-compliance/similar-domain/references/entities.md +67 -0
- package/skills/risk-compliance/similar-domain/references/fingerprints.md +134 -0
- package/skills/risk-compliance/similar-domain/references/pivots.md +82 -0
- package/skills/risk-compliance/similar-domain/references/report-template.md +93 -0
- package/skills/risk-compliance/similar-domain/references/scoring.md +130 -0
- package/skills/risk-compliance/similar-domain/references/terminology.md +41 -0
- package/skills/risk-compliance/similar-domain/references/workflow.md +85 -0
- package/skills/risk-compliance/similar-domain/release-check.mjs +93 -0
- package/skills/risk-compliance/tld-detection/LICENSE +3 -0
- package/skills/risk-compliance/tld-detection/SKILL.md +245 -0
- package/skills/risk-compliance/tld-detection/agents/openai.yaml +9 -0
- package/skills/risk-compliance/tld-detection/references/chinese-polish.md +55 -0
- package/skills/risk-compliance/tld-detection/references/clean.md +51 -0
- package/skills/risk-compliance/tld-detection/references/clustering.md +235 -0
- package/skills/risk-compliance/tld-detection/references/decision.md +189 -0
- package/skills/risk-compliance/tld-detection/references/fx-conversion.md +232 -0
- package/skills/risk-compliance/tld-detection/references/report-template.md +272 -0
- package/skills/risk-compliance/tld-detection/references/streams.md +141 -0
- package/skills/risk-compliance/tld-detection/references/terminology.md +95 -0
- package/skills/risk-compliance/tld-detection/references/workflow.md +95 -0
- package/skills/risk-compliance/tld-detection/release-check.mjs +93 -0
- package/skills/risk-compliance/tld-detection/scripts/detect_ladders.py +390 -0
- package/skills/risk-compliance/tld-detection/scripts/detect_ladders.test.mjs +14 -0
- package/skills/risk-compliance/tld-detection/scripts/detect_streams.py +650 -0
- package/skills/risk-compliance/tld-detection/scripts/detect_streams.test.mjs +14 -0
- package/skills/risk-compliance/tld-detection/tests/test_detect_ladders.py +134 -0
- package/skills/risk-compliance/tld-detection/tests/test_detect_streams.py +520 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Android foundation gotchas
|
|
2
|
+
|
|
3
|
+
Known traps, each as signal, cause and fix. Match the signal before you dig. If none
|
|
4
|
+
matches, [confirm the suspected cause](#confirm-a-suspected-cause) before changing code.
|
|
5
|
+
|
|
6
|
+
## Emulator and AVD
|
|
7
|
+
|
|
8
|
+
### A hand-written AVD misses the screen
|
|
9
|
+
|
|
10
|
+
- **Signal:** taps or swipes land nowhere, or a control below the fold never scrolls into
|
|
11
|
+
view, though the same journey passes elsewhere. The device reports `Physical size:
|
|
12
|
+
320x480`.
|
|
13
|
+
- **Cause:** `config.ini` was written from scratch without the hardware keys. Without
|
|
14
|
+
`hw.lcd.*` the emulator defaults to 320x480, so a journey's display override and fixed
|
|
15
|
+
coordinates no longer match.
|
|
16
|
+
- **Fix:** copy the hardware keys from an `avdmanager`-made AVD on the same runner:
|
|
17
|
+
`hw.lcd.width`, `hw.lcd.height`, `hw.lcd.density` and `disk.dataPartition.size`. Set
|
|
18
|
+
`hw.ramSize=4096` instead of copying its value; see
|
|
19
|
+
[adb transport drops](#the-adb-transport-drops-mid-journey).
|
|
20
|
+
|
|
21
|
+
### `avdmanager` cannot see an installed image
|
|
22
|
+
|
|
23
|
+
- **Signal:** `avdmanager create avd --package …` fails with `Package path is not valid` and
|
|
24
|
+
lists only the images under its own SDK.
|
|
25
|
+
- **Cause:** `avdmanager` derives its SDK root from its own install location. It ignores
|
|
26
|
+
`ANDROID_SDK_ROOT` and `ANDROID_HOME`, so an image under another root (a slot-local
|
|
27
|
+
overlay, for example) is invisible to it.
|
|
28
|
+
- **Fix:** write the AVD's `.ini` and `config.ini` yourself, with `image.sysdir.1` relative
|
|
29
|
+
to the SDK root the emulator uses. Then apply
|
|
30
|
+
[the hardware keys](#a-hand-written-avd-misses-the-screen). An image that ships a `data/`
|
|
31
|
+
tree instead of `userdata.img` is fine: the emulator seeds userdata from it on first
|
|
32
|
+
boot.
|
|
33
|
+
|
|
34
|
+
### The emulator boots in software
|
|
35
|
+
|
|
36
|
+
- **Signal:** boot takes 10+ minutes.
|
|
37
|
+
- **Cause:** KVM is unusable to the emulator. A host where `test -r/-w /dev/kvm` passes but
|
|
38
|
+
Node's `fs.accessSync(R_OK | W_OK)` fails still falls back to software.
|
|
39
|
+
- **Fix:** check KVM with `accessSync` in the preflight, and set
|
|
40
|
+
`disable-linux-hw-accel: false`.
|
|
41
|
+
|
|
42
|
+
### Two jobs fight over `emulator-5554` or Metro's port
|
|
43
|
+
|
|
44
|
+
- **Cause:** runner slots share the host network, and the ports are not slot-derived.
|
|
45
|
+
- **Fix:** derive the ADB server, emulator console, backend and Metro ports from the slot
|
|
46
|
+
number ([ci.md](ci.md#runner)).
|
|
47
|
+
|
|
48
|
+
## Metro and adb
|
|
49
|
+
|
|
50
|
+
### Lost `adb reverse`
|
|
51
|
+
|
|
52
|
+
- **Signal:** earlier steps passed, then a screen's first Metro asset fails: `Unable to
|
|
53
|
+
download asset from url: http://127.0.0.1:8081/assets/…`, often an icon font. With
|
|
54
|
+
`expo-font`/`expo-asset`, every mounted icon reports a rejection (a burst of a dozen or
|
|
55
|
+
more). API calls on the same screen still succeed.
|
|
56
|
+
- **Cause:** an adb transport reconnect keeps the emulator in `device` state but deletes
|
|
57
|
+
every `adb reverse` mapping; `adb reverse --list` comes back empty. UI automation
|
|
58
|
+
recovers, Metro becomes unreachable, and a debug build loads assets from Metro. A
|
|
59
|
+
backend reached at `10.0.2.2` does not use adb, so it keeps working. The usual trigger is
|
|
60
|
+
an [adb transport drop](#the-adb-transport-drops-mid-journey); fix that first.
|
|
61
|
+
- **Fix:** re-prove the bridge before every step whose screen is the first to load a Metro
|
|
62
|
+
asset: re-apply the reverse and check, from inside the device, that Metro answers. Doing
|
|
63
|
+
it only at app launch is not enough. Release builds embed their assets, so this is a
|
|
64
|
+
harness failure, not a product failure.
|
|
65
|
+
|
|
66
|
+
### The adb transport drops mid-journey
|
|
67
|
+
|
|
68
|
+
- **Signal:** the host adb server's transport trace (`ADB_TRACE=transport`) shows
|
|
69
|
+
`remote local: terminated (data)` then `emulator-NNNN: connection terminated: read
|
|
70
|
+
failed` after boot, while the emulator stays up. About 0.5 s later the device is back
|
|
71
|
+
in `device` state, but [every `adb reverse` is gone](#lost-adb-reverse). Steps fail at
|
|
72
|
+
random, often during bursts of guest-to-host data (`dumpsys`, hierarchy dumps,
|
|
73
|
+
logcat). A drop during boot, before `sys.boot_completed`, is normal: adbd restarts once.
|
|
74
|
+
- **Cause:** guest memory, seen on x86_64 API 35/36 images with `android15-6.6` kernels
|
|
75
|
+
6.6.50 and 6.6.66. GKI `android15-6.6-2025-09` and later cap these pieces at about
|
|
76
|
+
28 KiB, which should avoid it, but no emulator image with such a kernel was tested. The guest kernel sends adb
|
|
77
|
+
data over virtio-vsock in pieces of up to 64 KiB, each needing one contiguous 128 KiB
|
|
78
|
+
allocation. At 2 GB (the usual AVD value), a busy journey fragments guest memory until that
|
|
79
|
+
allocation fails. adbd's `write()` gets `ENOMEM` (`error 12: Out of memory`), adbd
|
|
80
|
+
treats it as fatal, logs `connection terminated: write failed` and closes the transport
|
|
81
|
+
itself, so the host side is not the cause. In the traced runs only the job's own adb
|
|
82
|
+
server was connected to the emulator.
|
|
83
|
+
- **Fix:** give the guest 4 GB: `hw.ramSize=4096` in the AVD's `config.ini`, replacing any
|
|
84
|
+
existing value. At 4 GB the guest kept 127+ free blocks of 128 KiB or larger, with no
|
|
85
|
+
allocation stalls and no drops; at 2 GB it fell to 1 such block, with hundreds of
|
|
86
|
+
stalls. Keep re-proving `adb reverse` before Metro-dependent steps as a safety net.
|
|
87
|
+
- **Confirm:** with `adb root`, set `persist.adb.trace_mask=rwx,transport`, restart
|
|
88
|
+
adbd, and look for `writex: fd=N error 12` in `/data/adb/adb-*`. Guest tracepoints
|
|
89
|
+
`vsock/virtio_transport_{alloc,recv}_pkt` show adbd's own `SHUTDOWN` going out first;
|
|
90
|
+
`/proc/buddyinfo` shows order-5 and larger blocks (128 KiB+ contiguous) near zero.
|
|
91
|
+
- **Dead ends:**
|
|
92
|
+
- `-feature -VirtioVsockPipe`: adb stays `offline` forever on API 35.
|
|
93
|
+
- adb over TCP through the emulator console's `redir`: works only on boots where guest
|
|
94
|
+
`eth0` gets `10.0.2.15`.
|
|
95
|
+
- A newer emulator or platform-tools: no relevant fix in their release notes.
|
|
96
|
+
|
|
97
|
+
### `RemoteDisconnected` right after a new process connects
|
|
98
|
+
|
|
99
|
+
- **Signal:** the first uiautomator2 RPC in a newly started Python process raises
|
|
100
|
+
`RemoteDisconnected`. The adb transport stays registered: the trace shows `tcp:9008`
|
|
101
|
+
refused (`OPEN` then immediate `CLSE`), then a single stream `CLSE` with no response,
|
|
102
|
+
and no `connection terminated`.
|
|
103
|
+
- **Cause:** uiautomator2 keeps its on-device server inside an adb shell session owned by
|
|
104
|
+
the Python process that started it. When that process exits the server dies, and the
|
|
105
|
+
next process relaunches it. An RPC sent while it starts gets cut off, especially with
|
|
106
|
+
uiautomator2's own restart and retry bypassed.
|
|
107
|
+
- **Fix:** drive the whole journey from one process, or wait until the server answers
|
|
108
|
+
`/ping` before the first RPC. This is not an [adb drop](#the-adb-transport-drops-mid-journey).
|
|
109
|
+
|
|
110
|
+
## Journey harness
|
|
111
|
+
|
|
112
|
+
### A navigation check passes on the previous screen
|
|
113
|
+
|
|
114
|
+
- **Signal:** intermittently, a wait right after the next tap times out even though the
|
|
115
|
+
app works. The screen at failure is the destination of the previous navigation, often
|
|
116
|
+
scrolled by the harness's own swipes, and the app records no navigation for that tap.
|
|
117
|
+
- **Cause:** the check that should confirm arrival also matches text on the origin
|
|
118
|
+
screen, so it passes before the new screen lands. The next tap then hits the screen
|
|
119
|
+
mid-transition and is sometimes lost.
|
|
120
|
+
- **Fix:** after a navigation, wait for something only the destination shows, such as its
|
|
121
|
+
own record ID next to its label, never a value the origin also displays. To prove it,
|
|
122
|
+
make the unit tests' fake UI (the scripted hierarchy the harness tests read) keep the
|
|
123
|
+
origin on screen for a few reads and drop taps in that window; the test must fail
|
|
124
|
+
without the fix.
|
|
125
|
+
- **Example:** after `Original Payment Transaction` on a refund, the check waited for the
|
|
126
|
+
original's Provider Reference, which the refund also shows as `Parent Provider
|
|
127
|
+
Reference`. `Back to History` landed about 75 ms into the transition, and about one
|
|
128
|
+
cold run in three failed with `Timed out: return to History list`. Waiting for the
|
|
129
|
+
original's `Payment Transaction ID` fixed it.
|
|
130
|
+
|
|
131
|
+
### A wait never scrolls to its label
|
|
132
|
+
|
|
133
|
+
- **Signal:** a wait for a label times out only on a short or landscape screen (812x360,
|
|
134
|
+
for example) and passes on the phone. The screen at failure shows the content above the
|
|
135
|
+
label.
|
|
136
|
+
- **Cause:** UiAutomator lists only nodes that are on screen, and the wait checks the
|
|
137
|
+
hierarchy without scrolling. On a short screen the label sits below the fold.
|
|
138
|
+
- **First:** check `adb shell wm size`. A 320x480 screen is
|
|
139
|
+
[a hand-written AVD](#a-hand-written-avd-misses-the-screen), not this.
|
|
140
|
+
- **Fix:** scroll toward the label before or while waiting. To prove it, make the harness
|
|
141
|
+
test's fake UI keep the label off screen until a scroll; the test must fail without the
|
|
142
|
+
fix.
|
|
143
|
+
|
|
144
|
+
### A harness test fails on the runner's real state
|
|
145
|
+
|
|
146
|
+
- **Signal:** a harness unit test fails before the APK builds with a host-resource message
|
|
147
|
+
(`Retained native owner requires 2 GiB reserve`), and passes on a developer machine.
|
|
148
|
+
- **Cause:** the code under test reads real host state (free disk, SDK paths) that the
|
|
149
|
+
fixture does not fake, and the runner's state differs from the developer's.
|
|
150
|
+
- **Fix:** fake that state in the fixture. Then check the runner itself: a slot below the
|
|
151
|
+
threshold fails the real journey too.
|
|
152
|
+
|
|
153
|
+
### A new journey fails in the commit that adds it
|
|
154
|
+
|
|
155
|
+
- **Signal:** a journey added or changed in this commit fails waiting for a screen (`Select
|
|
156
|
+
your Store`) that the app no longer shows; the screen at failure shows the current app.
|
|
157
|
+
- **Cause:** often the journey was written against the old screen. A product regression
|
|
158
|
+
that only this journey exercises shows the same signal.
|
|
159
|
+
- **Fix:** read the screen at failure and the commit's product diff before choosing. If the
|
|
160
|
+
app shows the intended screen, update the journey; never change product code to match
|
|
161
|
+
a journey.
|
|
162
|
+
|
|
163
|
+
## CI runners
|
|
164
|
+
|
|
165
|
+
### The Android check is cancelled on the exact head
|
|
166
|
+
|
|
167
|
+
- **Signal:** the queue reads the cancelled check as failing.
|
|
168
|
+
- **Cause:** GitHub can deliver one push as two identical `pull_request` events.
|
|
169
|
+
- **Fix:** if Android has its own workflow, key `concurrency.group` on `github.run_id`
|
|
170
|
+
with `cancel-in-progress: false`.
|
|
171
|
+
|
|
172
|
+
### The native build takes ~20 minutes on an 8-CPU slot
|
|
173
|
+
|
|
174
|
+
- **Cause:** Gradle saw every host core.
|
|
175
|
+
- **Fix:** size `--max-workers` from the cgroup quota (`/sys/fs/cgroup/cpu.max`), not
|
|
176
|
+
`nproc`.
|
|
177
|
+
|
|
178
|
+
### Postgres setup hooks time out
|
|
179
|
+
|
|
180
|
+
- **Cause:** durability is on.
|
|
181
|
+
- **Fix:** disable `fsync` and `synchronous_commit` on the disposable service.
|
|
182
|
+
|
|
183
|
+
### The job never starts
|
|
184
|
+
|
|
185
|
+
- **Cause:** no online runner carries the label set.
|
|
186
|
+
- **Fix:** see the `github-actions` runner guide.
|
|
187
|
+
|
|
188
|
+
### `setup-java` or `setup-python` takes 10+ minutes on a new runner slot
|
|
189
|
+
|
|
190
|
+
- **Cause:** the slot's tool cache is empty, so the JDK or Python downloads from the
|
|
191
|
+
internet.
|
|
192
|
+
- **Fix:** seed the runner's `_tool/` directory from a sibling slot with the same image.
|
|
193
|
+
|
|
194
|
+
### A Backend call fails only in CI: the runner lacks a tool the app launches
|
|
195
|
+
|
|
196
|
+
- **Signal:** the journey passes locally but in CI a step that reaches the Backend
|
|
197
|
+
(receipt email, PDF share, export) gets a 5xx, and the backend log names a missing
|
|
198
|
+
program, e.g. `Receipt PDF generation failed: Browser was not found at the configured
|
|
199
|
+
executablePath`.
|
|
200
|
+
- **Cause:** the journey's Backend runs on the runner itself, and the self-hosted runner
|
|
201
|
+
image has no browser (or other app-launched tool). A developer machine does, so it only
|
|
202
|
+
fails in CI.
|
|
203
|
+
- **Fix:** don't install it on the runner, and don't treat it as a product bug. Point the
|
|
204
|
+
app's browser variable (`CHROMIUM_PATH`) at a wrapper that runs the pinned Playwright
|
|
205
|
+
image's browser: `github-actions` → `references/runners.md`, "A host process that needs
|
|
206
|
+
a browser binary". Prove it in CI; Docker Desktop on macOS cannot reach the wrapper's
|
|
207
|
+
host-network port.
|
|
208
|
+
|
|
209
|
+
### A failed run's Metro log is gone
|
|
210
|
+
|
|
211
|
+
- **Cause:** the journey writes raw service logs under the checkout (`test-results/`), and
|
|
212
|
+
the next job's checkout removes them.
|
|
213
|
+
- **Fix:** for a diagnosis, copy the Metro log and a full `adb logcat` to persistent
|
|
214
|
+
storage outside the checkout. Keep them off uploaded artifacts: they are unsanitized.
|
|
215
|
+
|
|
216
|
+
## Confirm a suspected cause
|
|
217
|
+
|
|
218
|
+
Inject the suspected cause on purpose, for example `adb reverse --remove tcp:8081` right
|
|
219
|
+
before the failing step, and check that it reproduces the exact failure signature: the same
|
|
220
|
+
step, error and error count. Then show that the fix passes the same injection. A cause that
|
|
221
|
+
does not reproduce its signature is a guess, and a fix for a guess is not proof.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Android foundation: shell snippets
|
|
2
|
+
|
|
3
|
+
Replace each `<placeholder>` with the repo's real value. Tool shells do not keep variables,
|
|
4
|
+
functions or traps between calls: step 1 writes `.cache/android-env.sh`, which also `cd`s
|
|
5
|
+
into the worktree, and every later block starts by sourcing it by absolute path, and steps 6–8 run as one command through the bundled
|
|
6
|
+
`scripts/device-run.sh`.
|
|
7
|
+
|
|
8
|
+
## 1. Checkout and environment
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
git fetch origin main
|
|
13
|
+
git worktree add -b <new-branch> ../<repo>-android-setup origin/main
|
|
14
|
+
cd ../<repo>-android-setup
|
|
15
|
+
git rev-parse HEAD
|
|
16
|
+
mkdir -p .cache
|
|
17
|
+
{ echo 'set -euo pipefail'; printf 'cd %q\n' "$PWD"; } > .cache/android-env.sh
|
|
18
|
+
cat >> .cache/android-env.sh <<'ENV'
|
|
19
|
+
|
|
20
|
+
# Repo-specific names, read from the repo's journey wrapper and device harness.
|
|
21
|
+
export APP_FILTER=<android-workspace-package> # pnpm --filter target
|
|
22
|
+
export DEVICE_PYTHON_DIR=<venv-dir-the-wrapper-reads> # e.g. the default in the wrapper
|
|
23
|
+
export DB_NAME_PREFIX=<db-prefix-the-harness-accepts> # the harness rejects other names
|
|
24
|
+
export DB_URL_VAR=<harness-admin-url-variable> # e.g. SHARD_ADMIN_URL
|
|
25
|
+
export DB_NAME_VAR=<harness-db-name-variable> # e.g. SHARD_DB_NAME
|
|
26
|
+
|
|
27
|
+
# Host paths. Example values are for Apple Silicon with Android Studio.
|
|
28
|
+
export JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
|
|
29
|
+
export ANDROID_HOME="$HOME/Library/Android/sdk"
|
|
30
|
+
export ANDROID_SDK_ROOT="$ANDROID_HOME"
|
|
31
|
+
export SOURCE_AVD="$HOME/.android/avd/<installed-avd>.avd"
|
|
32
|
+
export SEED_GRADLE_HOME="$HOME/.gradle"
|
|
33
|
+
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/platform-tools:$PATH"
|
|
34
|
+
|
|
35
|
+
# Private caches.
|
|
36
|
+
export GRADLE_USER_HOME="$PWD/.cache/gradle"
|
|
37
|
+
export ANDROID_USER_HOME="$PWD/.cache/android-user"
|
|
38
|
+
export ANDROID_AVD_HOME="$PWD/.cache/android-avd"
|
|
39
|
+
export TMPDIR="$PWD/.cache/tmp"
|
|
40
|
+
export npm_config_cache="$PWD/.cache/npm"
|
|
41
|
+
export npm_config_devdir="$PWD/.cache/node-gyp"
|
|
42
|
+
export PNPM_CONFIG_STORE_DIR="$PWD/.cache/pnpm-store"
|
|
43
|
+
export PNPM_CONFIG_CACHE_DIR="$PWD/.cache/pnpm"
|
|
44
|
+
case "${JAVA_TOOL_OPTIONS:-}" in *java.io.tmpdir*) ;; *)
|
|
45
|
+
export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS:+$JAVA_TOOL_OPTIONS }-Djava.io.tmpdir=$TMPDIR" ;; esac
|
|
46
|
+
|
|
47
|
+
# Run identifiers: an even console port in 5554-5584 (adb scans only that range),
|
|
48
|
+
# and backend/Metro ports under the names the journey wrapper reads.
|
|
49
|
+
export SETUP_AVD=<new-unique-avd-name>
|
|
50
|
+
export EMULATOR_PORT=<even-port-5554-5584>
|
|
51
|
+
export ANDROID_BACKEND_PORT=<free-port>
|
|
52
|
+
export ANDROID_METRO_PORT=<free-port>
|
|
53
|
+
ENV
|
|
54
|
+
source .cache/android-env.sh
|
|
55
|
+
mkdir -p "$TMPDIR" "$npm_config_cache" "$npm_config_devdir" \
|
|
56
|
+
"$ANDROID_USER_HOME" "$ANDROID_AVD_HOME" .cache/logs
|
|
57
|
+
|
|
58
|
+
node --version; pnpm --version; java -version; python3 --version
|
|
59
|
+
adb version; "$ANDROID_HOME/emulator/emulator" -version
|
|
60
|
+
# Versions come from the repo's native config and CI preflight.
|
|
61
|
+
for component in platforms/android-<api> build-tools/<build-tools> ndk/<ndk> cmake/<cmake>; do
|
|
62
|
+
test -d "$ANDROID_HOME/$component" || { echo "Missing SDK: $component" >&2; exit 1; }
|
|
63
|
+
done
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If the wrapper reads its port or Python variables under other names, export those names in
|
|
67
|
+
`android-env.sh` instead.
|
|
68
|
+
|
|
69
|
+
## 2. Install and check
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
source <worktree>/.cache/android-env.sh
|
|
73
|
+
pnpm install --frozen-lockfile --store-dir "$PWD/.cache/pnpm-store"
|
|
74
|
+
pnpm --filter "$APP_FILTER" test
|
|
75
|
+
pnpm --filter "$APP_FILTER" typecheck
|
|
76
|
+
EXPO_PUBLIC_API_URL=https://app.invalid \
|
|
77
|
+
pnpm --filter "$APP_FILTER" exec expo export --platform android
|
|
78
|
+
python3 -m venv "$DEVICE_PYTHON_DIR"
|
|
79
|
+
"$DEVICE_PYTHON_DIR/bin/python3" -m pip install uiautomator2==<harness-pinned-version>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 3. Gradle dependencies (pick one)
|
|
83
|
+
|
|
84
|
+
Seed from a trusted Gradle home:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
source <worktree>/.cache/android-env.sh
|
|
88
|
+
mkdir -p "$GRADLE_USER_HOME/caches/modules-2/files-2.1"
|
|
89
|
+
rsync -r --ignore-existing \
|
|
90
|
+
--exclude='*.lock' --exclude='*.lck' --exclude='*.tmp' \
|
|
91
|
+
"$SEED_GRADLE_HOME/caches/modules-2/files-2.1/" \
|
|
92
|
+
"$GRADLE_USER_HOME/caches/modules-2/files-2.1/"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Or wire a trusted Maven proxy into the private Gradle home. Append the exports to
|
|
96
|
+
`android-env.sh` so the build in step 4 sees them. Route every repository the build uses,
|
|
97
|
+
JitPack included; a route left unset goes straight upstream.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
source <worktree>/.cache/android-env.sh
|
|
101
|
+
cat >> "$PWD/.cache/android-env.sh" <<'ENV'
|
|
102
|
+
export GRADLE_MAVEN_REPOSITORY=<proxy>/maven/
|
|
103
|
+
export GRADLE_GOOGLE_REPOSITORY=<proxy>/google-maven/
|
|
104
|
+
export GRADLE_PLUGIN_REPOSITORY=<proxy>/gradle-plugins/
|
|
105
|
+
export GRADLE_JITPACK_REPOSITORY=<proxy>/jitpack/
|
|
106
|
+
ENV
|
|
107
|
+
curl --fail --silent --show-error --max-time 10 <proxy-health-url>
|
|
108
|
+
install -d "$GRADLE_USER_HOME/init.d"
|
|
109
|
+
install -m 0644 <path/to/proxy.init.gradle> "$GRADLE_USER_HOME/init.d/proxy.init.gradle"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 4. Build
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
source <worktree>/.cache/android-env.sh
|
|
116
|
+
pnpm build:android --max-workers=2 -Dorg.gradle.parallel=false \
|
|
117
|
+
-Pandroid.builder.sdkDownload=false --console=plain --info \
|
|
118
|
+
2>&1 | tee .cache/logs/gradle.log
|
|
119
|
+
APK=<path/to/app/build/outputs/apk/debug/app-debug.apk>
|
|
120
|
+
shasum -a 256 "$APK" # sha256sum on Linux
|
|
121
|
+
unzip -l "$APK" | grep -E 'lib/[^/]+/libreactnative\.so'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 5. Owned emulator
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
source <worktree>/.cache/android-env.sh
|
|
128
|
+
test -f "$SOURCE_AVD/config.ini"
|
|
129
|
+
test ! -e "$ANDROID_AVD_HOME/$SETUP_AVD.ini"
|
|
130
|
+
test ! -e "$ANDROID_AVD_HOME/$SETUP_AVD.avd"
|
|
131
|
+
grep '^image.sysdir.1' "$SOURCE_AVD/config.ini" # must be an installed, host-compatible image
|
|
132
|
+
mkdir "$ANDROID_AVD_HOME/$SETUP_AVD.avd"
|
|
133
|
+
# Copy without the source's RAM size and give the guest 4 GB (gotchas: adb transport drops).
|
|
134
|
+
grep -Ev '^hw\.ramSize[[:space:]]*=' "$SOURCE_AVD/config.ini" > "$ANDROID_AVD_HOME/$SETUP_AVD.avd/config.ini"
|
|
135
|
+
echo 'hw.ramSize=4096' >> "$ANDROID_AVD_HOME/$SETUP_AVD.avd/config.ini"
|
|
136
|
+
printf 'avd.ini.encoding=UTF-8\npath=%s\ntarget=android-<api>\n' \
|
|
137
|
+
"$ANDROID_AVD_HOME/$SETUP_AVD.avd" > "$ANDROID_AVD_HOME/$SETUP_AVD.ini"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 6–8. Cleanup, resources and journey: one command
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
source <worktree>/.cache/android-env.sh
|
|
144
|
+
bash <skill-base-dir>/scripts/device-run.sh \
|
|
145
|
+
--drop node <path/to/device-harness.mjs> drop \
|
|
146
|
+
-- bash <path/to/foundation-journey-wrapper.sh>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Pass each command as separate words, not as one quoted string. The script:
|
|
150
|
+
|
|
151
|
+
1. Registers the cleanup trap before anything starts.
|
|
152
|
+
2. Refuses an emulator port outside 5554–5584 and any busy port.
|
|
153
|
+
3. Starts the ADB server, then the emulator (its PID recorded), then `postgres` with
|
|
154
|
+
`--cidfile` on a random loopback port. Override the image with `POSTGRES_IMAGE`.
|
|
155
|
+
4. Waits for `sys.boot_completed=1` and `pg_isready`. Every command has a 30-second limit
|
|
156
|
+
(`BOUNDED_SECONDS`) that kills the command's whole process group; exit 124 is terminal.
|
|
157
|
+
5. Exports `$DB_URL_VAR`, `$DB_NAME_VAR` (`$DB_NAME_PREFIX` plus a unique suffix) and
|
|
158
|
+
`ANDROID_EMULATOR_SERIAL`, then runs the journey.
|
|
159
|
+
6. Drops the database, stops the emulator PID (`TERM`, then `KILL` after 10 seconds),
|
|
160
|
+
removes the container by its CID, and prints `original_stage_exit=<n> cleanup_exit=<n>`.
|
|
161
|
+
It exits with the journey's status if the journey failed, else the cleanup status.
|
|
162
|
+
|
|
163
|
+
The journey stops its own backend and Metro children. Capture the command's exit status and
|
|
164
|
+
the last output line for the evidence record.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
9
|
+
const WEEK_MS = 7 * DAY_MS;
|
|
10
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
function readJson(path, fallback = {}) {
|
|
13
|
+
try { return JSON.parse(readFileSync(path, 'utf8')); } catch { return fallback; }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function frontmatterValue(text, key) {
|
|
17
|
+
const frontmatter = /^---\n([\s\S]*?)\n---/.exec(text)?.[1] ?? '';
|
|
18
|
+
const match = new RegExp('^' + key + ':\\s*([^\\n]+)$', 'm').exec(frontmatter);
|
|
19
|
+
return match?.[1].trim().replace(/^['"]|['"]$/g, '') ?? null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function repositoryOf(source) {
|
|
23
|
+
const value = String(source ?? '').trim();
|
|
24
|
+
const match = /^(?:git@github\.com:|https:\/\/github\.com\/)?([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+?)(?:\.git)?$/.exec(value);
|
|
25
|
+
return match?.[1] ?? null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function stableVersion(value) {
|
|
29
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)$/.exec(String(value ?? '').trim());
|
|
30
|
+
return match ? match.slice(1).map(Number) : null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function newer(left, right) {
|
|
34
|
+
for (let index = 0; index < 3; index += 1) {
|
|
35
|
+
if (left[index] !== right[index]) return left[index] > right[index];
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function writeCache(path, value) {
|
|
41
|
+
try {
|
|
42
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
43
|
+
writeFileSync(path, JSON.stringify(value));
|
|
44
|
+
} catch { /* A read-only cache must not block skill use. */ }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function main(now = Date.now()) {
|
|
48
|
+
if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
|
|
49
|
+
const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
|
|
50
|
+
const name = frontmatterValue(skill, 'name');
|
|
51
|
+
const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
|
|
52
|
+
if (!name || !localVersion) return;
|
|
53
|
+
|
|
54
|
+
const lock = readJson(join(process.env.HOME || homedir(), '.agents', '.skill-lock.json'));
|
|
55
|
+
const entry = lock.skills?.[name];
|
|
56
|
+
const repository = repositoryOf(entry?.sourceUrl || entry?.source);
|
|
57
|
+
if (!repository) return;
|
|
58
|
+
|
|
59
|
+
const cacheRoot = process.env.XDG_CACHE_HOME || join(process.env.HOME || homedir(), '.cache');
|
|
60
|
+
const cachePath = join(cacheRoot, '1aboveio-skills', 'release-check.json');
|
|
61
|
+
const all = readJson(cachePath);
|
|
62
|
+
const cache = all[repository] && typeof all[repository] === 'object' ? all[repository] : {};
|
|
63
|
+
|
|
64
|
+
if (!cache.lastCheck || now - cache.lastCheck >= DAY_MS) {
|
|
65
|
+
const result = spawnSync('gh', ['api', 'repos/' + repository + '/releases/latest', '--jq', '.tag_name'], {
|
|
66
|
+
encoding: 'utf8',
|
|
67
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
68
|
+
timeout: 1500,
|
|
69
|
+
});
|
|
70
|
+
cache.lastCheck = now;
|
|
71
|
+
if (result.status === 0 && stableVersion(result.stdout)) cache.latestTag = result.stdout.trim();
|
|
72
|
+
else delete cache.latestTag;
|
|
73
|
+
all[repository] = cache;
|
|
74
|
+
writeCache(cachePath, all);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const latestVersion = stableVersion(cache.latestTag);
|
|
78
|
+
if (!latestVersion || !newer(latestVersion, localVersion)) return;
|
|
79
|
+
if (cache.notifiedTag === cache.latestTag && cache.notifiedAt && now - cache.notifiedAt < WEEK_MS) return;
|
|
80
|
+
|
|
81
|
+
cache.notifiedTag = cache.latestTag;
|
|
82
|
+
cache.notifiedAt = now;
|
|
83
|
+
all[repository] = cache;
|
|
84
|
+
writeCache(cachePath, all);
|
|
85
|
+
const command = `npx skills@1.5.23 add '${repository}#${cache.latestTag}' --global --agent universal claude-code --skill ${name} --yes`;
|
|
86
|
+
process.stdout.write(
|
|
87
|
+
`UPDATE_AVAILABLE: A newer 1AboveIO skills release (${cache.latestTag}) is available; this skill is `
|
|
88
|
+
+ `v${localVersion.join('.')}. Ask once whether to refresh ${name}. On approval run \`${command}\`. `
|
|
89
|
+
+ 'The refreshed instructions apply next session. Either way, continue the current task and do not ask again this session.\n',
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
try { main(); } catch { /* Update checks are advisory and always fail silent. */ }
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Boot an owned emulator and a disposable PostgreSQL, run the device journey, and
|
|
3
|
+
# clean up only what this run started. Run it as ONE command: an agent's tool
|
|
4
|
+
# shell does not keep variables, functions or traps between calls.
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# device-run.sh --drop <db-drop command...> -- <journey command...>
|
|
8
|
+
#
|
|
9
|
+
# Required environment:
|
|
10
|
+
# ANDROID_HOME SDK root (emulator/emulator)
|
|
11
|
+
# SETUP_AVD private AVD name under $ANDROID_AVD_HOME
|
|
12
|
+
# EMULATOR_PORT even console port, 5554-5584 (adb scans only this range)
|
|
13
|
+
# ANDROID_BACKEND_PORT backend port the journey uses
|
|
14
|
+
# ANDROID_METRO_PORT Metro port the journey uses
|
|
15
|
+
# DB_NAME_PREFIX database-name prefix the harness accepts, e.g. app_e2e_
|
|
16
|
+
# Optional environment:
|
|
17
|
+
# POSTGRES_IMAGE (postgres:17) DB_URL_VAR (SHARD_ADMIN_URL) DB_NAME_VAR (SHARD_DB_NAME)
|
|
18
|
+
# LOG_DIR (.cache/logs) BOUNDED_SECONDS (30) BOOT_ATTEMPTS (60) KILL_GRACE_SECONDS (10)
|
|
19
|
+
#
|
|
20
|
+
# Exports ANDROID_EMULATOR_SERIAL, $DB_URL_VAR and $DB_NAME_VAR to both commands.
|
|
21
|
+
# Prints `original_stage_exit=<n> cleanup_exit=<n>` last and exits with the
|
|
22
|
+
# stage's status when it failed, else the cleanup status.
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
drop_cmd=()
|
|
26
|
+
journey_cmd=()
|
|
27
|
+
if test "${1:-}" != --drop; then
|
|
28
|
+
echo "usage: device-run.sh --drop <cmd...> -- <journey cmd...>" >&2
|
|
29
|
+
exit 2
|
|
30
|
+
fi
|
|
31
|
+
shift
|
|
32
|
+
while test $# -gt 0 && test "$1" != --; do drop_cmd+=("$1"); shift; done
|
|
33
|
+
if test $# -eq 0; then echo "missing -- before the journey command" >&2; exit 2; fi
|
|
34
|
+
shift
|
|
35
|
+
journey_cmd=("$@")
|
|
36
|
+
if test ${#drop_cmd[@]} -eq 0 || test ${#journey_cmd[@]} -eq 0; then
|
|
37
|
+
echo "both the drop command and the journey command are required" >&2
|
|
38
|
+
exit 2
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
: "${ANDROID_HOME:?}" "${SETUP_AVD:?}" "${EMULATOR_PORT:?}"
|
|
42
|
+
: "${ANDROID_BACKEND_PORT:?}" "${ANDROID_METRO_PORT:?}" "${DB_NAME_PREFIX:?}"
|
|
43
|
+
POSTGRES_IMAGE="${POSTGRES_IMAGE:-postgres:17}"
|
|
44
|
+
DB_URL_VAR="${DB_URL_VAR:-SHARD_ADMIN_URL}"
|
|
45
|
+
DB_NAME_VAR="${DB_NAME_VAR:-SHARD_DB_NAME}"
|
|
46
|
+
LOG_DIR="${LOG_DIR:-.cache/logs}"
|
|
47
|
+
BOUNDED_SECONDS="${BOUNDED_SECONDS:-30}"
|
|
48
|
+
BOOT_ATTEMPTS="${BOOT_ATTEMPTS:-60}"
|
|
49
|
+
KILL_GRACE_SECONDS="${KILL_GRACE_SECONDS:-10}"
|
|
50
|
+
|
|
51
|
+
if ! [[ "$EMULATOR_PORT" =~ ^[0-9]+$ ]] || (( EMULATOR_PORT < 5554 || EMULATOR_PORT > 5584 || EMULATOR_PORT % 2 )); then
|
|
52
|
+
echo "EMULATOR_PORT must be an even port in 5554-5584: $EMULATOR_PORT" >&2
|
|
53
|
+
exit 2
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
mkdir -p "$LOG_DIR"
|
|
57
|
+
run_dir="$(mktemp -d "${TMPDIR:-/tmp}/android-device-run.XXXXXX")"
|
|
58
|
+
emulator_pid=""
|
|
59
|
+
db_ready=""
|
|
60
|
+
export ANDROID_EMULATOR_SERIAL="emulator-$EMULATOR_PORT"
|
|
61
|
+
|
|
62
|
+
bounded() {
|
|
63
|
+
# Kill the whole process group on timeout: a surviving grandchild would hold
|
|
64
|
+
# the output pipe open and stall the caller past the deadline.
|
|
65
|
+
python3 -c 'import os, signal, subprocess, sys
|
|
66
|
+
limit = float(sys.argv[1])
|
|
67
|
+
child = subprocess.Popen(sys.argv[2:], start_new_session=True)
|
|
68
|
+
try:
|
|
69
|
+
sys.exit(child.wait(timeout=limit))
|
|
70
|
+
except subprocess.TimeoutExpired:
|
|
71
|
+
os.killpg(child.pid, signal.SIGKILL)
|
|
72
|
+
child.wait()
|
|
73
|
+
print("Command exceeded %s seconds: %s" % (sys.argv[1], " ".join(sys.argv[2:])), file=sys.stderr)
|
|
74
|
+
sys.exit(124)' "$BOUNDED_SECONDS" "$@"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
cleanup() {
|
|
78
|
+
original_status=$?
|
|
79
|
+
trap - EXIT INT TERM
|
|
80
|
+
set +e
|
|
81
|
+
cleanup_status=0
|
|
82
|
+
if test -n "$db_ready"; then
|
|
83
|
+
bounded "${drop_cmd[@]}" || cleanup_status=1
|
|
84
|
+
fi
|
|
85
|
+
if test -n "$emulator_pid"; then
|
|
86
|
+
if kill -0 "$emulator_pid" 2>/dev/null; then
|
|
87
|
+
kill -TERM "$emulator_pid" || cleanup_status=1
|
|
88
|
+
fi
|
|
89
|
+
for _ in $(seq 1 "$KILL_GRACE_SECONDS"); do
|
|
90
|
+
kill -0 "$emulator_pid" 2>/dev/null || break
|
|
91
|
+
sleep 1
|
|
92
|
+
done
|
|
93
|
+
if kill -0 "$emulator_pid" 2>/dev/null; then
|
|
94
|
+
cleanup_status=1
|
|
95
|
+
kill -KILL "$emulator_pid"
|
|
96
|
+
sleep 1
|
|
97
|
+
fi
|
|
98
|
+
if kill -0 "$emulator_pid" 2>/dev/null; then
|
|
99
|
+
cleanup_status=1
|
|
100
|
+
else
|
|
101
|
+
wait "$emulator_pid"
|
|
102
|
+
emulator_status=$?
|
|
103
|
+
# 0 = clean exit; 143 = ended by our TERM. A KILL was already counted above.
|
|
104
|
+
case "$emulator_status" in 0|143) ;; *) cleanup_status=1 ;; esac
|
|
105
|
+
fi
|
|
106
|
+
fi
|
|
107
|
+
if test -s "$run_dir/postgres.cid"; then
|
|
108
|
+
container_id="$(< "$run_dir/postgres.cid")"
|
|
109
|
+
bounded docker rm --force "$container_id" >/dev/null || cleanup_status=1
|
|
110
|
+
remaining="$(bounded docker ps -a --no-trunc --filter "id=$container_id" --format '{{.ID}}')" || cleanup_status=1
|
|
111
|
+
test -z "$remaining" || cleanup_status=1
|
|
112
|
+
fi
|
|
113
|
+
printf 'original_stage_exit=%s cleanup_exit=%s\n' "$original_status" "$cleanup_status"
|
|
114
|
+
if test "$original_status" -ne 0; then exit "$original_status"; fi
|
|
115
|
+
exit "$cleanup_status"
|
|
116
|
+
}
|
|
117
|
+
trap cleanup EXIT
|
|
118
|
+
trap 'exit 130' INT
|
|
119
|
+
trap 'exit 143' TERM
|
|
120
|
+
|
|
121
|
+
# Every port this run listens on or dials must be free before anything starts.
|
|
122
|
+
python3 -c 'import socket, sys
|
|
123
|
+
for port in map(int, sys.argv[1:]):
|
|
124
|
+
with socket.socket() as probe:
|
|
125
|
+
probe.bind(("127.0.0.1", port))' \
|
|
126
|
+
"$EMULATOR_PORT" "$((EMULATOR_PORT + 1))" "$ANDROID_BACKEND_PORT" "$ANDROID_METRO_PORT"
|
|
127
|
+
|
|
128
|
+
# Start the ADB server first so the emulator registers with it on boot.
|
|
129
|
+
bounded adb start-server
|
|
130
|
+
|
|
131
|
+
# -memory 4096 overrides the AVD's hw.ramSize, so a reused 2 GB AVD cannot starve the
|
|
132
|
+
# guest kernel's vsock allocations and drop adb mid-journey (references/gotchas.md).
|
|
133
|
+
"$ANDROID_HOME/emulator/emulator" -avd "$SETUP_AVD" -port "$EMULATOR_PORT" -memory 4096 \
|
|
134
|
+
-no-window -no-audio -no-snapshot -gpu swiftshader_indirect -accel on \
|
|
135
|
+
> "$LOG_DIR/emulator.log" 2>&1 &
|
|
136
|
+
emulator_pid=$!
|
|
137
|
+
|
|
138
|
+
container_name="android-device-run-$(date +%s)-$$"
|
|
139
|
+
bounded docker run --detach --name "$container_name" --cidfile "$run_dir/postgres.cid" \
|
|
140
|
+
--publish 127.0.0.1::5432 --env POSTGRES_USER=postgres \
|
|
141
|
+
--env POSTGRES_PASSWORD=postgres --env POSTGRES_DB=postgres "$POSTGRES_IMAGE" >/dev/null
|
|
142
|
+
db_port="$(bounded docker port "$container_name" 5432/tcp | head -1 | awk -F: '{print $NF}')"
|
|
143
|
+
test -n "$db_port"
|
|
144
|
+
|
|
145
|
+
boot_state=""
|
|
146
|
+
for _ in $(seq 1 "$BOOT_ATTEMPTS"); do
|
|
147
|
+
if boot_state="$(bounded adb -s "$ANDROID_EMULATOR_SERIAL" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')"; then
|
|
148
|
+
if test "$boot_state" = 1; then break; fi
|
|
149
|
+
else
|
|
150
|
+
probe_status=$?
|
|
151
|
+
# A stalled command is terminal, not "not ready yet".
|
|
152
|
+
if test "$probe_status" -eq 124; then exit 124; fi
|
|
153
|
+
fi
|
|
154
|
+
sleep 2
|
|
155
|
+
done
|
|
156
|
+
if test "$boot_state" != 1; then echo "emulator did not finish booting" >&2; exit 1; fi
|
|
157
|
+
|
|
158
|
+
pg_ready=""
|
|
159
|
+
for _ in $(seq 1 30); do
|
|
160
|
+
if bounded docker exec "$container_name" pg_isready -U postgres >/dev/null; then
|
|
161
|
+
pg_ready=1
|
|
162
|
+
break
|
|
163
|
+
else
|
|
164
|
+
probe_status=$?
|
|
165
|
+
if test "$probe_status" -eq 124; then exit 124; fi
|
|
166
|
+
fi
|
|
167
|
+
sleep 1
|
|
168
|
+
done
|
|
169
|
+
if test -z "$pg_ready"; then echo "PostgreSQL did not become ready" >&2; exit 1; fi
|
|
170
|
+
|
|
171
|
+
# The password belongs only to this disposable loopback container.
|
|
172
|
+
export "$DB_URL_VAR=postgresql://postgres:postgres@127.0.0.1:$db_port/postgres"
|
|
173
|
+
export "$DB_NAME_VAR=${DB_NAME_PREFIX}$(date +%s)_$$"
|
|
174
|
+
db_ready=1
|
|
175
|
+
|
|
176
|
+
"${journey_cmd[@]}"
|