@ketecode/loom 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +616 -2
- package/agents/accessibility-reviewer/AGENT.md +70 -0
- package/agents/accessibility-reviewer/evals/triggers.json +15 -0
- package/agents/agent-evaluator/AGENT.md +74 -0
- package/agents/agent-evaluator/evals/triggers.json +15 -0
- package/agents/architect/AGENT.md +82 -0
- package/agents/architect/evals/triggers.json +17 -0
- package/agents/billing-reviewer/AGENT.md +68 -0
- package/agents/billing-reviewer/evals/triggers.json +16 -0
- package/agents/code-reviewer/AGENT.md +51 -0
- package/agents/code-reviewer/evals/behavior.json +60 -0
- package/agents/code-reviewer/evals/triggers.json +14 -0
- package/agents/code-simplifier/AGENT.md +74 -0
- package/agents/code-simplifier/evals/triggers.json +15 -0
- package/agents/cpp-build-resolver/AGENT.md +73 -0
- package/agents/cpp-build-resolver/evals/triggers.json +16 -0
- package/agents/cpp-reviewer/AGENT.md +59 -0
- package/agents/cpp-reviewer/evals/triggers.json +16 -0
- package/agents/csharp-build-resolver/AGENT.md +84 -0
- package/agents/csharp-build-resolver/evals/triggers.json +17 -0
- package/agents/csharp-reviewer/AGENT.md +88 -0
- package/agents/csharp-reviewer/evals/triggers.json +17 -0
- package/agents/dart-build-resolver/AGENT.md +80 -0
- package/agents/dart-build-resolver/evals/triggers.json +17 -0
- package/agents/dart-reviewer/AGENT.md +66 -0
- package/agents/dart-reviewer/evals/triggers.json +17 -0
- package/agents/database-reviewer/AGENT.md +72 -0
- package/agents/database-reviewer/evals/triggers.json +16 -0
- package/agents/django-reviewer/AGENT.md +61 -0
- package/agents/django-reviewer/evals/triggers.json +15 -0
- package/agents/doc-updater/AGENT.md +92 -0
- package/agents/doc-updater/evals/triggers.json +14 -0
- package/agents/e2e-runner/AGENT.md +88 -0
- package/agents/e2e-runner/evals/triggers.json +16 -0
- package/agents/fastapi-reviewer/AGENT.md +63 -0
- package/agents/fastapi-reviewer/evals/triggers.json +15 -0
- package/agents/flutter-reviewer/AGENT.md +70 -0
- package/agents/flutter-reviewer/evals/triggers.json +15 -0
- package/agents/fsharp-build-resolver/AGENT.md +81 -0
- package/agents/fsharp-build-resolver/evals/triggers.json +15 -0
- package/agents/fsharp-reviewer/AGENT.md +77 -0
- package/agents/fsharp-reviewer/evals/triggers.json +15 -0
- package/agents/go-build-resolver/AGENT.md +85 -0
- package/agents/go-build-resolver/evals/triggers.json +16 -0
- package/agents/go-reviewer/AGENT.md +66 -0
- package/agents/go-reviewer/evals/triggers.json +16 -0
- package/agents/healthcare-reviewer/AGENT.md +65 -0
- package/agents/healthcare-reviewer/evals/triggers.json +16 -0
- package/agents/i18n-reviewer/AGENT.md +64 -0
- package/agents/i18n-reviewer/evals/triggers.json +16 -0
- package/agents/inbox-triager/AGENT.md +98 -0
- package/agents/inbox-triager/evals/triggers.json +16 -0
- package/agents/infra-reviewer/AGENT.md +93 -0
- package/agents/infra-reviewer/evals/triggers.json +15 -0
- package/agents/java-build-resolver/AGENT.md +82 -0
- package/agents/java-build-resolver/evals/triggers.json +16 -0
- package/agents/java-reviewer/AGENT.md +64 -0
- package/agents/java-reviewer/evals/triggers.json +16 -0
- package/agents/kotlin-build-resolver/AGENT.md +89 -0
- package/agents/kotlin-build-resolver/evals/triggers.json +16 -0
- package/agents/kotlin-reviewer/AGENT.md +75 -0
- package/agents/kotlin-reviewer/evals/triggers.json +16 -0
- package/agents/mle-reviewer/AGENT.md +68 -0
- package/agents/mle-reviewer/evals/triggers.json +16 -0
- package/agents/network-config-reviewer/AGENT.md +68 -0
- package/agents/network-config-reviewer/evals/triggers.json +17 -0
- package/agents/payments-reviewer/AGENT.md +64 -0
- package/agents/payments-reviewer/evals/triggers.json +16 -0
- package/agents/performance-optimizer/AGENT.md +86 -0
- package/agents/performance-optimizer/evals/triggers.json +16 -0
- package/agents/perl-build-resolver/AGENT.md +84 -0
- package/agents/perl-build-resolver/evals/triggers.json +15 -0
- package/agents/perl-reviewer/AGENT.md +77 -0
- package/agents/perl-reviewer/evals/triggers.json +15 -0
- package/agents/php-build-resolver/AGENT.md +88 -0
- package/agents/php-build-resolver/evals/triggers.json +16 -0
- package/agents/php-reviewer/AGENT.md +61 -0
- package/agents/php-reviewer/evals/triggers.json +15 -0
- package/agents/planner/AGENT.md +75 -0
- package/agents/planner/evals/triggers.json +17 -0
- package/agents/pr-test-analyzer/AGENT.md +82 -0
- package/agents/pr-test-analyzer/evals/triggers.json +16 -0
- package/agents/python-build-resolver/AGENT.md +87 -0
- package/agents/python-build-resolver/evals/triggers.json +16 -0
- package/agents/python-reviewer/AGENT.md +63 -0
- package/agents/python-reviewer/evals/triggers.json +15 -0
- package/agents/rag-reviewer/AGENT.md +71 -0
- package/agents/rag-reviewer/evals/triggers.json +16 -0
- package/agents/react-reviewer/AGENT.md +70 -0
- package/agents/react-reviewer/evals/triggers.json +16 -0
- package/agents/refactor-cleaner/AGENT.md +82 -0
- package/agents/refactor-cleaner/evals/triggers.json +16 -0
- package/agents/ruby-build-resolver/AGENT.md +93 -0
- package/agents/ruby-build-resolver/evals/triggers.json +16 -0
- package/agents/ruby-reviewer/AGENT.md +62 -0
- package/agents/ruby-reviewer/evals/triggers.json +16 -0
- package/agents/rust-build-resolver/AGENT.md +98 -0
- package/agents/rust-build-resolver/evals/triggers.json +16 -0
- package/agents/rust-reviewer/AGENT.md +78 -0
- package/agents/rust-reviewer/evals/triggers.json +15 -0
- package/agents/security-reviewer/AGENT.md +84 -0
- package/agents/security-reviewer/evals/triggers.json +16 -0
- package/agents/silent-failure-hunter/AGENT.md +66 -0
- package/agents/silent-failure-hunter/evals/triggers.json +16 -0
- package/agents/solidity-reviewer/AGENT.md +70 -0
- package/agents/solidity-reviewer/evals/triggers.json +16 -0
- package/agents/spec-reviewer/AGENT.md +95 -0
- package/agents/spec-reviewer/evals/behavior.json +57 -0
- package/agents/spec-reviewer/evals/triggers.json +16 -0
- package/agents/swift-build-resolver/AGENT.md +85 -0
- package/agents/swift-build-resolver/evals/triggers.json +15 -0
- package/agents/swift-reviewer/AGENT.md +75 -0
- package/agents/swift-reviewer/evals/triggers.json +15 -0
- package/agents/task-implementer/AGENT.md +89 -0
- package/agents/task-implementer/evals/behavior.json +47 -0
- package/agents/task-implementer/evals/triggers.json +16 -0
- package/agents/typescript-build-resolver/AGENT.md +76 -0
- package/agents/typescript-build-resolver/evals/triggers.json +15 -0
- package/agents/typescript-reviewer/AGENT.md +76 -0
- package/agents/typescript-reviewer/evals/triggers.json +15 -0
- package/agents/vue-reviewer/AGENT.md +75 -0
- package/agents/vue-reviewer/evals/triggers.json +15 -0
- package/bin/kete-loom.js +723 -0
- package/commands/aside.md +19 -0
- package/commands/brainstorm.md +25 -0
- package/commands/build-fix.md +26 -0
- package/commands/campaign.md +19 -0
- package/commands/changelog.md +36 -0
- package/commands/checkpoint.md +26 -0
- package/commands/codemap.md +25 -0
- package/commands/commit.md +26 -0
- package/commands/debug.md +27 -0
- package/commands/deps-audit.md +32 -0
- package/commands/dual-review.md +34 -0
- package/commands/epic-decompose.md +21 -0
- package/commands/explain.md +37 -0
- package/commands/feature-dev.md +23 -0
- package/commands/finish-branch.md +26 -0
- package/commands/fix-bug.md +38 -0
- package/commands/hookify.md +23 -0
- package/commands/i18n-check.md +39 -0
- package/commands/issue-sync.md +22 -0
- package/commands/jira.md +19 -0
- package/commands/learn.md +23 -0
- package/commands/loom.md +21 -0
- package/commands/loop.md +20 -0
- package/commands/model-route.md +27 -0
- package/commands/onboard.md +35 -0
- package/commands/orchestrate.md +21 -0
- package/commands/plan-feature.md +36 -0
- package/commands/postmortem.md +42 -0
- package/commands/pr-describe.md +39 -0
- package/commands/pr.md +22 -0
- package/commands/prd.md +41 -0
- package/commands/production-readiness.md +45 -0
- package/commands/project-init.md +21 -0
- package/commands/refactor-clean.md +24 -0
- package/commands/resume-session.md +22 -0
- package/commands/review.md +35 -0
- package/commands/save-session.md +37 -0
- package/commands/security-scan.md +32 -0
- package/commands/sessions.md +21 -0
- package/commands/skill-create.md +21 -0
- package/commands/tdd.md +36 -0
- package/commands/test-coverage.md +24 -0
- package/commands/threat-model.md +36 -0
- package/commands/update-docs.md +25 -0
- package/commands/usage-report.md +43 -0
- package/commands/verify.md +21 -0
- package/hooks/block-dangerous-commands/HOOK.md +30 -0
- package/hooks/block-dangerous-commands/cases.json +50 -0
- package/hooks/block-dangerous-commands/hook.js +75 -0
- package/hooks/block-foreground-servers/HOOK.md +34 -0
- package/hooks/block-foreground-servers/cases.json +31 -0
- package/hooks/block-foreground-servers/hook.js +41 -0
- package/hooks/block-no-verify/HOOK.md +25 -0
- package/hooks/block-no-verify/cases.json +30 -0
- package/hooks/block-no-verify/hook.js +43 -0
- package/hooks/capture-lessons/HOOK.md +24 -0
- package/hooks/capture-lessons/hook.js +48 -0
- package/hooks/format-on-edit/HOOK.md +24 -0
- package/hooks/format-on-edit/hook.js +89 -0
- package/hooks/guard-secrets/HOOK.md +19 -0
- package/hooks/guard-secrets/cases.json +110 -0
- package/hooks/guard-secrets/hook.js +44 -0
- package/hooks/load-session-context/HOOK.md +20 -0
- package/hooks/load-session-context/hook.js +56 -0
- package/hooks/notify-on-stop/HOOK.md +25 -0
- package/hooks/notify-on-stop/hook.js +27 -0
- package/hooks/protect-files/HOOK.md +24 -0
- package/hooks/protect-files/cases.json +27 -0
- package/hooks/protect-files/hook.js +39 -0
- package/hooks/protect-lint-config/HOOK.md +29 -0
- package/hooks/protect-lint-config/cases.json +18 -0
- package/hooks/protect-lint-config/fixtures/.eslintrc.json +1 -0
- package/hooks/protect-lint-config/fixtures/.golangci.yml +1 -0
- package/hooks/protect-lint-config/fixtures/.prettierrc +1 -0
- package/hooks/protect-lint-config/fixtures/.rubocop.yml +1 -0
- package/hooks/protect-lint-config/fixtures/biome.json +1 -0
- package/hooks/protect-lint-config/fixtures/eslint.config.mjs +1 -0
- package/hooks/protect-lint-config/fixtures/ruff.toml +1 -0
- package/hooks/protect-lint-config/hook.js +25 -0
- package/hooks/read-before-edit/HOOK.md +26 -0
- package/hooks/read-before-edit/cases.json +15 -0
- package/hooks/read-before-edit/hook.js +50 -0
- package/hooks/run.js +148 -0
- package/hooks/verify-before-stop/HOOK.md +32 -0
- package/hooks/verify-before-stop/hook.js +70 -0
- package/mcp/atlassian.json +11 -0
- package/mcp/chrome-devtools.json +18 -0
- package/mcp/clickhouse.json +11 -0
- package/mcp/cloudflare.json +11 -0
- package/mcp/context7.json +11 -0
- package/mcp/exa.json +11 -0
- package/mcp/fetch.json +17 -0
- package/mcp/figma.json +11 -0
- package/mcp/firecrawl.json +11 -0
- package/mcp/git.json +17 -0
- package/mcp/github.json +11 -0
- package/mcp/linear.json +11 -0
- package/mcp/memory.json +18 -0
- package/mcp/notion.json +11 -0
- package/mcp/playwright.json +18 -0
- package/mcp/sentry.json +11 -0
- package/mcp/stripe.json +11 -0
- package/mcp/supabase.json +11 -0
- package/mcp/time.json +17 -0
- package/mcp/vercel.json +11 -0
- package/package.json +61 -4
- package/profiles.json +214 -0
- package/rules/common.md +21 -0
- package/rules/cpp.md +29 -0
- package/rules/csharp.md +25 -0
- package/rules/dart.md +29 -0
- package/rules/fsharp.md +28 -0
- package/rules/git.md +26 -0
- package/rules/go.md +29 -0
- package/rules/java.md +29 -0
- package/rules/kotlin.md +27 -0
- package/rules/perl.md +26 -0
- package/rules/php.md +28 -0
- package/rules/python.md +30 -0
- package/rules/ruby.md +27 -0
- package/rules/rust.md +26 -0
- package/rules/security.md +29 -0
- package/rules/swift.md +28 -0
- package/rules/testing.md +25 -0
- package/rules/typescript.md +29 -0
- package/rules/use-skills.md +23 -0
- package/schemas/skill-frontmatter.schema.json +52 -0
- package/scripts/lib/audit.js +96 -0
- package/scripts/lib/behavior.js +52 -0
- package/scripts/lib/frontmatter.js +65 -0
- package/scripts/lib/hooks-install.js +294 -0
- package/scripts/lib/i18n.js +51 -0
- package/scripts/lib/inventory.js +85 -0
- package/scripts/lib/lint.js +180 -0
- package/scripts/lib/mcp-install.js +288 -0
- package/scripts/lib/profiles.js +128 -0
- package/scripts/lib/render.js +92 -0
- package/scripts/lib/rules-install.js +118 -0
- package/scripts/lib/skills.js +87 -0
- package/scripts/lib/targets.js +123 -0
- package/skills/accounting-api-integration/SKILL.md +81 -0
- package/skills/accounting-api-integration/evals/triggers.json +17 -0
- package/skills/accounting-api-integration/references/quickbooks.md +48 -0
- package/skills/accounting-api-integration/references/xero.md +45 -0
- package/skills/agent-failure-debugging/SKILL.md +92 -0
- package/skills/agent-failure-debugging/evals/triggers.json +16 -0
- package/skills/agent-harness-design/SKILL.md +125 -0
- package/skills/agent-harness-design/evals/triggers.json +21 -0
- package/skills/agent-outbound-messaging/SKILL.md +92 -0
- package/skills/agent-outbound-messaging/evals/triggers.json +16 -0
- package/skills/agent-security/SKILL.md +117 -0
- package/skills/agent-security/evals/triggers.json +16 -0
- package/skills/agent-security/references/host-configs.md +37 -0
- package/skills/ai-media-generation/SKILL.md +89 -0
- package/skills/ai-media-generation/evals/triggers.json +16 -0
- package/skills/ai-media-generation/references/job-pipeline.md +76 -0
- package/skills/angular-patterns/SKILL.md +122 -0
- package/skills/angular-patterns/evals/triggers.json +16 -0
- package/skills/api-client-integration/SKILL.md +86 -0
- package/skills/api-client-integration/evals/triggers.json +16 -0
- package/skills/api-client-integration/references/resilience.md +57 -0
- package/skills/api-design/SKILL.md +96 -0
- package/skills/api-design/evals/triggers.json +18 -0
- package/skills/api-design/references/conventions.md +133 -0
- package/skills/architecture-decision-records/SKILL.md +98 -0
- package/skills/architecture-decision-records/evals/triggers.json +17 -0
- package/skills/article-writing/SKILL.md +108 -0
- package/skills/article-writing/evals/triggers.json +16 -0
- package/skills/aspnet-core-patterns/SKILL.md +149 -0
- package/skills/aspnet-core-patterns/evals/triggers.json +16 -0
- package/skills/auth-patterns/SKILL.md +104 -0
- package/skills/auth-patterns/evals/triggers.json +17 -0
- package/skills/auth-patterns/references/oauth-oidc.md +64 -0
- package/skills/autonomous-loops/SKILL.md +99 -0
- package/skills/autonomous-loops/evals/triggers.json +14 -0
- package/skills/aws-patterns/SKILL.md +91 -0
- package/skills/aws-patterns/evals/triggers.json +16 -0
- package/skills/azure-patterns/SKILL.md +86 -0
- package/skills/azure-patterns/evals/triggers.json +16 -0
- package/skills/benchmark-methodology/SKILL.md +88 -0
- package/skills/benchmark-methodology/evals/triggers.json +16 -0
- package/skills/benchmark-methodology/references/language-harnesses.md +130 -0
- package/skills/bgp-diagnostics/SKILL.md +84 -0
- package/skills/bgp-diagnostics/evals/triggers.json +18 -0
- package/skills/bgp-diagnostics/references/bgp-reference.md +81 -0
- package/skills/bioinformatics-workflows/SKILL.md +108 -0
- package/skills/bioinformatics-workflows/evals/triggers.json +16 -0
- package/skills/bioinformatics-workflows/references/commands.md +71 -0
- package/skills/bioinformatics-workflows/references/formats.md +24 -0
- package/skills/bioinformatics-workflows/references/workflow-managers.md +107 -0
- package/skills/blender-automation/SKILL.md +100 -0
- package/skills/blender-automation/evals/triggers.json +16 -0
- package/skills/blender-automation/references/batch-and-render.md +77 -0
- package/skills/blender-automation/references/bpy-inspection.md +91 -0
- package/skills/blender-automation/references/rig-and-retarget-checks.md +23 -0
- package/skills/brand-strategy/SKILL.md +83 -0
- package/skills/brand-strategy/evals/triggers.json +16 -0
- package/skills/brand-voice/SKILL.md +112 -0
- package/skills/brand-voice/evals/triggers.json +16 -0
- package/skills/browser-qa/SKILL.md +99 -0
- package/skills/browser-qa/evals/triggers.json +16 -0
- package/skills/bun-runtime/SKILL.md +93 -0
- package/skills/bun-runtime/evals/triggers.json +16 -0
- package/skills/change-impact-analysis/SKILL.md +89 -0
- package/skills/change-impact-analysis/evals/triggers.json +16 -0
- package/skills/change-impact-analysis/references/graph-commands.md +28 -0
- package/skills/cisco-ios-config/SKILL.md +101 -0
- package/skills/cisco-ios-config/evals/triggers.json +18 -0
- package/skills/cisco-ios-config/references/verification.md +63 -0
- package/skills/clickhouse-patterns/SKILL.md +101 -0
- package/skills/clickhouse-patterns/evals/triggers.json +18 -0
- package/skills/clickhouse-patterns/references/engines-and-views.md +138 -0
- package/skills/clinical-decision-support/SKILL.md +90 -0
- package/skills/clinical-decision-support/evals/triggers.json +16 -0
- package/skills/clinical-decision-support/references/cds-hooks.md +76 -0
- package/skills/clinical-decision-support/references/regulatory-boundaries.md +37 -0
- package/skills/code-tour/SKILL.md +97 -0
- package/skills/code-tour/evals/triggers.json +14 -0
- package/skills/codebase-onboarding/SKILL.md +112 -0
- package/skills/codebase-onboarding/evals/triggers.json +14 -0
- package/skills/cold-outreach-sequences/SKILL.md +90 -0
- package/skills/cold-outreach-sequences/evals/triggers.json +16 -0
- package/skills/content-repurposing/SKILL.md +82 -0
- package/skills/content-repurposing/evals/triggers.json +16 -0
- package/skills/context-budget/SKILL.md +84 -0
- package/skills/context-budget/evals/triggers.json +14 -0
- package/skills/contract-drafting/SKILL.md +96 -0
- package/skills/contract-drafting/evals/triggers.json +16 -0
- package/skills/contract-drafting/references/term-sheets.md +68 -0
- package/skills/contract-first-development/SKILL.md +86 -0
- package/skills/contract-first-development/evals/triggers.json +16 -0
- package/skills/contract-first-development/references/tooling.md +46 -0
- package/skills/conventional-commits/SKILL.md +144 -0
- package/skills/conventional-commits/evals/triggers.json +16 -0
- package/skills/cpp-patterns/SKILL.md +129 -0
- package/skills/cpp-patterns/evals/triggers.json +16 -0
- package/skills/cpp-patterns/references/cmake-and-tooling.md +88 -0
- package/skills/cpp-patterns/references/undefined-behaviour.md +75 -0
- package/skills/cpp-testing/SKILL.md +131 -0
- package/skills/cpp-testing/evals/triggers.json +16 -0
- package/skills/csharp-patterns/SKILL.md +110 -0
- package/skills/csharp-patterns/evals/triggers.json +17 -0
- package/skills/csharp-patterns/references/analyzers.md +59 -0
- package/skills/csharp-testing/SKILL.md +85 -0
- package/skills/csharp-testing/evals/triggers.json +17 -0
- package/skills/csharp-testing/references/integration-tests.md +77 -0
- package/skills/css-architecture/SKILL.md +143 -0
- package/skills/css-architecture/evals/triggers.json +16 -0
- package/skills/customs-trade-compliance/SKILL.md +95 -0
- package/skills/customs-trade-compliance/evals/triggers.json +16 -0
- package/skills/customs-trade-compliance/references/incoterms-2020.md +42 -0
- package/skills/dart-patterns/SKILL.md +157 -0
- package/skills/dart-patterns/evals/triggers.json +18 -0
- package/skills/dart-testing/SKILL.md +164 -0
- package/skills/dart-testing/evals/triggers.json +18 -0
- package/skills/data-analysis-notebooks/SKILL.md +113 -0
- package/skills/data-analysis-notebooks/evals/triggers.json +16 -0
- package/skills/data-analysis-notebooks/references/dataframe-pitfalls.md +49 -0
- package/skills/data-analysis-notebooks/references/statistics-pitfalls.md +24 -0
- package/skills/data-pipelines/SKILL.md +90 -0
- package/skills/data-pipelines/evals/triggers.json +16 -0
- package/skills/data-pipelines/references/orchestrators.md +64 -0
- package/skills/database-migrations/SKILL.md +102 -0
- package/skills/database-migrations/evals/triggers.json +16 -0
- package/skills/database-migrations/references/recipes.md +98 -0
- package/skills/database-migrations/references/tools.md +21 -0
- package/skills/dbt-patterns/SKILL.md +96 -0
- package/skills/dbt-patterns/evals/triggers.json +16 -0
- package/skills/dbt-patterns/references/yaml-examples.md +114 -0
- package/skills/decision-council/SKILL.md +98 -0
- package/skills/decision-council/evals/triggers.json +16 -0
- package/skills/deep-research/SKILL.md +107 -0
- package/skills/deep-research/evals/triggers.json +14 -0
- package/skills/dependency-audit/SKILL.md +103 -0
- package/skills/dependency-audit/evals/triggers.json +16 -0
- package/skills/dependency-audit/references/tools.md +124 -0
- package/skills/deployment-strategies/SKILL.md +108 -0
- package/skills/deployment-strategies/evals/triggers.json +16 -0
- package/skills/design-brainstorming/SKILL.md +132 -0
- package/skills/design-brainstorming/evals/behavior.json +55 -0
- package/skills/design-brainstorming/evals/triggers.json +16 -0
- package/skills/design-brainstorming/references/visual-mockups.md +34 -0
- package/skills/desktop-app-testing/SKILL.md +104 -0
- package/skills/desktop-app-testing/evals/triggers.json +16 -0
- package/skills/desktop-app-testing/references/drivers.md +81 -0
- package/skills/django-patterns/SKILL.md +123 -0
- package/skills/django-patterns/evals/triggers.json +16 -0
- package/skills/docker-patterns/SKILL.md +132 -0
- package/skills/docker-patterns/evals/triggers.json +16 -0
- package/skills/docker-patterns/references/dockerfiles.md +105 -0
- package/skills/document-processing/SKILL.md +100 -0
- package/skills/document-processing/evals/triggers.json +17 -0
- package/skills/document-processing/references/extraction-and-ocr.md +71 -0
- package/skills/document-processing/references/forms-and-conversion.md +69 -0
- package/skills/document-processing/references/redaction.md +61 -0
- package/skills/e2e-testing-playwright/SKILL.md +94 -0
- package/skills/e2e-testing-playwright/evals/triggers.json +16 -0
- package/skills/e2e-testing-playwright/references/config-and-ci.md +129 -0
- package/skills/ef-core-patterns/SKILL.md +117 -0
- package/skills/ef-core-patterns/evals/triggers.json +16 -0
- package/skills/email-deliverability/SKILL.md +99 -0
- package/skills/email-deliverability/evals/triggers.json +17 -0
- package/skills/email-deliverability/references/dns-records.md +85 -0
- package/skills/energy-procurement/SKILL.md +106 -0
- package/skills/energy-procurement/evals/triggers.json +16 -0
- package/skills/error-handling-patterns/SKILL.md +112 -0
- package/skills/error-handling-patterns/evals/triggers.json +18 -0
- package/skills/error-handling-patterns/references/language-idioms.md +49 -0
- package/skills/estimation-and-scoping/SKILL.md +97 -0
- package/skills/estimation-and-scoping/evals/triggers.json +14 -0
- package/skills/evm-dapp-integration/SKILL.md +73 -0
- package/skills/evm-dapp-integration/evals/triggers.json +16 -0
- package/skills/fastapi-patterns/SKILL.md +127 -0
- package/skills/fastapi-patterns/evals/triggers.json +16 -0
- package/skills/ffmpeg-media-processing/SKILL.md +94 -0
- package/skills/ffmpeg-media-processing/evals/triggers.json +16 -0
- package/skills/ffmpeg-media-processing/references/recipes.md +112 -0
- package/skills/fhir-integration/SKILL.md +81 -0
- package/skills/fhir-integration/evals/triggers.json +16 -0
- package/skills/fhir-integration/references/search-and-bundles.md +73 -0
- package/skills/fhir-integration/references/smart-on-fhir.md +50 -0
- package/skills/finishing-a-branch/SKILL.md +127 -0
- package/skills/finishing-a-branch/evals/behavior.json +49 -0
- package/skills/finishing-a-branch/evals/triggers.json +16 -0
- package/skills/flask-patterns/SKILL.md +132 -0
- package/skills/flask-patterns/evals/triggers.json +16 -0
- package/skills/flutter-patterns/SKILL.md +99 -0
- package/skills/flutter-patterns/evals/triggers.json +16 -0
- package/skills/flutterwave-integration/SKILL.md +75 -0
- package/skills/flutterwave-integration/evals/triggers.json +16 -0
- package/skills/flutterwave-integration/references/api.md +73 -0
- package/skills/flutterwave-integration/references/webhooks.md +49 -0
- package/skills/freight-carrier-management/SKILL.md +107 -0
- package/skills/freight-carrier-management/evals/triggers.json +16 -0
- package/skills/fsharp-patterns/SKILL.md +133 -0
- package/skills/fsharp-patterns/evals/triggers.json +16 -0
- package/skills/fsharp-testing/SKILL.md +136 -0
- package/skills/fsharp-testing/evals/triggers.json +16 -0
- package/skills/gcp-patterns/SKILL.md +86 -0
- package/skills/gcp-patterns/evals/triggers.json +16 -0
- package/skills/git-workflow/SKILL.md +114 -0
- package/skills/git-workflow/evals/triggers.json +16 -0
- package/skills/git-worktrees/SKILL.md +130 -0
- package/skills/git-worktrees/evals/behavior.json +56 -0
- package/skills/git-worktrees/evals/triggers.json +16 -0
- package/skills/github-actions-ci/SKILL.md +117 -0
- package/skills/github-actions-ci/evals/triggers.json +16 -0
- package/skills/github-api-automation/SKILL.md +101 -0
- package/skills/github-api-automation/evals/triggers.json +17 -0
- package/skills/go-patterns/SKILL.md +118 -0
- package/skills/go-patterns/evals/triggers.json +17 -0
- package/skills/go-patterns/references/concurrency.md +162 -0
- package/skills/go-testing/SKILL.md +154 -0
- package/skills/go-testing/evals/triggers.json +17 -0
- package/skills/google-workspace-integration/SKILL.md +65 -0
- package/skills/google-workspace-integration/evals/triggers.json +17 -0
- package/skills/google-workspace-integration/references/api.md +121 -0
- package/skills/harmonyos-arkts/SKILL.md +117 -0
- package/skills/harmonyos-arkts/evals/triggers.json +16 -0
- package/skills/harmonyos-arkts/references/build-errors.md +42 -0
- package/skills/hexagonal-architecture/SKILL.md +89 -0
- package/skills/hexagonal-architecture/evals/triggers.json +17 -0
- package/skills/hipaa-compliance/SKILL.md +91 -0
- package/skills/hipaa-compliance/evals/triggers.json +18 -0
- package/skills/hipaa-compliance/references/safeguards.md +68 -0
- package/skills/hl7v2-integration/SKILL.md +69 -0
- package/skills/hl7v2-integration/evals/triggers.json +16 -0
- package/skills/hl7v2-integration/references/messages-and-ack.md +78 -0
- package/skills/homelab-network-setup/SKILL.md +125 -0
- package/skills/homelab-network-setup/evals/triggers.json +18 -0
- package/skills/homelab-network-setup/references/firewall-and-dns.md +45 -0
- package/skills/homelab-network-setup/references/wireguard.md +72 -0
- package/skills/hubtel-integration/SKILL.md +77 -0
- package/skills/hubtel-integration/evals/triggers.json +16 -0
- package/skills/hubtel-integration/references/api.md +92 -0
- package/skills/i18n-localization/SKILL.md +114 -0
- package/skills/i18n-localization/evals/triggers.json +16 -0
- package/skills/i18n-localization/references/libraries.md +52 -0
- package/skills/implementation-plans/SKILL.md +117 -0
- package/skills/implementation-plans/evals/behavior.json +54 -0
- package/skills/implementation-plans/evals/triggers.json +16 -0
- package/skills/incident-postmortem/SKILL.md +118 -0
- package/skills/incident-postmortem/evals/triggers.json +14 -0
- package/skills/inventory-demand-planning/SKILL.md +89 -0
- package/skills/inventory-demand-planning/evals/triggers.json +16 -0
- package/skills/inventory-demand-planning/references/formulas.md +62 -0
- package/skills/investor-materials/SKILL.md +127 -0
- package/skills/investor-materials/evals/triggers.json +16 -0
- package/skills/investor-materials/references/templates.md +74 -0
- package/skills/invoicing-and-tax/SKILL.md +84 -0
- package/skills/invoicing-and-tax/evals/triggers.json +17 -0
- package/skills/invoicing-and-tax/references/e-invoicing.md +24 -0
- package/skills/invoicing-and-tax/references/invoice-fields.md +38 -0
- package/skills/invoicing-and-tax/references/rounding.md +26 -0
- package/skills/ios-platform-features/SKILL.md +99 -0
- package/skills/ios-platform-features/evals/triggers.json +16 -0
- package/skills/ios-platform-features/references/foundation-models.md +90 -0
- package/skills/java-patterns/SKILL.md +141 -0
- package/skills/java-patterns/evals/triggers.json +17 -0
- package/skills/java-testing/SKILL.md +142 -0
- package/skills/java-testing/evals/triggers.json +16 -0
- package/skills/jetpack-compose-patterns/SKILL.md +88 -0
- package/skills/jetpack-compose-patterns/evals/triggers.json +16 -0
- package/skills/jira-integration/SKILL.md +92 -0
- package/skills/jira-integration/evals/triggers.json +17 -0
- package/skills/jpa-hibernate/SKILL.md +92 -0
- package/skills/jpa-hibernate/evals/triggers.json +18 -0
- package/skills/jpa-hibernate/references/mapping.md +99 -0
- package/skills/jvm-sql-mappers/SKILL.md +98 -0
- package/skills/jvm-sql-mappers/evals/triggers.json +16 -0
- package/skills/jvm-sql-mappers/references/examples.md +129 -0
- package/skills/kotlin-multiplatform/SKILL.md +97 -0
- package/skills/kotlin-multiplatform/evals/triggers.json +16 -0
- package/skills/kotlin-patterns/SKILL.md +128 -0
- package/skills/kotlin-patterns/evals/triggers.json +16 -0
- package/skills/kotlin-testing/SKILL.md +117 -0
- package/skills/kotlin-testing/evals/triggers.json +16 -0
- package/skills/ktor-patterns/SKILL.md +135 -0
- package/skills/ktor-patterns/evals/triggers.json +18 -0
- package/skills/kubernetes-patterns/SKILL.md +106 -0
- package/skills/kubernetes-patterns/evals/triggers.json +16 -0
- package/skills/kubernetes-patterns/references/manifests.md +115 -0
- package/skills/laravel-patterns/SKILL.md +136 -0
- package/skills/laravel-patterns/evals/triggers.json +16 -0
- package/skills/linear-integration/SKILL.md +98 -0
- package/skills/linear-integration/evals/triggers.json +17 -0
- package/skills/literature-review/SKILL.md +109 -0
- package/skills/literature-review/evals/triggers.json +16 -0
- package/skills/literature-review/references/appraisal.md +41 -0
- package/skills/literature-review/references/search-sources.md +39 -0
- package/skills/llm-app-patterns/SKILL.md +97 -0
- package/skills/llm-app-patterns/evals/triggers.json +17 -0
- package/skills/llm-evals/SKILL.md +98 -0
- package/skills/llm-evals/evals/triggers.json +16 -0
- package/skills/llm-evals/references/graders.md +66 -0
- package/skills/logistics-exception-management/SKILL.md +90 -0
- package/skills/logistics-exception-management/evals/triggers.json +16 -0
- package/skills/manim-animations/SKILL.md +106 -0
- package/skills/manim-animations/evals/triggers.json +16 -0
- package/skills/market-research/SKILL.md +117 -0
- package/skills/market-research/evals/triggers.json +16 -0
- package/skills/marketing-campaign/SKILL.md +111 -0
- package/skills/marketing-campaign/evals/triggers.json +16 -0
- package/skills/mcp-server-patterns/SKILL.md +127 -0
- package/skills/mcp-server-patterns/evals/triggers.json +18 -0
- package/skills/mcp-server-patterns/references/protocol-notes.md +68 -0
- package/skills/metrics-dashboards/SKILL.md +113 -0
- package/skills/metrics-dashboards/evals/triggers.json +16 -0
- package/skills/ml-experiment-workflow/SKILL.md +125 -0
- package/skills/ml-experiment-workflow/evals/triggers.json +16 -0
- package/skills/mobile-accessibility/SKILL.md +94 -0
- package/skills/mobile-accessibility/evals/triggers.json +16 -0
- package/skills/mongodb-patterns/SKILL.md +115 -0
- package/skills/mongodb-patterns/evals/triggers.json +18 -0
- package/skills/mongodb-patterns/references/indexes-and-aggregation.md +94 -0
- package/skills/mpesa-daraja-integration/SKILL.md +70 -0
- package/skills/mpesa-daraja-integration/evals/triggers.json +16 -0
- package/skills/mpesa-daraja-integration/references/api.md +103 -0
- package/skills/mpesa-daraja-integration/references/callbacks.md +74 -0
- package/skills/mtn-momo-integration/SKILL.md +66 -0
- package/skills/mtn-momo-integration/evals/triggers.json +16 -0
- package/skills/mtn-momo-integration/references/api.md +153 -0
- package/skills/mtn-momo-integration/references/callbacks.md +92 -0
- package/skills/mtn-momo-integration/references/sandbox-and-go-live.md +51 -0
- package/skills/mtn-momo-integration/scripts/sandbox-setup.js +79 -0
- package/skills/mysql-patterns/SKILL.md +96 -0
- package/skills/mysql-patterns/evals/triggers.json +16 -0
- package/skills/mysql-patterns/references/explain.md +34 -0
- package/skills/mysql-patterns/references/online-ddl.md +41 -0
- package/skills/nestjs-patterns/SKILL.md +114 -0
- package/skills/nestjs-patterns/evals/triggers.json +16 -0
- package/skills/nestjs-patterns/references/testing.md +68 -0
- package/skills/network-automation/SKILL.md +107 -0
- package/skills/network-automation/evals/triggers.json +18 -0
- package/skills/network-automation/references/tool-snippets.md +153 -0
- package/skills/network-design/SKILL.md +98 -0
- package/skills/network-design/evals/triggers.json +16 -0
- package/skills/network-troubleshooting/SKILL.md +152 -0
- package/skills/network-troubleshooting/evals/triggers.json +18 -0
- package/skills/network-troubleshooting/references/commands.md +33 -0
- package/skills/nextjs-patterns/SKILL.md +150 -0
- package/skills/nextjs-patterns/evals/triggers.json +18 -0
- package/skills/nextjs-patterns/references/caching.md +87 -0
- package/skills/node-backend-patterns/SKILL.md +103 -0
- package/skills/node-backend-patterns/evals/triggers.json +16 -0
- package/skills/node-backend-patterns/references/templates.md +122 -0
- package/skills/nuxt-patterns/SKILL.md +103 -0
- package/skills/nuxt-patterns/evals/triggers.json +16 -0
- package/skills/observability/SKILL.md +125 -0
- package/skills/observability/evals/triggers.json +17 -0
- package/skills/observability/references/otel-setup.md +87 -0
- package/skills/observability/references/slo-alerts.md +70 -0
- package/skills/open-source-release/SKILL.md +107 -0
- package/skills/open-source-release/evals/triggers.json +15 -0
- package/skills/open-source-release/references/history-scrub.md +65 -0
- package/skills/parallel-agent-orchestration/SKILL.md +106 -0
- package/skills/parallel-agent-orchestration/evals/triggers.json +14 -0
- package/skills/patent-research/SKILL.md +94 -0
- package/skills/patent-research/evals/triggers.json +16 -0
- package/skills/patent-research/references/databases-and-queries.md +52 -0
- package/skills/paystack-integration/SKILL.md +59 -0
- package/skills/paystack-integration/evals/triggers.json +14 -0
- package/skills/paystack-integration/references/api.md +73 -0
- package/skills/paystack-integration/references/mobile-money.md +50 -0
- package/skills/paystack-integration/references/webhooks.md +80 -0
- package/skills/pci-dss-scope/SKILL.md +103 -0
- package/skills/pci-dss-scope/evals/triggers.json +18 -0
- package/skills/pci-dss-scope/references/saq-and-data.md +36 -0
- package/skills/perl-patterns/SKILL.md +135 -0
- package/skills/perl-patterns/evals/triggers.json +18 -0
- package/skills/perl-testing/SKILL.md +126 -0
- package/skills/perl-testing/evals/triggers.json +17 -0
- package/skills/php-patterns/SKILL.md +116 -0
- package/skills/php-patterns/evals/triggers.json +16 -0
- package/skills/php-testing/SKILL.md +123 -0
- package/skills/php-testing/evals/triggers.json +16 -0
- package/skills/postgres-patterns/SKILL.md +103 -0
- package/skills/postgres-patterns/evals/triggers.json +17 -0
- package/skills/postgres-patterns/references/explain.md +59 -0
- package/skills/postgres-patterns/references/locks.md +53 -0
- package/skills/prd-writing/SKILL.md +124 -0
- package/skills/prd-writing/evals/triggers.json +15 -0
- package/skills/prisma-patterns/SKILL.md +83 -0
- package/skills/prisma-patterns/evals/triggers.json +18 -0
- package/skills/prisma-patterns/references/prisma-8.md +46 -0
- package/skills/prisma-patterns/references/workflow.md +50 -0
- package/skills/privacy-compliance/SKILL.md +121 -0
- package/skills/privacy-compliance/evals/triggers.json +18 -0
- package/skills/privacy-compliance/references/jurisdictions.md +51 -0
- package/skills/production-scheduling/SKILL.md +98 -0
- package/skills/production-scheduling/evals/triggers.json +16 -0
- package/skills/prompt-engineering/SKILL.md +92 -0
- package/skills/prompt-engineering/evals/triggers.json +16 -0
- package/skills/prospect-research/SKILL.md +87 -0
- package/skills/prospect-research/evals/triggers.json +16 -0
- package/skills/python-app-distribution/SKILL.md +107 -0
- package/skills/python-app-distribution/evals/triggers.json +16 -0
- package/skills/python-app-distribution/references/pypi-trusted-publishing.md +55 -0
- package/skills/python-app-distribution/references/windows-macos-signing.md +70 -0
- package/skills/python-patterns/SKILL.md +107 -0
- package/skills/python-patterns/evals/triggers.json +16 -0
- package/skills/python-patterns/references/tooling.md +101 -0
- package/skills/python-testing/SKILL.md +126 -0
- package/skills/python-testing/evals/triggers.json +16 -0
- package/skills/python-testing/references/mocking.md +71 -0
- package/skills/pytorch-patterns/SKILL.md +139 -0
- package/skills/pytorch-patterns/evals/triggers.json +16 -0
- package/skills/pytorch-patterns/references/debugging.md +39 -0
- package/skills/quality-nonconformance/SKILL.md +107 -0
- package/skills/quality-nonconformance/evals/triggers.json +16 -0
- package/skills/quality-nonconformance/references/8d-and-capa.md +46 -0
- package/skills/quarkus-patterns/SKILL.md +93 -0
- package/skills/quarkus-patterns/evals/triggers.json +18 -0
- package/skills/rag-pipeline-patterns/SKILL.md +117 -0
- package/skills/rag-pipeline-patterns/evals/triggers.json +18 -0
- package/skills/rag-pipeline-patterns/references/evaluation.md +37 -0
- package/skills/rag-pipeline-patterns/references/retrieval-recipes.md +78 -0
- package/skills/rails-patterns/SKILL.md +132 -0
- package/skills/rails-patterns/evals/triggers.json +16 -0
- package/skills/react-native-patterns/SKILL.md +101 -0
- package/skills/react-native-patterns/evals/triggers.json +16 -0
- package/skills/react-patterns/SKILL.md +140 -0
- package/skills/react-patterns/evals/triggers.json +18 -0
- package/skills/react-performance/SKILL.md +107 -0
- package/skills/react-performance/evals/triggers.json +18 -0
- package/skills/react-testing/SKILL.md +121 -0
- package/skills/react-testing/evals/triggers.json +18 -0
- package/skills/react-testing/references/msw.md +64 -0
- package/skills/react-testing/references/queries.md +41 -0
- package/skills/react-testing/references/setup.md +74 -0
- package/skills/recommender-systems/SKILL.md +119 -0
- package/skills/recommender-systems/evals/triggers.json +16 -0
- package/skills/recommender-systems/references/evaluation.md +39 -0
- package/skills/redis-patterns/SKILL.md +109 -0
- package/skills/redis-patterns/evals/triggers.json +18 -0
- package/skills/redis-patterns/references/operations.md +61 -0
- package/skills/refactoring-safely/SKILL.md +107 -0
- package/skills/refactoring-safely/evals/behavior.json +57 -0
- package/skills/refactoring-safely/evals/triggers.json +17 -0
- package/skills/release-management/SKILL.md +141 -0
- package/skills/release-management/evals/triggers.json +16 -0
- package/skills/remotion-video/SKILL.md +91 -0
- package/skills/remotion-video/evals/triggers.json +16 -0
- package/skills/remotion-video/references/lambda.md +66 -0
- package/skills/reproducible-dev-environments/SKILL.md +132 -0
- package/skills/reproducible-dev-environments/evals/triggers.json +16 -0
- package/skills/responding-to-code-review/SKILL.md +124 -0
- package/skills/responding-to-code-review/evals/behavior.json +54 -0
- package/skills/responding-to-code-review/evals/triggers.json +16 -0
- package/skills/returns-reverse-logistics/SKILL.md +97 -0
- package/skills/returns-reverse-logistics/evals/triggers.json +16 -0
- package/skills/ruby-patterns/SKILL.md +127 -0
- package/skills/ruby-patterns/evals/triggers.json +18 -0
- package/skills/ruby-testing/SKILL.md +113 -0
- package/skills/ruby-testing/evals/triggers.json +18 -0
- package/skills/runbook-writing/SKILL.md +101 -0
- package/skills/runbook-writing/evals/triggers.json +14 -0
- package/skills/rust-patterns/SKILL.md +118 -0
- package/skills/rust-patterns/evals/triggers.json +16 -0
- package/skills/rust-patterns/references/cargo-and-clippy.md +105 -0
- package/skills/rust-patterns/references/errors-and-traits.md +97 -0
- package/skills/rust-testing/SKILL.md +148 -0
- package/skills/rust-testing/evals/triggers.json +16 -0
- package/skills/rust-testing/references/fakes-proptest-async.md +113 -0
- package/skills/search-first/SKILL.md +73 -0
- package/skills/search-first/evals/triggers.json +14 -0
- package/skills/security-review/SKILL.md +58 -0
- package/skills/security-review/evals/behavior.json +56 -0
- package/skills/security-review/evals/triggers.json +14 -0
- package/skills/security-review/references/checklist.md +54 -0
- package/skills/security-review/scripts/scan-secrets.js +79 -0
- package/skills/seo-audit/SKILL.md +111 -0
- package/skills/seo-audit/evals/triggers.json +16 -0
- package/skills/seo-audit/references/checks.md +65 -0
- package/skills/session-handoff/SKILL.md +101 -0
- package/skills/session-handoff/evals/behavior.json +55 -0
- package/skills/session-handoff/evals/triggers.json +14 -0
- package/skills/skill-authoring/SKILL.md +98 -0
- package/skills/skill-authoring/evals/triggers.json +15 -0
- package/skills/skill-authoring/references/frontmatter.md +40 -0
- package/skills/skill-authoring/references/pressure-testing.md +87 -0
- package/skills/slack-app-integration/SKILL.md +108 -0
- package/skills/slack-app-integration/evals/triggers.json +17 -0
- package/skills/slide-decks/SKILL.md +107 -0
- package/skills/slide-decks/evals/triggers.json +18 -0
- package/skills/slide-decks/references/html-decks.md +86 -0
- package/skills/slide-decks/references/layouts.md +45 -0
- package/skills/slide-decks/references/pptx.md +87 -0
- package/skills/smart-contract-security/SKILL.md +110 -0
- package/skills/smart-contract-security/evals/triggers.json +16 -0
- package/skills/smart-contract-security/references/vulnerability-checklist.md +79 -0
- package/skills/social-media-publishing/SKILL.md +84 -0
- package/skills/social-media-publishing/evals/triggers.json +17 -0
- package/skills/social-media-publishing/references/platform-apis.md +116 -0
- package/skills/solidity-patterns/SKILL.md +95 -0
- package/skills/solidity-patterns/evals/triggers.json +16 -0
- package/skills/spring-boot-patterns/SKILL.md +128 -0
- package/skills/spring-boot-patterns/evals/triggers.json +18 -0
- package/skills/spring-boot-patterns/references/testing.md +72 -0
- package/skills/stripe-integration/SKILL.md +69 -0
- package/skills/stripe-integration/evals/triggers.json +16 -0
- package/skills/stripe-integration/references/api.md +71 -0
- package/skills/stripe-integration/references/billing.md +58 -0
- package/skills/stripe-integration/references/webhooks.md +76 -0
- package/skills/subagent-driven-development/SKILL.md +109 -0
- package/skills/subagent-driven-development/evals/behavior.json +53 -0
- package/skills/subagent-driven-development/evals/triggers.json +15 -0
- package/skills/subagent-driven-development/references/implementer-brief.md +60 -0
- package/skills/subagent-driven-development/references/reviewer-briefs.md +52 -0
- package/skills/subscription-billing-ops/SKILL.md +118 -0
- package/skills/subscription-billing-ops/evals/triggers.json +17 -0
- package/skills/subscription-billing-ops/references/proration.md +47 -0
- package/skills/subscription-billing-ops/references/revenue-metrics.md +38 -0
- package/skills/svelte-patterns/SKILL.md +122 -0
- package/skills/svelte-patterns/evals/triggers.json +16 -0
- package/skills/swift-patterns/SKILL.md +113 -0
- package/skills/swift-patterns/evals/triggers.json +16 -0
- package/skills/swift-patterns/references/concurrency-migration.md +40 -0
- package/skills/swift-testing/SKILL.md +121 -0
- package/skills/swift-testing/evals/triggers.json +16 -0
- package/skills/swift-testing/references/swift-testing-cheatsheet.md +81 -0
- package/skills/swiftui-patterns/SKILL.md +102 -0
- package/skills/swiftui-patterns/evals/triggers.json +16 -0
- package/skills/systematic-debugging/SKILL.md +92 -0
- package/skills/systematic-debugging/evals/behavior.json +59 -0
- package/skills/systematic-debugging/evals/triggers.json +16 -0
- package/skills/systematic-debugging/references/condition-waiting.md +52 -0
- package/skills/systematic-debugging/references/root-cause-tracing.md +49 -0
- package/skills/systematic-debugging/references/test-pollution.md +46 -0
- package/skills/tdd-workflow/SKILL.md +69 -0
- package/skills/tdd-workflow/evals/behavior.json +55 -0
- package/skills/tdd-workflow/evals/triggers.json +15 -0
- package/skills/tdd-workflow/references/testing-anti-patterns.md +87 -0
- package/skills/technical-writing/SKILL.md +95 -0
- package/skills/technical-writing/evals/triggers.json +14 -0
- package/skills/terraform-patterns/SKILL.md +122 -0
- package/skills/terraform-patterns/evals/triggers.json +16 -0
- package/skills/terraform-patterns/references/backends.md +67 -0
- package/skills/test-coverage-improvement/SKILL.md +107 -0
- package/skills/test-coverage-improvement/evals/triggers.json +16 -0
- package/skills/threat-modeling/SKILL.md +113 -0
- package/skills/threat-modeling/evals/triggers.json +16 -0
- package/skills/transactional-email/SKILL.md +68 -0
- package/skills/transactional-email/evals/triggers.json +17 -0
- package/skills/transactional-email/references/providers.md +63 -0
- package/skills/typescript-patterns/SKILL.md +122 -0
- package/skills/typescript-patterns/evals/triggers.json +16 -0
- package/skills/typescript-testing/SKILL.md +101 -0
- package/skills/typescript-testing/evals/triggers.json +16 -0
- package/skills/ui-demo-recording/SKILL.md +93 -0
- package/skills/ui-demo-recording/evals/triggers.json +16 -0
- package/skills/ui-demo-recording/references/cursor-and-captions.md +48 -0
- package/skills/ui-demo-recording/references/playwright-recording.md +63 -0
- package/skills/ui-demo-recording/references/post-processing.md +57 -0
- package/skills/ui-design-polish/SKILL.md +113 -0
- package/skills/ui-design-polish/evals/triggers.json +18 -0
- package/skills/ui-design-polish/references/detail-checklist.md +45 -0
- package/skills/ui-design-polish/references/tokens.md +68 -0
- package/skills/ui-flow-audit/SKILL.md +112 -0
- package/skills/ui-flow-audit/evals/triggers.json +17 -0
- package/skills/ui-motion/SKILL.md +103 -0
- package/skills/ui-motion/evals/triggers.json +18 -0
- package/skills/ui-motion/references/patterns.md +138 -0
- package/skills/ui-motion/references/tokens.md +52 -0
- package/skills/unicode-text-processing/SKILL.md +103 -0
- package/skills/unicode-text-processing/evals/triggers.json +17 -0
- package/skills/unicode-text-processing/references/apis.md +89 -0
- package/skills/unicode-text-processing/references/script-notes.md +50 -0
- package/skills/verification-loop/SKILL.md +70 -0
- package/skills/verification-loop/evals/behavior.json +52 -0
- package/skills/verification-loop/evals/triggers.json +14 -0
- package/skills/verification-loop/scripts/detect-checks.js +102 -0
- package/skills/video-editing/SKILL.md +111 -0
- package/skills/video-editing/evals/triggers.json +16 -0
- package/skills/video-editing/references/edl-and-logging.md +44 -0
- package/skills/video-editing/references/ffmpeg-edit-recipes.md +92 -0
- package/skills/video-editing/references/resolve-scripting.md +53 -0
- package/skills/vite-patterns/SKILL.md +117 -0
- package/skills/vite-patterns/evals/triggers.json +16 -0
- package/skills/vue-patterns/SKILL.md +104 -0
- package/skills/vue-patterns/evals/triggers.json +16 -0
- package/skills/web-accessibility/SKILL.md +119 -0
- package/skills/web-accessibility/evals/triggers.json +16 -0
- package/skills/web-performance/SKILL.md +107 -0
- package/skills/web-performance/evals/triggers.json +16 -0
- package/skills/web-scraping/SKILL.md +80 -0
- package/skills/web-scraping/evals/triggers.json +16 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Go concurrency patterns
|
|
2
|
+
|
|
3
|
+
Each pattern stops cleanly when the context is cancelled and waits for every goroutine it starts.
|
|
4
|
+
|
|
5
|
+
## Fan-out with errgroup and a concurrency limit
|
|
6
|
+
|
|
7
|
+
```go
|
|
8
|
+
import "golang.org/x/sync/errgroup"
|
|
9
|
+
|
|
10
|
+
func fetchAll(ctx context.Context, ids []string) ([]Item, error) {
|
|
11
|
+
items := make([]Item, len(ids)) // each goroutine writes its own index: no lock needed
|
|
12
|
+
g, ctx := errgroup.WithContext(ctx)
|
|
13
|
+
g.SetLimit(8)
|
|
14
|
+
for i, id := range ids {
|
|
15
|
+
g.Go(func() error {
|
|
16
|
+
it, err := fetch(ctx, id)
|
|
17
|
+
if err != nil {
|
|
18
|
+
return fmt.Errorf("fetch %s: %w", id, err)
|
|
19
|
+
}
|
|
20
|
+
items[i] = it
|
|
21
|
+
return nil
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
if err := g.Wait(); err != nil {
|
|
25
|
+
return nil, err
|
|
26
|
+
}
|
|
27
|
+
return items, nil
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Since Go 1.22 each loop iteration has its own `i` and `id`, so capturing them is safe. On a module whose `go` directive is older than 1.22, copy them first (`i, id := i, id`).
|
|
32
|
+
|
|
33
|
+
## Worker pool over a channel
|
|
34
|
+
|
|
35
|
+
```go
|
|
36
|
+
func process(ctx context.Context, jobs []Job, workers int) error {
|
|
37
|
+
in := make(chan Job)
|
|
38
|
+
g, ctx := errgroup.WithContext(ctx)
|
|
39
|
+
|
|
40
|
+
g.Go(func() error { // producer owns and closes in
|
|
41
|
+
defer close(in)
|
|
42
|
+
for _, j := range jobs {
|
|
43
|
+
select {
|
|
44
|
+
case in <- j:
|
|
45
|
+
case <-ctx.Done():
|
|
46
|
+
return ctx.Err()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return nil
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
for range workers {
|
|
53
|
+
g.Go(func() error {
|
|
54
|
+
for j := range in {
|
|
55
|
+
if err := handle(ctx, j); err != nil {
|
|
56
|
+
return err
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return nil
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
return g.Wait()
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`for range workers` (ranging over an int) needs Go 1.22+; use `for i := 0; i < workers; i++` on older modules.
|
|
67
|
+
|
|
68
|
+
## Pipeline stage that cannot leak
|
|
69
|
+
|
|
70
|
+
```go
|
|
71
|
+
func squares(ctx context.Context, in <-chan int) <-chan int {
|
|
72
|
+
out := make(chan int)
|
|
73
|
+
go func() {
|
|
74
|
+
defer close(out)
|
|
75
|
+
for v := range in {
|
|
76
|
+
select {
|
|
77
|
+
case out <- v * v:
|
|
78
|
+
case <-ctx.Done():
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}()
|
|
83
|
+
return out
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The `select` on `ctx.Done()` is what prevents the leak: without it the goroutine blocks forever on `out <-` once the consumer stops reading.
|
|
88
|
+
|
|
89
|
+
## First result wins (with no leak)
|
|
90
|
+
|
|
91
|
+
```go
|
|
92
|
+
func first(ctx context.Context, replicas []string) (Result, error) {
|
|
93
|
+
ctx, cancel := context.WithCancel(ctx)
|
|
94
|
+
defer cancel()
|
|
95
|
+
ch := make(chan Result, len(replicas)) // buffered: losers never block
|
|
96
|
+
for _, r := range replicas {
|
|
97
|
+
go func() {
|
|
98
|
+
if res, err := query(ctx, r); err == nil {
|
|
99
|
+
ch <- res
|
|
100
|
+
}
|
|
101
|
+
}()
|
|
102
|
+
}
|
|
103
|
+
select {
|
|
104
|
+
case res := <-ch:
|
|
105
|
+
return res, nil
|
|
106
|
+
case <-ctx.Done():
|
|
107
|
+
return Result{}, ctx.Err()
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If every replica fails this waits for the parent context; add a timeout or count failures if that is not acceptable.
|
|
113
|
+
|
|
114
|
+
## Mutex-guarded state
|
|
115
|
+
|
|
116
|
+
```go
|
|
117
|
+
type Counter struct {
|
|
118
|
+
mu sync.Mutex
|
|
119
|
+
n map[string]int // guarded by mu
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
func (c *Counter) Inc(k string) {
|
|
123
|
+
c.mu.Lock()
|
|
124
|
+
defer c.mu.Unlock()
|
|
125
|
+
if c.n == nil {
|
|
126
|
+
c.n = make(map[string]int)
|
|
127
|
+
}
|
|
128
|
+
c.n[k]++
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Methods use a pointer receiver so the mutex is never copied. `go vet` (copylocks) flags copies.
|
|
133
|
+
|
|
134
|
+
## Graceful HTTP shutdown
|
|
135
|
+
|
|
136
|
+
```go
|
|
137
|
+
func run(ctx context.Context) error {
|
|
138
|
+
ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
|
|
139
|
+
defer stop()
|
|
140
|
+
|
|
141
|
+
srv := &http.Server{Addr: ":8080", Handler: routes(), ReadHeaderTimeout: 5 * time.Second}
|
|
142
|
+
errCh := make(chan error, 1)
|
|
143
|
+
go func() { errCh <- srv.ListenAndServe() }()
|
|
144
|
+
|
|
145
|
+
select {
|
|
146
|
+
case err := <-errCh:
|
|
147
|
+
return err
|
|
148
|
+
case <-ctx.Done():
|
|
149
|
+
}
|
|
150
|
+
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
151
|
+
defer cancel()
|
|
152
|
+
return srv.Shutdown(shutdownCtx)
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`ListenAndServe` returns `http.ErrServerClosed` after `Shutdown`; treat that as success if you read `errCh` afterwards. The shutdown context is deliberately new: the signal context is already cancelled.
|
|
157
|
+
|
|
158
|
+
## Detecting leaks and races
|
|
159
|
+
|
|
160
|
+
- `go test -race ./...` on every change that touches goroutines or shared state.
|
|
161
|
+
- `go.uber.org/goleak` (`defer goleak.VerifyNone(t)` or `goleak.VerifyTestMain(m)`) catches goroutines still running at test end, if the project accepts the dependency.
|
|
162
|
+
- A goroutine dump (`SIGQUIT`, or `net/http/pprof` at `/debug/pprof/goroutine?debug=2`) shows where leaked goroutines are blocked.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: go-testing
|
|
3
|
+
description: Writes and fixes Go tests with the standard testing package, including table-driven tests with t.Run subtests, t.Helper and t.Cleanup, httptest servers and recorders, hand-written fakes instead of mock frameworks, the race detector, native fuzzing, benchmarks and golden files. Use when adding or repairing _test.go files, making flaky Go tests deterministic, testing an HTTP handler or client in Go, or writing a Go fuzz target or benchmark.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Needs the go toolchain.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: testing
|
|
9
|
+
kete-loom/risk: runs-commands
|
|
10
|
+
kete-loom/requires: "go"
|
|
11
|
+
kete-loom/owner: "Kete-org"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Go testing
|
|
15
|
+
|
|
16
|
+
Use the standard `testing` package and the project's existing test style. Add an assertion library only if the project already uses one.
|
|
17
|
+
|
|
18
|
+
## 0. Before you write
|
|
19
|
+
|
|
20
|
+
1. Find the test command (Makefile, CI workflow, README). Default: `go test ./...`.
|
|
21
|
+
2. Run the package's tests once and record the result. If they already fail, **stop and tell the user** which ones before changing anything.
|
|
22
|
+
3. Read the `go` directive in `go.mod`; do not use testing APIs newer than it.
|
|
23
|
+
4. Look at a neighbouring `_test.go` file for naming, helpers, fixtures and whether tests are in `package foo` (white-box) or `package foo_test` (black-box). Prefer `foo_test` for testing the public API.
|
|
24
|
+
|
|
25
|
+
## 1. Table-driven tests with subtests
|
|
26
|
+
|
|
27
|
+
```go
|
|
28
|
+
func TestParseDuration(t *testing.T) {
|
|
29
|
+
tests := []struct {
|
|
30
|
+
name string
|
|
31
|
+
in string
|
|
32
|
+
want time.Duration
|
|
33
|
+
wantErr bool
|
|
34
|
+
}{
|
|
35
|
+
{name: "minutes", in: "5m", want: 5 * time.Minute},
|
|
36
|
+
{name: "empty", in: "", wantErr: true},
|
|
37
|
+
{name: "negative", in: "-1s", wantErr: true},
|
|
38
|
+
}
|
|
39
|
+
for _, tt := range tests {
|
|
40
|
+
t.Run(tt.name, func(t *testing.T) {
|
|
41
|
+
got, err := ParseDuration(tt.in)
|
|
42
|
+
if (err != nil) != tt.wantErr {
|
|
43
|
+
t.Fatalf("ParseDuration(%q) error = %v, wantErr %v", tt.in, err, tt.wantErr)
|
|
44
|
+
}
|
|
45
|
+
if got != tt.want {
|
|
46
|
+
t.Errorf("ParseDuration(%q) = %v, want %v", tt.in, got, tt.want)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Rules:
|
|
54
|
+
- Every case has a `name`; run one with `go test -run 'TestParseDuration/negative' ./pkg`.
|
|
55
|
+
- Failure messages say `Func(input) = got, want want`. Use `t.Errorf` to keep going, `t.Fatalf` only when later checks would be meaningless.
|
|
56
|
+
- Compare structs and slices with `github.com/google/go-cmp/cmp` (`cmp.Diff(want, got)`) if available, otherwise `reflect.DeepEqual`. Check errors with `errors.Is`, not string equality.
|
|
57
|
+
- `t.Parallel()` only when cases share no mutable state. On modules with a `go` directive before 1.22, copy the loop variable (`tt := tt`) before a parallel subtest.
|
|
58
|
+
|
|
59
|
+
## 2. Helpers and cleanup
|
|
60
|
+
|
|
61
|
+
- Call `t.Helper()` first in every helper that calls `t.Fatal`/`t.Error`, so failures point at the caller.
|
|
62
|
+
- Helpers take `t *testing.T` (or `testing.TB` to share with benchmarks) and fail directly instead of returning errors.
|
|
63
|
+
- Use `t.Context()` (Go 1.24+, cancelled just before cleanup runs) instead of `context.Background()` in tests where available.
|
|
64
|
+
- Use `t.Cleanup(fn)` for teardown, `t.TempDir()` for files, `t.Setenv` for environment variables (it cannot be combined with `t.Parallel`).
|
|
65
|
+
- Put fixture files in `testdata/`; the go tool ignores that directory when building.
|
|
66
|
+
|
|
67
|
+
## 3. Fakes over mocks
|
|
68
|
+
|
|
69
|
+
- Depend on a small interface at the consumer, then write a fake by hand in the test file: a struct with fields recording calls and returning canned results.
|
|
70
|
+
- Prefer real implementations when they are cheap: `bytes.Buffer` for `io.Writer`, `fstest.MapFS` for `fs.FS`, `httptest` for HTTP, an in-memory store.
|
|
71
|
+
- Do not add a mock generator to a project that does not already use one. Never mock the unit under test.
|
|
72
|
+
- Inject time and randomness (`now func() time.Time`, a seeded `*rand.Rand`) instead of sleeping or relying on wall time.
|
|
73
|
+
|
|
74
|
+
## 4. HTTP
|
|
75
|
+
|
|
76
|
+
- Handlers: `rec := httptest.NewRecorder(); req := httptest.NewRequest(http.MethodGet, "/items/1", nil); h.ServeHTTP(rec, req)`, then check `rec.Code`, headers and `rec.Body`.
|
|
77
|
+
- Clients: `srv := httptest.NewServer(http.HandlerFunc(...)); defer srv.Close()` and point the client at `srv.URL`. Use `httptest.NewTLSServer` with `srv.Client()` for TLS.
|
|
78
|
+
- Assert the request the fake server received (method, path, body) as well as the client's result.
|
|
79
|
+
- No real network calls in unit tests.
|
|
80
|
+
|
|
81
|
+
## 5. Concurrency and the race detector
|
|
82
|
+
|
|
83
|
+
- Run `go test -race ./...` for any package with goroutines or shared state. A race report is a bug to fix, not a flake.
|
|
84
|
+
- Never use `time.Sleep` to wait for a goroutine. Wait on a channel, a `sync.WaitGroup`, or poll a condition with a deadline.
|
|
85
|
+
- For code built on timers and goroutines, the `testing/synctest` package (`synctest.Test`, Go 1.25+) runs the test in a bubble with a fake clock; use it if the module's Go version allows.
|
|
86
|
+
- Find flakes with `go test -race -count=50 -run TestName ./pkg`. Use `-shuffle=on` to expose order dependence.
|
|
87
|
+
|
|
88
|
+
## 6. Fuzzing
|
|
89
|
+
|
|
90
|
+
```go
|
|
91
|
+
func FuzzParseDuration(f *testing.F) {
|
|
92
|
+
for _, s := range []string{"5m", "", "1h30m", "-1s"} {
|
|
93
|
+
f.Add(s)
|
|
94
|
+
}
|
|
95
|
+
f.Fuzz(func(t *testing.T, s string) {
|
|
96
|
+
d, err := ParseDuration(s)
|
|
97
|
+
if err != nil {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
if again, err := ParseDuration(d.String()); err != nil || again != d {
|
|
101
|
+
t.Fatalf("round trip %q -> %v -> %v, %v", s, d, again, err)
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- Run with `go test -fuzz=FuzzParseDuration -fuzztime=30s ./pkg`. Only one fuzz target per package per run.
|
|
108
|
+
- Assert properties (round trip, no panic, invariants), not exact outputs.
|
|
109
|
+
- Failing inputs are written to `testdata/fuzz/FuzzName/`. Commit them: they become regression cases run by a plain `go test`.
|
|
110
|
+
|
|
111
|
+
## 7. Benchmarks
|
|
112
|
+
|
|
113
|
+
- Name `BenchmarkXxx(b *testing.B)`. On Go 1.24+ write the loop as `for b.Loop() { ... }`; setup before the loop is excluded automatically. On older versions use `for i := 0; i < b.N; i++` with `b.ResetTimer()` after setup.
|
|
114
|
+
- Run with `go test -run '^$' -bench BenchmarkName -benchmem -count=10 ./pkg`.
|
|
115
|
+
- Compare before and after with `golang.org/x/perf/cmd/benchstat old.txt new.txt`. Never claim a speed-up from a single run.
|
|
116
|
+
|
|
117
|
+
## 8. Golden files
|
|
118
|
+
|
|
119
|
+
```go
|
|
120
|
+
var update = flag.Bool("update", false, "rewrite golden files")
|
|
121
|
+
|
|
122
|
+
func TestRender(t *testing.T) {
|
|
123
|
+
got := Render(input)
|
|
124
|
+
golden := filepath.Join("testdata", t.Name()+".golden")
|
|
125
|
+
if *update {
|
|
126
|
+
if err := os.WriteFile(golden, got, 0o644); err != nil {
|
|
127
|
+
t.Fatal(err)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
want, err := os.ReadFile(golden)
|
|
131
|
+
if err != nil {
|
|
132
|
+
t.Fatal(err)
|
|
133
|
+
}
|
|
134
|
+
if diff := cmp.Diff(string(want), string(got)); diff != "" {
|
|
135
|
+
t.Errorf("Render mismatch (-want +got):\n%s", diff)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Regenerate with `go test ./pkg -run TestRender -update`, then **read the diff** before committing. Subtest names contain `/`; sanitise or create directories when using `t.Name()` in a path.
|
|
141
|
+
|
|
142
|
+
## 9. Coverage
|
|
143
|
+
|
|
144
|
+
`go test -coverprofile=cover.out ./... && go tool cover -func=cover.out`. Cover the error paths and boundaries the user cares about; do not chase a percentage.
|
|
145
|
+
|
|
146
|
+
## Never
|
|
147
|
+
|
|
148
|
+
- Delete, skip (`t.Skip`) or weaken an existing test to get green without the user's agreement.
|
|
149
|
+
- Sleep to synchronise, hit the real network, or depend on test execution order.
|
|
150
|
+
- Leave goroutines running after a test returns.
|
|
151
|
+
|
|
152
|
+
## Report back
|
|
153
|
+
|
|
154
|
+
End with: tests added or changed (names), the exact commands run (including `-race`), pass/fail counts, and anything left untested.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Write table-driven tests with subtests for my Go ParseAmount function",
|
|
4
|
+
"This Go test is flaky under -race and uses time.Sleep, make it deterministic",
|
|
5
|
+
"Test my Go HTTP handler for POST /orders using httptest without a real server",
|
|
6
|
+
"Add a fuzz target for the Go URL normaliser and commit any crashing inputs",
|
|
7
|
+
"Benchmark these two Go JSON encoders properly and compare them with benchstat",
|
|
8
|
+
"Replace the gomock mocks in this _test.go file with a simple hand-written fake"
|
|
9
|
+
],
|
|
10
|
+
"should_not_trigger": [
|
|
11
|
+
"How should I structure packages and interfaces in my new Go service?",
|
|
12
|
+
"Review this Go diff for data races and context misuse before I merge",
|
|
13
|
+
"go vet reports 'copylocks: call of foo copies lock value', fix the build",
|
|
14
|
+
"Write pytest fixtures and parametrized tests for my Flask app",
|
|
15
|
+
"Add Playwright end-to-end tests for the signup page"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: google-workspace-integration
|
|
3
|
+
description: Calls the Google Drive v3, Docs, Sheets and Slides REST APIs from application code, covering the choice between user OAuth, a service account and domain-wide delegation, the narrowest scopes (drive.file before restricted drive), files.list queries with shared-drive flags, documents and presentations batchUpdate requests applied in descending index order, Sheets A1 ranges with valueInputOption, and per-minute quotas handled with truncated exponential backoff on 429 and 403 rate errors. Use when code must create, read, fill or export Google Docs, Sheets, Slides or Drive files, a service account gets 403 or storageQuotaExceeded, or a Workspace sync hits rate limits.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Live calls need network access to googleapis.com and a Google Cloud project with the APIs enabled. Examples use the official googleapis client libraries; the rules apply to raw REST too.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: integrations
|
|
9
|
+
kete-loom/risk: network
|
|
10
|
+
kete-loom/owner: "Kete-org"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Google Workspace integration
|
|
14
|
+
|
|
15
|
+
Build Drive, Docs, Sheets and Slides automation that asks for the least access, acts as the right identity, survives quota limits and does not corrupt documents with misplaced indexes. For Cloud IAM, Cloud Run and other Google Cloud infrastructure use `gcp-patterns`; this skill is about Workspace content APIs.
|
|
16
|
+
|
|
17
|
+
## Ground rules
|
|
18
|
+
|
|
19
|
+
1. **Pick the identity first** (table below). It decides scopes, file ownership and whether an admin must be involved.
|
|
20
|
+
2. **Narrowest scope that works.** `drive.file` (only files the app created or the user opened with it) is non-sensitive; `drive`, `drive.readonly` and `drive.metadata*` are restricted and need Google's restricted-scope verification for a public app. Prefer `spreadsheets`, `documents` or `presentations` plus `drive.file` over full `drive`.
|
|
21
|
+
3. **Credentials stay out of code.** OAuth client secrets, refresh tokens and service account key JSON come from a secret store or environment. Prefer keyless service account auth (attached service account, Workload Identity Federation) over downloaded key files.
|
|
22
|
+
4. **Batch, and treat a batch as one unit.** Sheets, Docs and Slides `batchUpdate` apply all requests atomically: one invalid request means none apply. Each batch counts as one request against quota.
|
|
23
|
+
5. **Back off on rate errors.** Retry 429, and 403 with reason `userRateLimitExceeded` or `rateLimitExceeded`, plus 5xx, with truncated exponential backoff: wait `min(2^n seconds + random up to 1000 ms, 32 to 64 s)`, then give up after a bounded number of tries. Never retry 400, 401 or a 403 for permissions.
|
|
24
|
+
6. **Ask only for the fields you use.** Pass `fields` on Drive and Docs reads (`files(id,name,mimeType,modifiedTime),nextPageToken`); it cuts payload and latency.
|
|
25
|
+
|
|
26
|
+
## Choose the identity
|
|
27
|
+
|
|
28
|
+
| Situation | Use |
|
|
29
|
+
|---|---|
|
|
30
|
+
| Users act on their own files (an add-on, a "connect Google Drive" button) | OAuth 2.0 user consent, offline access for a refresh token, incremental scopes |
|
|
31
|
+
| A backend job owns its own documents or works in a team folder | Service account; give it access by sharing a **shared drive** or folder with its email |
|
|
32
|
+
| A Workspace org's backend must act as many users without each consenting | Service account with **domain-wide delegation**: a super admin authorises the client ID and an exact scope list in the Admin console (API controls); the code impersonates a user with `subject` |
|
|
33
|
+
|
|
34
|
+
Service accounts have no Drive storage of their own: creating files in a My Drive folder shared with them fails with `storageQuotaExceeded`. Put the work in a shared drive, or impersonate a real user with delegation. Cloud IAM roles do not grant access to Workspace files; sharing does.
|
|
35
|
+
|
|
36
|
+
## Implementation steps
|
|
37
|
+
|
|
38
|
+
1. **Project setup**: enable each API (Drive, Docs, Sheets, Slides) in the Google Cloud project, configure the OAuth consent screen with only the scopes you request, and create the OAuth client or service account.
|
|
39
|
+
2. **Auth client**: build it once and reuse it; the libraries refresh access tokens. For delegation, set the subject user per request and keep the scope list identical to the one the admin approved, or token requests fail with `unauthorized_client`.
|
|
40
|
+
3. **Drive**: find files with `files.list` and a `q` query; page with `pageToken` until `nextPageToken` is absent. For shared drives pass `supportsAllDrives=true` and `includeItemsFromAllDrives=true` (plus `corpora`/`driveId`), or results silently miss them. Create Google-native files by setting `mimeType` (for example `application/vnd.google-apps.document`). Export with `files.export` (10 MB cap on exported content). Query syntax and MIME types in `references/api.md`.
|
|
41
|
+
4. **Sheets**: read and write values with `spreadsheets.values.get/update/append/batchGet/batchUpdate`. Write with `valueInputOption` `RAW` (stored literally) or `USER_ENTERED` (parsed like typing: formulas, dates). Read with `valueRenderOption` `UNFORMATTED_VALUE` when you need numbers, not display strings. Formatting, new tabs and protected ranges go through `spreadsheets.batchUpdate`, which addresses sheets by numeric `sheetId`, not title. A1 rules in `references/api.md`.
|
|
42
|
+
5. **Docs**: `documents.get` returns a structure of elements with `startIndex`/`endIndex`; body text starts at index 1. In one `documents.batchUpdate`, order inserts and deletes from the highest index to the lowest so earlier edits don't shift later ones. For templates prefer `replaceAllText` on placeholders like `{{customer_name}}`. Pass `writeControl.requiredRevisionId` from your read to refuse a write if someone edited the doc in between.
|
|
43
|
+
6. **Slides**: copy a template deck with Drive `files.copy`, then `presentations.batchUpdate` with `replaceAllText` and `replaceAllShapesWithImage` (image must be a public PNG, JPEG or GIF URL). Custom `objectId`s are 5 to 50 characters and unique in the deck.
|
|
44
|
+
7. **Retries and idempotency**: wrap every call in the backoff helper. A retried create can make a second file, so before creating, search for an existing file by a stable name or an `appProperties` key you set, or generate IDs first with `files.generateIds` and create with that ID.
|
|
45
|
+
8. **Watch for changes** with `changes.watch` or `files.watch` push channels to an HTTPS endpoint, or poll `changes.list` with a saved `startPageToken`. Channels expire; renew them before expiry.
|
|
46
|
+
|
|
47
|
+
## Reviewing an existing integration
|
|
48
|
+
|
|
49
|
+
- Full `drive` scope where `drive.file` would do; scopes requested that no code uses.
|
|
50
|
+
- Service account key JSON committed or baked into an image.
|
|
51
|
+
- Service account writing into a personal My Drive (fails on storage quota), or files left owned by an employee who may leave.
|
|
52
|
+
- `files.list` without paging, without `fields`, or without shared-drive flags.
|
|
53
|
+
- Docs edits applied in ascending index order, or text located by hard-coded indexes from an old copy of the template.
|
|
54
|
+
- Sheets writes with `USER_ENTERED` on user-supplied text, so a value beginning with `=` becomes a live formula (formula injection); use `RAW` or prefix with `'`.
|
|
55
|
+
- One API call per cell or row in a loop instead of a batch; no backoff, or retrying non-retryable errors.
|
|
56
|
+
|
|
57
|
+
## Stop and ask the user
|
|
58
|
+
|
|
59
|
+
- Before requesting a restricted scope (`drive`, `drive.readonly`, Gmail) for an app other people will install; it triggers Google's verification and possibly a security assessment.
|
|
60
|
+
- Before setting up domain-wide delegation: it lets the service account act as any user for the approved scopes, and a super admin must approve it.
|
|
61
|
+
- Before bulk-changing sharing permissions, deleting files or emptying trash.
|
|
62
|
+
|
|
63
|
+
## Before you finish
|
|
64
|
+
|
|
65
|
+
Quotas, scope classifications and limits change (Drive moved to per-unit quotas for projects created from May 2026), so check the official limits page for each API at developers.google.com/workspace. Test with a throwaway spreadsheet, document and shared drive; confirm a forced 429 is retried and a 403 permission error is not; confirm a retried create does not leave a duplicate file.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Our Node backend should fill a Google Docs contract template with customer details and export it as a PDF",
|
|
4
|
+
"Append each new order as a row in a Google Sheet from our Python service using a service account",
|
|
5
|
+
"Service account upload to Drive fails with storageQuotaExceeded even though the folder is shared with it",
|
|
6
|
+
"Which OAuth scopes do we need to read files a user picks from their Google Drive without asking for full drive access?",
|
|
7
|
+
"Generate a weekly Google Slides report deck from a template and swap the chart placeholders for images",
|
|
8
|
+
"Our Sheets sync keeps getting 429 Too many requests, how should we batch and back off?"
|
|
9
|
+
],
|
|
10
|
+
"should_not_trigger": [
|
|
11
|
+
"Grant a Cloud Run service account the right IAM role to read from Cloud Storage",
|
|
12
|
+
"Build a pivot table and VLOOKUP formulas in this Excel workbook",
|
|
13
|
+
"Write the Apps Script for a custom menu inside our spreadsheet",
|
|
14
|
+
"Our password reset emails sent through Amazon SES land in spam",
|
|
15
|
+
"Triage my Gmail inbox and draft replies for the important threads"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Google Workspace API reference notes
|
|
2
|
+
|
|
3
|
+
Read this when writing Drive queries, Sheets ranges or batchUpdate bodies. Field names come from the v3 Drive, v4 Sheets, v1 Docs and v1 Slides REST references; confirm against developers.google.com/workspace if a call is rejected.
|
|
4
|
+
|
|
5
|
+
## Scopes (prefix `https://www.googleapis.com/auth/`)
|
|
6
|
+
|
|
7
|
+
| Scope | Classification | Grants |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `drive.file` | non-sensitive | files the app created or the user opened with it (Picker) |
|
|
10
|
+
| `drive.appdata` | non-sensitive | the app's hidden config folder |
|
|
11
|
+
| `drive.readonly` | restricted | read every Drive file |
|
|
12
|
+
| `drive` | restricted | read and write every Drive file |
|
|
13
|
+
| `drive.metadata.readonly` | restricted | metadata of every file |
|
|
14
|
+
| `spreadsheets.readonly` / `spreadsheets` | sensitive | all of the user's Sheets |
|
|
15
|
+
| `documents.readonly` / `documents` | sensitive | all of the user's Docs |
|
|
16
|
+
| `presentations.readonly` / `presentations` | sensitive | all of the user's Slides |
|
|
17
|
+
|
|
18
|
+
## Drive `files.list` queries (`q`)
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
'FOLDER_ID' in parents and trashed = false
|
|
22
|
+
mimeType = 'application/vnd.google-apps.spreadsheet'
|
|
23
|
+
name contains 'Invoice' and modifiedTime > '2026-01-01T00:00:00'
|
|
24
|
+
appProperties has { key='orderId' and value='A123' }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Escape a `'` inside a value as `\'`. Combine with `and`, `or`, `not`.
|
|
28
|
+
|
|
29
|
+
Common params: `fields=nextPageToken,files(id,name,mimeType,parents,modifiedTime)`, `pageSize` (up to 1000), `pageToken`, `orderBy=modifiedTime desc`, `supportsAllDrives=true`, `includeItemsFromAllDrives=true`, `corpora=drive&driveId=...` for one shared drive.
|
|
30
|
+
|
|
31
|
+
Native MIME types: `application/vnd.google-apps.document`, `.spreadsheet`, `.presentation`, `.folder`. Export targets include `application/pdf`, `text/csv` (first sheet only), `application/vnd.openxmlformats-officedocument.wordprocessingml.document`.
|
|
32
|
+
|
|
33
|
+
Upload: `uploadType=media` for small content-only uploads, `multipart` for content plus metadata, `resumable` for large files or unreliable networks.
|
|
34
|
+
|
|
35
|
+
## Drive quotas (projects created on or after 1 May 2026)
|
|
36
|
+
|
|
37
|
+
Per-unit: 1,000,000 units per minute per project, 325,000 per minute per user per project. Costs: read 5, list 100, download 200, edit 50, other (e.g. `files.generateIds`) 5. Usage above 400,000,000 units per project per day may be billed, so prefer `changes.list` over repeated full `files.list` scans. 750 GB per user per day of uploads and copies across My Drive and shared drives. Projects that used the API between November 2025 and April 2026 keep their previous quotas. Errors: `403 userRateLimitExceeded`, `429`.
|
|
38
|
+
|
|
39
|
+
## Sheets
|
|
40
|
+
|
|
41
|
+
Quota: 300 read and 300 write requests per minute per project, 60 per minute per user per project; a batch counts as one request. Recommended payload under 2 MB; a request times out after 180 s.
|
|
42
|
+
|
|
43
|
+
A1 notation:
|
|
44
|
+
|
|
45
|
+
| Range | Meaning |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `Sheet1!A1:C10` | block on Sheet1 |
|
|
48
|
+
| `'Q3 Sales'!A:A` | whole column; quote titles with spaces or symbols, double any `'` inside |
|
|
49
|
+
| `Sheet1!2:2` | whole row 2 |
|
|
50
|
+
| `Sheet1!A5:C` | columns A-C from row 5 down |
|
|
51
|
+
| `Sheet1` | whole sheet |
|
|
52
|
+
| `A1:B2` | first visible sheet (avoid; be explicit) |
|
|
53
|
+
|
|
54
|
+
Values calls:
|
|
55
|
+
|
|
56
|
+
```http
|
|
57
|
+
PUT /v4/spreadsheets/{id}/values/'Orders'!A2:C2?valueInputOption=RAW
|
|
58
|
+
{ "values": [["A123", 4999, "paid"]] }
|
|
59
|
+
|
|
60
|
+
POST /v4/spreadsheets/{id}/values/Orders!A:C:append?valueInputOption=RAW&insertDataOption=INSERT_ROWS
|
|
61
|
+
{ "values": [["A124", 1500, "pending"]] }
|
|
62
|
+
|
|
63
|
+
POST /v4/spreadsheets/{id}/values:batchUpdate
|
|
64
|
+
{ "valueInputOption": "USER_ENTERED", "data": [ { "range": "Summary!B1", "values": [["=SUM(Orders!B:B)"]] } ] }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`valueRenderOption`: `FORMATTED_VALUE` (default, display strings), `UNFORMATTED_VALUE`, `FORMULA`. `dateTimeRenderOption`: `SERIAL_NUMBER` (default) or `FORMATTED_STRING`, only when not `FORMATTED_VALUE`.
|
|
68
|
+
|
|
69
|
+
Structure changes use `spreadsheets.batchUpdate` with requests such as `addSheet`, `repeatCell` (with a `GridRange` of `sheetId`, zero-based, end-exclusive row and column indexes and a `fields` mask), `autoResizeDimensions`, `addProtectedRange`. Get `sheetId`s from `spreadsheets.get?fields=sheets.properties`.
|
|
70
|
+
|
|
71
|
+
## Docs `documents.batchUpdate`
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"requests": [
|
|
76
|
+
{ "replaceAllText": { "containsText": { "text": "{{customer_name}}", "matchCase": true }, "replaceText": "Ama Mensah" } },
|
|
77
|
+
{ "insertText": { "location": { "index": 120 }, "text": "Second paragraph\n" } },
|
|
78
|
+
{ "insertText": { "location": { "index": 1 }, "text": "Heading\n" } }
|
|
79
|
+
],
|
|
80
|
+
"writeControl": { "requiredRevisionId": "<revisionId from documents.get>" }
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Order index-based edits highest index first. `targetRevisionId` instead of `requiredRevisionId` merges with collaborators' edits rather than failing.
|
|
85
|
+
|
|
86
|
+
## Slides `presentations.batchUpdate`
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"requests": [
|
|
91
|
+
{ "replaceAllText": { "containsText": { "text": "{{quarter}}", "matchCase": true }, "replaceText": "Q3 2026" } },
|
|
92
|
+
{ "replaceAllShapesWithImage": { "containsText": { "text": "{{chart}}" }, "imageUrl": "https://example.com/chart.png", "imageReplaceMethod": "CENTER_INSIDE" } },
|
|
93
|
+
{ "createSlide": { "objectId": "summary_slide_01", "slideLayoutReference": { "predefinedLayout": "TITLE_AND_BODY" } } }
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Images: public PNG, JPEG or GIF, under 50 MB and 25 megapixels, URL at most 2 KB; fetched once at insert. `objectId`: 5-50 chars, first char `[a-zA-Z0-9_]`, then `[a-zA-Z0-9_-:]`.
|
|
99
|
+
|
|
100
|
+
## Backoff helper (TypeScript)
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const RETRYABLE = new Set(["rateLimitExceeded", "userRateLimitExceeded", "backendError"]);
|
|
104
|
+
|
|
105
|
+
export async function withBackoff<T>(call: () => Promise<T>, maxTries = 6): Promise<T> {
|
|
106
|
+
for (let n = 0; ; n++) {
|
|
107
|
+
try {
|
|
108
|
+
return await call();
|
|
109
|
+
} catch (err: any) {
|
|
110
|
+
// googleapis/gaxios: HTTP status is on response.status; err.code may be a network code string like "ECONNRESET"
|
|
111
|
+
const status = err?.response?.status ?? (typeof err?.code === "number" ? err.code : undefined);
|
|
112
|
+
const reason = err?.response?.data?.error?.errors?.[0]?.reason ?? err?.errors?.[0]?.reason;
|
|
113
|
+
const network = status === undefined && ["ECONNRESET", "ETIMEDOUT", "EAI_AGAIN"].includes(err?.code);
|
|
114
|
+
const retryable = network || status === 429 || status >= 500 || (status === 403 && RETRYABLE.has(reason));
|
|
115
|
+
if (!retryable || n + 1 >= maxTries) throw err;
|
|
116
|
+
const wait = Math.min(2 ** n * 1000 + Math.random() * 1000, 64_000);
|
|
117
|
+
await new Promise((r) => setTimeout(r, wait));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harmonyos-arkts
|
|
3
|
+
description: Builds and fixes HarmonyOS NEXT apps written in ArkTS with ArkUI declarative components, choosing between the V1 state decorators (@State, @Prop, @Link, @Observed/@ObjectLink) and the V2 set (@ComponentV2, @Local, @Param, @Event, @ObservedV2/@Trace, @Monitor, @Computed) without mixing them illegally, wiring the UIAbility lifecycle and page routing, and running hvigorw and ohpm builds and clearing typical ArkTS compiler, signing and dependency errors. Use when writing or restructuring ArkUI pages and components, migrating state from V1 to V2 decorators, debugging a UI that does not refresh, or getting a HarmonyOS project in DevEco Studio or CI to build and install a HAP.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Builds need the HarmonyOS SDK with hvigorw and ohpm (from DevEco Studio or the command-line tools); installing needs hdc and a device or emulator. Decorator availability depends on the API level in build-profile.json5.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: coding
|
|
9
|
+
kete-loom/risk: runs-commands
|
|
10
|
+
kete-loom/requires: "hvigorw, ohpm"
|
|
11
|
+
kete-loom/owner: "Kete-org"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# HarmonyOS ArkTS and ArkUI
|
|
15
|
+
|
|
16
|
+
Write ArkTS that compiles under the strict ArkTS rules, keeps UI state observable, and builds the same way in DevEco Studio and CI.
|
|
17
|
+
|
|
18
|
+
## 0. Before you start
|
|
19
|
+
|
|
20
|
+
1. Read the project layout: `AppScope/app.json5` (bundle name, version), `build-profile.json5` (products, `compatibleSdkVersion`/`targetSdkVersion`, signing configs, modules), `oh-package.json5` (dependencies), each module's `src/main/module.json5` (abilities, permissions) and `src/main/resources/base/profile/main_pages.json` (routable pages).
|
|
21
|
+
2. Note the API level. State management V2 needs API 12 or later; check the official docs for anything newer before using it.
|
|
22
|
+
3. Find which state model the code uses: `@Component` structs are V1, `@ComponentV2` structs are V2. Follow the one already in use unless the user asks to migrate.
|
|
23
|
+
4. Install dependencies and build once (section 4) before editing, and record the errors that already exist.
|
|
24
|
+
|
|
25
|
+
## 1. ArkTS rules the compiler enforces
|
|
26
|
+
|
|
27
|
+
ArkTS is stricter than TypeScript. Write it this way from the start:
|
|
28
|
+
|
|
29
|
+
- No `any` or `unknown`; give everything an explicit type (`arkts-no-any-unknown`). Type `JSON.parse` results, for example as a declared class or `Record<string, Object>`.
|
|
30
|
+
- Object literals must match a declared class or interface (`arkts-no-untyped-obj-literals`). Declare an `interface` or `class` and annotate.
|
|
31
|
+
- No dynamic property access on objects by string index (`arkts-no-props-by-index`); use a `Map` or declared fields.
|
|
32
|
+
- No structural typing tricks, no runtime-added fields, no `delete`, limited destructuring and spread; prefer classes and explicit types.
|
|
33
|
+
- Import system APIs from kits: `@kit.AbilityKit`, `@kit.ArkUI`, `@kit.NetworkKit`, `@kit.PerformanceAnalysisKit` (for `hilog`).
|
|
34
|
+
|
|
35
|
+
When the compiler names a rule tag, look it up in the official ArkTS migration guide ("Adaptation Cases") and apply its fix pattern; do not silence the check.
|
|
36
|
+
|
|
37
|
+
## 2. Components and state
|
|
38
|
+
|
|
39
|
+
A component is a `struct` with a decorator and a `build()` method that describes UI. Keep `build()` free of side effects; do work in lifecycle callbacks (`aboutToAppear`, `aboutToDisappear`) or event handlers.
|
|
40
|
+
|
|
41
|
+
| Need | V1 (`@Component`) | V2 (`@ComponentV2`) |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| Local state | `@State` | `@Local` |
|
|
44
|
+
| Read-only input from parent | `@Prop` (copied) | `@Param` (add `@Require` if mandatory) |
|
|
45
|
+
| Input initialised once, then owned locally | `@State` initialised from parent | `@Param @Once` |
|
|
46
|
+
| Child changes parent state | `@Link` | `@Param` plus an `@Event` callback the parent handles |
|
|
47
|
+
| Pass down many levels | `@Provide` / `@Consume` | `@Provider()` / `@Consumer()` |
|
|
48
|
+
| Observe nested object fields | `@Observed` class + `@ObjectLink` | `@ObservedV2` class with `@Trace` fields |
|
|
49
|
+
| React to a change | `@Watch('method')` | `@Monitor('path')` |
|
|
50
|
+
| Derived value | getter (recomputed each build) | `@Computed get` |
|
|
51
|
+
| App-wide state | `AppStorage` / `@StorageLink` / `LocalStorage` | `AppStorageV2`, `PersistenceV2` |
|
|
52
|
+
|
|
53
|
+
Rules:
|
|
54
|
+
|
|
55
|
+
1. Never put V2 decorators inside a `@Component` struct or V1 decorators inside a `@ComponentV2` struct; it does not compile. A struct cannot be both.
|
|
56
|
+
2. When mixing, a V1 component can contain a V2 child when no state is passed between them; passing state across the boundary has restrictions, so read the official "mixed scenarios" page before doing it, or migrate the whole subtree.
|
|
57
|
+
3. `@Local` and `@State` observe assignment of the value and, for arrays, the mutating array methods (`push`, `splice`, index assignment). They do not see a field change inside an element or nested object: for that use `@ObservedV2` + `@Trace` (V2) or `@Observed` + `@ObjectLink` (V1).
|
|
58
|
+
4. Data flows down; events flow up. A child never mutates a `@Param`; it calls the parent's `@Event`.
|
|
59
|
+
5. Use `ForEach(items, (item: Item) => { ... }, (item: Item) => item.id.toString())` with a stable key generator that returns a string, and `LazyForEach` with an `IDataSource` for long lists.
|
|
60
|
+
|
|
61
|
+
UI not refreshing? Check, in order: the field is decorated; the changed thing is the observed level (object vs field); the object is a decorated class instance and not a plain literal; the `ForEach` key changes when content changes.
|
|
62
|
+
|
|
63
|
+
## 3. UIAbility lifecycle and pages
|
|
64
|
+
|
|
65
|
+
1. The entry ability (`EntryAbility.ets`) extends `UIAbility`. Callbacks run in this order: `onCreate(want, launchParam)`, `onWindowStageCreate(windowStage)`, `onForeground()`, then `onBackground()`, `onWindowStageDestroy()`, `onDestroy()`.
|
|
66
|
+
2. Load the first page in `onWindowStageCreate` with `windowStage.loadContent('pages/Index', (err) => { ... })` and log failures with `hilog`.
|
|
67
|
+
3. Release resources in `onBackground` (pause timers, sensors) and in `onWindowStageDestroy` (UI listeners).
|
|
68
|
+
4. Register every `@Entry` page in `main_pages.json`. For navigation, follow what the project uses; current docs recommend the `Navigation` component with `NavPathStack` over the older `router` module for new code. Check the docs for your API level.
|
|
69
|
+
5. Declare permissions in `module.json5` and request user-granted ones at runtime with `abilityAccessCtrl`; never assume they are granted.
|
|
70
|
+
|
|
71
|
+
## 4. Build and run
|
|
72
|
+
|
|
73
|
+
From the project root:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
ohpm install # dependencies from oh-package.json5
|
|
77
|
+
hvigorw clean --no-daemon
|
|
78
|
+
hvigorw assembleHap --mode module -p product=default -p buildMode=debug --no-daemon
|
|
79
|
+
hdc install <module>/build/default/outputs/default/<module>-default-signed.hap
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- The HAP lands under `<module>/build/<product>/outputs/<target>/`. Use `buildMode=release` for release builds.
|
|
83
|
+
- Use `--no-daemon` in CI.
|
|
84
|
+
- Installing on a device needs a signed HAP: configure `signingConfigs` in `build-profile.json5` (DevEco Studio can generate debug signing). Never commit keystores or passwords; read them from CI secrets.
|
|
85
|
+
- If `hvigor/hvigor-config.json5` pulls npm packages, CI needs an npm registry configured.
|
|
86
|
+
|
|
87
|
+
For specific build errors and their fixes, read `references/build-errors.md`.
|
|
88
|
+
|
|
89
|
+
## 5. Verify
|
|
90
|
+
|
|
91
|
+
1. The build finishes with no ArkTS errors and no new warnings.
|
|
92
|
+
2. Install and launch on a device or emulator; open each changed page; exercise each state change and confirm the UI updates.
|
|
93
|
+
3. Send to background and back; rotate if supported; confirm nothing leaks or crashes (`hdc hilog` for logs).
|
|
94
|
+
4. Run the module's tests if the project has them (`ohosTest` source set).
|
|
95
|
+
|
|
96
|
+
## Stop and ask the user
|
|
97
|
+
|
|
98
|
+
- Migrating a whole app from V1 to V2 decorators, or from `router` to `Navigation`: confirm scope first.
|
|
99
|
+
- Raising `compatibleSdkVersion`, changing the bundle name, or touching signing configs.
|
|
100
|
+
- A third-party ohpm package has no HarmonyOS NEXT version.
|
|
101
|
+
|
|
102
|
+
## Never
|
|
103
|
+
|
|
104
|
+
- Never use `any`, `// @ts-ignore` or casts to get past ArkTS checks.
|
|
105
|
+
- Never mix V1 and V2 decorators in one struct.
|
|
106
|
+
- Never do network or file I/O inside `build()`.
|
|
107
|
+
- Never commit signing material.
|
|
108
|
+
|
|
109
|
+
## Report back
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
API level / state model: <API n, V1 or V2>
|
|
113
|
+
Changed: <files and components>, decorators used: <list>
|
|
114
|
+
Build: <commands run> -> <result>; installed on: <device/emulator>
|
|
115
|
+
Checked in docs: <APIs>; not verified: <list>
|
|
116
|
+
Follow-ups: <migration or signing items>
|
|
117
|
+
```
|