@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
package/README.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @1aboveio/skills
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Every 1aboveio skill package in one: install once, then choose which packages Pi loads with npx @1aboveio/skills select.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pi install npm:@1aboveio/skills
|
|
9
|
+
npx @1aboveio/skills # choose packages interactively
|
|
10
|
+
npx @1aboveio/skills engineering cicd # or name them
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The command writes a Pi package filter (`skills/<package>/**`) to `~/.pi/agent/settings.json`
|
|
14
|
+
(`--local`: the project's `.pi/settings.json`), adds core when a chosen package uses it, and
|
|
15
|
+
hides Skills CLI copies of the loaded skills from Pi so these versions win. Until you run it,
|
|
16
|
+
Pi loads every package. `pi config` toggles single skills.
|
|
17
|
+
|
|
18
|
+
Each package also publishes on its own; install either this bundle or the packages, not both.
|
|
19
|
+
|
|
20
|
+
## Packages
|
|
21
|
+
|
|
22
|
+
| Package | Also published as | Skills |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `core` | `@1aboveio/core-skills` | distill-writing, doc-to-md, editorial-review, house-style, polish-cn, reg-parser, terminology, write-doc |
|
|
25
|
+
| `engineering` | `@1aboveio/engineering-skills` | better-review, e2e-test, engineering-runtime, ensure-coverage, golden-path, harness-runtime, resolve-issues, resolve-release, rush-issues, rush-release, test-quality |
|
|
26
|
+
| `cicd` | `@1aboveio/cicd-skills` | cloud-build, cloud-debug, cloud-deploy, docker, github-actions, github-flow, google-cloud, mergify, podman |
|
|
27
|
+
| `app-dev` | `@1aboveio/app-dev-skills` | airflow, android-foundation, app-debug, better-auth, data-catalog, ios-foundation, monorepo, nextjs-fullstack, prisma-setup, pyspark, python-backend, shadcn, zod-v4 |
|
|
28
|
+
| `risk-compliance` | `@1aboveio/risk-compliance-skills` | compliance-audit, contract-compare, contract-review, doc-authenticity, fraud-analysis, payment-analysis, report-writing, similar-domain, tld-detection |
|
|
29
|
+
| `content` | `@1aboveio/content-skills` | article-review, article-to-image, flowchart-svg, image-gen, mermaid, wechat-article-writer, wechat-publisher, wechat-search, xai-search |
|
|
30
|
+
|
|
31
|
+
Generated from [1aboveio/ai](https://github.com/1aboveio/ai) `skills/distribution/packages/`. Do not edit.
|
package/bin/cli.mjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Entry point of `npx @1aboveio/skills`; ships as bin/cli.mjs beside bin/select-core.mjs.
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
import { main } from './select-core.mjs';
|
|
6
|
+
|
|
7
|
+
const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
8
|
+
main(process.argv.slice(2), { meta: { name: manifest.name, ...manifest.skillsPackage } }).then(
|
|
9
|
+
(code) => process.exit(code),
|
|
10
|
+
(error) => {
|
|
11
|
+
console.error(error.message);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
},
|
|
14
|
+
);
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// The select command of @1aboveio/skills: choose which of its packages Pi loads.
|
|
2
|
+
//
|
|
3
|
+
// The package ships every skill under skills/<package-id>/<skill>/, so a selection is one Pi
|
|
4
|
+
// package filter per package id (`skills/<id>/**`); a skill added to a selected package later loads
|
|
5
|
+
// on the next `pi update` without selecting again. Selecting a package that uses core skills adds
|
|
6
|
+
// core. In personal settings it also hides the Skills CLI copies of selected skills
|
|
7
|
+
// (~/.agents/skills/<name> installed from 1aboveio/ai): Pi keeps the first skill of a name and
|
|
8
|
+
// ranks package skills last, so those copies would otherwise win. Claude Code still reads them.
|
|
9
|
+
//
|
|
10
|
+
// Ships in the package as bin/select-core.mjs, an import-only core run by bin/cli.mjs; it has no
|
|
11
|
+
// dependencies.
|
|
12
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import { dirname, join, resolve } from 'node:path';
|
|
15
|
+
import { createInterface } from 'node:readline/promises';
|
|
16
|
+
|
|
17
|
+
const USAGE = `Usage: npx @1aboveio/skills [select] [<package>... | --all] [--local] [--dry-run]
|
|
18
|
+
npx @1aboveio/skills list
|
|
19
|
+
|
|
20
|
+
(no arguments) choose interactively which packages Pi loads
|
|
21
|
+
<id>... load only these packages (core is added when they need it)
|
|
22
|
+
--all load every package
|
|
23
|
+
--local write the project's .pi/settings.json instead of ~/.pi/agent/settings.json
|
|
24
|
+
--dry-run print the settings change without writing it
|
|
25
|
+
list print the packages and their skills`;
|
|
26
|
+
|
|
27
|
+
// select is the default command, so a bare `npx @1aboveio/skills` asks interactively.
|
|
28
|
+
export function parseArgs(argv) {
|
|
29
|
+
const [command, ...rest] = ['select', 'list'].includes(argv[0]) ? argv : ['select', ...argv];
|
|
30
|
+
const options = { command, ids: [], all: false, local: false, dryRun: false };
|
|
31
|
+
for (const arg of rest) {
|
|
32
|
+
if (arg === '--all') options.all = true;
|
|
33
|
+
else if (arg === '--local') options.local = true;
|
|
34
|
+
else if (arg === '--dry-run') options.dryRun = true;
|
|
35
|
+
else if (arg.startsWith('-')) throw new Error(`Unknown option: ${arg}\n\n${USAGE}`);
|
|
36
|
+
else options.ids.push(...arg.split(',').filter(Boolean));
|
|
37
|
+
}
|
|
38
|
+
if (options.all && options.ids.length) throw new Error('Pass package ids or --all, not both.');
|
|
39
|
+
return options;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function filterFor(id) {
|
|
43
|
+
return `skills/${id}/**`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function matchesSource(source, name) {
|
|
47
|
+
return source === `npm:${name}` || source.startsWith(`npm:${name}@`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function entrySource(entry) {
|
|
51
|
+
return typeof entry === 'string' ? entry : entry?.source;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The package ids an existing settings entry loads; every id when it has no skills filter.
|
|
55
|
+
export function currentSelection(entry, meta) {
|
|
56
|
+
const all = meta.groups.map((group) => group.id);
|
|
57
|
+
if (typeof entry === 'string' || !Array.isArray(entry.skills)) return all;
|
|
58
|
+
return all.filter((id) => entry.skills.includes(filterFor(id)));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// The ids to load, in package order, with core added when a chosen package needs it.
|
|
62
|
+
export function planSelection(meta, ids) {
|
|
63
|
+
const known = new Map(meta.groups.map((group) => [group.id, group]));
|
|
64
|
+
const unknown = ids.filter((id) => !known.has(id));
|
|
65
|
+
if (unknown.length) throw new Error(`Unknown package: ${unknown.join(', ')}. Packages: ${[...known.keys()].join(', ')}`);
|
|
66
|
+
if (!ids.length) throw new Error('Select at least one package.');
|
|
67
|
+
const chosen = new Set(ids);
|
|
68
|
+
const added = [];
|
|
69
|
+
if (!chosen.has(meta.core) && ids.some((id) => known.get(id).needsCore)) {
|
|
70
|
+
chosen.add(meta.core);
|
|
71
|
+
added.push(meta.core);
|
|
72
|
+
}
|
|
73
|
+
return { ids: meta.groups.map((group) => group.id).filter((id) => chosen.has(id)), added };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Skills CLI copies of these skills: ~/.agents/skills/<name> whose lock entry names 1aboveio/ai.
|
|
77
|
+
export function skillsCliCopies(home, names) {
|
|
78
|
+
const lockPath = join(home, '.agents/.skill-lock.json');
|
|
79
|
+
if (!existsSync(lockPath)) return [];
|
|
80
|
+
const lock = JSON.parse(readFileSync(lockPath, 'utf8')).skills ?? {};
|
|
81
|
+
return names.filter((name) => lock[name]?.source === '1aboveio/ai' && existsSync(join(home, '.agents/skills', name, 'SKILL.md')));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Returns { settings, notes } with the package entry narrowed to `ids` and, when `hide` is given
|
|
85
|
+
// (personal settings), the Skills CLI copies of the loaded skills hidden from Pi. Hide entries this
|
|
86
|
+
// command wrote before are recomputed, so deselecting a package shows its copies again.
|
|
87
|
+
export function applySelection(settings, meta, ids, { home, hide } = {}) {
|
|
88
|
+
const next = structuredClone(settings);
|
|
89
|
+
const packages = next.packages ?? [];
|
|
90
|
+
const index = packages.findIndex((entry) => matchesSource(entrySource(entry) ?? '', meta.name));
|
|
91
|
+
if (index < 0) throw new Error(`${meta.name} is not installed here. Run: pi install npm:${meta.name}${next.packages ? '' : ' (or pass --local for a project install)'}`);
|
|
92
|
+
const source = entrySource(packages[index]);
|
|
93
|
+
const everything = ids.length === meta.groups.length;
|
|
94
|
+
if (typeof packages[index] === 'string') packages[index] = everything ? source : { source, skills: ids.map(filterFor) };
|
|
95
|
+
else if (everything) delete packages[index].skills;
|
|
96
|
+
else packages[index].skills = ids.map(filterFor);
|
|
97
|
+
if (typeof packages[index] === 'object' && Object.keys(packages[index]).length === 1) packages[index] = source;
|
|
98
|
+
|
|
99
|
+
const notes = [];
|
|
100
|
+
const domain = packages.map(entrySource).filter((s) => s && meta.groups.some((group) => matchesSource(s, group.packageName)));
|
|
101
|
+
if (domain.length) notes.push(`Also installed: ${domain.join(', ')}. Their skills duplicate this package's; remove them with pi remove, or Pi keeps whichever loads first.`);
|
|
102
|
+
|
|
103
|
+
if (hide) {
|
|
104
|
+
const agentsSkills = join(home, '.agents/skills');
|
|
105
|
+
const ours = new Set(meta.groups.flatMap((group) => group.skills).map((name) => `-${join(agentsSkills, name)}`));
|
|
106
|
+
const kept = (next.skills ?? []).filter((entry) => !ours.has(entry));
|
|
107
|
+
const loaded = meta.groups.filter((group) => ids.includes(group.id)).flatMap((group) => group.skills);
|
|
108
|
+
const copies = skillsCliCopies(home, loaded);
|
|
109
|
+
const skills = [...kept, ...copies.map((name) => `-${join(agentsSkills, name)}`)];
|
|
110
|
+
if (skills.length) next.skills = skills;
|
|
111
|
+
else delete next.skills;
|
|
112
|
+
if (copies.length) notes.push(`Hid ${copies.length} Skills CLI cop${copies.length === 1 ? 'y' : 'ies'} in ${agentsSkills} from Pi so this package's versions load; Claude Code still uses them.`);
|
|
113
|
+
}
|
|
114
|
+
return { settings: next, notes };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function settingsPath({ local, home, cwd }) {
|
|
118
|
+
return local ? join(cwd, '.pi/settings.json') : join(process.env.PI_CODING_AGENT_DIR ? resolve(process.env.PI_CODING_AGENT_DIR) : join(home, '.pi/agent'), 'settings.json');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function describe(meta, ids) {
|
|
122
|
+
const mark = (on) => `[${on ? 'x' : ' '}]`;
|
|
123
|
+
const total = meta.groups.reduce((sum, group) => sum + group.skills.length, 0);
|
|
124
|
+
return [
|
|
125
|
+
` 0. ${mark(ids.length === meta.groups.length)} ${'all'.padEnd(16)} ${total} skills — every package`,
|
|
126
|
+
...meta.groups.map((group, i) => ` ${i + 1}. ${mark(ids.includes(group.id))} ${group.id.padEnd(16)} ${group.skills.length} skills — ${group.description}`),
|
|
127
|
+
].join('\n');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Reads a selection from the terminal: numbers or ids, 0 or "all", or nothing to keep the current one.
|
|
131
|
+
async function ask(meta, current, input, output) {
|
|
132
|
+
const rl = createInterface({ input, output });
|
|
133
|
+
try {
|
|
134
|
+
output.write(`${meta.name}: choose which packages Pi loads\n${describe(meta, current)}\n`);
|
|
135
|
+
const keep = current.length ? 'Enter keeps the current selection' : 'Enter loads all';
|
|
136
|
+
const answer = (await rl.question(`Packages to load (numbers or ids, 0 for all; ${keep}): `)).trim();
|
|
137
|
+
const tokens = answer.split(/[\s,]+/).filter(Boolean);
|
|
138
|
+
if (!tokens.length) return current.length ? current : meta.groups.map((group) => group.id);
|
|
139
|
+
if (tokens.some((token) => token === '0' || token === 'all')) return meta.groups.map((group) => group.id);
|
|
140
|
+
return tokens.map((token) => (/^\d+$/.test(token) ? meta.groups[Number(token) - 1]?.id ?? token : token));
|
|
141
|
+
} finally {
|
|
142
|
+
rl.close();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function main(argv, { meta, log = console.log, home = homedir(), cwd = process.cwd(), input = process.stdin, output = process.stdout } = {}) {
|
|
147
|
+
const options = parseArgs(argv);
|
|
148
|
+
if (options.command === 'list') {
|
|
149
|
+
for (const group of meta.groups) log(`${group.id} (${group.packageName}): ${group.skills.join(', ')}`);
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
152
|
+
const path = settingsPath({ local: options.local, home, cwd });
|
|
153
|
+
const settings = existsSync(path) ? JSON.parse(readFileSync(path, 'utf8')) : {};
|
|
154
|
+
const entry = (settings.packages ?? []).find((e) => matchesSource(entrySource(e) ?? '', meta.name));
|
|
155
|
+
let ids = options.all ? meta.groups.map((group) => group.id) : options.ids;
|
|
156
|
+
if (!ids.length) {
|
|
157
|
+
if (!input.isTTY) throw new Error(`No packages given and no terminal to ask.\n\n${USAGE}`);
|
|
158
|
+
ids = await ask(meta, entry ? currentSelection(entry, meta) : [], input, output);
|
|
159
|
+
}
|
|
160
|
+
const plan = planSelection(meta, ids);
|
|
161
|
+
const { settings: next, notes } = applySelection(settings, meta, plan.ids, { home, hide: !options.local });
|
|
162
|
+
if (plan.added.length) log(`Added ${plan.added.join(', ')}: the selected packages use its skills.`);
|
|
163
|
+
if (options.dryRun) {
|
|
164
|
+
log(JSON.stringify(next, null, 2));
|
|
165
|
+
} else {
|
|
166
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
167
|
+
writeFileSync(path, `${JSON.stringify(next, null, 2)}\n`);
|
|
168
|
+
}
|
|
169
|
+
for (const note of notes) log(note);
|
|
170
|
+
log(`${options.dryRun ? 'Would load' : 'Pi loads'}: ${plan.ids.join(', ')} (${path}). Run /reload in an open Pi session.`);
|
|
171
|
+
return 0;
|
|
172
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,148 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1aboveio/skills",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Every 1aboveio skill package in one: install once, then choose which packages Pi loads with npx @1aboveio/skills select.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/1aboveio/ai.git",
|
|
9
|
+
"directory": "skills/distribution/packages"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/1aboveio/ai/releases?q=%401aboveio%2Fskills&expanded=true",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"pi-package",
|
|
14
|
+
"agent-skills",
|
|
15
|
+
"skills"
|
|
16
|
+
],
|
|
17
|
+
"type": "module",
|
|
18
|
+
"bin": {
|
|
19
|
+
"1aboveio-skills": "bin/cli.mjs"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"skills",
|
|
23
|
+
"bin",
|
|
24
|
+
"README.md"
|
|
25
|
+
],
|
|
26
|
+
"pi": {
|
|
27
|
+
"skills": [
|
|
28
|
+
"./skills"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"skillsPackage": {
|
|
32
|
+
"core": "core",
|
|
33
|
+
"groups": [
|
|
34
|
+
{
|
|
35
|
+
"id": "core",
|
|
36
|
+
"packageName": "@1aboveio/core-skills",
|
|
37
|
+
"description": "Shared writing and document foundation: house style, editorial review, Chinese polish, terminology, write-doc, distill-writing, doc-to-md and reg-parser.",
|
|
38
|
+
"needsCore": false,
|
|
39
|
+
"skills": [
|
|
40
|
+
"distill-writing",
|
|
41
|
+
"doc-to-md",
|
|
42
|
+
"editorial-review",
|
|
43
|
+
"house-style",
|
|
44
|
+
"polish-cn",
|
|
45
|
+
"reg-parser",
|
|
46
|
+
"terminology",
|
|
47
|
+
"write-doc"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "engineering",
|
|
52
|
+
"packageName": "@1aboveio/engineering-skills",
|
|
53
|
+
"description": "Issue-to-PR and release orchestrators, review, coverage, golden paths and test quality.",
|
|
54
|
+
"needsCore": false,
|
|
55
|
+
"skills": [
|
|
56
|
+
"better-review",
|
|
57
|
+
"e2e-test",
|
|
58
|
+
"engineering-runtime",
|
|
59
|
+
"ensure-coverage",
|
|
60
|
+
"golden-path",
|
|
61
|
+
"harness-runtime",
|
|
62
|
+
"resolve-issues",
|
|
63
|
+
"resolve-release",
|
|
64
|
+
"rush-issues",
|
|
65
|
+
"rush-release",
|
|
66
|
+
"test-quality"
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "cicd",
|
|
71
|
+
"packageName": "@1aboveio/cicd-skills",
|
|
72
|
+
"description": "GitHub Actions and flow, Mergify, Docker and Podman, Cloud Build, Cloud Deploy and Google Cloud.",
|
|
73
|
+
"needsCore": false,
|
|
74
|
+
"skills": [
|
|
75
|
+
"cloud-build",
|
|
76
|
+
"cloud-debug",
|
|
77
|
+
"cloud-deploy",
|
|
78
|
+
"docker",
|
|
79
|
+
"github-actions",
|
|
80
|
+
"github-flow",
|
|
81
|
+
"google-cloud",
|
|
82
|
+
"mergify",
|
|
83
|
+
"podman"
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": "app-dev",
|
|
88
|
+
"packageName": "@1aboveio/app-dev-skills",
|
|
89
|
+
"description": "Next.js, React Native, auth, Prisma, shadcn, Python backends, Airflow and PySpark.",
|
|
90
|
+
"needsCore": false,
|
|
91
|
+
"skills": [
|
|
92
|
+
"airflow",
|
|
93
|
+
"android-foundation",
|
|
94
|
+
"app-debug",
|
|
95
|
+
"better-auth",
|
|
96
|
+
"data-catalog",
|
|
97
|
+
"ios-foundation",
|
|
98
|
+
"monorepo",
|
|
99
|
+
"nextjs-fullstack",
|
|
100
|
+
"prisma-setup",
|
|
101
|
+
"pyspark",
|
|
102
|
+
"python-backend",
|
|
103
|
+
"shadcn",
|
|
104
|
+
"zod-v4"
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "risk-compliance",
|
|
109
|
+
"packageName": "@1aboveio/risk-compliance-skills",
|
|
110
|
+
"description": "Compliance audits, contract review, payment and fraud analysis.",
|
|
111
|
+
"needsCore": true,
|
|
112
|
+
"skills": [
|
|
113
|
+
"compliance-audit",
|
|
114
|
+
"contract-compare",
|
|
115
|
+
"contract-review",
|
|
116
|
+
"doc-authenticity",
|
|
117
|
+
"fraud-analysis",
|
|
118
|
+
"payment-analysis",
|
|
119
|
+
"report-writing",
|
|
120
|
+
"similar-domain",
|
|
121
|
+
"tld-detection"
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "content",
|
|
126
|
+
"packageName": "@1aboveio/content-skills",
|
|
127
|
+
"description": "WeChat articles, reviews and covers, diagrams, image generation and xAI search.",
|
|
128
|
+
"needsCore": false,
|
|
129
|
+
"skills": [
|
|
130
|
+
"article-review",
|
|
131
|
+
"article-to-image",
|
|
132
|
+
"flowchart-svg",
|
|
133
|
+
"image-gen",
|
|
134
|
+
"mermaid",
|
|
135
|
+
"wechat-article-writer",
|
|
136
|
+
"wechat-publisher",
|
|
137
|
+
"wechat-search",
|
|
138
|
+
"xai-search"
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"digest": "730da168eda4e3eedfb448db5dae6f8d0bc8c518bcb35a2c43e0b0acf538151e"
|
|
143
|
+
},
|
|
144
|
+
"publishConfig": {
|
|
145
|
+
"registry": "https://registry.npmjs.org/",
|
|
146
|
+
"access": "public"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: airflow
|
|
3
|
+
description: Airflow DAG architecture and conventions. Use when designing, writing, reviewing, testing, or debugging Airflow DAGs and tasks, including TaskGroups, data intervals, timezone-aware date parameters, CLI validation, environment-based scheduling, and pytest integrity tests.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
release-version: 0.36.0
|
|
6
|
+
---
|
|
7
|
+
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
8
|
+
# Airflow DAG Development Patterns
|
|
9
|
+
|
|
10
|
+
## 1. Organize Data Pipelines with TaskGroups
|
|
11
|
+
|
|
12
|
+
Use `TaskGroup` to make meaningful pipeline stages visible in the Airflow graph. For data warehouse pipelines, group tasks by warehouse layer such as `stg`, `ods`, `dwd`, `dws`, and `ads`. For other pipelines, use domain-specific groups such as `features`, `exports`, `quality_checks`, or `notifications`.
|
|
13
|
+
|
|
14
|
+
Keep groups aligned with real ownership or dependency boundaries; do not create a group solely to wrap one trivial task. Express dependencies between groups so the graph communicates the pipeline's high-level flow.
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
from airflow.decorators import dag
|
|
18
|
+
from airflow.utils.task_group import TaskGroup
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dag(...)
|
|
22
|
+
def customer_metrics():
|
|
23
|
+
with TaskGroup(group_id="stg") as stg:
|
|
24
|
+
load_stg_customers()
|
|
25
|
+
load_stg_orders()
|
|
26
|
+
|
|
27
|
+
with TaskGroup(group_id="dwd") as dwd:
|
|
28
|
+
build_dwd_customers()
|
|
29
|
+
build_dwd_orders()
|
|
30
|
+
|
|
31
|
+
with TaskGroup(group_id="ads") as ads:
|
|
32
|
+
build_ads_customer_metrics()
|
|
33
|
+
|
|
34
|
+
stg >> dwd >> ads
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
customer_metrics()
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 2. Use Timezone-Aware Data Intervals
|
|
41
|
+
|
|
42
|
+
Prefer Airflow's `data_interval_start` and `data_interval_end` as task date-range inputs. They are timezone-aware logical boundaries and behave correctly for scheduled runs, catchup, and daylight-saving transitions. Treat `data_interval_end` as an exclusive boundary.
|
|
43
|
+
|
|
44
|
+
Prepare one shared set of templated date variables for the whole DAG, converting the interval boundaries to the DAG's business timezone. Pass those variables to every task that reads or writes partitioned data. Keep the conversion in Jinja so it happens for each DAG run, not while the scheduler parses the DAG file.
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import pendulum
|
|
48
|
+
from airflow.decorators import dag, task
|
|
49
|
+
from airflow.utils.task_group import TaskGroup
|
|
50
|
+
|
|
51
|
+
LOCAL_TIMEZONE = "Asia/Shanghai"
|
|
52
|
+
|
|
53
|
+
# These values are rendered separately for every DAG run. The end is exclusive.
|
|
54
|
+
DATE_RANGE = {
|
|
55
|
+
"start_date": (
|
|
56
|
+
f"{{{{ data_interval_start.in_timezone('{LOCAL_TIMEZONE}') | ds }}}}"
|
|
57
|
+
),
|
|
58
|
+
"end_date": (
|
|
59
|
+
f"{{{{ data_interval_end.in_timezone('{LOCAL_TIMEZONE}') | ds }}}}"
|
|
60
|
+
),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dag(
|
|
65
|
+
schedule="0 2 * * *",
|
|
66
|
+
start_date=pendulum.datetime(2024, 1, 1, tz=LOCAL_TIMEZONE),
|
|
67
|
+
catchup=True,
|
|
68
|
+
)
|
|
69
|
+
def daily_warehouse():
|
|
70
|
+
@task
|
|
71
|
+
def load_partition(start_date: str, end_date: str) -> None:
|
|
72
|
+
# Read records in the half-open range [start_date, end_date).
|
|
73
|
+
...
|
|
74
|
+
|
|
75
|
+
with TaskGroup(group_id="stg"):
|
|
76
|
+
load_partition(**DATE_RANGE)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
daily_warehouse()
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use timestamps instead of dates when a task needs sub-day precision:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
INTERVAL_RANGE = {
|
|
86
|
+
"interval_start": "{{ data_interval_start.in_timezone('Asia/Shanghai').to_iso8601_string() }}",
|
|
87
|
+
"interval_end": "{{ data_interval_end.in_timezone('Asia/Shanghai').to_iso8601_string() }}",
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 3. Operations: Wait for DAG Auto-Reload
|
|
92
|
+
|
|
93
|
+
Airflow periodically scans the DAG directory and automatically reloads changed DAG files. The refresh cadence depends on the deployment's scheduler and DAG-processing configuration, and commonly takes a few minutes.
|
|
94
|
+
|
|
95
|
+
After updating a DAG file, do not restart the Airflow services by default. Watch for the DAG to refresh in the Airflow UI or CLI after the configured scan interval. Investigate import errors or deployment synchronization only if the update does not appear after a reasonable interval.
|
|
96
|
+
|
|
97
|
+
## 4. Quick DAG Validation with Airflow CLI
|
|
98
|
+
|
|
99
|
+
Use these commands for fast feedback during development:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# List import errors (fastest check - catches syntax and import issues)
|
|
103
|
+
airflow dags list-import-errors
|
|
104
|
+
|
|
105
|
+
# Full lint check (comprehensive - catches best practice violations)
|
|
106
|
+
airflow dags lint
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**When to use:**
|
|
110
|
+
- `list-import-errors`: During active development for quick syntax/import validation
|
|
111
|
+
- `lint`: Before commits to catch style and best practice issues
|
|
112
|
+
|
|
113
|
+
## 5. Environment-Based Schedule Override
|
|
114
|
+
|
|
115
|
+
Disable schedules in local development to prevent accidental runs:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
import os
|
|
119
|
+
from datetime import datetime
|
|
120
|
+
from airflow import DAG
|
|
121
|
+
|
|
122
|
+
def get_schedule(production_schedule: str) -> str | None:
|
|
123
|
+
"""Return None for local dev, actual schedule for deployed environments.
|
|
124
|
+
|
|
125
|
+
Set AIRFLOW_ENV=local in .env for local development.
|
|
126
|
+
Cloud Run deployments set AIRFLOW_ENV=dev|staging|prod.
|
|
127
|
+
"""
|
|
128
|
+
env = os.getenv("AIRFLOW_ENV", "local")
|
|
129
|
+
if env == "local":
|
|
130
|
+
return None
|
|
131
|
+
return production_schedule
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Usage in DAG:**
|
|
135
|
+
```python
|
|
136
|
+
with DAG(
|
|
137
|
+
dag_id="my_dag",
|
|
138
|
+
schedule=get_schedule("0 4 * * *"), # Daily 4 AM in prod, None locally
|
|
139
|
+
start_date=datetime(2024, 1, 1),
|
|
140
|
+
catchup=False,
|
|
141
|
+
) as dag:
|
|
142
|
+
...
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Environment setup:**
|
|
146
|
+
- **Local:** Add `AIRFLOW_ENV=local` to `.env`
|
|
147
|
+
- **Cloud Run:** Set via cloudbuild.yaml substitutions (`_AIRFLOW_ENV: dev|staging|prod`)
|
|
148
|
+
|
|
149
|
+
## 6. Pytest DAG Integrity Tests
|
|
150
|
+
|
|
151
|
+
Standard pytest patterns for validating DAG quality:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# tests/test_dag_integrity.py
|
|
155
|
+
import pytest
|
|
156
|
+
from airflow.models import DagBag
|
|
157
|
+
|
|
158
|
+
@pytest.fixture(scope="session")
|
|
159
|
+
def dagbag():
|
|
160
|
+
return DagBag(dag_folder="dags/", include_examples=False)
|
|
161
|
+
|
|
162
|
+
def test_no_import_errors(dagbag):
|
|
163
|
+
"""Verify all DAGs load without import errors."""
|
|
164
|
+
assert not dagbag.import_errors, f"DAG import errors: {dagbag.import_errors}"
|
|
165
|
+
|
|
166
|
+
def test_dags_have_tags(dagbag):
|
|
167
|
+
"""Verify all DAGs have at least one tag for organization."""
|
|
168
|
+
for dag_id, dag in dagbag.dags.items():
|
|
169
|
+
assert dag.tags, f"DAG {dag_id} has no tags"
|
|
170
|
+
|
|
171
|
+
def test_dags_have_owner(dagbag):
|
|
172
|
+
"""Verify all DAGs have an owner in default_args."""
|
|
173
|
+
for dag_id, dag in dagbag.dags.items():
|
|
174
|
+
assert dag.default_args.get("owner"), f"DAG {dag_id} missing owner"
|
|
175
|
+
|
|
176
|
+
def test_no_cycles(dagbag):
|
|
177
|
+
"""Verify DAGs don't have circular dependencies."""
|
|
178
|
+
for dag_id, dag in dagbag.dags.items():
|
|
179
|
+
# DagBag already validates this, but explicit test for clarity
|
|
180
|
+
assert dag.topo_sort(), f"DAG {dag_id} has cycles"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Run tests:**
|
|
184
|
+
```bash
|
|
185
|
+
# Run all DAG tests
|
|
186
|
+
pytest tests/test_dag_integrity.py -v
|
|
187
|
+
|
|
188
|
+
# Run specific test
|
|
189
|
+
pytest tests/test_dag_integrity.py::test_no_import_errors -v
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Quick Reference
|
|
193
|
+
|
|
194
|
+
| Task | Command |
|
|
195
|
+
|------|---------|
|
|
196
|
+
| Check import errors | `airflow dags list-import-errors` |
|
|
197
|
+
| Lint DAGs | `airflow dags lint` |
|
|
198
|
+
| Run integrity tests | `pytest tests/test_dag_integrity.py -v` |
|
|
199
|
+
| Trigger manual run | `airflow dags trigger <dag_id>` |
|
|
@@ -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. */ }
|