compact-agent 1.10.1 → 1.11.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/ecc-hooks.cjs +110 -0
- package/dist/ecc.d.ts +11 -0
- package/dist/ecc.js +142 -27
- package/dist/ecc.js.map +1 -1
- package/dist/index.js +47 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/resources/ecc/agents/a11y-architect.md +149 -0
- package/resources/ecc/agents/architect.md +11 -3
- package/resources/ecc/agents/build-error-resolver.md +11 -4
- package/resources/ecc/agents/chief-of-staff.md +11 -4
- package/resources/ecc/agents/code-architect.md +80 -0
- package/resources/ecc/agents/code-explorer.md +78 -0
- package/resources/ecc/agents/code-reviewer.md +89 -4
- package/resources/ecc/agents/code-simplifier.md +56 -0
- package/resources/ecc/agents/comment-analyzer.md +54 -0
- package/resources/ecc/agents/conversation-analyzer.md +61 -0
- package/resources/ecc/agents/cpp-build-resolver.md +99 -0
- package/resources/ecc/agents/cpp-reviewer.md +81 -0
- package/resources/ecc/agents/csharp-reviewer.md +110 -0
- package/resources/ecc/agents/dart-build-resolver.md +210 -0
- package/resources/ecc/agents/database-reviewer.md +11 -3
- package/resources/ecc/agents/django-build-resolver.md +252 -0
- package/resources/ecc/agents/django-reviewer.md +169 -0
- package/resources/ecc/agents/doc-updater.md +11 -3
- package/resources/ecc/agents/docs-lookup.md +77 -0
- package/resources/ecc/agents/e2e-runner.md +11 -4
- package/resources/ecc/agents/fastapi-reviewer.md +79 -0
- package/resources/ecc/agents/flutter-reviewer.md +252 -0
- package/resources/ecc/agents/fsharp-reviewer.md +109 -0
- package/resources/ecc/agents/gan-evaluator.md +218 -0
- package/resources/ecc/agents/gan-generator.md +140 -0
- package/resources/ecc/agents/gan-planner.md +108 -0
- package/resources/ecc/agents/go-build-resolver.md +11 -4
- package/resources/ecc/agents/go-reviewer.md +11 -3
- package/resources/ecc/agents/harmonyos-app-resolver.md +182 -0
- package/resources/ecc/agents/harness-optimizer.md +12 -2
- package/resources/ecc/agents/healthcare-reviewer.md +92 -0
- package/resources/ecc/agents/homelab-architect.md +107 -0
- package/resources/ecc/agents/java-build-resolver.md +275 -0
- package/resources/ecc/agents/java-reviewer.md +190 -0
- package/resources/ecc/agents/kotlin-build-resolver.md +127 -0
- package/resources/ecc/agents/kotlin-reviewer.md +168 -0
- package/resources/ecc/agents/loop-operator.md +12 -3
- package/resources/ecc/agents/mle-reviewer.md +162 -0
- package/resources/ecc/agents/network-architect.md +106 -0
- package/resources/ecc/agents/network-config-reviewer.md +106 -0
- package/resources/ecc/agents/network-troubleshooter.md +128 -0
- package/resources/ecc/agents/opensource-forker.md +207 -0
- package/resources/ecc/agents/opensource-packager.md +258 -0
- package/resources/ecc/agents/opensource-sanitizer.md +197 -0
- package/resources/ecc/agents/performance-optimizer.md +455 -0
- package/resources/ecc/agents/planner.md +11 -2
- package/resources/ecc/agents/pr-test-analyzer.md +54 -0
- package/resources/ecc/agents/python-reviewer.md +11 -3
- package/resources/ecc/agents/pytorch-build-resolver.md +129 -0
- package/resources/ecc/agents/refactor-cleaner.md +11 -4
- package/resources/ecc/agents/rust-build-resolver.md +157 -0
- package/resources/ecc/agents/rust-reviewer.md +103 -0
- package/resources/ecc/agents/security-reviewer.md +11 -3
- package/resources/ecc/agents/seo-specialist.md +71 -0
- package/resources/ecc/agents/silent-failure-hunter.md +59 -0
- package/resources/ecc/agents/swift-build-resolver.md +170 -0
- package/resources/ecc/agents/swift-reviewer.md +116 -0
- package/resources/ecc/agents/tdd-guide.md +11 -4
- package/resources/ecc/agents/type-design-analyzer.md +50 -0
- package/resources/ecc/agents/typescript-reviewer.md +121 -0
- package/resources/ecc/commands/aside.md +164 -0
- package/resources/ecc/commands/auto-update.md +28 -0
- package/resources/ecc/commands/build-fix.md +66 -0
- package/resources/ecc/commands/checkpoint.md +78 -0
- package/resources/ecc/commands/code-review.md +289 -0
- package/resources/ecc/commands/cost-report.md +107 -0
- package/resources/ecc/commands/cpp-build.md +173 -0
- package/resources/ecc/commands/cpp-review.md +132 -0
- package/resources/ecc/commands/cpp-test.md +251 -0
- package/resources/ecc/commands/ecc-guide.md +93 -0
- package/resources/ecc/commands/evolve.md +178 -0
- package/resources/ecc/commands/fastapi-review.md +39 -0
- package/resources/ecc/commands/feature-dev.md +49 -0
- package/resources/ecc/commands/flutter-build.md +164 -0
- package/resources/ecc/commands/flutter-review.md +116 -0
- package/resources/ecc/commands/flutter-test.md +144 -0
- package/resources/ecc/commands/gan-build.md +103 -0
- package/resources/ecc/commands/gan-design.md +39 -0
- package/resources/ecc/commands/go-build.md +183 -0
- package/resources/ecc/commands/go-review.md +148 -0
- package/resources/ecc/commands/go-test.md +268 -0
- package/resources/ecc/commands/gradle-build.md +70 -0
- package/resources/ecc/commands/harness-audit.md +77 -0
- package/resources/ecc/commands/hookify-configure.md +14 -0
- package/resources/ecc/commands/hookify-help.md +46 -0
- package/resources/ecc/commands/hookify-list.md +21 -0
- package/resources/ecc/commands/hookify.md +50 -0
- package/resources/ecc/commands/instinct-export.md +66 -0
- package/resources/ecc/commands/instinct-import.md +114 -0
- package/resources/ecc/commands/instinct-status.md +59 -0
- package/resources/ecc/commands/jira.md +106 -0
- package/resources/ecc/commands/kotlin-build.md +174 -0
- package/resources/ecc/commands/kotlin-review.md +140 -0
- package/resources/ecc/commands/kotlin-test.md +312 -0
- package/resources/ecc/commands/learn-eval.md +116 -0
- package/resources/ecc/commands/learn.md +74 -0
- package/resources/ecc/commands/loop-start.md +36 -0
- package/resources/ecc/commands/loop-status.md +77 -0
- package/resources/ecc/commands/model-route.md +30 -0
- package/resources/ecc/commands/multi-backend.md +162 -0
- package/resources/ecc/commands/multi-execute.md +319 -0
- package/resources/ecc/commands/multi-frontend.md +162 -0
- package/resources/ecc/commands/multi-plan.md +272 -0
- package/resources/ecc/commands/multi-workflow.md +195 -0
- package/resources/ecc/commands/plan-prd.md +160 -0
- package/resources/ecc/commands/plan.md +200 -0
- package/resources/ecc/commands/pm2.md +276 -0
- package/resources/ecc/commands/pr.md +184 -0
- package/resources/ecc/commands/project-init.md +86 -0
- package/resources/ecc/commands/projects.md +39 -0
- package/resources/ecc/commands/promote.md +41 -0
- package/resources/ecc/commands/prp-commit.md +112 -0
- package/resources/ecc/commands/prp-implement.md +385 -0
- package/resources/ecc/commands/prp-plan.md +502 -0
- package/resources/ecc/commands/prp-pr.md +184 -0
- package/resources/ecc/commands/prp-prd.md +447 -0
- package/resources/ecc/commands/prune.md +31 -0
- package/resources/ecc/commands/python-review.md +297 -0
- package/resources/ecc/commands/quality-gate.md +33 -0
- package/resources/ecc/commands/refactor-clean.md +84 -0
- package/resources/ecc/commands/resume-session.md +156 -0
- package/resources/ecc/commands/review-pr.md +37 -0
- package/resources/ecc/commands/rust-build.md +187 -0
- package/resources/ecc/commands/rust-review.md +142 -0
- package/resources/ecc/commands/rust-test.md +308 -0
- package/resources/ecc/commands/santa-loop.md +175 -0
- package/resources/ecc/commands/save-session.md +275 -0
- package/resources/ecc/commands/security-scan.md +92 -0
- package/resources/ecc/commands/sessions.md +339 -0
- package/resources/ecc/commands/setup-pm.md +80 -0
- package/resources/ecc/commands/skill-create.md +174 -0
- package/resources/ecc/commands/skill-health.md +54 -0
- package/resources/ecc/commands/test-coverage.md +73 -0
- package/resources/ecc/commands/update-codemaps.md +76 -0
- package/resources/ecc/commands/update-docs.md +88 -0
- package/resources/ecc/rules/README.md +120 -0
- package/resources/ecc/rules/angular/coding-style.md +182 -0
- package/resources/ecc/rules/angular/hooks.md +25 -0
- package/resources/ecc/rules/angular/patterns.md +249 -0
- package/resources/ecc/rules/angular/security.md +87 -0
- package/resources/ecc/rules/angular/testing.md +164 -0
- package/resources/ecc/rules/arkts/coding-style.md +153 -0
- package/resources/ecc/rules/arkts/hooks.md +135 -0
- package/resources/ecc/rules/arkts/patterns.md +236 -0
- package/resources/ecc/rules/arkts/security.md +141 -0
- package/resources/ecc/rules/arkts/testing.md +126 -0
- package/resources/ecc/rules/{common-agents.md → common/agents.md} +2 -4
- package/resources/ecc/rules/common/code-review.md +124 -0
- package/resources/ecc/rules/{common-coding-style.md → common/coding-style.md} +42 -4
- package/resources/ecc/rules/common/development-workflow.md +44 -0
- package/resources/ecc/rules/{common-git-workflow.md → common/git-workflow.md} +1 -5
- package/resources/ecc/rules/{common-hooks.md → common/hooks.md} +0 -4
- package/resources/ecc/rules/{common-patterns.md → common/patterns.md} +0 -4
- package/resources/ecc/rules/{common-performance.md → common/performance.md} +0 -4
- package/resources/ecc/rules/{common-security.md → common/security.md} +0 -4
- package/resources/ecc/rules/{common-testing.md → common/testing.md} +28 -4
- package/resources/ecc/rules/cpp/coding-style.md +44 -0
- package/resources/ecc/rules/cpp/hooks.md +39 -0
- package/resources/ecc/rules/cpp/patterns.md +51 -0
- package/resources/ecc/rules/cpp/security.md +51 -0
- package/resources/ecc/rules/cpp/testing.md +44 -0
- package/resources/ecc/rules/csharp/coding-style.md +72 -0
- package/resources/ecc/rules/csharp/hooks.md +25 -0
- package/resources/ecc/rules/csharp/patterns.md +50 -0
- package/resources/ecc/rules/csharp/security.md +58 -0
- package/resources/ecc/rules/csharp/testing.md +46 -0
- package/resources/ecc/rules/dart/coding-style.md +159 -0
- package/resources/ecc/rules/dart/hooks.md +66 -0
- package/resources/ecc/rules/dart/patterns.md +261 -0
- package/resources/ecc/rules/dart/security.md +135 -0
- package/resources/ecc/rules/dart/testing.md +215 -0
- package/resources/ecc/rules/fsharp/coding-style.md +112 -0
- package/resources/ecc/rules/fsharp/hooks.md +26 -0
- package/resources/ecc/rules/fsharp/patterns.md +111 -0
- package/resources/ecc/rules/fsharp/security.md +76 -0
- package/resources/ecc/rules/fsharp/testing.md +62 -0
- package/resources/ecc/rules/{golang-coding-style.md → golang/coding-style.md} +6 -5
- package/resources/ecc/rules/{golang-hooks.md → golang/hooks.md} +5 -4
- package/resources/ecc/rules/{golang-patterns.md → golang/patterns.md} +5 -4
- package/resources/ecc/rules/{golang-security.md → golang/security.md} +5 -4
- package/resources/ecc/rules/{golang-testing.md → golang/testing.md} +5 -4
- package/resources/ecc/rules/java/coding-style.md +114 -0
- package/resources/ecc/rules/java/hooks.md +18 -0
- package/resources/ecc/rules/java/patterns.md +147 -0
- package/resources/ecc/rules/java/security.md +101 -0
- package/resources/ecc/rules/java/testing.md +133 -0
- package/resources/ecc/rules/kotlin/coding-style.md +86 -0
- package/resources/ecc/rules/{kotlin-hooks.md → kotlin/hooks.md} +5 -4
- package/resources/ecc/rules/kotlin/patterns.md +146 -0
- package/resources/ecc/rules/kotlin/security.md +82 -0
- package/resources/ecc/rules/kotlin/testing.md +128 -0
- package/resources/ecc/rules/perl/coding-style.md +46 -0
- package/resources/ecc/rules/perl/hooks.md +22 -0
- package/resources/ecc/rules/perl/patterns.md +76 -0
- package/resources/ecc/rules/perl/security.md +69 -0
- package/resources/ecc/rules/perl/testing.md +54 -0
- package/resources/ecc/rules/php/coding-style.md +40 -0
- package/resources/ecc/rules/{php-hooks.md → php/hooks.md} +7 -4
- package/resources/ecc/rules/php/patterns.md +33 -0
- package/resources/ecc/rules/php/security.md +37 -0
- package/resources/ecc/rules/php/testing.md +39 -0
- package/resources/ecc/rules/{python-coding-style.md → python/coding-style.md} +4 -4
- package/resources/ecc/rules/python/fastapi.md +58 -0
- package/resources/ecc/rules/{python-hooks.md → python/hooks.md} +4 -4
- package/resources/ecc/rules/{python-patterns.md → python/patterns.md} +4 -4
- package/resources/ecc/rules/{python-security.md → python/security.md} +4 -4
- package/resources/ecc/rules/{python-testing.md → python/testing.md} +4 -4
- package/resources/ecc/rules/ruby/coding-style.md +46 -0
- package/resources/ecc/rules/ruby/hooks.md +37 -0
- package/resources/ecc/rules/ruby/patterns.md +44 -0
- package/resources/ecc/rules/ruby/security.md +51 -0
- package/resources/ecc/rules/ruby/testing.md +51 -0
- package/resources/ecc/rules/rust/coding-style.md +151 -0
- package/resources/ecc/rules/rust/hooks.md +16 -0
- package/resources/ecc/rules/rust/patterns.md +168 -0
- package/resources/ecc/rules/rust/security.md +141 -0
- package/resources/ecc/rules/rust/testing.md +154 -0
- package/resources/ecc/rules/{swift-coding-style.md → swift/coding-style.md} +6 -6
- package/resources/ecc/rules/swift/hooks.md +20 -0
- package/resources/ecc/rules/{swift-patterns.md → swift/patterns.md} +5 -5
- package/resources/ecc/rules/{swift-security.md → swift/security.md} +7 -7
- package/resources/ecc/rules/{swift-testing.md → swift/testing.md} +5 -5
- package/resources/ecc/rules/typescript/coding-style.md +199 -0
- package/resources/ecc/rules/{typescript-hooks.md → typescript/hooks.md} +6 -4
- package/resources/ecc/rules/{typescript-patterns.md → typescript/patterns.md} +6 -4
- package/resources/ecc/rules/{typescript-security.md → typescript/security.md} +6 -4
- package/resources/ecc/rules/typescript/testing.md +18 -0
- package/resources/ecc/rules/web/coding-style.md +96 -0
- package/resources/ecc/rules/web/design-quality.md +63 -0
- package/resources/ecc/rules/web/hooks.md +129 -0
- package/resources/ecc/rules/web/patterns.md +79 -0
- package/resources/ecc/rules/web/performance.md +64 -0
- package/resources/ecc/rules/web/security.md +57 -0
- package/resources/ecc/rules/web/testing.md +55 -0
- package/resources/ecc/rules/zh/README.md +108 -0
- package/resources/ecc/rules/zh/agents.md +50 -0
- package/resources/ecc/rules/zh/code-review.md +124 -0
- package/resources/ecc/rules/zh/coding-style.md +48 -0
- package/resources/ecc/rules/zh/development-workflow.md +44 -0
- package/resources/ecc/rules/zh/git-workflow.md +24 -0
- package/resources/ecc/rules/zh/hooks.md +30 -0
- package/resources/ecc/rules/zh/patterns.md +31 -0
- package/resources/ecc/rules/zh/performance.md +55 -0
- package/resources/ecc/rules/zh/security.md +29 -0
- package/resources/ecc/rules/zh/testing.md +29 -0
- package/resources/ecc/skills/accessibility/SKILL.md +146 -0
- package/resources/ecc/skills/agent-architecture-audit/SKILL.md +256 -0
- package/resources/ecc/skills/agent-eval/SKILL.md +145 -0
- package/resources/ecc/skills/agent-harness-construction/SKILL.md +73 -0
- package/resources/ecc/skills/agent-introspection-debugging/SKILL.md +1 -0
- package/resources/ecc/skills/agent-payment-x402/SKILL.md +224 -0
- package/resources/ecc/skills/agent-sort/SKILL.md +1 -0
- package/resources/ecc/skills/agentic-engineering/SKILL.md +63 -0
- package/resources/ecc/skills/agentic-os/SKILL.md +387 -0
- package/resources/ecc/skills/ai-first-engineering/SKILL.md +51 -0
- package/resources/ecc/skills/ai-regression-testing/SKILL.md +385 -0
- package/resources/ecc/skills/android-clean-architecture/SKILL.md +339 -0
- package/resources/ecc/skills/angular-developer/SKILL.md +154 -0
- package/resources/ecc/skills/angular-developer/references/angular-animations.md +160 -0
- package/resources/ecc/skills/angular-developer/references/angular-aria.md +410 -0
- package/resources/ecc/skills/angular-developer/references/cli.md +86 -0
- package/resources/ecc/skills/angular-developer/references/component-harnesses.md +59 -0
- package/resources/ecc/skills/angular-developer/references/component-styling.md +91 -0
- package/resources/ecc/skills/angular-developer/references/components.md +117 -0
- package/resources/ecc/skills/angular-developer/references/creating-services.md +97 -0
- package/resources/ecc/skills/angular-developer/references/data-resolvers.md +69 -0
- package/resources/ecc/skills/angular-developer/references/define-routes.md +67 -0
- package/resources/ecc/skills/angular-developer/references/defining-providers.md +72 -0
- package/resources/ecc/skills/angular-developer/references/di-fundamentals.md +120 -0
- package/resources/ecc/skills/angular-developer/references/e2e-testing.md +56 -0
- package/resources/ecc/skills/angular-developer/references/effects.md +83 -0
- package/resources/ecc/skills/angular-developer/references/hierarchical-injectors.md +43 -0
- package/resources/ecc/skills/angular-developer/references/host-elements.md +80 -0
- package/resources/ecc/skills/angular-developer/references/injection-context.md +63 -0
- package/resources/ecc/skills/angular-developer/references/inputs.md +101 -0
- package/resources/ecc/skills/angular-developer/references/linked-signal.md +59 -0
- package/resources/ecc/skills/angular-developer/references/loading-strategies.md +61 -0
- package/resources/ecc/skills/angular-developer/references/mcp.md +108 -0
- package/resources/ecc/skills/angular-developer/references/navigate-to-routes.md +69 -0
- package/resources/ecc/skills/angular-developer/references/outputs.md +86 -0
- package/resources/ecc/skills/angular-developer/references/reactive-forms.md +122 -0
- package/resources/ecc/skills/angular-developer/references/rendering-strategies.md +44 -0
- package/resources/ecc/skills/angular-developer/references/resource.md +77 -0
- package/resources/ecc/skills/angular-developer/references/route-animations.md +56 -0
- package/resources/ecc/skills/angular-developer/references/route-guards.md +52 -0
- package/resources/ecc/skills/angular-developer/references/router-lifecycle.md +45 -0
- package/resources/ecc/skills/angular-developer/references/router-testing.md +87 -0
- package/resources/ecc/skills/angular-developer/references/show-routes-with-outlets.md +68 -0
- package/resources/ecc/skills/angular-developer/references/signal-forms.md +795 -0
- package/resources/ecc/skills/angular-developer/references/signals-overview.md +94 -0
- package/resources/ecc/skills/angular-developer/references/tailwind-css.md +69 -0
- package/resources/ecc/skills/angular-developer/references/template-driven-forms.md +114 -0
- package/resources/ecc/skills/angular-developer/references/testing-fundamentals.md +65 -0
- package/resources/ecc/skills/api-connector-builder/SKILL.md +120 -0
- package/resources/ecc/skills/api-design/SKILL.md +1 -0
- package/resources/ecc/skills/architecture-decision-records/SKILL.md +179 -0
- package/resources/ecc/skills/article-writing/SKILL.md +1 -0
- package/resources/ecc/skills/automation-audit-ops/SKILL.md +142 -0
- package/resources/ecc/skills/autonomous-agent-harness/SKILL.md +273 -0
- package/resources/ecc/skills/autonomous-loops/SKILL.md +610 -0
- package/resources/ecc/skills/backend-patterns/SKILL.md +8 -44
- package/resources/ecc/skills/benchmark/SKILL.md +93 -0
- package/resources/ecc/skills/blueprint/SKILL.md +105 -0
- package/resources/ecc/skills/brand-voice/SKILL.md +1 -0
- package/resources/ecc/skills/browser-qa/SKILL.md +87 -0
- package/resources/ecc/skills/bun-runtime/SKILL.md +1 -0
- package/resources/ecc/skills/canary-watch/SKILL.md +99 -0
- package/resources/ecc/skills/carrier-relationship-management/SKILL.md +212 -0
- package/resources/ecc/skills/cisco-ios-patterns/SKILL.md +163 -0
- package/resources/ecc/skills/ck/SKILL.md +147 -0
- package/resources/ecc/skills/ck/commands/forget.mjs +44 -0
- package/resources/ecc/skills/ck/commands/info.mjs +24 -0
- package/resources/ecc/skills/ck/commands/init.mjs +143 -0
- package/resources/ecc/skills/ck/commands/list.mjs +40 -0
- package/resources/ecc/skills/ck/commands/migrate.mjs +202 -0
- package/resources/ecc/skills/ck/commands/resume.mjs +36 -0
- package/resources/ecc/skills/ck/commands/save.mjs +210 -0
- package/resources/ecc/skills/ck/commands/shared.mjs +387 -0
- package/resources/ecc/skills/ck/hooks/session-start.mjs +224 -0
- package/resources/ecc/skills/claude-devfleet/SKILL.md +103 -0
- package/resources/ecc/skills/click-path-audit/SKILL.md +244 -0
- package/resources/ecc/skills/clickhouse-io/SKILL.md +439 -0
- package/resources/ecc/skills/code-tour/SKILL.md +236 -0
- package/resources/ecc/skills/codebase-onboarding/SKILL.md +233 -0
- package/resources/ecc/skills/coding-standards/SKILL.md +1 -0
- package/resources/ecc/skills/compose-multiplatform-patterns/SKILL.md +299 -0
- package/resources/ecc/skills/configure-ecc/SKILL.md +384 -0
- package/resources/ecc/skills/connections-optimizer/SKILL.md +189 -0
- package/resources/ecc/skills/content-engine/SKILL.md +1 -0
- package/resources/ecc/skills/content-hash-cache-pattern/SKILL.md +161 -0
- package/resources/ecc/skills/context-budget/SKILL.md +135 -0
- package/resources/ecc/skills/continuous-agent-loop/SKILL.md +45 -0
- package/resources/ecc/skills/continuous-learning/SKILL.md +131 -0
- package/resources/ecc/skills/continuous-learning/config.json +18 -0
- package/resources/ecc/skills/continuous-learning/evaluate-session.sh +69 -0
- package/resources/ecc/skills/continuous-learning-v2/SKILL.md +360 -0
- package/resources/ecc/skills/continuous-learning-v2/agents/observer-loop.sh +322 -0
- package/resources/ecc/skills/continuous-learning-v2/agents/observer.md +198 -0
- package/resources/ecc/skills/continuous-learning-v2/agents/session-guardian.sh +150 -0
- package/resources/ecc/skills/continuous-learning-v2/agents/start-observer.sh +248 -0
- package/resources/ecc/skills/continuous-learning-v2/config.json +8 -0
- package/resources/ecc/skills/continuous-learning-v2/hooks/observe.sh +476 -0
- package/resources/ecc/skills/continuous-learning-v2/scripts/detect-project.sh +288 -0
- package/resources/ecc/skills/continuous-learning-v2/scripts/instinct-cli.py +1519 -0
- package/resources/ecc/skills/continuous-learning-v2/scripts/lib/homunculus-dir.sh +31 -0
- package/resources/ecc/skills/continuous-learning-v2/scripts/migrate-homunculus.sh +62 -0
- package/resources/ecc/skills/continuous-learning-v2/scripts/test_parse_instinct.py +1018 -0
- package/resources/ecc/skills/cost-aware-llm-pipeline/SKILL.md +183 -0
- package/resources/ecc/skills/cost-tracking/SKILL.md +147 -0
- package/resources/ecc/skills/council/SKILL.md +203 -0
- package/resources/ecc/skills/cpp-coding-standards/SKILL.md +723 -0
- package/resources/ecc/skills/cpp-testing/SKILL.md +324 -0
- package/resources/ecc/skills/crosspost/SKILL.md +1 -0
- package/resources/ecc/skills/csharp-testing/SKILL.md +321 -0
- package/resources/ecc/skills/customer-billing-ops/SKILL.md +140 -0
- package/resources/ecc/skills/customs-trade-compliance/SKILL.md +263 -0
- package/resources/ecc/skills/dart-flutter-patterns/SKILL.md +563 -0
- package/resources/ecc/skills/dashboard-builder/SKILL.md +108 -0
- package/resources/ecc/skills/data-scraper-agent/SKILL.md +764 -0
- package/resources/ecc/skills/database-migrations/SKILL.md +429 -0
- package/resources/ecc/skills/deep-research/SKILL.md +5 -0
- package/resources/ecc/skills/defi-amm-security/SKILL.md +166 -0
- package/resources/ecc/skills/deployment-patterns/SKILL.md +427 -0
- package/resources/ecc/skills/design-system/SKILL.md +82 -0
- package/resources/ecc/skills/django-celery/SKILL.md +457 -0
- package/resources/ecc/skills/django-patterns/SKILL.md +734 -0
- package/resources/ecc/skills/django-security/SKILL.md +593 -0
- package/resources/ecc/skills/django-tdd/SKILL.md +729 -0
- package/resources/ecc/skills/django-verification/SKILL.md +469 -0
- package/resources/ecc/skills/dmux-workflows/SKILL.md +52 -4
- package/resources/ecc/skills/docker-patterns/SKILL.md +364 -0
- package/resources/ecc/skills/documentation-lookup/SKILL.md +1 -0
- package/resources/ecc/skills/dotnet-patterns/SKILL.md +321 -0
- package/resources/ecc/skills/e2e-testing/SKILL.md +1 -0
- package/resources/ecc/skills/ecc-guide/SKILL.md +189 -0
- package/resources/ecc/skills/ecc-tools-cost-audit/SKILL.md +160 -0
- package/resources/ecc/skills/email-ops/SKILL.md +121 -0
- package/resources/ecc/skills/energy-procurement/SKILL.md +228 -0
- package/resources/ecc/skills/enterprise-agent-ops/SKILL.md +50 -0
- package/resources/ecc/skills/error-handling/SKILL.md +376 -0
- package/resources/ecc/skills/eval-harness/SKILL.md +36 -1
- package/resources/ecc/skills/evm-token-decimals/SKILL.md +130 -0
- package/resources/ecc/skills/exa-search/SKILL.md +18 -80
- package/resources/ecc/skills/fal-ai-media/SKILL.md +32 -20
- package/resources/ecc/skills/fastapi-patterns/SKILL.md +327 -0
- package/resources/ecc/skills/finance-billing-ops/SKILL.md +127 -0
- package/resources/ecc/skills/flox-environments/SKILL.md +496 -0
- package/resources/ecc/skills/flutter-dart-code-review/SKILL.md +435 -0
- package/resources/ecc/skills/foundation-models-on-device/SKILL.md +243 -0
- package/resources/ecc/skills/frontend-design-direction/SKILL.md +92 -0
- package/resources/ecc/skills/frontend-patterns/SKILL.md +1 -6
- package/resources/ecc/skills/frontend-slides/SKILL.md +2 -1
- package/resources/ecc/skills/frontend-slides/animation-patterns.md +122 -0
- package/resources/ecc/skills/frontend-slides/html-template.md +419 -0
- package/resources/ecc/skills/frontend-slides/scripts/export-pdf.sh +418 -0
- package/resources/ecc/skills/frontend-slides/scripts/extract-pptx.py +96 -0
- package/resources/ecc/skills/frontend-slides/viewport-base.css +153 -0
- package/resources/ecc/skills/fsharp-testing/SKILL.md +280 -0
- package/resources/ecc/skills/gan-style-harness/SKILL.md +278 -0
- package/resources/ecc/skills/gateguard/SKILL.md +125 -0
- package/resources/ecc/skills/git-workflow/SKILL.md +715 -0
- package/resources/ecc/skills/github-ops/SKILL.md +144 -0
- package/resources/ecc/skills/golang-patterns/SKILL.md +674 -0
- package/resources/ecc/skills/golang-testing/SKILL.md +720 -0
- package/resources/ecc/skills/google-workspace-ops/SKILL.md +95 -0
- package/resources/ecc/skills/healthcare-cdss-patterns/SKILL.md +245 -0
- package/resources/ecc/skills/healthcare-emr-patterns/SKILL.md +159 -0
- package/resources/ecc/skills/healthcare-eval-harness/SKILL.md +207 -0
- package/resources/ecc/skills/healthcare-phi-compliance/SKILL.md +145 -0
- package/resources/ecc/skills/hermes-imports/SKILL.md +88 -0
- package/resources/ecc/skills/hexagonal-architecture/SKILL.md +276 -0
- package/resources/ecc/skills/hipaa-compliance/SKILL.md +78 -0
- package/resources/ecc/skills/homelab-network-readiness/SKILL.md +169 -0
- package/resources/ecc/skills/homelab-network-setup/SKILL.md +129 -0
- package/resources/ecc/skills/homelab-pihole-dns/SKILL.md +274 -0
- package/resources/ecc/skills/homelab-vlan-segmentation/SKILL.md +311 -0
- package/resources/ecc/skills/homelab-wireguard-vpn/SKILL.md +305 -0
- package/resources/ecc/skills/hookify-rules/SKILL.md +128 -0
- package/resources/ecc/skills/inventory-demand-planning/SKILL.md +247 -0
- package/resources/ecc/skills/investor-materials/SKILL.md +1 -0
- package/resources/ecc/skills/investor-outreach/SKILL.md +1 -0
- package/resources/ecc/skills/ios-icon-gen/SKILL.md +157 -0
- package/resources/ecc/skills/ios-icon-gen/scripts/generate_icons.swift +258 -0
- package/resources/ecc/skills/ios-icon-gen/scripts/iconify_gen.sh +235 -0
- package/resources/ecc/skills/iterative-retrieval/SKILL.md +211 -0
- package/resources/ecc/skills/java-coding-standards/SKILL.md +383 -0
- package/resources/ecc/skills/jira-integration/SKILL.md +293 -0
- package/resources/ecc/skills/jpa-patterns/SKILL.md +151 -0
- package/resources/ecc/skills/knowledge-ops/SKILL.md +154 -0
- package/resources/ecc/skills/kotlin-coroutines-flows/SKILL.md +284 -0
- package/resources/ecc/skills/kotlin-exposed-patterns/SKILL.md +719 -0
- package/resources/ecc/skills/kotlin-ktor-patterns/SKILL.md +689 -0
- package/resources/ecc/skills/kotlin-patterns/SKILL.md +711 -0
- package/resources/ecc/skills/kotlin-testing/SKILL.md +824 -0
- package/resources/ecc/skills/laravel-patterns/SKILL.md +415 -0
- package/resources/ecc/skills/laravel-plugin-discovery/SKILL.md +229 -0
- package/resources/ecc/skills/laravel-security/SKILL.md +285 -0
- package/resources/ecc/skills/laravel-tdd/SKILL.md +283 -0
- package/resources/ecc/skills/laravel-verification/SKILL.md +179 -0
- package/resources/ecc/skills/lead-intelligence/SKILL.md +321 -0
- package/resources/ecc/skills/lead-intelligence/agents/enrichment-agent.md +85 -0
- package/resources/ecc/skills/lead-intelligence/agents/mutual-mapper.md +75 -0
- package/resources/ecc/skills/lead-intelligence/agents/outreach-drafter.md +98 -0
- package/resources/ecc/skills/lead-intelligence/agents/signal-scorer.md +60 -0
- package/resources/ecc/skills/liquid-glass-design/SKILL.md +279 -0
- package/resources/ecc/skills/llm-trading-agent-security/SKILL.md +146 -0
- package/resources/ecc/skills/logistics-exception-management/SKILL.md +222 -0
- package/resources/ecc/skills/make-interfaces-feel-better/SKILL.md +151 -0
- package/resources/ecc/skills/manim-video/SKILL.md +89 -0
- package/resources/ecc/skills/manim-video/assets/network_graph_scene.py +52 -0
- package/resources/ecc/skills/market-research/SKILL.md +1 -0
- package/resources/ecc/skills/mcp-server-patterns/SKILL.md +3 -0
- package/resources/ecc/skills/messages-ops/SKILL.md +104 -0
- package/resources/ecc/skills/mle-workflow/SKILL.md +1 -1
- package/resources/ecc/skills/motion-advanced/SKILL.md +596 -0
- package/resources/ecc/skills/motion-foundations/SKILL.md +299 -0
- package/resources/ecc/skills/motion-patterns/SKILL.md +435 -0
- package/resources/ecc/skills/motion-ui/SKILL.md +575 -0
- package/resources/ecc/skills/mysql-patterns/SKILL.md +412 -0
- package/resources/ecc/skills/nanoclaw-repl/SKILL.md +33 -0
- package/resources/ecc/skills/nestjs-patterns/SKILL.md +230 -0
- package/resources/ecc/skills/netmiko-ssh-automation/SKILL.md +173 -0
- package/resources/ecc/skills/network-bgp-diagnostics/SKILL.md +167 -0
- package/resources/ecc/skills/network-config-validation/SKILL.md +210 -0
- package/resources/ecc/skills/network-interface-health/SKILL.md +152 -0
- package/resources/ecc/skills/nextjs-turbopack/SKILL.md +1 -0
- package/resources/ecc/skills/nodejs-keccak256/SKILL.md +102 -0
- package/resources/ecc/skills/nutrient-document-processing/SKILL.md +167 -0
- package/resources/ecc/skills/nuxt4-patterns/SKILL.md +100 -0
- package/resources/ecc/skills/openclaw-persona-forge/SKILL.md +288 -0
- package/resources/ecc/skills/openclaw-persona-forge/gacha.py +224 -0
- package/resources/ecc/skills/openclaw-persona-forge/gacha.sh +5 -0
- package/resources/ecc/skills/openclaw-persona-forge/references/avatar-style.md +124 -0
- package/resources/ecc/skills/openclaw-persona-forge/references/boundary-rules.md +53 -0
- package/resources/ecc/skills/openclaw-persona-forge/references/error-handling.md +53 -0
- package/resources/ecc/skills/openclaw-persona-forge/references/identity-tension.md +48 -0
- package/resources/ecc/skills/openclaw-persona-forge/references/naming-system.md +39 -0
- package/resources/ecc/skills/openclaw-persona-forge/references/output-template.md +166 -0
- package/resources/ecc/skills/opensource-pipeline/SKILL.md +255 -0
- package/resources/ecc/skills/perl-patterns/SKILL.md +504 -0
- package/resources/ecc/skills/perl-security/SKILL.md +503 -0
- package/resources/ecc/skills/perl-testing/SKILL.md +475 -0
- package/resources/ecc/skills/plan-orchestrate/SKILL.md +262 -0
- package/resources/ecc/skills/plankton-code-quality/SKILL.md +236 -0
- package/resources/ecc/skills/postgres-patterns/SKILL.md +147 -0
- package/resources/ecc/skills/product-capability/SKILL.md +1 -0
- package/resources/ecc/skills/product-lens/SKILL.md +92 -0
- package/resources/ecc/skills/production-audit/SKILL.md +206 -0
- package/resources/ecc/skills/production-scheduling/SKILL.md +238 -0
- package/resources/ecc/skills/project-flow-ops/SKILL.md +111 -0
- package/resources/ecc/skills/prompt-optimizer/SKILL.md +398 -0
- package/resources/ecc/skills/python-patterns/SKILL.md +750 -0
- package/resources/ecc/skills/python-testing/SKILL.md +816 -0
- package/resources/ecc/skills/pytorch-patterns/SKILL.md +396 -0
- package/resources/ecc/skills/quality-nonconformance/SKILL.md +260 -0
- package/resources/ecc/skills/quarkus-patterns/SKILL.md +722 -0
- package/resources/ecc/skills/quarkus-security/SKILL.md +467 -0
- package/resources/ecc/skills/quarkus-tdd/SKILL.md +811 -0
- package/resources/ecc/skills/quarkus-verification/SKILL.md +479 -0
- package/resources/ecc/skills/ralphinho-rfc-pipeline/SKILL.md +67 -0
- package/resources/ecc/skills/redis-patterns/SKILL.md +403 -0
- package/resources/ecc/skills/regex-vs-llm-structured-text/SKILL.md +220 -0
- package/resources/ecc/skills/remotion-video-creation/SKILL.md +43 -0
- package/resources/ecc/skills/remotion-video-creation/rules/3d.md +86 -0
- package/resources/ecc/skills/remotion-video-creation/rules/animations.md +29 -0
- package/resources/ecc/skills/remotion-video-creation/rules/assets/charts-bar-chart.tsx +173 -0
- package/resources/ecc/skills/remotion-video-creation/rules/assets/text-animations-typewriter.tsx +100 -0
- package/resources/ecc/skills/remotion-video-creation/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/resources/ecc/skills/remotion-video-creation/rules/assets.md +78 -0
- package/resources/ecc/skills/remotion-video-creation/rules/audio.md +172 -0
- package/resources/ecc/skills/remotion-video-creation/rules/calculate-metadata.md +104 -0
- package/resources/ecc/skills/remotion-video-creation/rules/can-decode.md +75 -0
- package/resources/ecc/skills/remotion-video-creation/rules/charts.md +58 -0
- package/resources/ecc/skills/remotion-video-creation/rules/compositions.md +146 -0
- package/resources/ecc/skills/remotion-video-creation/rules/display-captions.md +126 -0
- package/resources/ecc/skills/remotion-video-creation/rules/extract-frames.md +229 -0
- package/resources/ecc/skills/remotion-video-creation/rules/fonts.md +152 -0
- package/resources/ecc/skills/remotion-video-creation/rules/get-audio-duration.md +58 -0
- package/resources/ecc/skills/remotion-video-creation/rules/get-video-dimensions.md +68 -0
- package/resources/ecc/skills/remotion-video-creation/rules/get-video-duration.md +58 -0
- package/resources/ecc/skills/remotion-video-creation/rules/gifs.md +138 -0
- package/resources/ecc/skills/remotion-video-creation/rules/images.md +130 -0
- package/resources/ecc/skills/remotion-video-creation/rules/import-srt-captions.md +67 -0
- package/resources/ecc/skills/remotion-video-creation/rules/lottie.md +67 -0
- package/resources/ecc/skills/remotion-video-creation/rules/measuring-dom-nodes.md +34 -0
- package/resources/ecc/skills/remotion-video-creation/rules/measuring-text.md +143 -0
- package/resources/ecc/skills/remotion-video-creation/rules/sequencing.md +106 -0
- package/resources/ecc/skills/remotion-video-creation/rules/tailwind.md +11 -0
- package/resources/ecc/skills/remotion-video-creation/rules/text-animations.md +20 -0
- package/resources/ecc/skills/remotion-video-creation/rules/timing.md +179 -0
- package/resources/ecc/skills/remotion-video-creation/rules/transcribe-captions.md +19 -0
- package/resources/ecc/skills/remotion-video-creation/rules/transitions.md +122 -0
- package/resources/ecc/skills/remotion-video-creation/rules/trimming.md +52 -0
- package/resources/ecc/skills/remotion-video-creation/rules/videos.md +171 -0
- package/resources/ecc/skills/repo-scan/SKILL.md +78 -0
- package/resources/ecc/skills/research-ops/SKILL.md +112 -0
- package/resources/ecc/skills/returns-reverse-logistics/SKILL.md +240 -0
- package/resources/ecc/skills/rules-distill/SKILL.md +264 -0
- package/resources/ecc/skills/rules-distill/scripts/scan-rules.sh +58 -0
- package/resources/ecc/skills/rules-distill/scripts/scan-skills.sh +129 -0
- package/resources/ecc/skills/rust-patterns/SKILL.md +499 -0
- package/resources/ecc/skills/rust-testing/SKILL.md +500 -0
- package/resources/ecc/skills/safety-guard/SKILL.md +75 -0
- package/resources/ecc/skills/santa-method/SKILL.md +306 -0
- package/resources/ecc/skills/scientific-db-pubmed-database/SKILL.md +175 -0
- package/resources/ecc/skills/scientific-db-uspto-database/SKILL.md +177 -0
- package/resources/ecc/skills/scientific-pkg-gget/SKILL.md +166 -0
- package/resources/ecc/skills/scientific-thinking-literature-review/SKILL.md +192 -0
- package/resources/ecc/skills/scientific-thinking-scholar-evaluation/SKILL.md +160 -0
- package/resources/ecc/skills/search-first/SKILL.md +182 -0
- package/resources/ecc/skills/security-bounty-hunter/SKILL.md +99 -0
- package/resources/ecc/skills/security-review/SKILL.md +11 -2
- package/resources/ecc/skills/security-review/cloud-infrastructure-security.md +361 -0
- package/resources/ecc/skills/security-scan/SKILL.md +165 -0
- package/resources/ecc/skills/seo/SKILL.md +154 -0
- package/resources/ecc/skills/skill-comply/SKILL.md +58 -0
- package/resources/ecc/skills/skill-comply/fixtures/compliant_trace.jsonl +5 -0
- package/resources/ecc/skills/skill-comply/fixtures/noncompliant_trace.jsonl +3 -0
- package/resources/ecc/skills/skill-comply/fixtures/tdd_spec.yaml +44 -0
- package/resources/ecc/skills/skill-comply/prompts/classifier.md +24 -0
- package/resources/ecc/skills/skill-comply/prompts/scenario_generator.md +62 -0
- package/resources/ecc/skills/skill-comply/prompts/spec_generator.md +42 -0
- package/resources/ecc/skills/skill-comply/pyproject.toml +15 -0
- package/resources/ecc/skills/skill-comply/scripts/__init__.py +0 -0
- package/resources/ecc/skills/skill-comply/scripts/classifier.py +85 -0
- package/resources/ecc/skills/skill-comply/scripts/grader.py +124 -0
- package/resources/ecc/skills/skill-comply/scripts/parser.py +107 -0
- package/resources/ecc/skills/skill-comply/scripts/report.py +170 -0
- package/resources/ecc/skills/skill-comply/scripts/run.py +127 -0
- package/resources/ecc/skills/skill-comply/scripts/runner.py +186 -0
- package/resources/ecc/skills/skill-comply/scripts/scenario_generator.py +70 -0
- package/resources/ecc/skills/skill-comply/scripts/spec_generator.py +72 -0
- package/resources/ecc/skills/skill-comply/scripts/utils.py +13 -0
- package/resources/ecc/skills/skill-comply/tests/test_grader.py +197 -0
- package/resources/ecc/skills/skill-comply/tests/test_parser.py +90 -0
- package/resources/ecc/skills/skill-comply/tests/test_runner.py +172 -0
- package/resources/ecc/skills/skill-scout/SKILL.md +140 -0
- package/resources/ecc/skills/skill-stocktake/SKILL.md +194 -0
- package/resources/ecc/skills/skill-stocktake/scripts/quick-diff.sh +87 -0
- package/resources/ecc/skills/skill-stocktake/scripts/save-results.sh +56 -0
- package/resources/ecc/skills/skill-stocktake/scripts/scan.sh +170 -0
- package/resources/ecc/skills/social-graph-ranker/SKILL.md +154 -0
- package/resources/ecc/skills/springboot-patterns/SKILL.md +314 -0
- package/resources/ecc/skills/springboot-security/SKILL.md +272 -0
- package/resources/ecc/skills/springboot-tdd/SKILL.md +158 -0
- package/resources/ecc/skills/springboot-verification/SKILL.md +231 -0
- package/resources/ecc/skills/strategic-compact/SKILL.md +31 -2
- package/resources/ecc/skills/strategic-compact/suggest-compact.sh +54 -0
- package/resources/ecc/skills/swift-actor-persistence/SKILL.md +143 -0
- package/resources/ecc/skills/swift-concurrency-6-2/SKILL.md +216 -0
- package/resources/ecc/skills/swift-protocol-di-testing/SKILL.md +190 -0
- package/resources/ecc/skills/swiftui-patterns/SKILL.md +259 -0
- package/resources/ecc/skills/tdd-workflow/SKILL.md +54 -0
- package/resources/ecc/skills/team-builder/SKILL.md +168 -0
- package/resources/ecc/skills/terminal-ops/SKILL.md +109 -0
- package/resources/ecc/skills/tinystruct-patterns/SKILL.md +131 -0
- package/resources/ecc/skills/tinystruct-patterns/references/architecture.md +77 -0
- package/resources/ecc/skills/tinystruct-patterns/references/data-handling.md +35 -0
- package/resources/ecc/skills/tinystruct-patterns/references/routing.md +57 -0
- package/resources/ecc/skills/tinystruct-patterns/references/system-usage.md +74 -0
- package/resources/ecc/skills/tinystruct-patterns/references/testing.md +59 -0
- package/resources/ecc/skills/token-budget-advisor/SKILL.md +133 -0
- package/resources/ecc/skills/ui-demo/SKILL.md +465 -0
- package/resources/ecc/skills/ui-to-vue/SKILL.md +134 -0
- package/resources/ecc/skills/unified-notifications-ops/SKILL.md +187 -0
- package/resources/ecc/skills/verification-loop/SKILL.md +1 -0
- package/resources/ecc/skills/video-editing/SKILL.md +4 -1
- package/resources/ecc/skills/videodb/SKILL.md +374 -0
- package/resources/ecc/skills/videodb/reference/api-reference.md +550 -0
- package/resources/ecc/skills/videodb/reference/capture-reference.md +407 -0
- package/resources/ecc/skills/videodb/reference/capture.md +101 -0
- package/resources/ecc/skills/videodb/reference/editor.md +443 -0
- package/resources/ecc/skills/videodb/reference/generative.md +331 -0
- package/resources/ecc/skills/videodb/reference/rtstream-reference.md +564 -0
- package/resources/ecc/skills/videodb/reference/rtstream.md +65 -0
- package/resources/ecc/skills/videodb/reference/search.md +230 -0
- package/resources/ecc/skills/videodb/reference/streaming.md +406 -0
- package/resources/ecc/skills/videodb/reference/use-cases.md +118 -0
- package/resources/ecc/skills/videodb/scripts/ws_listener.py +282 -0
- package/resources/ecc/skills/visa-doc-translate/README.md +86 -0
- package/resources/ecc/skills/visa-doc-translate/SKILL.md +117 -0
- package/resources/ecc/skills/vite-patterns/SKILL.md +449 -0
- package/resources/ecc/skills/windows-desktop-e2e/SKILL.md +788 -0
- package/resources/ecc/skills/workspace-surface-audit/SKILL.md +125 -0
- package/resources/ecc/skills/x-api/SKILL.md +5 -0
- package/resources/ecc/agents/architect.json +0 -16
- package/resources/ecc/agents/build-error-resolver.json +0 -17
- package/resources/ecc/agents/chief-of-staff.json +0 -17
- package/resources/ecc/agents/code-reviewer.json +0 -16
- package/resources/ecc/agents/database-reviewer.json +0 -16
- package/resources/ecc/agents/doc-updater.json +0 -16
- package/resources/ecc/agents/e2e-runner.json +0 -17
- package/resources/ecc/agents/go-build-resolver.json +0 -17
- package/resources/ecc/agents/go-reviewer.json +0 -16
- package/resources/ecc/agents/harness-optimizer.json +0 -15
- package/resources/ecc/agents/loop-operator.json +0 -16
- package/resources/ecc/agents/planner.json +0 -15
- package/resources/ecc/agents/python-reviewer.json +0 -16
- package/resources/ecc/agents/refactor-cleaner.json +0 -17
- package/resources/ecc/agents/security-reviewer.json +0 -16
- package/resources/ecc/agents/tdd-guide.json +0 -17
- package/resources/ecc/commands/add-language-rules.md +0 -39
- package/resources/ecc/commands/database-migration.md +0 -36
- package/resources/ecc/commands/feature-development.md +0 -38
- package/resources/ecc/rules/common-development-workflow.md +0 -33
- package/resources/ecc/rules/kotlin-coding-style.md +0 -39
- package/resources/ecc/rules/kotlin-patterns.md +0 -50
- package/resources/ecc/rules/kotlin-security.md +0 -58
- package/resources/ecc/rules/kotlin-testing.md +0 -38
- package/resources/ecc/rules/php-coding-style.md +0 -25
- package/resources/ecc/rules/php-patterns.md +0 -23
- package/resources/ecc/rules/php-security.md +0 -24
- package/resources/ecc/rules/php-testing.md +0 -26
- package/resources/ecc/rules/swift-hooks.md +0 -20
- package/resources/ecc/rules/typescript-coding-style.md +0 -63
- package/resources/ecc/rules/typescript-testing.md +0 -16
- package/resources/ecc/skills/agent-introspection-debugging/agents/openai.yaml +0 -7
- package/resources/ecc/skills/agent-sort/agents/openai.yaml +0 -7
- package/resources/ecc/skills/api-design/agents/openai.yaml +0 -7
- package/resources/ecc/skills/article-writing/agents/openai.yaml +0 -7
- package/resources/ecc/skills/backend-patterns/agents/openai.yaml +0 -7
- package/resources/ecc/skills/brand-voice/agents/openai.yaml +0 -7
- package/resources/ecc/skills/bun-runtime/agents/openai.yaml +0 -7
- package/resources/ecc/skills/coding-standards/agents/openai.yaml +0 -7
- package/resources/ecc/skills/content-engine/agents/openai.yaml +0 -7
- package/resources/ecc/skills/crosspost/agents/openai.yaml +0 -7
- package/resources/ecc/skills/deep-research/agents/openai.yaml +0 -7
- package/resources/ecc/skills/dmux-workflows/agents/openai.yaml +0 -7
- package/resources/ecc/skills/documentation-lookup/agents/openai.yaml +0 -7
- package/resources/ecc/skills/e2e-testing/agents/openai.yaml +0 -7
- package/resources/ecc/skills/eval-harness/agents/openai.yaml +0 -7
- package/resources/ecc/skills/everything-claude-code/SKILL.md +0 -442
- package/resources/ecc/skills/everything-claude-code/agents/openai.yaml +0 -7
- package/resources/ecc/skills/exa-search/agents/openai.yaml +0 -7
- package/resources/ecc/skills/fal-ai-media/agents/openai.yaml +0 -7
- package/resources/ecc/skills/frontend-patterns/agents/openai.yaml +0 -7
- package/resources/ecc/skills/frontend-slides/agents/openai.yaml +0 -7
- package/resources/ecc/skills/investor-materials/agents/openai.yaml +0 -7
- package/resources/ecc/skills/investor-outreach/agents/openai.yaml +0 -7
- package/resources/ecc/skills/market-research/agents/openai.yaml +0 -7
- package/resources/ecc/skills/mcp-server-patterns/agents/openai.yaml +0 -7
- package/resources/ecc/skills/mle-workflow/agents/openai.yaml +0 -7
- package/resources/ecc/skills/nextjs-turbopack/agents/openai.yaml +0 -7
- package/resources/ecc/skills/product-capability/agents/openai.yaml +0 -7
- package/resources/ecc/skills/security-review/agents/openai.yaml +0 -7
- package/resources/ecc/skills/strategic-compact/agents/openai.yaml +0 -7
- package/resources/ecc/skills/tdd-workflow/agents/openai.yaml +0 -7
- package/resources/ecc/skills/verification-loop/agents/openai.yaml +0 -7
- package/resources/ecc/skills/video-editing/agents/openai.yaml +0 -7
- package/resources/ecc/skills/x-api/agents/openai.yaml +0 -7
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.dart"
|
|
4
|
+
- "**/pubspec.yaml"
|
|
5
|
+
- "**/AndroidManifest.xml"
|
|
6
|
+
- "**/Info.plist"
|
|
7
|
+
---
|
|
8
|
+
# Dart/Flutter Security
|
|
9
|
+
|
|
10
|
+
> This file extends [common/security.md](../common/security.md) with Dart, Flutter, and mobile-specific content.
|
|
11
|
+
|
|
12
|
+
## Secrets Management
|
|
13
|
+
|
|
14
|
+
- Never hardcode API keys, tokens, or credentials in Dart source
|
|
15
|
+
- Use `--dart-define` or `--dart-define-from-file` for compile-time config (values are not truly secret — use a backend proxy for server-side secrets)
|
|
16
|
+
- Use `flutter_dotenv` or equivalent, with `.env` files listed in `.gitignore`
|
|
17
|
+
- Store runtime secrets in platform-secure storage: `flutter_secure_storage` (Keychain on iOS, EncryptedSharedPreferences on Android)
|
|
18
|
+
|
|
19
|
+
```dart
|
|
20
|
+
// BAD
|
|
21
|
+
const apiKey = 'sk-abc123...';
|
|
22
|
+
|
|
23
|
+
// GOOD — compile-time config (not secret, just configurable)
|
|
24
|
+
const apiKey = String.fromEnvironment('API_KEY');
|
|
25
|
+
|
|
26
|
+
// GOOD — runtime secret from secure storage
|
|
27
|
+
final token = await secureStorage.read(key: 'auth_token');
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Network Security
|
|
31
|
+
|
|
32
|
+
- Enforce HTTPS — no `http://` calls in production
|
|
33
|
+
- Configure Android `network_security_config.xml` to block cleartext traffic
|
|
34
|
+
- Set `NSAppTransportSecurity` in `Info.plist` to disallow arbitrary loads
|
|
35
|
+
- Set request timeouts on all HTTP clients — never leave defaults
|
|
36
|
+
- Consider certificate pinning for high-security endpoints
|
|
37
|
+
|
|
38
|
+
```dart
|
|
39
|
+
// Dio with timeout and HTTPS enforcement
|
|
40
|
+
final dio = Dio(BaseOptions(
|
|
41
|
+
baseUrl: 'https://api.example.com',
|
|
42
|
+
connectTimeout: const Duration(seconds: 10),
|
|
43
|
+
receiveTimeout: const Duration(seconds: 30),
|
|
44
|
+
));
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Input Validation
|
|
48
|
+
|
|
49
|
+
- Validate and sanitize all user input before sending to API or storage
|
|
50
|
+
- Never pass unsanitized input to SQL queries — use parameterized queries (sqflite, drift)
|
|
51
|
+
- Sanitize deep link URLs before navigation — validate scheme, host, and path parameters
|
|
52
|
+
- Use `Uri.tryParse` and validate before navigating
|
|
53
|
+
|
|
54
|
+
```dart
|
|
55
|
+
// BAD — SQL injection
|
|
56
|
+
await db.rawQuery("SELECT * FROM users WHERE email = '$userInput'");
|
|
57
|
+
|
|
58
|
+
// GOOD — parameterized
|
|
59
|
+
await db.query('users', where: 'email = ?', whereArgs: [userInput]);
|
|
60
|
+
|
|
61
|
+
// BAD — unvalidated deep link
|
|
62
|
+
final uri = Uri.parse(incomingLink);
|
|
63
|
+
context.go(uri.path); // could navigate to any route
|
|
64
|
+
|
|
65
|
+
// GOOD — validated deep link
|
|
66
|
+
final uri = Uri.tryParse(incomingLink);
|
|
67
|
+
if (uri != null && uri.host == 'myapp.com' && _allowedPaths.contains(uri.path)) {
|
|
68
|
+
context.go(uri.path);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Data Protection
|
|
73
|
+
|
|
74
|
+
- Store tokens, PII, and credentials only in `flutter_secure_storage`
|
|
75
|
+
- Never write sensitive data to `SharedPreferences` or local files in plaintext
|
|
76
|
+
- Clear auth state on logout: tokens, cached user data, cookies
|
|
77
|
+
- Use biometric authentication (`local_auth`) for sensitive operations
|
|
78
|
+
- Avoid logging sensitive data — no `print(token)` or `debugPrint(password)`
|
|
79
|
+
|
|
80
|
+
## Android-Specific
|
|
81
|
+
|
|
82
|
+
- Declare only required permissions in `AndroidManifest.xml`
|
|
83
|
+
- Export Android components (`Activity`, `Service`, `BroadcastReceiver`) only when necessary; add `android:exported="false"` where not needed
|
|
84
|
+
- Review intent filters — exported components with implicit intent filters are accessible by any app
|
|
85
|
+
- Use `FLAG_SECURE` for screens displaying sensitive data (prevents screenshots)
|
|
86
|
+
|
|
87
|
+
```xml
|
|
88
|
+
<!-- AndroidManifest.xml — restrict exported components -->
|
|
89
|
+
<activity android:name=".MainActivity" android:exported="true">
|
|
90
|
+
<!-- Only the launcher activity needs exported=true -->
|
|
91
|
+
</activity>
|
|
92
|
+
<activity android:name=".SensitiveActivity" android:exported="false" />
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## iOS-Specific
|
|
96
|
+
|
|
97
|
+
- Declare only required usage descriptions in `Info.plist` (`NSCameraUsageDescription`, etc.)
|
|
98
|
+
- Store secrets in Keychain — `flutter_secure_storage` uses Keychain on iOS
|
|
99
|
+
- Use App Transport Security (ATS) — disallow arbitrary loads
|
|
100
|
+
- Enable data protection entitlement for sensitive files
|
|
101
|
+
|
|
102
|
+
## WebView Security
|
|
103
|
+
|
|
104
|
+
- Use `webview_flutter` v4+ (`WebViewController` / `WebViewWidget`) — the legacy `WebView` widget is removed
|
|
105
|
+
- Disable JavaScript unless explicitly required (`JavaScriptMode.disabled`)
|
|
106
|
+
- Validate URLs before loading — never load arbitrary URLs from deep links
|
|
107
|
+
- Never expose Dart callbacks to JavaScript unless absolutely needed and carefully sandboxed
|
|
108
|
+
- Use `NavigationDelegate.onNavigationRequest` to intercept and validate navigation requests
|
|
109
|
+
|
|
110
|
+
```dart
|
|
111
|
+
// webview_flutter v4+ API (WebViewController + WebViewWidget)
|
|
112
|
+
final controller = WebViewController()
|
|
113
|
+
..setJavaScriptMode(JavaScriptMode.disabled) // disabled unless required
|
|
114
|
+
..setNavigationDelegate(
|
|
115
|
+
NavigationDelegate(
|
|
116
|
+
onNavigationRequest: (request) {
|
|
117
|
+
final uri = Uri.tryParse(request.url);
|
|
118
|
+
if (uri == null || uri.host != 'trusted.example.com') {
|
|
119
|
+
return NavigationDecision.prevent;
|
|
120
|
+
}
|
|
121
|
+
return NavigationDecision.navigate;
|
|
122
|
+
},
|
|
123
|
+
),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
// In your widget tree:
|
|
127
|
+
WebViewWidget(controller: controller)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Obfuscation and Build Security
|
|
131
|
+
|
|
132
|
+
- Enable obfuscation in release builds: `flutter build apk --obfuscate --split-debug-info=./debug-info/`
|
|
133
|
+
- Keep `--split-debug-info` output out of version control (used for crash symbolication only)
|
|
134
|
+
- Ensure ProGuard/R8 rules don't inadvertently expose serialized classes
|
|
135
|
+
- Run `flutter analyze` and address all warnings before release
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.dart"
|
|
4
|
+
- "**/pubspec.yaml"
|
|
5
|
+
- "**/analysis_options.yaml"
|
|
6
|
+
---
|
|
7
|
+
# Dart/Flutter Testing
|
|
8
|
+
|
|
9
|
+
> This file extends [common/testing.md](../common/testing.md) with Dart and Flutter-specific content.
|
|
10
|
+
|
|
11
|
+
## Test Framework
|
|
12
|
+
|
|
13
|
+
- **flutter_test** / **dart:test** — built-in test runner
|
|
14
|
+
- **mockito** (with `@GenerateMocks`) or **mocktail** (no codegen) for mocking
|
|
15
|
+
- **bloc_test** for BLoC/Cubit unit tests
|
|
16
|
+
- **fake_async** for controlling time in unit tests
|
|
17
|
+
- **integration_test** for end-to-end device tests
|
|
18
|
+
|
|
19
|
+
## Test Types
|
|
20
|
+
|
|
21
|
+
| Type | Tool | Location | When to Write |
|
|
22
|
+
|------|------|----------|---------------|
|
|
23
|
+
| Unit | `dart:test` | `test/unit/` | All domain logic, state managers, repositories |
|
|
24
|
+
| Widget | `flutter_test` | `test/widget/` | All widgets with meaningful behavior |
|
|
25
|
+
| Golden | `flutter_test` | `test/golden/` | Design-critical UI components |
|
|
26
|
+
| Integration | `integration_test` | `integration_test/` | Critical user flows on real device/emulator |
|
|
27
|
+
|
|
28
|
+
## Unit Tests: State Managers
|
|
29
|
+
|
|
30
|
+
### BLoC with `bloc_test`
|
|
31
|
+
|
|
32
|
+
```dart
|
|
33
|
+
group('CartBloc', () {
|
|
34
|
+
late CartBloc bloc;
|
|
35
|
+
late MockCartRepository repository;
|
|
36
|
+
|
|
37
|
+
setUp(() {
|
|
38
|
+
repository = MockCartRepository();
|
|
39
|
+
bloc = CartBloc(repository);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
tearDown(() => bloc.close());
|
|
43
|
+
|
|
44
|
+
blocTest<CartBloc, CartState>(
|
|
45
|
+
'emits updated items when CartItemAdded',
|
|
46
|
+
build: () => bloc,
|
|
47
|
+
act: (b) => b.add(CartItemAdded(testItem)),
|
|
48
|
+
expect: () => [CartState(items: [testItem])],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
blocTest<CartBloc, CartState>(
|
|
52
|
+
'emits empty cart when CartCleared',
|
|
53
|
+
seed: () => CartState(items: [testItem]),
|
|
54
|
+
build: () => bloc,
|
|
55
|
+
act: (b) => b.add(CartCleared()),
|
|
56
|
+
expect: () => [const CartState()],
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Riverpod with `ProviderContainer`
|
|
62
|
+
|
|
63
|
+
```dart
|
|
64
|
+
test('usersProvider loads users from repository', () async {
|
|
65
|
+
final container = ProviderContainer(
|
|
66
|
+
overrides: [userRepositoryProvider.overrideWithValue(FakeUserRepository())],
|
|
67
|
+
);
|
|
68
|
+
addTearDown(container.dispose);
|
|
69
|
+
|
|
70
|
+
final result = await container.read(usersProvider.future);
|
|
71
|
+
expect(result, isNotEmpty);
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Widget Tests
|
|
76
|
+
|
|
77
|
+
```dart
|
|
78
|
+
testWidgets('CartPage shows item count badge', (tester) async {
|
|
79
|
+
await tester.pumpWidget(
|
|
80
|
+
ProviderScope(
|
|
81
|
+
overrides: [
|
|
82
|
+
cartNotifierProvider.overrideWith(() => FakeCartNotifier([testItem])),
|
|
83
|
+
],
|
|
84
|
+
child: const MaterialApp(home: CartPage()),
|
|
85
|
+
),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
await tester.pump();
|
|
89
|
+
expect(find.text('1'), findsOneWidget);
|
|
90
|
+
expect(find.byType(CartItemTile), findsOneWidget);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
testWidgets('shows empty state when cart is empty', (tester) async {
|
|
94
|
+
await tester.pumpWidget(
|
|
95
|
+
ProviderScope(
|
|
96
|
+
overrides: [cartNotifierProvider.overrideWith(() => FakeCartNotifier([]))],
|
|
97
|
+
child: const MaterialApp(home: CartPage()),
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
await tester.pump();
|
|
102
|
+
expect(find.text('Your cart is empty'), findsOneWidget);
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Fakes Over Mocks
|
|
107
|
+
|
|
108
|
+
Prefer hand-written fakes for complex dependencies:
|
|
109
|
+
|
|
110
|
+
```dart
|
|
111
|
+
class FakeUserRepository implements UserRepository {
|
|
112
|
+
final _users = <String, User>{};
|
|
113
|
+
Object? fetchError;
|
|
114
|
+
|
|
115
|
+
@override
|
|
116
|
+
Future<User?> getById(String id) async {
|
|
117
|
+
if (fetchError != null) throw fetchError!;
|
|
118
|
+
return _users[id];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@override
|
|
122
|
+
Future<List<User>> getAll() async {
|
|
123
|
+
if (fetchError != null) throw fetchError!;
|
|
124
|
+
return _users.values.toList();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@override
|
|
128
|
+
Stream<List<User>> watchAll() => Stream.value(_users.values.toList());
|
|
129
|
+
|
|
130
|
+
@override
|
|
131
|
+
Future<void> save(User user) async {
|
|
132
|
+
_users[user.id] = user;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@override
|
|
136
|
+
Future<void> delete(String id) async {
|
|
137
|
+
_users.remove(id);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
void addUser(User user) => _users[user.id] = user;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Async Testing
|
|
145
|
+
|
|
146
|
+
```dart
|
|
147
|
+
// Use fake_async for controlling timers and Futures
|
|
148
|
+
test('debounce triggers after 300ms', () {
|
|
149
|
+
fakeAsync((async) {
|
|
150
|
+
final debouncer = Debouncer(delay: const Duration(milliseconds: 300));
|
|
151
|
+
var callCount = 0;
|
|
152
|
+
debouncer.run(() => callCount++);
|
|
153
|
+
expect(callCount, 0);
|
|
154
|
+
async.elapse(const Duration(milliseconds: 200));
|
|
155
|
+
expect(callCount, 0);
|
|
156
|
+
async.elapse(const Duration(milliseconds: 200));
|
|
157
|
+
expect(callCount, 1);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Golden Tests
|
|
163
|
+
|
|
164
|
+
```dart
|
|
165
|
+
testWidgets('UserCard golden test', (tester) async {
|
|
166
|
+
await tester.pumpWidget(
|
|
167
|
+
MaterialApp(home: UserCard(user: testUser)),
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
await expectLater(
|
|
171
|
+
find.byType(UserCard),
|
|
172
|
+
matchesGoldenFile('goldens/user_card.png'),
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Run `flutter test --update-goldens` when intentional visual changes are made.
|
|
178
|
+
|
|
179
|
+
## Test Naming
|
|
180
|
+
|
|
181
|
+
Use descriptive, behavior-focused names:
|
|
182
|
+
|
|
183
|
+
```dart
|
|
184
|
+
test('returns null when user does not exist', () { ... });
|
|
185
|
+
test('throws NotFoundException when id is empty string', () { ... });
|
|
186
|
+
testWidgets('disables submit button while form is invalid', (tester) async { ... });
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Test Organization
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
test/
|
|
193
|
+
├── unit/
|
|
194
|
+
│ ├── domain/
|
|
195
|
+
│ │ └── usecases/
|
|
196
|
+
│ └── data/
|
|
197
|
+
│ └── repositories/
|
|
198
|
+
├── widget/
|
|
199
|
+
│ └── presentation/
|
|
200
|
+
│ └── pages/
|
|
201
|
+
└── golden/
|
|
202
|
+
└── widgets/
|
|
203
|
+
|
|
204
|
+
integration_test/
|
|
205
|
+
└── flows/
|
|
206
|
+
├── login_flow_test.dart
|
|
207
|
+
└── checkout_flow_test.dart
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Coverage
|
|
211
|
+
|
|
212
|
+
- Target 80%+ line coverage for business logic (domain + state managers)
|
|
213
|
+
- All state transitions must have tests: loading → success, loading → error, retry
|
|
214
|
+
- Run `flutter test --coverage` and inspect `lcov.info` with a coverage reporter
|
|
215
|
+
- Coverage failures should block CI when below threshold
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.fs"
|
|
4
|
+
- "**/*.fsx"
|
|
5
|
+
---
|
|
6
|
+
# F# Coding Style
|
|
7
|
+
|
|
8
|
+
> This file extends [common/coding-style.md](../common/coding-style.md) with F#-specific content.
|
|
9
|
+
|
|
10
|
+
## Standards
|
|
11
|
+
|
|
12
|
+
- Follow standard F# conventions and leverage the type system for correctness
|
|
13
|
+
- Prefer immutability by default; use `mutable` only when justified by performance
|
|
14
|
+
- Keep modules focused and cohesive
|
|
15
|
+
|
|
16
|
+
## Types and Models
|
|
17
|
+
|
|
18
|
+
- Prefer discriminated unions for domain modeling over class hierarchies
|
|
19
|
+
- Use records for data with named fields
|
|
20
|
+
- Use single-case unions for type-safe wrappers around primitives
|
|
21
|
+
- Avoid classes unless interop or mutable state requires them
|
|
22
|
+
|
|
23
|
+
```fsharp
|
|
24
|
+
type EmailAddress = EmailAddress of string
|
|
25
|
+
|
|
26
|
+
type OrderStatus =
|
|
27
|
+
| Pending
|
|
28
|
+
| Confirmed of confirmedAt: DateTimeOffset
|
|
29
|
+
| Shipped of trackingNumber: string
|
|
30
|
+
| Cancelled of reason: string
|
|
31
|
+
|
|
32
|
+
type Order =
|
|
33
|
+
{ Id: Guid
|
|
34
|
+
CustomerId: string
|
|
35
|
+
Status: OrderStatus
|
|
36
|
+
Items: OrderItem list }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Immutability
|
|
40
|
+
|
|
41
|
+
- Records are immutable by default; use `with` expressions for updates
|
|
42
|
+
- Prefer `list`, `map`, `set` over mutable collections
|
|
43
|
+
- Avoid `ref` cells and mutable fields in domain logic
|
|
44
|
+
|
|
45
|
+
```fsharp
|
|
46
|
+
let rename (profile: UserProfile) newName =
|
|
47
|
+
{ profile with Name = newName }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Function Style
|
|
51
|
+
|
|
52
|
+
- Prefer small, composable functions over large methods
|
|
53
|
+
- Use the pipe operator `|>` to build readable data pipelines
|
|
54
|
+
- Prefer pattern matching over if/else chains
|
|
55
|
+
- Use `Option` instead of null; use `Result` for operations that can fail
|
|
56
|
+
|
|
57
|
+
```fsharp
|
|
58
|
+
let processOrder order =
|
|
59
|
+
order
|
|
60
|
+
|> validateItems
|
|
61
|
+
|> Result.bind calculateTotal
|
|
62
|
+
|> Result.map applyDiscount
|
|
63
|
+
|> Result.mapError OrderError
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Async and Error Handling
|
|
67
|
+
|
|
68
|
+
- Use `task { }` for interop with .NET async APIs
|
|
69
|
+
- Use `async { }` for F#-native async workflows
|
|
70
|
+
- Propagate `CancellationToken` through public async APIs
|
|
71
|
+
- Prefer `Result` and railway-oriented programming over exceptions for expected failures
|
|
72
|
+
|
|
73
|
+
```fsharp
|
|
74
|
+
let loadOrderAsync (orderId: Guid) (ct: CancellationToken) =
|
|
75
|
+
task {
|
|
76
|
+
let! order = repository.FindAsync(orderId, ct)
|
|
77
|
+
return
|
|
78
|
+
order
|
|
79
|
+
|> Option.defaultWith (fun () ->
|
|
80
|
+
failwith $"Order {orderId} was not found.")
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Formatting
|
|
85
|
+
|
|
86
|
+
- Use `fantomas` for automatic formatting
|
|
87
|
+
- Prefer significant whitespace; avoid unnecessary parentheses
|
|
88
|
+
- Remove unused `open` declarations
|
|
89
|
+
|
|
90
|
+
### Open Declaration Order
|
|
91
|
+
|
|
92
|
+
Group `open` statements into four sections separated by a blank line, each section sorted lexically within itself:
|
|
93
|
+
|
|
94
|
+
1. `System.*`
|
|
95
|
+
2. `Microsoft.*`
|
|
96
|
+
3. Third-party namespaces
|
|
97
|
+
4. First-party / project namespaces
|
|
98
|
+
|
|
99
|
+
```fsharp
|
|
100
|
+
open System
|
|
101
|
+
open System.Collections.Generic
|
|
102
|
+
open System.Threading.Tasks
|
|
103
|
+
|
|
104
|
+
open Microsoft.AspNetCore.Http
|
|
105
|
+
open Microsoft.Extensions.Logging
|
|
106
|
+
|
|
107
|
+
open FsCheck.Xunit
|
|
108
|
+
open Swensen.Unquote
|
|
109
|
+
|
|
110
|
+
open MyApp.Domain
|
|
111
|
+
open MyApp.Infrastructure
|
|
112
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.fs"
|
|
4
|
+
- "**/*.fsx"
|
|
5
|
+
- "**/*.fsproj"
|
|
6
|
+
- "**/*.sln"
|
|
7
|
+
- "**/*.slnx"
|
|
8
|
+
- "**/Directory.Build.props"
|
|
9
|
+
- "**/Directory.Build.targets"
|
|
10
|
+
---
|
|
11
|
+
# F# Hooks
|
|
12
|
+
|
|
13
|
+
> This file extends [common/hooks.md](../common/hooks.md) with F#-specific content.
|
|
14
|
+
|
|
15
|
+
## PostToolUse Hooks
|
|
16
|
+
|
|
17
|
+
Configure in `~/.claude/settings.json`:
|
|
18
|
+
|
|
19
|
+
- **fantomas**: Auto-format edited F# files
|
|
20
|
+
- **dotnet build**: Verify the solution or project still compiles after edits
|
|
21
|
+
- **dotnet test --no-build**: Re-run the nearest relevant test project after behavior changes
|
|
22
|
+
|
|
23
|
+
## Stop Hooks
|
|
24
|
+
|
|
25
|
+
- Run a final `dotnet build` before ending a session with broad F# changes
|
|
26
|
+
- Warn on modified `appsettings*.json` files so secrets do not get committed
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.fs"
|
|
4
|
+
- "**/*.fsx"
|
|
5
|
+
---
|
|
6
|
+
# F# Patterns
|
|
7
|
+
|
|
8
|
+
> This file extends [common/patterns.md](../common/patterns.md) with F#-specific content.
|
|
9
|
+
|
|
10
|
+
## Result Type for Error Handling
|
|
11
|
+
|
|
12
|
+
Use `Result<'T, 'TError>` with railway-oriented programming instead of exceptions for expected failures.
|
|
13
|
+
|
|
14
|
+
```fsharp
|
|
15
|
+
type OrderError =
|
|
16
|
+
| InvalidCustomer of string
|
|
17
|
+
| EmptyItems
|
|
18
|
+
| ItemOutOfStock of sku: string
|
|
19
|
+
|
|
20
|
+
let validateOrder (request: CreateOrderRequest) : Result<ValidatedOrder, OrderError> =
|
|
21
|
+
if String.IsNullOrWhiteSpace request.CustomerId then
|
|
22
|
+
Error(InvalidCustomer "CustomerId is required")
|
|
23
|
+
elif request.Items |> List.isEmpty then
|
|
24
|
+
Error EmptyItems
|
|
25
|
+
else
|
|
26
|
+
Ok { CustomerId = request.CustomerId; Items = request.Items }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Option for Missing Values
|
|
30
|
+
|
|
31
|
+
Prefer `Option<'T>` over null. Use `Option.map`, `Option.bind`, and `Option.defaultValue` to transform.
|
|
32
|
+
|
|
33
|
+
```fsharp
|
|
34
|
+
let findUser (id: Guid) : User option =
|
|
35
|
+
users |> Map.tryFind id
|
|
36
|
+
|
|
37
|
+
let getUserEmail userId =
|
|
38
|
+
findUser userId
|
|
39
|
+
|> Option.map (fun u -> u.Email)
|
|
40
|
+
|> Option.defaultValue "unknown@example.com"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Discriminated Unions for Domain Modeling
|
|
44
|
+
|
|
45
|
+
Model business states explicitly. The compiler enforces exhaustive handling.
|
|
46
|
+
|
|
47
|
+
```fsharp
|
|
48
|
+
type PaymentState =
|
|
49
|
+
| AwaitingPayment of amount: decimal
|
|
50
|
+
| Paid of paidAt: DateTimeOffset * transactionId: string
|
|
51
|
+
| Refunded of refundedAt: DateTimeOffset * reason: string
|
|
52
|
+
| Failed of error: string
|
|
53
|
+
|
|
54
|
+
let describePayment = function
|
|
55
|
+
| AwaitingPayment amount -> $"Awaiting payment of {amount:C}"
|
|
56
|
+
| Paid (at, txn) -> $"Paid at {at} (txn: {txn})"
|
|
57
|
+
| Refunded (at, reason) -> $"Refunded at {at}: {reason}"
|
|
58
|
+
| Failed error -> $"Payment failed: {error}"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Computation Expressions
|
|
62
|
+
|
|
63
|
+
Use computation expressions to simplify sequential operations that may fail.
|
|
64
|
+
|
|
65
|
+
```fsharp
|
|
66
|
+
let placeOrder request =
|
|
67
|
+
result {
|
|
68
|
+
let! validated = validateOrder request
|
|
69
|
+
let! inventory = checkInventory validated.Items
|
|
70
|
+
let! order = createOrder validated inventory
|
|
71
|
+
return order
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Module Organization
|
|
76
|
+
|
|
77
|
+
- Group related functions in modules rather than classes
|
|
78
|
+
- Use `[<RequireQualifiedAccess>]` to prevent name collisions
|
|
79
|
+
- Keep modules small and focused on a single responsibility
|
|
80
|
+
|
|
81
|
+
```fsharp
|
|
82
|
+
[<RequireQualifiedAccess>]
|
|
83
|
+
module Order =
|
|
84
|
+
let create customerId items = { Id = Guid.NewGuid(); CustomerId = customerId; Items = items; Status = Pending }
|
|
85
|
+
let confirm order = { order with Status = Confirmed(DateTimeOffset.UtcNow) }
|
|
86
|
+
let cancel reason order = { order with Status = Cancelled reason }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Dependency Injection
|
|
90
|
+
|
|
91
|
+
- Define dependencies as function parameters or record-of-functions
|
|
92
|
+
- Use interfaces sparingly, primarily at the boundary with .NET libraries
|
|
93
|
+
- Prefer partial application for injecting dependencies into pipelines
|
|
94
|
+
|
|
95
|
+
```fsharp
|
|
96
|
+
type OrderDeps =
|
|
97
|
+
{ FindOrder: Guid -> Task<Order option>
|
|
98
|
+
SaveOrder: Order -> Task<unit>
|
|
99
|
+
SendNotification: Order -> Task<unit> }
|
|
100
|
+
|
|
101
|
+
let processOrder (deps: OrderDeps) orderId =
|
|
102
|
+
task {
|
|
103
|
+
match! deps.FindOrder orderId with
|
|
104
|
+
| None -> return Error "Order not found"
|
|
105
|
+
| Some order ->
|
|
106
|
+
let confirmed = Order.confirm order
|
|
107
|
+
do! deps.SaveOrder confirmed
|
|
108
|
+
do! deps.SendNotification confirmed
|
|
109
|
+
return Ok confirmed
|
|
110
|
+
}
|
|
111
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.fs"
|
|
4
|
+
- "**/*.fsx"
|
|
5
|
+
- "**/*.fsproj"
|
|
6
|
+
- "**/appsettings*.json"
|
|
7
|
+
---
|
|
8
|
+
# F# Security
|
|
9
|
+
|
|
10
|
+
> This file extends [common/security.md](../common/security.md) with F#-specific content.
|
|
11
|
+
|
|
12
|
+
## Secret Management
|
|
13
|
+
|
|
14
|
+
- Never hardcode API keys, tokens, or connection strings in source code
|
|
15
|
+
- Use environment variables, user secrets for local development, and a secret manager in production
|
|
16
|
+
- Keep `appsettings.*.json` free of real credentials
|
|
17
|
+
|
|
18
|
+
```fsharp
|
|
19
|
+
// BAD
|
|
20
|
+
let apiKey = "sk-live-123"
|
|
21
|
+
|
|
22
|
+
// GOOD
|
|
23
|
+
let apiKey =
|
|
24
|
+
configuration["OpenAI:ApiKey"]
|
|
25
|
+
|> Option.ofObj
|
|
26
|
+
|> Option.defaultWith (fun () -> failwith "OpenAI:ApiKey is not configured.")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## SQL Injection Prevention
|
|
30
|
+
|
|
31
|
+
- Always use parameterized queries with ADO.NET, Dapper, or EF Core
|
|
32
|
+
- Never concatenate user input into SQL strings
|
|
33
|
+
- Validate sort fields and filter operators before using dynamic query composition
|
|
34
|
+
|
|
35
|
+
```fsharp
|
|
36
|
+
let findByCustomer (connection: IDbConnection) customerId =
|
|
37
|
+
task {
|
|
38
|
+
let sql = "SELECT * FROM Orders WHERE CustomerId = @customerId"
|
|
39
|
+
return! connection.QueryAsync<Order>(sql, {| customerId = customerId |})
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Input Validation
|
|
44
|
+
|
|
45
|
+
- Validate inputs at the application boundary using types
|
|
46
|
+
- Use single-case discriminated unions for validated values
|
|
47
|
+
- Reject invalid input before it enters domain logic
|
|
48
|
+
|
|
49
|
+
```fsharp
|
|
50
|
+
type ValidatedEmail = private ValidatedEmail of string
|
|
51
|
+
|
|
52
|
+
module ValidatedEmail =
|
|
53
|
+
let create (input: string) =
|
|
54
|
+
if System.Text.RegularExpressions.Regex.IsMatch(input, @"^[^@]+@[^@]+\.[^@]+$") then
|
|
55
|
+
Ok(ValidatedEmail input)
|
|
56
|
+
else
|
|
57
|
+
Error "Invalid email address"
|
|
58
|
+
|
|
59
|
+
let value (ValidatedEmail v) = v
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Authentication and Authorization
|
|
63
|
+
|
|
64
|
+
- Prefer framework auth handlers instead of custom token parsing
|
|
65
|
+
- Enforce authorization policies at endpoint or handler boundaries
|
|
66
|
+
- Never log raw tokens, passwords, or PII
|
|
67
|
+
|
|
68
|
+
## Error Handling
|
|
69
|
+
|
|
70
|
+
- Return safe client-facing messages
|
|
71
|
+
- Log detailed exceptions with structured context server-side
|
|
72
|
+
- Do not expose stack traces, SQL text, or filesystem paths in API responses
|
|
73
|
+
|
|
74
|
+
## References
|
|
75
|
+
|
|
76
|
+
See skill: `security-review` for broader application security review checklists.
|