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,445 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cli-configuration-management
|
|
3
|
+
description: Configuration file patterns for CLI tools covering file formats, XDG Base Directory spec, config precedence, merging, secret handling, validation, and migration. Use when building CLI tools that need persistent user or project configuration.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# CLI Configuration Management
|
|
8
|
+
|
|
9
|
+
Implement robust configuration for CLI tools with proper file discovery, precedence, and migration.
|
|
10
|
+
|
|
11
|
+
## Config File Formats
|
|
12
|
+
|
|
13
|
+
| Format | Pros | Cons | Best For |
|
|
14
|
+
|--------|------|------|----------|
|
|
15
|
+
| TOML | Human-readable, typed values, comments | Less familiar to some users | Rust/Go CLIs, Cargo, Poetry |
|
|
16
|
+
| YAML | Widespread, supports complex structures, comments | Indentation-sensitive, type coercion gotchas | DevOps tools, k8s, Docker Compose |
|
|
17
|
+
| JSON | Universal, strict parsing | No comments, verbose | JavaScript ecosystem, APIs |
|
|
18
|
+
| JSON5 / JSONC | JSON with comments and trailing commas | Non-standard, needs special parser | VS Code settings, tsconfig |
|
|
19
|
+
| INI | Simple, widely supported | No nesting, no arrays | Legacy tools, git config |
|
|
20
|
+
|
|
21
|
+
```toml
|
|
22
|
+
# TOML - Recommended for new CLI tools
|
|
23
|
+
# ~/.config/mycli/config.toml
|
|
24
|
+
|
|
25
|
+
[defaults]
|
|
26
|
+
environment = "staging"
|
|
27
|
+
output_format = "table"
|
|
28
|
+
color = "auto" # "auto", "always", "never"
|
|
29
|
+
|
|
30
|
+
[auth]
|
|
31
|
+
# Token stored in OS keyring, not here
|
|
32
|
+
provider = "oauth"
|
|
33
|
+
api_url = "https://api.example.com"
|
|
34
|
+
|
|
35
|
+
[deploy]
|
|
36
|
+
replicas = 3
|
|
37
|
+
timeout = 300
|
|
38
|
+
health_check_path = "/healthz"
|
|
39
|
+
|
|
40
|
+
[deploy.staging]
|
|
41
|
+
replicas = 1
|
|
42
|
+
auto_approve = true
|
|
43
|
+
|
|
44
|
+
[deploy.production]
|
|
45
|
+
replicas = 5
|
|
46
|
+
auto_approve = false
|
|
47
|
+
require_tag = true
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Rule**: TOML is the recommended format for new CLI tools. It has typed values (strings, integers, booleans, dates), supports comments, and avoids YAML's type coercion pitfalls (e.g., YAML parses `no` as `false`).
|
|
51
|
+
|
|
52
|
+
## XDG Base Directory Spec
|
|
53
|
+
|
|
54
|
+
The XDG Base Directory specification defines standard locations for config, data, cache, and state files on Unix systems.
|
|
55
|
+
|
|
56
|
+
| Variable | Default | Purpose | Example |
|
|
57
|
+
|----------|---------|---------|---------|
|
|
58
|
+
| `$XDG_CONFIG_HOME` | `~/.config` | Configuration files | `~/.config/mycli/config.toml` |
|
|
59
|
+
| `$XDG_DATA_HOME` | `~/.local/share` | Persistent data | `~/.local/share/mycli/db.sqlite` |
|
|
60
|
+
| `$XDG_CACHE_HOME` | `~/.cache` | Non-essential cached data | `~/.cache/mycli/http-cache/` |
|
|
61
|
+
| `$XDG_STATE_HOME` | `~/.local/state` | State data (logs, history) | `~/.local/state/mycli/history` |
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import os from 'os';
|
|
65
|
+
import path from 'path';
|
|
66
|
+
|
|
67
|
+
function getConfigDir(appName: string): string {
|
|
68
|
+
// Windows: %APPDATA%\mycli
|
|
69
|
+
if (process.platform === 'win32') {
|
|
70
|
+
return path.join(process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'), appName);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// macOS: ~/Library/Application Support/mycli (or XDG if set)
|
|
74
|
+
// Linux: $XDG_CONFIG_HOME/mycli or ~/.config/mycli
|
|
75
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
76
|
+
return path.join(xdgConfig, appName);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function getDataDir(appName: string): string {
|
|
80
|
+
if (process.platform === 'win32') {
|
|
81
|
+
return path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'), appName);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');
|
|
85
|
+
return path.join(xdgData, appName);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getCacheDir(appName: string): string {
|
|
89
|
+
if (process.platform === 'win32') {
|
|
90
|
+
return path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'), appName, 'cache');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// macOS: ~/Library/Caches/mycli
|
|
94
|
+
if (process.platform === 'darwin') {
|
|
95
|
+
return path.join(os.homedir(), 'Library', 'Caches', appName);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const xdgCache = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');
|
|
99
|
+
return path.join(xdgCache, appName);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Rule**: Always use `$XDG_CONFIG_HOME` if set. Never hardcode `~/.config` without checking the environment variable first.
|
|
104
|
+
**Anti-pattern**: Dumping everything into `~/.mycli/`. Separate config, data, cache, and state into XDG directories.
|
|
105
|
+
|
|
106
|
+
## Config Precedence
|
|
107
|
+
|
|
108
|
+
Configuration values are resolved in order from highest to lowest priority.
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
Environment Variables (MYCLI_*)
|
|
112
|
+
↓ overrides
|
|
113
|
+
Command-line Flags (--option=value)
|
|
114
|
+
↓ overrides
|
|
115
|
+
Project Config (.mycli.toml in cwd or parent dirs)
|
|
116
|
+
↓ overrides
|
|
117
|
+
User/Global Config (~/.config/mycli/config.toml)
|
|
118
|
+
↓ overrides
|
|
119
|
+
Built-in Defaults
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { z } from 'zod';
|
|
124
|
+
import TOML from '@iarna/toml';
|
|
125
|
+
import fs from 'fs';
|
|
126
|
+
import path from 'path';
|
|
127
|
+
|
|
128
|
+
const ConfigSchema = z.object({
|
|
129
|
+
environment: z.enum(['dev', 'staging', 'production']).default('staging'),
|
|
130
|
+
outputFormat: z.enum(['table', 'json', 'csv']).default('table'),
|
|
131
|
+
color: z.enum(['auto', 'always', 'never']).default('auto'),
|
|
132
|
+
replicas: z.number().int().min(1).max(20).default(3),
|
|
133
|
+
timeout: z.number().int().min(1).default(300),
|
|
134
|
+
verbose: z.boolean().default(false),
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
type Config = z.infer<typeof ConfigSchema>;
|
|
138
|
+
|
|
139
|
+
function resolveConfig(flags: Partial<Config>): Config {
|
|
140
|
+
// 1. Built-in defaults (from Zod schema defaults)
|
|
141
|
+
const defaults = ConfigSchema.parse({});
|
|
142
|
+
|
|
143
|
+
// 2. Global config
|
|
144
|
+
const globalConfig = loadTomlConfig(
|
|
145
|
+
path.join(getConfigDir('mycli'), 'config.toml')
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// 3. Project config (walk up from cwd)
|
|
149
|
+
const projectConfig = loadTomlConfig(
|
|
150
|
+
findProjectConfig(process.cwd(), '.mycli.toml')
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// 4. Environment variables
|
|
154
|
+
const envConfig: Partial<Config> = {};
|
|
155
|
+
if (process.env.MYCLI_ENVIRONMENT) envConfig.environment = process.env.MYCLI_ENVIRONMENT as Config['environment'];
|
|
156
|
+
if (process.env.MYCLI_OUTPUT_FORMAT) envConfig.outputFormat = process.env.MYCLI_OUTPUT_FORMAT as Config['outputFormat'];
|
|
157
|
+
if (process.env.MYCLI_REPLICAS) envConfig.replicas = parseInt(process.env.MYCLI_REPLICAS, 10);
|
|
158
|
+
if (process.env.MYCLI_VERBOSE) envConfig.verbose = process.env.MYCLI_VERBOSE === 'true';
|
|
159
|
+
|
|
160
|
+
// 5. Command-line flags (highest priority)
|
|
161
|
+
const merged = { ...defaults, ...globalConfig, ...projectConfig, ...envConfig, ...stripUndefined(flags) };
|
|
162
|
+
|
|
163
|
+
return ConfigSchema.parse(merged);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function findProjectConfig(startDir: string, filename: string): string | null {
|
|
167
|
+
let dir = startDir;
|
|
168
|
+
while (true) {
|
|
169
|
+
const candidate = path.join(dir, filename);
|
|
170
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
171
|
+
const parent = path.dirname(dir);
|
|
172
|
+
if (parent === dir) return null; // Reached root
|
|
173
|
+
dir = parent;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function loadTomlConfig(filePath: string | null): Partial<Config> {
|
|
178
|
+
if (!filePath || !fs.existsSync(filePath)) return {};
|
|
179
|
+
try {
|
|
180
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
181
|
+
return TOML.parse(content) as Partial<Config>;
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error(`Warning: Failed to parse config at ${filePath}: ${(error as Error).message}`);
|
|
184
|
+
return {};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function stripUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {
|
|
189
|
+
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Config File Discovery and Merging
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Walk up directory tree looking for project config
|
|
197
|
+
// Similar to how .eslintrc, .prettierrc, .gitignore work
|
|
198
|
+
|
|
199
|
+
function findConfigFiles(startDir: string): string[] {
|
|
200
|
+
const configs: string[] = [];
|
|
201
|
+
let dir = startDir;
|
|
202
|
+
|
|
203
|
+
while (true) {
|
|
204
|
+
const candidate = path.join(dir, '.mycli.toml');
|
|
205
|
+
if (fs.existsSync(candidate)) {
|
|
206
|
+
configs.unshift(candidate); // Parent configs first (lower priority)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Stop at git repo root or filesystem root
|
|
210
|
+
if (fs.existsSync(path.join(dir, '.git'))) break;
|
|
211
|
+
const parent = path.dirname(dir);
|
|
212
|
+
if (parent === dir) break;
|
|
213
|
+
dir = parent;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return configs;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Merge multiple config files (deepest directory wins)
|
|
220
|
+
function mergeProjectConfigs(configPaths: string[]): Partial<Config> {
|
|
221
|
+
let merged: Partial<Config> = {};
|
|
222
|
+
for (const configPath of configPaths) {
|
|
223
|
+
const config = loadTomlConfig(configPath);
|
|
224
|
+
merged = { ...merged, ...config };
|
|
225
|
+
}
|
|
226
|
+
return merged;
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Secret Handling in Config
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import keytar from 'keytar';
|
|
234
|
+
|
|
235
|
+
const SERVICE_NAME = 'mycli';
|
|
236
|
+
|
|
237
|
+
// Secrets NEVER go in config files
|
|
238
|
+
async function getApiToken(): Promise<string> {
|
|
239
|
+
// 1. Check environment variable first (CI/CD)
|
|
240
|
+
if (process.env.MYCLI_API_TOKEN) {
|
|
241
|
+
return process.env.MYCLI_API_TOKEN;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 2. Check OS keyring
|
|
245
|
+
const stored = await keytar.getPassword(SERVICE_NAME, 'api-token');
|
|
246
|
+
if (stored) return stored;
|
|
247
|
+
|
|
248
|
+
// 3. Interactive prompt (only in TTY)
|
|
249
|
+
if (process.stdin.isTTY) {
|
|
250
|
+
const token = await promptForToken();
|
|
251
|
+
await keytar.setPassword(SERVICE_NAME, 'api-token', token);
|
|
252
|
+
return token;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
console.error('Error: API token required. Set MYCLI_API_TOKEN or run `mycli auth login`.');
|
|
256
|
+
process.exit(1);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Warn if secrets are found in config files
|
|
260
|
+
function auditConfigForSecrets(configPath: string): void {
|
|
261
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
262
|
+
const sensitivePatterns = [
|
|
263
|
+
/token\s*=\s*["'][^"']+["']/i,
|
|
264
|
+
/password\s*=\s*["'][^"']+["']/i,
|
|
265
|
+
/secret\s*=\s*["'][^"']+["']/i,
|
|
266
|
+
/api[_-]?key\s*=\s*["'][^"']+["']/i,
|
|
267
|
+
];
|
|
268
|
+
|
|
269
|
+
for (const pattern of sensitivePatterns) {
|
|
270
|
+
if (pattern.test(content)) {
|
|
271
|
+
console.error(
|
|
272
|
+
`Warning: Possible secret found in ${configPath}. ` +
|
|
273
|
+
`Use 'mycli auth login' to store credentials securely in the OS keyring.`
|
|
274
|
+
);
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Rule**: Config files should never contain secrets. Secrets belong in the OS keyring or environment variables.
|
|
282
|
+
**Rule**: If a config file contains what looks like a secret, warn the user loudly.
|
|
283
|
+
|
|
284
|
+
## Config Validation and Migration
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { z } from 'zod';
|
|
288
|
+
|
|
289
|
+
// Versioned config schema
|
|
290
|
+
const ConfigV1Schema = z.object({
|
|
291
|
+
version: z.literal(1),
|
|
292
|
+
server: z.string().url(),
|
|
293
|
+
timeout: z.number(),
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
const ConfigV2Schema = z.object({
|
|
297
|
+
version: z.literal(2),
|
|
298
|
+
api: z.object({
|
|
299
|
+
url: z.string().url(),
|
|
300
|
+
timeout: z.number(),
|
|
301
|
+
retries: z.number().default(3),
|
|
302
|
+
}),
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
type ConfigV1 = z.infer<typeof ConfigV1Schema>;
|
|
306
|
+
type ConfigV2 = z.infer<typeof ConfigV2Schema>;
|
|
307
|
+
|
|
308
|
+
const CURRENT_VERSION = 2;
|
|
309
|
+
|
|
310
|
+
function migrateConfig(raw: unknown): ConfigV2 {
|
|
311
|
+
const obj = raw as Record<string, unknown>;
|
|
312
|
+
const version = (obj.version as number) ?? 1;
|
|
313
|
+
|
|
314
|
+
if (version === CURRENT_VERSION) {
|
|
315
|
+
return ConfigV2Schema.parse(raw);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (version === 1) {
|
|
319
|
+
const v1 = ConfigV1Schema.parse(raw);
|
|
320
|
+
const migrated: ConfigV2 = {
|
|
321
|
+
version: 2,
|
|
322
|
+
api: {
|
|
323
|
+
url: v1.server,
|
|
324
|
+
timeout: v1.timeout,
|
|
325
|
+
retries: 3,
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
console.error(`Migrated config from v${version} to v${CURRENT_VERSION}`);
|
|
330
|
+
return ConfigV2Schema.parse(migrated);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
throw new Error(`Unknown config version: ${version}. Expected ${CURRENT_VERSION}.`);
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## `init` / `config set` Subcommand Patterns
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
// mycli init - Create config file interactively
|
|
341
|
+
async function initConfig(): Promise<void> {
|
|
342
|
+
const configPath = path.join(getConfigDir('mycli'), 'config.toml');
|
|
343
|
+
|
|
344
|
+
if (fs.existsSync(configPath)) {
|
|
345
|
+
const { overwrite } = await inquirer.prompt([{
|
|
346
|
+
type: 'confirm',
|
|
347
|
+
name: 'overwrite',
|
|
348
|
+
message: `Config already exists at ${configPath}. Overwrite?`,
|
|
349
|
+
default: false,
|
|
350
|
+
}]);
|
|
351
|
+
if (!overwrite) return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const answers = await inquirer.prompt([
|
|
355
|
+
{
|
|
356
|
+
type: 'list',
|
|
357
|
+
name: 'environment',
|
|
358
|
+
message: 'Default environment:',
|
|
359
|
+
choices: ['dev', 'staging', 'production'],
|
|
360
|
+
default: 'staging',
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
type: 'list',
|
|
364
|
+
name: 'outputFormat',
|
|
365
|
+
message: 'Default output format:',
|
|
366
|
+
choices: ['table', 'json', 'csv'],
|
|
367
|
+
default: 'table',
|
|
368
|
+
},
|
|
369
|
+
]);
|
|
370
|
+
|
|
371
|
+
const toml = generateToml(answers);
|
|
372
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
373
|
+
fs.writeFileSync(configPath, toml, 'utf-8');
|
|
374
|
+
console.log(`Config written to ${configPath}`);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// mycli config set <key> <value>
|
|
378
|
+
async function configSet(key: string, value: string): Promise<void> {
|
|
379
|
+
const configPath = path.join(getConfigDir('mycli'), 'config.toml');
|
|
380
|
+
const config = loadTomlConfig(configPath) ?? {};
|
|
381
|
+
|
|
382
|
+
// Dot notation: "deploy.replicas" -> config.deploy.replicas
|
|
383
|
+
setNestedValue(config, key, parseValue(value));
|
|
384
|
+
|
|
385
|
+
// Validate the full config
|
|
386
|
+
const validated = ConfigSchema.safeParse(config);
|
|
387
|
+
if (!validated.success) {
|
|
388
|
+
console.error(`Invalid value for ${key}: ${validated.error.message}`);
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
fs.writeFileSync(configPath, TOML.stringify(config), 'utf-8');
|
|
393
|
+
console.log(`Set ${key} = ${value}`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// mycli config get <key>
|
|
397
|
+
function configGet(key: string): void {
|
|
398
|
+
const config = resolveConfig({});
|
|
399
|
+
const value = getNestedValue(config, key);
|
|
400
|
+
|
|
401
|
+
if (value === undefined) {
|
|
402
|
+
console.error(`Unknown config key: ${key}`);
|
|
403
|
+
process.exit(1);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
console.log(value);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// mycli config list
|
|
410
|
+
function configList(options: { format: string }): void {
|
|
411
|
+
const config = resolveConfig({});
|
|
412
|
+
if (options.format === 'json') {
|
|
413
|
+
console.log(JSON.stringify(config, null, 2));
|
|
414
|
+
} else {
|
|
415
|
+
for (const [key, value] of flattenConfig(config)) {
|
|
416
|
+
console.log(`${key} = ${value}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Dotfile Conventions
|
|
423
|
+
|
|
424
|
+
| Pattern | Example | Used By |
|
|
425
|
+
|---------|---------|---------|
|
|
426
|
+
| Dotfile in home | `~/.myclirc` | Older tools (bash, vim) |
|
|
427
|
+
| XDG config dir | `~/.config/mycli/config.toml` | Modern tools (recommended) |
|
|
428
|
+
| Project dotfile | `.mycli.toml` in project root | ESLint, Prettier, EditorConfig |
|
|
429
|
+
| package.json field | `"mycli": { ... }` in package.json | Jest, Babel (JS ecosystem only) |
|
|
430
|
+
|
|
431
|
+
**Rule**: For new tools, use XDG config directory for global config and a dotfile in project root for project config. Do not create dotfiles in `$HOME` directly.
|
|
432
|
+
|
|
433
|
+
## Output Checklist
|
|
434
|
+
|
|
435
|
+
- [ ] Config file uses TOML (or YAML if ecosystem expects it)
|
|
436
|
+
- [ ] Config file location follows XDG Base Directory spec
|
|
437
|
+
- [ ] Config precedence: env vars > flags > project config > global config > defaults
|
|
438
|
+
- [ ] Project config discovered by walking up directory tree
|
|
439
|
+
- [ ] Config validated with Zod schema
|
|
440
|
+
- [ ] Config migration handles version upgrades
|
|
441
|
+
- [ ] Secrets stored in OS keyring, not config files
|
|
442
|
+
- [ ] Warning emitted if secrets detected in config files
|
|
443
|
+
- [ ] `mycli init` creates config interactively
|
|
444
|
+
- [ ] `mycli config get/set/list` subcommands available
|
|
445
|
+
- [ ] Config file paths reported in `--verbose` output
|