@softspark/ai-toolkit 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/AGENTS.md +412 -0
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +632 -0
- package/action.yml +53 -0
- package/app/.claude-plugin/plugin.json +44 -0
- package/app/ARCHITECTURE.md +306 -0
- package/app/CLAUDE.md.template +23 -0
- package/app/agents/ai-engineer.md +128 -0
- package/app/agents/backend-specialist.md +193 -0
- package/app/agents/business-intelligence.md +54 -0
- package/app/agents/chaos-monkey.md +67 -0
- package/app/agents/chief-of-staff.md +51 -0
- package/app/agents/code-archaeologist.md +127 -0
- package/app/agents/code-reviewer.md +184 -0
- package/app/agents/command-expert.md +131 -0
- package/app/agents/data-analyst.md +205 -0
- package/app/agents/data-scientist.md +151 -0
- package/app/agents/database-architect.md +317 -0
- package/app/agents/debugger.md +238 -0
- package/app/agents/devops-implementer.md +194 -0
- package/app/agents/documenter.md +364 -0
- package/app/agents/explorer-agent.md +145 -0
- package/app/agents/fact-checker.md +172 -0
- package/app/agents/frontend-specialist.md +209 -0
- package/app/agents/game-developer.md +216 -0
- package/app/agents/incident-responder.md +226 -0
- package/app/agents/infrastructure-architect.md +127 -0
- package/app/agents/infrastructure-validator.md +247 -0
- package/app/agents/llm-ops-engineer.md +237 -0
- package/app/agents/mcp-expert.md +228 -0
- package/app/agents/mcp-server-architect.md +195 -0
- package/app/agents/mcp-testing-engineer.md +292 -0
- package/app/agents/meta-architect.md +58 -0
- package/app/agents/ml-engineer.md +136 -0
- package/app/agents/mobile-developer.md +190 -0
- package/app/agents/night-watchman.md +55 -0
- package/app/agents/nlp-engineer.md +154 -0
- package/app/agents/orchestrator.md +437 -0
- package/app/agents/performance-optimizer.md +254 -0
- package/app/agents/predictive-analyst.md +57 -0
- package/app/agents/product-manager.md +194 -0
- package/app/agents/project-planner.md +287 -0
- package/app/agents/prompt-engineer.md +103 -0
- package/app/agents/qa-automation-engineer.md +182 -0
- package/app/agents/rag-engineer.md +201 -0
- package/app/agents/research-synthesizer.md +138 -0
- package/app/agents/search-specialist.md +101 -0
- package/app/agents/security-architect.md +62 -0
- package/app/agents/security-auditor.md +293 -0
- package/app/agents/seo-specialist.md +111 -0
- package/app/agents/system-governor.md +57 -0
- package/app/agents/tech-lead.md +62 -0
- package/app/agents/technical-researcher.md +103 -0
- package/app/agents/test-engineer.md +264 -0
- package/app/constitution.md +38 -0
- package/app/hooks/_profile-check.sh +11 -0
- package/app/hooks/guard-destructive.sh +74 -0
- package/app/hooks/guard-path.sh +73 -0
- package/app/hooks/post-tool-use.sh +35 -0
- package/app/hooks/pre-compact.sh +31 -0
- package/app/hooks/quality-check.sh +22 -0
- package/app/hooks/quality-gate.sh +49 -0
- package/app/hooks/save-session.sh +24 -0
- package/app/hooks/session-end.sh +37 -0
- package/app/hooks/session-start.sh +29 -0
- package/app/hooks/subagent-start.sh +16 -0
- package/app/hooks/subagent-stop.sh +16 -0
- package/app/hooks/track-usage.sh +50 -0
- package/app/hooks/user-prompt-submit.sh +25 -0
- package/app/hooks.json +178 -0
- package/app/mcp-defaults.json +23 -0
- package/app/output-styles/golden-rules.md +43 -0
- package/app/plugins/README.md +19 -0
- package/app/plugins/csharp-pack/README.md +11 -0
- package/app/plugins/csharp-pack/plugin.json +18 -0
- package/app/plugins/enterprise-pack/README.md +16 -0
- package/app/plugins/enterprise-pack/hooks/output-style.sh +6 -0
- package/app/plugins/enterprise-pack/hooks/status-line.sh +8 -0
- package/app/plugins/enterprise-pack/plugin.json +24 -0
- package/app/plugins/frontend-pack/README.md +14 -0
- package/app/plugins/frontend-pack/plugin.json +22 -0
- package/app/plugins/java-pack/README.md +11 -0
- package/app/plugins/java-pack/plugin.json +18 -0
- package/app/plugins/kotlin-pack/README.md +11 -0
- package/app/plugins/kotlin-pack/plugin.json +18 -0
- package/app/plugins/memory-pack/README.md +24 -0
- package/app/plugins/memory-pack/hooks/observation-capture.sh +67 -0
- package/app/plugins/memory-pack/hooks/session-summary.sh +71 -0
- package/app/plugins/memory-pack/plugin.json +22 -0
- package/app/plugins/memory-pack/scripts/init_db.py +81 -0
- package/app/plugins/memory-pack/scripts/strip_private.py +22 -0
- package/app/plugins/memory-pack/skills/mem-search/SKILL.md +70 -0
- package/app/plugins/research-pack/README.md +14 -0
- package/app/plugins/research-pack/plugin.json +22 -0
- package/app/plugins/ruby-pack/README.md +11 -0
- package/app/plugins/ruby-pack/plugin.json +18 -0
- package/app/plugins/rust-pack/README.md +11 -0
- package/app/plugins/rust-pack/plugin.json +18 -0
- package/app/plugins/security-pack/README.md +15 -0
- package/app/plugins/security-pack/plugin.json +23 -0
- package/app/plugins/swift-pack/README.md +11 -0
- package/app/plugins/swift-pack/plugin.json +18 -0
- package/app/rules/claude-toolkit-rules.md +21 -0
- package/app/rules/git-conventions.md +5 -0
- package/app/rules/quality-gates.md +10 -0
- package/app/skills/_lib/__init__.py +1 -0
- package/app/skills/_lib/detect_utils.py +150 -0
- package/app/skills/agent-creator/SKILL.md +82 -0
- package/app/skills/analyze/SKILL.md +92 -0
- package/app/skills/analyze/scripts/complexity.py +165 -0
- package/app/skills/api-patterns/SKILL.md +305 -0
- package/app/skills/app-builder/SKILL.md +187 -0
- package/app/skills/architecture-audit/SKILL.md +141 -0
- package/app/skills/architecture-decision/SKILL.md +55 -0
- package/app/skills/architecture-decision/templates/adr-template.md +36 -0
- package/app/skills/biz-scan/SKILL.md +30 -0
- package/app/skills/briefing/SKILL.md +27 -0
- package/app/skills/build/SKILL.md +97 -0
- package/app/skills/build/scripts/detect-build.py +151 -0
- package/app/skills/chaos/SKILL.md +32 -0
- package/app/skills/ci/SKILL.md +77 -0
- package/app/skills/ci/scripts/ci-detect.py +135 -0
- package/app/skills/ci/templates/github-actions-node.yml +38 -0
- package/app/skills/ci/templates/github-actions-python.yml +42 -0
- package/app/skills/ci-cd-patterns/SKILL.md +299 -0
- package/app/skills/clean-code/SKILL.md +110 -0
- package/app/skills/clean-code/reference/dart.md +18 -0
- package/app/skills/clean-code/reference/go.md +23 -0
- package/app/skills/clean-code/reference/php.md +32 -0
- package/app/skills/clean-code/reference/python.md +180 -0
- package/app/skills/clean-code/reference/typescript.md +26 -0
- package/app/skills/command-creator/SKILL.md +83 -0
- package/app/skills/commit/SKILL.md +98 -0
- package/app/skills/commit/scripts/pre-commit-check.py +87 -0
- package/app/skills/commit/templates/conventional-commit.md +52 -0
- package/app/skills/csharp-patterns/SKILL.md +450 -0
- package/app/skills/database-patterns/SKILL.md +297 -0
- package/app/skills/debug/SKILL.md +154 -0
- package/app/skills/debug/scripts/error-parser.py +187 -0
- package/app/skills/debugging-tactics/SKILL.md +136 -0
- package/app/skills/deploy/SKILL.md +130 -0
- package/app/skills/deploy/scripts/pre_deploy_check.py +171 -0
- package/app/skills/deploy/templates/deployment-checklist.md +31 -0
- package/app/skills/design-an-interface/SKILL.md +105 -0
- package/app/skills/design-engineering/SKILL.md +260 -0
- package/app/skills/docker-devops/SKILL.md +303 -0
- package/app/skills/docs/SKILL.md +145 -0
- package/app/skills/docs/scripts/doc-inventory.py +176 -0
- package/app/skills/docs/templates/adr-template.md +36 -0
- package/app/skills/docs/templates/readme-template.md +67 -0
- package/app/skills/documentation-standards/SKILL.md +191 -0
- package/app/skills/ecommerce-patterns/SKILL.md +209 -0
- package/app/skills/evaluate/SKILL.md +132 -0
- package/app/skills/evolve/SKILL.md +27 -0
- package/app/skills/explain/SKILL.md +54 -0
- package/app/skills/explain/scripts/dependency-graph.py +215 -0
- package/app/skills/explore/SKILL.md +112 -0
- package/app/skills/explore/scripts/visualize.py +117 -0
- package/app/skills/fix/SKILL.md +78 -0
- package/app/skills/fix/scripts/error-classifier.py +191 -0
- package/app/skills/flutter-patterns/SKILL.md +254 -0
- package/app/skills/git-mastery/SKILL.md +70 -0
- package/app/skills/grill-me/SKILL.md +38 -0
- package/app/skills/health/SKILL.md +91 -0
- package/app/skills/health/scripts/health_check.py +162 -0
- package/app/skills/hive-mind/SKILL.md +56 -0
- package/app/skills/hook-creator/SKILL.md +107 -0
- package/app/skills/index/SKILL.md +74 -0
- package/app/skills/instinct-review/SKILL.md +77 -0
- package/app/skills/java-patterns/SKILL.md +442 -0
- package/app/skills/kotlin-patterns/SKILL.md +446 -0
- package/app/skills/lint/SKILL.md +103 -0
- package/app/skills/lint/scripts/detect-linters.py +112 -0
- package/app/skills/mcp-patterns/SKILL.md +270 -0
- package/app/skills/mem-search/SKILL.md +70 -0
- package/app/skills/migrate/SKILL.md +90 -0
- package/app/skills/migrate/scripts/migration-status.py +195 -0
- package/app/skills/migration-patterns/SKILL.md +260 -0
- package/app/skills/night-watch/SKILL.md +28 -0
- package/app/skills/observability-patterns/SKILL.md +203 -0
- package/app/skills/onboard/SKILL.md +76 -0
- package/app/skills/orchestrate/SKILL.md +86 -0
- package/app/skills/panic/SKILL.md +30 -0
- package/app/skills/performance-profiling/SKILL.md +59 -0
- package/app/skills/plan/SKILL.md +110 -0
- package/app/skills/plan/templates/plan-template.md +40 -0
- package/app/skills/plan-writing/SKILL.md +201 -0
- package/app/skills/plugin-creator/SKILL.md +78 -0
- package/app/skills/pr/SKILL.md +129 -0
- package/app/skills/pr/scripts/pr-summary.py +175 -0
- package/app/skills/prd-to-issues/SKILL.md +108 -0
- package/app/skills/prd-to-plan/SKILL.md +120 -0
- package/app/skills/predict/SKILL.md +30 -0
- package/app/skills/qa-session/SKILL.md +110 -0
- package/app/skills/rag-patterns/SKILL.md +203 -0
- package/app/skills/refactor/SKILL.md +124 -0
- package/app/skills/refactor/scripts/refactor-scan.py +210 -0
- package/app/skills/refactor-plan/SKILL.md +112 -0
- package/app/skills/repeat/SKILL.md +149 -0
- package/app/skills/research-mastery/SKILL.md +56 -0
- package/app/skills/review/SKILL.md +141 -0
- package/app/skills/review/scripts/diff-analyzer.py +170 -0
- package/app/skills/rollback/SKILL.md +87 -0
- package/app/skills/rollback/scripts/rollback_info.py +149 -0
- package/app/skills/ruby-patterns/SKILL.md +454 -0
- package/app/skills/rust-patterns/SKILL.md +446 -0
- package/app/skills/search/SKILL.md +64 -0
- package/app/skills/security-patterns/SKILL.md +91 -0
- package/app/skills/security-patterns/reference/authentication.md +37 -0
- package/app/skills/security-patterns/reference/authorization.md +22 -0
- package/app/skills/security-patterns/reference/input-validation.md +30 -0
- package/app/skills/security-patterns/reference/oauth-csrf-audit.md +131 -0
- package/app/skills/skill-creator/SKILL.md +154 -0
- package/app/skills/skill-creator/templates/dashboard/index.html +130 -0
- package/app/skills/skill-creator/templates/reasoning-engine/assets/example.json +12 -0
- package/app/skills/skill-creator/templates/reasoning-engine/search.py +110 -0
- package/app/skills/subagent-development/SKILL.md +225 -0
- package/app/skills/subagent-development/reference/code-quality-reviewer-prompt.md +145 -0
- package/app/skills/subagent-development/reference/implementer-prompt.md +118 -0
- package/app/skills/subagent-development/reference/spec-reviewer-prompt.md +100 -0
- package/app/skills/swarm/SKILL.md +81 -0
- package/app/skills/swift-patterns/SKILL.md +500 -0
- package/app/skills/tdd/SKILL.md +174 -0
- package/app/skills/tdd/reference/deep-modules.md +32 -0
- package/app/skills/tdd/reference/interface-design.md +32 -0
- package/app/skills/tdd/reference/mocking.md +52 -0
- package/app/skills/tdd/reference/refactoring.md +10 -0
- package/app/skills/tdd/reference/tests.md +59 -0
- package/app/skills/teams/SKILL.md +101 -0
- package/app/skills/test/SKILL.md +107 -0
- package/app/skills/test/scripts/detect-runner.py +113 -0
- package/app/skills/testing-patterns/SKILL.md +73 -0
- package/app/skills/testing-patterns/reference/flutter-testing.md +33 -0
- package/app/skills/testing-patterns/reference/go-testing.md +52 -0
- package/app/skills/testing-patterns/reference/php-phpunit.md +39 -0
- package/app/skills/testing-patterns/reference/python-pytest.md +228 -0
- package/app/skills/testing-patterns/reference/typescript-vitest.md +50 -0
- package/app/skills/triage-issue/SKILL.md +120 -0
- package/app/skills/typescript-patterns/SKILL.md +256 -0
- package/app/skills/ubiquitous-language/SKILL.md +74 -0
- package/app/skills/verification-before-completion/SKILL.md +108 -0
- package/app/skills/workflow/SKILL.md +250 -0
- package/app/skills/write-a-prd/SKILL.md +129 -0
- package/app/skills/write-a-prd/reference/visual-companion.md +78 -0
- package/app/skills/write-a-prd/scripts/frame-template.html +111 -0
- package/app/skills/write-a-prd/scripts/visual-server.cjs +79 -0
- package/app/templates/skill/generator/SKILL.md.template +40 -0
- package/app/templates/skill/knowledge/SKILL.md.template +52 -0
- package/app/templates/skill/linter/SKILL.md.template +34 -0
- package/app/templates/skill/reviewer/SKILL.md.template +51 -0
- package/app/templates/skill/workflow/SKILL.md.template +49 -0
- package/benchmarks/README.md +111 -0
- package/benchmarks/ecosystem-dashboard.json +148 -0
- package/benchmarks/ecosystem-harvest.json +148 -0
- package/benchmarks/results.json +38 -0
- package/benchmarks/run.py +351 -0
- package/bin/ai-toolkit.js +345 -0
- package/kb/best-practices/README.md +11 -0
- package/kb/howto/README.md +11 -0
- package/kb/procedures/maintenance-sop.md +306 -0
- package/kb/reference/agents-catalog.md +124 -0
- package/kb/reference/anti-pattern-registry-format.md +221 -0
- package/kb/reference/architecture-overview.md +232 -0
- package/kb/reference/benchmark-config.md +62 -0
- package/kb/reference/ci-integration.md +66 -0
- package/kb/reference/claude-ecosystem-benchmark-snapshot.md +80 -0
- package/kb/reference/claude-ecosystem-expansion-foundations.md +102 -0
- package/kb/reference/commands-catalog.md +21 -0
- package/kb/reference/distribution-model.md +63 -0
- package/kb/reference/global-install-model.md +56 -0
- package/kb/reference/hierarchical-override-pattern.md +200 -0
- package/kb/reference/hooks-catalog.md +306 -0
- package/kb/reference/integrations.md +88 -0
- package/kb/reference/language-packs.md +52 -0
- package/kb/reference/merge-friendly-install-model.md +58 -0
- package/kb/reference/plugin-pack-conventions.md +151 -0
- package/kb/reference/quick-wins-implementation-summary.md +70 -0
- package/kb/reference/skill-templates.md +50 -0
- package/kb/reference/skills-catalog.md +215 -0
- package/kb/reference/skills-unification.md +57 -0
- package/kb/reference/stats.md +69 -0
- package/kb/reference/sync.md +76 -0
- package/kb/troubleshooting/README.md +11 -0
- package/llms-full.txt +3068 -0
- package/llms.txt +39 -0
- package/package.json +75 -0
- package/scripts/_common.py +160 -0
- package/scripts/add_rule.py +50 -0
- package/scripts/benchmark_config.py +127 -0
- package/scripts/benchmark_ecosystem.py +288 -0
- package/scripts/check_deps.py +260 -0
- package/scripts/create_skill.py +118 -0
- package/scripts/doctor.py +504 -0
- package/scripts/eject.py +113 -0
- package/scripts/emission.py +256 -0
- package/scripts/evaluate_skills.py +260 -0
- package/scripts/frontmatter.py +58 -0
- package/scripts/generate_agents_md.py +91 -0
- package/scripts/generate_aider_conf.py +51 -0
- package/scripts/generate_cline.py +35 -0
- package/scripts/generate_copilot.py +30 -0
- package/scripts/generate_cursor_rules.py +35 -0
- package/scripts/generate_gemini.py +28 -0
- package/scripts/generate_llms_txt.py +164 -0
- package/scripts/generate_roo_modes.py +80 -0
- package/scripts/generate_windsurf.py +35 -0
- package/scripts/generator_base.py +140 -0
- package/scripts/harvest_ecosystem.py +50 -0
- package/scripts/inject_rule_cli.py +101 -0
- package/scripts/inject_section_cli.py +47 -0
- package/scripts/injection.py +180 -0
- package/scripts/install.py +236 -0
- package/scripts/install_git_hooks.py +71 -0
- package/scripts/install_steps/__init__.py +5 -0
- package/scripts/install_steps/ai_tools.py +261 -0
- package/scripts/install_steps/hooks.py +90 -0
- package/scripts/install_steps/markers.py +79 -0
- package/scripts/install_steps/symlinks.py +87 -0
- package/scripts/merge-hooks.py +192 -0
- package/scripts/plugin.py +642 -0
- package/scripts/plugin_schema.py +138 -0
- package/scripts/remove_rule.py +58 -0
- package/scripts/stats.py +81 -0
- package/scripts/sync.py +215 -0
- package/scripts/uninstall.py +292 -0
- package/scripts/validate.py +700 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ci-cd-patterns
|
|
3
|
+
description: "Loaded when user asks about CI/CD pipelines or deployment automation"
|
|
4
|
+
effort: medium
|
|
5
|
+
user-invocable: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# CI/CD Patterns
|
|
9
|
+
|
|
10
|
+
## GitHub Actions
|
|
11
|
+
|
|
12
|
+
### Standard Pipeline
|
|
13
|
+
```yaml
|
|
14
|
+
name: CI
|
|
15
|
+
on:
|
|
16
|
+
push:
|
|
17
|
+
branches: [main]
|
|
18
|
+
pull_request:
|
|
19
|
+
branches: [main]
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
lint:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- uses: actions/setup-node@v4
|
|
27
|
+
with:
|
|
28
|
+
node-version: 20
|
|
29
|
+
cache: "npm"
|
|
30
|
+
- run: npm ci
|
|
31
|
+
- run: npm run lint
|
|
32
|
+
- run: npm run typecheck
|
|
33
|
+
|
|
34
|
+
test:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
needs: lint
|
|
37
|
+
strategy:
|
|
38
|
+
matrix:
|
|
39
|
+
node-version: [18, 20, 22]
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
- uses: actions/setup-node@v4
|
|
43
|
+
with:
|
|
44
|
+
node-version: ${{ matrix.node-version }}
|
|
45
|
+
cache: "npm"
|
|
46
|
+
- run: npm ci
|
|
47
|
+
- run: npm test -- --coverage
|
|
48
|
+
- uses: actions/upload-artifact@v4
|
|
49
|
+
with:
|
|
50
|
+
name: coverage-${{ matrix.node-version }}
|
|
51
|
+
path: coverage/
|
|
52
|
+
|
|
53
|
+
build:
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
needs: test
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
- uses: actions/setup-node@v4
|
|
59
|
+
with:
|
|
60
|
+
node-version: 20
|
|
61
|
+
cache: "npm"
|
|
62
|
+
- run: npm ci
|
|
63
|
+
- run: npm run build
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Python CI
|
|
67
|
+
```yaml
|
|
68
|
+
name: Python CI
|
|
69
|
+
on: [push, pull_request]
|
|
70
|
+
|
|
71
|
+
jobs:
|
|
72
|
+
test:
|
|
73
|
+
runs-on: ubuntu-latest
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@v4
|
|
76
|
+
- uses: actions/setup-python@v5
|
|
77
|
+
with:
|
|
78
|
+
python-version: "3.12"
|
|
79
|
+
cache: "pip"
|
|
80
|
+
- run: pip install -e ".[dev]"
|
|
81
|
+
- run: ruff check .
|
|
82
|
+
- run: mypy --strict src/
|
|
83
|
+
- run: pytest --cov=src --cov-report=xml
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Docker Build & Push
|
|
87
|
+
```yaml
|
|
88
|
+
build-docker:
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
needs: test
|
|
91
|
+
steps:
|
|
92
|
+
- uses: actions/checkout@v4
|
|
93
|
+
- uses: docker/setup-buildx-action@v3
|
|
94
|
+
- uses: docker/login-action@v3
|
|
95
|
+
with:
|
|
96
|
+
registry: ghcr.io
|
|
97
|
+
username: ${{ github.actor }}
|
|
98
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
99
|
+
- uses: docker/build-push-action@v5
|
|
100
|
+
with:
|
|
101
|
+
context: .
|
|
102
|
+
push: ${{ github.ref == 'refs/heads/main' }}
|
|
103
|
+
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
|
|
104
|
+
cache-from: type=gha
|
|
105
|
+
cache-to: type=gha,mode=max
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## GitLab CI
|
|
109
|
+
|
|
110
|
+
```yaml
|
|
111
|
+
stages:
|
|
112
|
+
- lint
|
|
113
|
+
- test
|
|
114
|
+
- build
|
|
115
|
+
- deploy
|
|
116
|
+
|
|
117
|
+
lint:
|
|
118
|
+
stage: lint
|
|
119
|
+
image: node:20
|
|
120
|
+
cache:
|
|
121
|
+
key: $CI_COMMIT_REF_SLUG
|
|
122
|
+
paths: [node_modules/]
|
|
123
|
+
script:
|
|
124
|
+
- npm ci
|
|
125
|
+
- npm run lint
|
|
126
|
+
|
|
127
|
+
test:
|
|
128
|
+
stage: test
|
|
129
|
+
image: node:20
|
|
130
|
+
services:
|
|
131
|
+
- postgres:16
|
|
132
|
+
variables:
|
|
133
|
+
DATABASE_URL: "postgresql://postgres:postgres@postgres/test"
|
|
134
|
+
script:
|
|
135
|
+
- npm ci
|
|
136
|
+
- npm test
|
|
137
|
+
|
|
138
|
+
build:
|
|
139
|
+
stage: build
|
|
140
|
+
image: docker:24
|
|
141
|
+
services:
|
|
142
|
+
- docker:24-dind
|
|
143
|
+
script:
|
|
144
|
+
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
|
|
145
|
+
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
|
146
|
+
only:
|
|
147
|
+
- main
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Docker Multi-stage Builds
|
|
151
|
+
|
|
152
|
+
### Node.js
|
|
153
|
+
```dockerfile
|
|
154
|
+
# Stage 1: Dependencies
|
|
155
|
+
FROM node:20-alpine AS deps
|
|
156
|
+
WORKDIR /app
|
|
157
|
+
COPY package.json package-lock.json ./
|
|
158
|
+
RUN npm ci --production
|
|
159
|
+
|
|
160
|
+
# Stage 2: Build
|
|
161
|
+
FROM node:20-alpine AS build
|
|
162
|
+
WORKDIR /app
|
|
163
|
+
COPY package.json package-lock.json ./
|
|
164
|
+
RUN npm ci
|
|
165
|
+
COPY . .
|
|
166
|
+
RUN npm run build
|
|
167
|
+
|
|
168
|
+
# Stage 3: Production
|
|
169
|
+
FROM node:20-alpine AS production
|
|
170
|
+
WORKDIR /app
|
|
171
|
+
ENV NODE_ENV=production
|
|
172
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
173
|
+
COPY --from=build /app/dist ./dist
|
|
174
|
+
USER node
|
|
175
|
+
EXPOSE 3000
|
|
176
|
+
CMD ["node", "dist/index.js"]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Python
|
|
180
|
+
```dockerfile
|
|
181
|
+
FROM python:3.12-slim AS builder
|
|
182
|
+
WORKDIR /app
|
|
183
|
+
COPY pyproject.toml .
|
|
184
|
+
RUN pip install --no-cache-dir --target=/deps .
|
|
185
|
+
|
|
186
|
+
FROM python:3.12-slim
|
|
187
|
+
WORKDIR /app
|
|
188
|
+
COPY --from=builder /deps /usr/local/lib/python3.12/site-packages
|
|
189
|
+
COPY src/ ./src/
|
|
190
|
+
USER nobody
|
|
191
|
+
CMD ["python", "-m", "src.main"]
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Caching Strategies
|
|
195
|
+
|
|
196
|
+
### npm/pnpm
|
|
197
|
+
```yaml
|
|
198
|
+
- uses: actions/cache@v4
|
|
199
|
+
with:
|
|
200
|
+
path: ~/.npm
|
|
201
|
+
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
|
202
|
+
restore-keys: ${{ runner.os }}-npm-
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### pip
|
|
206
|
+
```yaml
|
|
207
|
+
- uses: actions/cache@v4
|
|
208
|
+
with:
|
|
209
|
+
path: ~/.cache/pip
|
|
210
|
+
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Docker Layer Caching
|
|
214
|
+
```yaml
|
|
215
|
+
- uses: docker/build-push-action@v5
|
|
216
|
+
with:
|
|
217
|
+
cache-from: type=gha
|
|
218
|
+
cache-to: type=gha,mode=max
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Kubernetes Deployment
|
|
222
|
+
|
|
223
|
+
### Rolling Update
|
|
224
|
+
```yaml
|
|
225
|
+
apiVersion: apps/v1
|
|
226
|
+
kind: Deployment
|
|
227
|
+
metadata:
|
|
228
|
+
name: api
|
|
229
|
+
spec:
|
|
230
|
+
replicas: 3
|
|
231
|
+
strategy:
|
|
232
|
+
type: RollingUpdate
|
|
233
|
+
rollingUpdate:
|
|
234
|
+
maxSurge: 1
|
|
235
|
+
maxUnavailable: 0
|
|
236
|
+
template:
|
|
237
|
+
spec:
|
|
238
|
+
containers:
|
|
239
|
+
- name: api
|
|
240
|
+
image: ghcr.io/org/api:latest
|
|
241
|
+
readinessProbe:
|
|
242
|
+
httpGet:
|
|
243
|
+
path: /ready
|
|
244
|
+
port: 3000
|
|
245
|
+
initialDelaySeconds: 5
|
|
246
|
+
livenessProbe:
|
|
247
|
+
httpGet:
|
|
248
|
+
path: /live
|
|
249
|
+
port: 3000
|
|
250
|
+
initialDelaySeconds: 10
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Secret Management
|
|
254
|
+
|
|
255
|
+
```yaml
|
|
256
|
+
# GitHub Actions - use secrets
|
|
257
|
+
env:
|
|
258
|
+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
259
|
+
API_KEY: ${{ secrets.API_KEY }}
|
|
260
|
+
|
|
261
|
+
# Never hardcode secrets in pipelines
|
|
262
|
+
# Use OIDC for cloud provider auth (no long-lived credentials)
|
|
263
|
+
- uses: aws-actions/configure-aws-credentials@v4
|
|
264
|
+
with:
|
|
265
|
+
role-to-assume: arn:aws:iam::123456789:role/deploy
|
|
266
|
+
aws-region: us-east-1
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Release Automation
|
|
270
|
+
|
|
271
|
+
### Semantic Release
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"branches": ["main"],
|
|
275
|
+
"plugins": [
|
|
276
|
+
"@semantic-release/commit-analyzer",
|
|
277
|
+
"@semantic-release/release-notes-generator",
|
|
278
|
+
"@semantic-release/changelog",
|
|
279
|
+
"@semantic-release/npm",
|
|
280
|
+
"@semantic-release/github",
|
|
281
|
+
"@semantic-release/git"
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Conventional Commits for Auto-versioning
|
|
287
|
+
| Prefix | Version Bump | Example |
|
|
288
|
+
|--------|-------------|---------|
|
|
289
|
+
| `fix:` | Patch (0.0.x) | `fix: resolve null pointer in auth` |
|
|
290
|
+
| `feat:` | Minor (0.x.0) | `feat: add user search endpoint` |
|
|
291
|
+
| `feat!:` / `BREAKING CHANGE:` | Major (x.0.0) | `feat!: change API response format` |
|
|
292
|
+
|
|
293
|
+
## Anti-Patterns
|
|
294
|
+
- Secrets in pipeline logs or environment dumps
|
|
295
|
+
- No caching (slow builds)
|
|
296
|
+
- Running tests only on main (should run on PRs)
|
|
297
|
+
- Manual deployments to production
|
|
298
|
+
- No rollback strategy
|
|
299
|
+
- Skipping linting/type-checking in CI
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clean-code
|
|
3
|
+
description: "Loaded when user asks about clean code, naming, or code quality"
|
|
4
|
+
effort: medium
|
|
5
|
+
user-invocable: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Clean Code Skill
|
|
9
|
+
|
|
10
|
+
## Core Principles
|
|
11
|
+
|
|
12
|
+
### 1. Meaningful Names
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
# Bad
|
|
16
|
+
def calc(a, b):
|
|
17
|
+
return a * b
|
|
18
|
+
|
|
19
|
+
# Good
|
|
20
|
+
def calculate_total_price(unit_price: float, quantity: int) -> float:
|
|
21
|
+
return unit_price * quantity
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 2. Single Responsibility
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
# Bad - does too much
|
|
28
|
+
def process_user(user_data):
|
|
29
|
+
validate(user_data)
|
|
30
|
+
user = create_user(user_data)
|
|
31
|
+
send_welcome_email(user)
|
|
32
|
+
log_creation(user)
|
|
33
|
+
return user
|
|
34
|
+
|
|
35
|
+
# Good - each function does one thing
|
|
36
|
+
def create_user(user_data: UserData) -> User:
|
|
37
|
+
return User(**user_data)
|
|
38
|
+
|
|
39
|
+
def onboard_user(user_data: UserData) -> User:
|
|
40
|
+
user = create_user(user_data)
|
|
41
|
+
send_welcome_email(user)
|
|
42
|
+
log_user_creation(user)
|
|
43
|
+
return user
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3. DRY (Don't Repeat Yourself)
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
# Bad
|
|
50
|
+
def get_active_users():
|
|
51
|
+
return [u for u in users if u.status == "active"]
|
|
52
|
+
|
|
53
|
+
def get_active_admins():
|
|
54
|
+
return [u for u in users if u.status == "active" and u.role == "admin"]
|
|
55
|
+
|
|
56
|
+
# Good
|
|
57
|
+
def filter_users(status: str | None = None, role: str | None = None) -> list[User]:
|
|
58
|
+
result = users
|
|
59
|
+
if status:
|
|
60
|
+
result = [u for u in result if u.status == status]
|
|
61
|
+
if role:
|
|
62
|
+
result = [u for u in result if u.role == role]
|
|
63
|
+
return result
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Code Organization
|
|
69
|
+
|
|
70
|
+
Keep modules focused. Order contents consistently: imports (stdlib, third-party, local), constants, public API, private helpers. Use clear visibility markers (underscore prefix in Python, access modifiers in other languages). Group related functionality into cohesive modules rather than dumping everything into a single file.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Anti-Patterns to Avoid
|
|
75
|
+
|
|
76
|
+
| Anti-Pattern | Problem | Solution |
|
|
77
|
+
|--------------|---------|----------|
|
|
78
|
+
| God class | Too many responsibilities | Split into smaller classes |
|
|
79
|
+
| Long methods | Hard to understand | Extract methods |
|
|
80
|
+
| Deep nesting | Complex control flow | Early returns, extract methods |
|
|
81
|
+
| Magic numbers | Unclear meaning | Use named constants |
|
|
82
|
+
| Bare except | Hides bugs | Catch specific exceptions |
|
|
83
|
+
| Mutable defaults | Shared state bugs | Use `None` and create inside |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Quality Checklist
|
|
88
|
+
|
|
89
|
+
- [ ] Functions are small (<20 lines ideal)
|
|
90
|
+
- [ ] Names are descriptive and consistent
|
|
91
|
+
- [ ] Type hints on all public APIs
|
|
92
|
+
- [ ] Docstrings on all public functions/classes
|
|
93
|
+
- [ ] No magic numbers (use constants)
|
|
94
|
+
- [ ] No hardcoded strings (use enums/constants)
|
|
95
|
+
- [ ] Error handling is specific
|
|
96
|
+
- [ ] Resources are properly cleaned up
|
|
97
|
+
- [ ] No code duplication
|
|
98
|
+
- [ ] Tests cover critical paths
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Language-Specific References
|
|
103
|
+
|
|
104
|
+
For detailed patterns, type hints, linting configuration, and idiomatic code per language:
|
|
105
|
+
|
|
106
|
+
- **Python:** type hints, docstrings, error handling, context managers, module/class structure, ruff/mypy config -- see [reference/python.md](reference/python.md)
|
|
107
|
+
- **TypeScript:** strict tsconfig, ESLint setup, discriminated unions, type safety -- see [reference/typescript.md](reference/typescript.md)
|
|
108
|
+
- **PHP:** PHPStan config, PSR-12, enums, constructor promotion -- see [reference/php.md](reference/php.md)
|
|
109
|
+
- **Go:** gofmt, error handling, receiver naming, early returns -- see [reference/go.md](reference/go.md)
|
|
110
|
+
- **Dart/Flutter:** null safety, named parameters, const constructors, dart analyze -- see [reference/dart.md](reference/dart.md)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Dart/Flutter Clean Code Patterns
|
|
2
|
+
|
|
3
|
+
## Patterns
|
|
4
|
+
|
|
5
|
+
```dart
|
|
6
|
+
// Use dart analyze with strict rules
|
|
7
|
+
// analysis_options.yaml: include: package:lints/recommended.yaml
|
|
8
|
+
|
|
9
|
+
// Null safety
|
|
10
|
+
String? getName() => _name; // nullable return
|
|
11
|
+
final name = getName() ?? 'default'; // null coalescing
|
|
12
|
+
|
|
13
|
+
// Named parameters for clarity
|
|
14
|
+
Widget buildCard({required String title, String? subtitle, VoidCallback? onTap}) { ... }
|
|
15
|
+
|
|
16
|
+
// Use const constructors
|
|
17
|
+
const EdgeInsets.all(16.0)
|
|
18
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Go Clean Code Patterns
|
|
2
|
+
|
|
3
|
+
## Patterns
|
|
4
|
+
|
|
5
|
+
```go
|
|
6
|
+
// Use gofmt (automatic), go vet, golangci-lint
|
|
7
|
+
// Error handling - always check errors
|
|
8
|
+
result, err := doSomething()
|
|
9
|
+
if err != nil {
|
|
10
|
+
return fmt.Errorf("doSomething failed: %w", err)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Use meaningful receiver names (not `this` or `self`)
|
|
14
|
+
func (s *Service) Search(query string) ([]Result, error) { ... }
|
|
15
|
+
|
|
16
|
+
// Return early to avoid deep nesting
|
|
17
|
+
func validate(input string) error {
|
|
18
|
+
if input == "" {
|
|
19
|
+
return errors.New("input cannot be empty")
|
|
20
|
+
}
|
|
21
|
+
// ... continue with valid input
|
|
22
|
+
}
|
|
23
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# PHP Clean Code Patterns
|
|
2
|
+
|
|
3
|
+
## Configuration
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
# phpstan.neon
|
|
7
|
+
parameters:
|
|
8
|
+
level: 8 # max strictness
|
|
9
|
+
paths: [src]
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Patterns
|
|
13
|
+
|
|
14
|
+
```php
|
|
15
|
+
// Type declarations (PHP 8+)
|
|
16
|
+
function calculatePrice(float $unitPrice, int $quantity): float {
|
|
17
|
+
return $unitPrice * $quantity;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Use enums (PHP 8.1+)
|
|
21
|
+
enum UserRole: string {
|
|
22
|
+
case Admin = 'admin';
|
|
23
|
+
case User = 'user';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Follow PSR-12 coding standard
|
|
27
|
+
// Use constructor promotion
|
|
28
|
+
public function __construct(
|
|
29
|
+
private readonly string $name,
|
|
30
|
+
private readonly string $email,
|
|
31
|
+
) {}
|
|
32
|
+
```
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Python Clean Code Patterns
|
|
2
|
+
|
|
3
|
+
## Type Hints (Required for Public APIs)
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
from typing import Optional, List, Dict
|
|
7
|
+
|
|
8
|
+
def search(
|
|
9
|
+
query: str,
|
|
10
|
+
limit: int = 10,
|
|
11
|
+
filters: Optional[Dict[str, str]] = None
|
|
12
|
+
) -> List[Dict[str, any]]:
|
|
13
|
+
"""Search the knowledge base.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
query: Search query string
|
|
17
|
+
limit: Maximum results to return
|
|
18
|
+
filters: Optional field filters
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
List of matching documents
|
|
22
|
+
|
|
23
|
+
Raises:
|
|
24
|
+
ValueError: If query is empty
|
|
25
|
+
"""
|
|
26
|
+
if not query:
|
|
27
|
+
raise ValueError("Query cannot be empty")
|
|
28
|
+
...
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Docstrings (Google Style)
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
def calculate_relevance(
|
|
35
|
+
query: str,
|
|
36
|
+
document: str,
|
|
37
|
+
weights: dict[str, float]
|
|
38
|
+
) -> float:
|
|
39
|
+
"""Calculate relevance score between query and document.
|
|
40
|
+
|
|
41
|
+
Uses hybrid scoring combining BM25 and semantic similarity.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
query: Search query
|
|
45
|
+
document: Document text
|
|
46
|
+
weights: Score weights {"bm25": 0.4, "semantic": 0.6}
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Relevance score between 0 and 1
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
ValueError: If weights don't sum to 1.0
|
|
53
|
+
|
|
54
|
+
Example:
|
|
55
|
+
>>> calculate_relevance("test", "test doc", {"bm25": 0.5, "semantic": 0.5})
|
|
56
|
+
0.85
|
|
57
|
+
"""
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Error Handling
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
# Bad - bare except
|
|
64
|
+
try:
|
|
65
|
+
result = risky_operation()
|
|
66
|
+
except:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
# Good - specific exceptions
|
|
70
|
+
try:
|
|
71
|
+
result = risky_operation()
|
|
72
|
+
except ConnectionError as e:
|
|
73
|
+
logger.error(f"Connection failed: {e}")
|
|
74
|
+
raise
|
|
75
|
+
except ValueError as e:
|
|
76
|
+
logger.warning(f"Invalid value: {e}")
|
|
77
|
+
return default_value
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Context Managers
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
# Bad
|
|
84
|
+
file = open("data.txt")
|
|
85
|
+
content = file.read()
|
|
86
|
+
file.close()
|
|
87
|
+
|
|
88
|
+
# Good
|
|
89
|
+
with open("data.txt") as file:
|
|
90
|
+
content = file.read()
|
|
91
|
+
|
|
92
|
+
# Custom context manager
|
|
93
|
+
from contextlib import contextmanager
|
|
94
|
+
|
|
95
|
+
@contextmanager
|
|
96
|
+
def database_connection():
|
|
97
|
+
conn = create_connection()
|
|
98
|
+
try:
|
|
99
|
+
yield conn
|
|
100
|
+
finally:
|
|
101
|
+
conn.close()
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Module Structure
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
"""Module docstring explaining purpose.
|
|
108
|
+
|
|
109
|
+
This module provides functions for searching the knowledge base.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
# Standard library imports
|
|
113
|
+
import logging
|
|
114
|
+
from typing import Optional
|
|
115
|
+
|
|
116
|
+
# Third-party imports
|
|
117
|
+
import httpx
|
|
118
|
+
from qdrant_client import QdrantClient
|
|
119
|
+
|
|
120
|
+
# Local imports
|
|
121
|
+
from .config import Settings
|
|
122
|
+
from .models import Document
|
|
123
|
+
|
|
124
|
+
# Module-level constants
|
|
125
|
+
DEFAULT_LIMIT = 10
|
|
126
|
+
LOGGER = logging.getLogger(__name__)
|
|
127
|
+
|
|
128
|
+
# Public functions
|
|
129
|
+
def search(query: str) -> list[Document]:
|
|
130
|
+
...
|
|
131
|
+
|
|
132
|
+
# Private functions (underscore prefix)
|
|
133
|
+
def _normalize_query(query: str) -> str:
|
|
134
|
+
...
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Class Structure
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
class SearchService:
|
|
141
|
+
"""Service for searching the knowledge base."""
|
|
142
|
+
|
|
143
|
+
def __init__(self, client: QdrantClient, settings: Settings):
|
|
144
|
+
"""Initialize search service.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
client: Qdrant client instance
|
|
148
|
+
settings: Application settings
|
|
149
|
+
"""
|
|
150
|
+
self._client = client
|
|
151
|
+
self._settings = settings
|
|
152
|
+
|
|
153
|
+
def search(self, query: str, limit: int = 10) -> list[Document]:
|
|
154
|
+
"""Search for documents."""
|
|
155
|
+
...
|
|
156
|
+
|
|
157
|
+
def _validate_query(self, query: str) -> None:
|
|
158
|
+
"""Validate search query (private method)."""
|
|
159
|
+
...
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Linting Configuration
|
|
163
|
+
|
|
164
|
+
### pyproject.toml
|
|
165
|
+
|
|
166
|
+
```toml
|
|
167
|
+
[tool.ruff]
|
|
168
|
+
line-length = 100
|
|
169
|
+
target-version = "py312"
|
|
170
|
+
|
|
171
|
+
[tool.ruff.lint]
|
|
172
|
+
select = ["E", "F", "I", "N", "W", "UP"]
|
|
173
|
+
ignore = ["E501"] # line too long (handled by formatter)
|
|
174
|
+
|
|
175
|
+
[tool.mypy]
|
|
176
|
+
python_version = "3.12"
|
|
177
|
+
strict = true
|
|
178
|
+
warn_return_any = true
|
|
179
|
+
warn_unused_ignores = true
|
|
180
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# TypeScript Clean Code Patterns
|
|
2
|
+
|
|
3
|
+
## Configuration
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
// tsconfig.json - strict mode
|
|
7
|
+
{ "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true } }
|
|
8
|
+
|
|
9
|
+
// .eslintrc - recommended rules
|
|
10
|
+
{ "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended-type-checked", "prettier"] }
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Patterns
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// Type-safe function signatures
|
|
17
|
+
function getUser(id: string): Promise<User | null> { ... }
|
|
18
|
+
|
|
19
|
+
// Prefer `unknown` over `any`
|
|
20
|
+
function parseData(raw: unknown): Result { ... }
|
|
21
|
+
|
|
22
|
+
// Use discriminated unions
|
|
23
|
+
type Result = { success: true; data: User } | { success: false; error: string };
|
|
24
|
+
|
|
25
|
+
// Avoid: `any`, non-null assertions `!`, type casting `as` without guards
|
|
26
|
+
```
|