cfsa-antigravity 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/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-extension-patterns
|
|
3
|
+
description: Browser extension development patterns covering Manifest V3, content scripts, service workers, message passing, storage, permissions, cross-browser compatibility, and store submission. Use when building Chrome, Firefox, or Safari browser extensions.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Browser Extension Patterns
|
|
8
|
+
|
|
9
|
+
Build browser extensions that work across Chrome, Firefox, and Safari with Manifest V3, minimal permissions, and reliable background processing.
|
|
10
|
+
|
|
11
|
+
## Manifest V3
|
|
12
|
+
|
|
13
|
+
Manifest V3 (MV3) is required for Chrome extensions and supported by Firefox and Safari. Key changes from V2:
|
|
14
|
+
|
|
15
|
+
| Feature | Manifest V2 | Manifest V3 |
|
|
16
|
+
|---------|-------------|-------------|
|
|
17
|
+
| Background | Persistent background page | Service worker (event-driven) |
|
|
18
|
+
| Remote code | `eval()`, remote scripts allowed | Blocked entirely |
|
|
19
|
+
| Network requests | `webRequest` blocking | `declarativeNetRequest` rules |
|
|
20
|
+
| Content Security | Relaxed CSP | Strict CSP, no `unsafe-eval` |
|
|
21
|
+
| Host permissions | In `permissions` | Separate `host_permissions` |
|
|
22
|
+
| Action | `browser_action` / `page_action` | Unified `action` |
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"manifest_version": 3,
|
|
27
|
+
"name": "My Extension",
|
|
28
|
+
"version": "1.0.0",
|
|
29
|
+
"description": "A useful browser extension",
|
|
30
|
+
"permissions": [
|
|
31
|
+
"storage",
|
|
32
|
+
"activeTab",
|
|
33
|
+
"contextMenus"
|
|
34
|
+
],
|
|
35
|
+
"host_permissions": [
|
|
36
|
+
"https://api.example.com/*"
|
|
37
|
+
],
|
|
38
|
+
"background": {
|
|
39
|
+
"service_worker": "background.js",
|
|
40
|
+
"type": "module"
|
|
41
|
+
},
|
|
42
|
+
"content_scripts": [
|
|
43
|
+
{
|
|
44
|
+
"matches": ["https://*.example.com/*"],
|
|
45
|
+
"js": ["content.js"],
|
|
46
|
+
"css": ["content.css"],
|
|
47
|
+
"run_at": "document_idle"
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"action": {
|
|
51
|
+
"default_popup": "popup.html",
|
|
52
|
+
"default_icon": {
|
|
53
|
+
"16": "icons/icon-16.png",
|
|
54
|
+
"32": "icons/icon-32.png",
|
|
55
|
+
"48": "icons/icon-48.png",
|
|
56
|
+
"128": "icons/icon-128.png"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"options_page": "options.html",
|
|
60
|
+
"icons": {
|
|
61
|
+
"16": "icons/icon-16.png",
|
|
62
|
+
"48": "icons/icon-48.png",
|
|
63
|
+
"128": "icons/icon-128.png"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Rule**: Request the minimum permissions needed. `"<all_urls>"` triggers a scary permission prompt and slows review.
|
|
69
|
+
**Rule**: Use `activeTab` instead of broad host permissions when you only need access to the current tab on user action.
|
|
70
|
+
|
|
71
|
+
## Content Scripts vs Background Service Workers
|
|
72
|
+
|
|
73
|
+
### Content Scripts
|
|
74
|
+
|
|
75
|
+
Run in the context of web pages. They can read and modify the DOM but have a separate JavaScript environment.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// content.ts - Runs in the context of matching web pages
|
|
79
|
+
// Has access to DOM but NOT to extension APIs directly
|
|
80
|
+
|
|
81
|
+
// Inject UI into the page
|
|
82
|
+
function injectSidebar() {
|
|
83
|
+
const container = document.createElement('div');
|
|
84
|
+
container.id = 'my-extension-sidebar';
|
|
85
|
+
container.attachShadow({ mode: 'closed' }); // Shadow DOM to avoid CSS conflicts
|
|
86
|
+
|
|
87
|
+
const shadow = container.shadowRoot!;
|
|
88
|
+
const style = document.createElement('style');
|
|
89
|
+
style.textContent = `
|
|
90
|
+
:host {
|
|
91
|
+
position: fixed;
|
|
92
|
+
right: 0;
|
|
93
|
+
top: 0;
|
|
94
|
+
width: 350px;
|
|
95
|
+
height: 100vh;
|
|
96
|
+
z-index: 2147483647;
|
|
97
|
+
font-family: system-ui, sans-serif;
|
|
98
|
+
}
|
|
99
|
+
`;
|
|
100
|
+
shadow.appendChild(style);
|
|
101
|
+
|
|
102
|
+
const app = document.createElement('div');
|
|
103
|
+
app.className = 'extension-app';
|
|
104
|
+
shadow.appendChild(app);
|
|
105
|
+
|
|
106
|
+
document.body.appendChild(container);
|
|
107
|
+
return app;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Read page content
|
|
111
|
+
function extractPageData(): PageData {
|
|
112
|
+
return {
|
|
113
|
+
title: document.title,
|
|
114
|
+
url: window.location.href,
|
|
115
|
+
selectedText: window.getSelection()?.toString() || '',
|
|
116
|
+
metaDescription: document.querySelector('meta[name="description"]')?.getAttribute('content') || '',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Listen for messages from background
|
|
121
|
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
122
|
+
if (message.type === 'GET_PAGE_DATA') {
|
|
123
|
+
sendResponse(extractPageData());
|
|
124
|
+
return true; // Keep channel open for async response
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (message.type === 'HIGHLIGHT_TEXT') {
|
|
128
|
+
highlightText(message.query);
|
|
129
|
+
sendResponse({ success: true });
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Rule**: Use Shadow DOM when injecting UI to prevent CSS conflicts with the host page.
|
|
135
|
+
**Rule**: Content scripts cannot use most `chrome.*` APIs directly. Use message passing to communicate with the service worker.
|
|
136
|
+
|
|
137
|
+
### Background Service Worker
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// background.ts - Event-driven service worker
|
|
141
|
+
// Has access to ALL extension APIs but NO DOM access
|
|
142
|
+
|
|
143
|
+
// Service workers are ephemeral -- they start on events and stop when idle
|
|
144
|
+
// NEVER rely on global state persisting between events
|
|
145
|
+
|
|
146
|
+
// Use chrome.storage instead of global variables
|
|
147
|
+
async function getState<T>(key: string, defaultValue: T): Promise<T> {
|
|
148
|
+
const result = await chrome.storage.local.get(key);
|
|
149
|
+
return (result[key] as T) ?? defaultValue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function setState<T>(key: string, value: T): Promise<void> {
|
|
153
|
+
await chrome.storage.local.set({ [key]: value });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Extension install/update
|
|
157
|
+
chrome.runtime.onInstalled.addListener(async (details) => {
|
|
158
|
+
if (details.reason === 'install') {
|
|
159
|
+
// First install: set defaults, show onboarding
|
|
160
|
+
await chrome.storage.local.set({ settings: DEFAULT_SETTINGS });
|
|
161
|
+
await chrome.tabs.create({ url: 'onboarding.html' });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (details.reason === 'update') {
|
|
165
|
+
// Migration on update
|
|
166
|
+
await migrateStorage(details.previousVersion!);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Register context menu items
|
|
170
|
+
chrome.contextMenus.create({
|
|
171
|
+
id: 'save-selection',
|
|
172
|
+
title: 'Save to My Extension',
|
|
173
|
+
contexts: ['selection'],
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Handle context menu clicks
|
|
178
|
+
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
|
|
179
|
+
if (info.menuItemId === 'save-selection' && info.selectionText) {
|
|
180
|
+
await saveSelection({
|
|
181
|
+
text: info.selectionText,
|
|
182
|
+
url: tab?.url || '',
|
|
183
|
+
timestamp: Date.now(),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Handle messages from content scripts and popup
|
|
189
|
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
190
|
+
if (message.type === 'FETCH_DATA') {
|
|
191
|
+
// Service worker can make cross-origin requests
|
|
192
|
+
fetchData(message.url)
|
|
193
|
+
.then((data) => sendResponse({ success: true, data }))
|
|
194
|
+
.catch((error) => sendResponse({ success: false, error: error.message }));
|
|
195
|
+
return true; // Required for async sendResponse
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Anti-pattern**: Storing state in global variables in the service worker. Service workers are terminated after ~30 seconds of inactivity. Use `chrome.storage.local` or `chrome.storage.session`.
|
|
201
|
+
|
|
202
|
+
## Message Passing Architecture
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
┌─────────────┐ chrome.runtime.sendMessage ┌──────────────────┐
|
|
206
|
+
│ Content │ ──────────────────────────────→ │ Background │
|
|
207
|
+
│ Script │ ←────────────────────────────── │ Service Worker │
|
|
208
|
+
│ │ sendResponse / chrome.tabs. │ │
|
|
209
|
+
└─────────────┘ sendMessage └──────────────────┘
|
|
210
|
+
↑↓
|
|
211
|
+
┌─────────────┐ chrome.runtime.sendMessage ┌──────────────────┐
|
|
212
|
+
│ Popup / │ ──────────────────────────────→ │ Background │
|
|
213
|
+
│ Side Panel │ ←────────────────────────────── │ Service Worker │
|
|
214
|
+
└─────────────┘ sendResponse └──────────────────┘
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
// Type-safe message passing
|
|
219
|
+
interface MessageMap {
|
|
220
|
+
GET_PAGE_DATA: { request: void; response: PageData };
|
|
221
|
+
SAVE_ITEM: { request: SaveItemPayload; response: { id: string } };
|
|
222
|
+
GET_SETTINGS: { request: void; response: Settings };
|
|
223
|
+
UPDATE_SETTINGS: { request: Partial<Settings>; response: Settings };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
type MessageType = keyof MessageMap;
|
|
227
|
+
|
|
228
|
+
// Typed sender (from popup or content script)
|
|
229
|
+
async function sendMessage<T extends MessageType>(
|
|
230
|
+
type: T,
|
|
231
|
+
payload?: MessageMap[T]['request']
|
|
232
|
+
): Promise<MessageMap[T]['response']> {
|
|
233
|
+
return new Promise((resolve, reject) => {
|
|
234
|
+
chrome.runtime.sendMessage({ type, payload }, (response) => {
|
|
235
|
+
if (chrome.runtime.lastError) {
|
|
236
|
+
reject(new Error(chrome.runtime.lastError.message));
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (response?.error) {
|
|
240
|
+
reject(new Error(response.error));
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
resolve(response);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Typed handler (in background service worker)
|
|
249
|
+
function handleMessage<T extends MessageType>(
|
|
250
|
+
type: T,
|
|
251
|
+
handler: (payload: MessageMap[T]['request']) => Promise<MessageMap[T]['response']>
|
|
252
|
+
): void {
|
|
253
|
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
254
|
+
if (message.type !== type) return;
|
|
255
|
+
|
|
256
|
+
handler(message.payload)
|
|
257
|
+
.then((response) => sendResponse(response))
|
|
258
|
+
.catch((error) => sendResponse({ error: (error as Error).message }));
|
|
259
|
+
|
|
260
|
+
return true; // Keep channel open for async response
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Registration
|
|
265
|
+
handleMessage('GET_SETTINGS', async () => {
|
|
266
|
+
return getState('settings', DEFAULT_SETTINGS);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
handleMessage('SAVE_ITEM', async (payload) => {
|
|
270
|
+
const id = await saveToStorage(payload);
|
|
271
|
+
return { id };
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Storage APIs
|
|
276
|
+
|
|
277
|
+
| API | Scope | Limit | Sync |
|
|
278
|
+
|-----|-------|-------|------|
|
|
279
|
+
| `chrome.storage.local` | Per device | 10 MB (unlimitedStorage: unlimited) | No |
|
|
280
|
+
| `chrome.storage.sync` | Synced across signed-in browsers | 100 KB total, 8 KB per item | Yes |
|
|
281
|
+
| `chrome.storage.session` | Per browser session, cleared on close | 10 MB | No |
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
// Storage with type safety and defaults
|
|
285
|
+
interface StorageSchema {
|
|
286
|
+
settings: Settings;
|
|
287
|
+
savedItems: SavedItem[];
|
|
288
|
+
lastSyncTimestamp: number;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const STORAGE_DEFAULTS: StorageSchema = {
|
|
292
|
+
settings: { theme: 'system', language: 'en', notifications: true },
|
|
293
|
+
savedItems: [],
|
|
294
|
+
lastSyncTimestamp: 0,
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
async function getStorage<K extends keyof StorageSchema>(key: K): Promise<StorageSchema[K]> {
|
|
298
|
+
const result = await chrome.storage.local.get(key);
|
|
299
|
+
return (result[key] as StorageSchema[K]) ?? STORAGE_DEFAULTS[key];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
async function setStorage<K extends keyof StorageSchema>(key: K, value: StorageSchema[K]): Promise<void> {
|
|
303
|
+
await chrome.storage.local.set({ [key]: value });
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Listen for storage changes (reactive)
|
|
307
|
+
chrome.storage.onChanged.addListener((changes, area) => {
|
|
308
|
+
if (area !== 'local') return;
|
|
309
|
+
|
|
310
|
+
for (const [key, { oldValue, newValue }] of Object.entries(changes)) {
|
|
311
|
+
console.log(`Storage ${key} changed:`, oldValue, '->', newValue);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Permission Model
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
// Request optional permissions at runtime (better UX than upfront)
|
|
320
|
+
async function requestHostPermission(origin: string): Promise<boolean> {
|
|
321
|
+
return chrome.permissions.request({
|
|
322
|
+
origins: [`${origin}/*`],
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Check if permission is granted before using it
|
|
327
|
+
async function hasPermission(permission: string): Promise<boolean> {
|
|
328
|
+
return chrome.permissions.contains({
|
|
329
|
+
permissions: [permission],
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// manifest.json - Declare optional permissions
|
|
334
|
+
// "optional_permissions": ["tabs", "bookmarks", "history"],
|
|
335
|
+
// "optional_host_permissions": ["https://*.github.com/*"]
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Rule**: Use `optional_permissions` for features the user may not need. Request them when the user activates the feature, not at install time.
|
|
339
|
+
|
|
340
|
+
## Popup vs Side Panel vs Content Injection
|
|
341
|
+
|
|
342
|
+
| Surface | Lifecycle | Best For |
|
|
343
|
+
|---------|-----------|----------|
|
|
344
|
+
| Popup | Opens on icon click, closes on blur | Quick actions, status display |
|
|
345
|
+
| Side Panel (Chrome 114+) | Persistent panel alongside page | Reference tools, note-taking |
|
|
346
|
+
| Content script injection | Runs on matching pages | Page augmentation, overlays |
|
|
347
|
+
| Options page | Separate tab/window | Settings, configuration |
|
|
348
|
+
| DevTools panel | Inside DevTools | Developer tools, debugging |
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
// Side Panel registration (Chrome 114+)
|
|
352
|
+
// manifest.json: "side_panel": { "default_path": "sidepanel.html" }
|
|
353
|
+
|
|
354
|
+
// Open side panel programmatically
|
|
355
|
+
chrome.sidePanel.setOptions({
|
|
356
|
+
tabId: tab.id,
|
|
357
|
+
path: 'sidepanel.html',
|
|
358
|
+
enabled: true,
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// Open side panel on action click instead of popup
|
|
362
|
+
chrome.action.onClicked.addListener(async (tab) => {
|
|
363
|
+
await chrome.sidePanel.open({ tabId: tab.id });
|
|
364
|
+
});
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Cross-Browser Compatibility
|
|
368
|
+
|
|
369
|
+
| API | Chrome | Firefox | Safari |
|
|
370
|
+
|-----|--------|---------|--------|
|
|
371
|
+
| Namespace | `chrome.*` | `browser.*` (Promise-based) or `chrome.*` | `browser.*` |
|
|
372
|
+
| Service worker | Yes (MV3) | Yes (MV3, Firefox 109+) | Yes (MV3, Safari 15.4+) |
|
|
373
|
+
| Side panel | Yes (Chrome 114+) | No | No |
|
|
374
|
+
| `declarativeNetRequest` | Yes | Yes (Firefox 113+) | Yes |
|
|
375
|
+
| `offscreen` document | Yes | No | No |
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
// Cross-browser compatibility layer
|
|
379
|
+
const browserAPI = typeof browser !== 'undefined' ? browser : chrome;
|
|
380
|
+
|
|
381
|
+
// Promisify Chrome callback APIs for consistency
|
|
382
|
+
function promisify<T>(fn: (...args: any[]) => void, ...args: any[]): Promise<T> {
|
|
383
|
+
return new Promise((resolve, reject) => {
|
|
384
|
+
fn(...args, (result: T) => {
|
|
385
|
+
if (chrome.runtime.lastError) {
|
|
386
|
+
reject(new Error(chrome.runtime.lastError.message));
|
|
387
|
+
} else {
|
|
388
|
+
resolve(result);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Or use webextension-polyfill for automatic Promise wrapping
|
|
395
|
+
// import browser from 'webextension-polyfill';
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## CSP Restrictions for Extensions
|
|
399
|
+
|
|
400
|
+
MV3 enforces strict CSP. You cannot:
|
|
401
|
+
|
|
402
|
+
- Use `eval()` or `new Function()`
|
|
403
|
+
- Load remote scripts (`<script src="https://...">`)
|
|
404
|
+
- Use inline scripts (`<script>alert('hi')</script>`)
|
|
405
|
+
- Use inline event handlers (`<button onclick="...">`)
|
|
406
|
+
|
|
407
|
+
```json
|
|
408
|
+
// manifest.json - Extension CSP (MV3 defaults, cannot be relaxed for scripts)
|
|
409
|
+
{
|
|
410
|
+
"content_security_policy": {
|
|
411
|
+
"extension_pages": "script-src 'self'; object-src 'self'"
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Rule**: All JavaScript must be bundled and shipped with the extension. No CDN scripts, no dynamic code generation.
|
|
417
|
+
**Workaround**: For sandboxed pages that need `eval()` (e.g., template engines), use the `sandbox` key in manifest to create sandboxed pages with relaxed CSP, communicating via `postMessage`.
|
|
418
|
+
|
|
419
|
+
## Web Store Review Requirements
|
|
420
|
+
|
|
421
|
+
### Chrome Web Store
|
|
422
|
+
|
|
423
|
+
| Requirement | Details |
|
|
424
|
+
|------------|---------|
|
|
425
|
+
| Manifest V3 | Required for new submissions as of 2024 |
|
|
426
|
+
| Single purpose | Extension must have one clear, well-defined purpose |
|
|
427
|
+
| Privacy policy | Required if collecting user data |
|
|
428
|
+
| Permissions justification | Must justify every permission in the review form |
|
|
429
|
+
| Data use disclosure | Must declare what data is collected and why |
|
|
430
|
+
| No obfuscated code | All code must be human-readable (minified is OK, obfuscated is not) |
|
|
431
|
+
| Review time | 1-3 business days (first submission may take longer) |
|
|
432
|
+
|
|
433
|
+
### Firefox Add-ons (AMO)
|
|
434
|
+
|
|
435
|
+
| Requirement | Details |
|
|
436
|
+
|------------|---------|
|
|
437
|
+
| Source code | May be requested for review (provide build instructions) |
|
|
438
|
+
| No remote code | Same as Chrome MV3 |
|
|
439
|
+
| Privacy policy | Required for data-collecting extensions |
|
|
440
|
+
| Review time | Auto-review for many, manual review 1-7 days |
|
|
441
|
+
|
|
442
|
+
## Extension Debugging
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Background service worker debugging
|
|
446
|
+
// Chrome: chrome://extensions > "Service worker" link > DevTools
|
|
447
|
+
// Firefox: about:debugging > This Firefox > your extension
|
|
448
|
+
|
|
449
|
+
// Content script debugging
|
|
450
|
+
// Chrome DevTools > Sources > Content Scripts folder
|
|
451
|
+
|
|
452
|
+
// Reload extension during development
|
|
453
|
+
chrome.management.getSelf((info) => {
|
|
454
|
+
console.log('Extension ID:', info.id);
|
|
455
|
+
console.log('Version:', info.version);
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// Development-only: auto-reload on file changes
|
|
459
|
+
// Use web-ext (Firefox) or Chrome Extension Reloader
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
# Firefox: web-ext for development
|
|
464
|
+
npx web-ext run --source-dir=./dist --target=firefox-desktop
|
|
465
|
+
|
|
466
|
+
# Chrome: load unpacked in chrome://extensions with Developer Mode enabled
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Output Checklist
|
|
470
|
+
|
|
471
|
+
- [ ] Manifest V3 with minimal required permissions
|
|
472
|
+
- [ ] Optional permissions requested at runtime when feature is activated
|
|
473
|
+
- [ ] Content scripts use Shadow DOM for injected UI
|
|
474
|
+
- [ ] Service worker does not rely on global state
|
|
475
|
+
- [ ] Message passing is type-safe with consistent request/response format
|
|
476
|
+
- [ ] Storage uses `chrome.storage` (not `localStorage`)
|
|
477
|
+
- [ ] Cross-browser compatibility via polyfill or abstraction layer
|
|
478
|
+
- [ ] No remote code, no `eval()`, no inline scripts
|
|
479
|
+
- [ ] Privacy policy provided for data-collecting features
|
|
480
|
+
- [ ] Extension tested on Chrome, Firefox, and Safari
|
|
481
|
+
- [ ] Icons provided at 16, 32, 48, and 128px sizes
|
|
482
|
+
- [ ] Single clear purpose documented in description
|