@codyswann/lisa 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/LICENSE +21 -0
- package/README.md +867 -0
- package/all/copy-overwrite/.claude/README.md +205 -0
- package/all/copy-overwrite/.claude/agents/agent-architect.md +311 -0
- package/all/copy-overwrite/.claude/agents/codebase-analyzer.md +146 -0
- package/all/copy-overwrite/.claude/agents/codebase-locator.md +125 -0
- package/all/copy-overwrite/.claude/agents/codebase-pattern-finder.md +237 -0
- package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +183 -0
- package/all/copy-overwrite/.claude/agents/hooks-expert.md +74 -0
- package/all/copy-overwrite/.claude/agents/skill-evaluator.md +246 -0
- package/all/copy-overwrite/.claude/agents/slash-command-architect.md +87 -0
- package/all/copy-overwrite/.claude/agents/web-search-researcher.md +112 -0
- package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +8 -0
- package/all/copy-overwrite/.claude/commands/git/commit.md +44 -0
- package/all/copy-overwrite/.claude/commands/git/prune.md +34 -0
- package/all/copy-overwrite/.claude/commands/git/submit-pr.md +50 -0
- package/all/copy-overwrite/.claude/commands/jira/create.md +50 -0
- package/all/copy-overwrite/.claude/commands/jira/verify.md +34 -0
- package/all/copy-overwrite/.claude/commands/project/archive.md +8 -0
- package/all/copy-overwrite/.claude/commands/project/bootstrap.md +49 -0
- package/all/copy-overwrite/.claude/commands/project/complete-task.md +7 -0
- package/all/copy-overwrite/.claude/commands/project/debrief.md +65 -0
- package/all/copy-overwrite/.claude/commands/project/execute.md +94 -0
- package/all/copy-overwrite/.claude/commands/project/implement.md +42 -0
- package/all/copy-overwrite/.claude/commands/project/local-code-review.md +88 -0
- package/all/copy-overwrite/.claude/commands/project/lower-code-complexity.md +74 -0
- package/all/copy-overwrite/.claude/commands/project/plan.md +314 -0
- package/all/copy-overwrite/.claude/commands/project/research.md +248 -0
- package/all/copy-overwrite/.claude/commands/project/review.md +63 -0
- package/all/copy-overwrite/.claude/commands/project/setup.md +19 -0
- package/all/copy-overwrite/.claude/commands/project/verify.md +38 -0
- package/all/copy-overwrite/.claude/commands/pull-request/review.md +12 -0
- package/all/copy-overwrite/.claude/commands/rules/format-md.md +72 -0
- package/all/copy-overwrite/.claude/commands/sonarqube/check.md +6 -0
- package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +3 -0
- package/all/copy-overwrite/.claude/hooks/README.md +301 -0
- package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +181 -0
- package/all/copy-overwrite/.claude/settings.json +41 -0
- package/all/copy-overwrite/.claude/settings.local.json.example +14 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/SKILL.md +405 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md +416 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/immutable-patterns.md +316 -0
- package/all/copy-overwrite/.claude/skills/prompt-complexity-scorer/SKILL.md +118 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +210 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/all/copy-overwrite/CLAUDE.md +77 -0
- package/all/copy-overwrite/HUMAN.md +17 -0
- package/all/copy-overwrite/specs/.keep +0 -0
- package/all/create-only/PROJECT_RULES.md +0 -0
- package/cdk/merge/package.json +20 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +107 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts.d.ts +45 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +58 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/core/config.d.ts +73 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +36 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lisa.d.ts +81 -0
- package/dist/core/lisa.d.ts.map +1 -0
- package/dist/core/lisa.js +459 -0
- package/dist/core/lisa.js.map +1 -0
- package/dist/core/manifest.d.ts +58 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +104 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/detection/detector.interface.d.ts +15 -0
- package/dist/detection/detector.interface.d.ts.map +1 -0
- package/dist/detection/detector.interface.js +2 -0
- package/dist/detection/detector.interface.js.map +1 -0
- package/dist/detection/detectors/cdk.d.ts +10 -0
- package/dist/detection/detectors/cdk.d.ts.map +1 -0
- package/dist/detection/detectors/cdk.js +34 -0
- package/dist/detection/detectors/cdk.js.map +1 -0
- package/dist/detection/detectors/expo.d.ts +10 -0
- package/dist/detection/detectors/expo.d.ts.map +1 -0
- package/dist/detection/detectors/expo.js +30 -0
- package/dist/detection/detectors/expo.js.map +1 -0
- package/dist/detection/detectors/nestjs.d.ts +10 -0
- package/dist/detection/detectors/nestjs.d.ts.map +1 -0
- package/dist/detection/detectors/nestjs.js +34 -0
- package/dist/detection/detectors/nestjs.js.map +1 -0
- package/dist/detection/detectors/npm-package.d.ts +13 -0
- package/dist/detection/detectors/npm-package.d.ts.map +1 -0
- package/dist/detection/detectors/npm-package.js +30 -0
- package/dist/detection/detectors/npm-package.js.map +1 -0
- package/dist/detection/detectors/typescript.d.ts +10 -0
- package/dist/detection/detectors/typescript.d.ts.map +1 -0
- package/dist/detection/detectors/typescript.js +25 -0
- package/dist/detection/detectors/typescript.js.map +1 -0
- package/dist/detection/index.d.ts +24 -0
- package/dist/detection/index.d.ts.map +1 -0
- package/dist/detection/index.js +57 -0
- package/dist/detection/index.js.map +1 -0
- package/dist/errors/index.d.ts +69 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +110 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/console-logger.d.ts +12 -0
- package/dist/logging/console-logger.d.ts.map +1 -0
- package/dist/logging/console-logger.js +22 -0
- package/dist/logging/console-logger.js.map +1 -0
- package/dist/logging/index.d.ts +4 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.interface.d.ts +20 -0
- package/dist/logging/logger.interface.d.ts.map +1 -0
- package/dist/logging/logger.interface.js +2 -0
- package/dist/logging/logger.interface.js.map +1 -0
- package/dist/logging/silent-logger.d.ts +12 -0
- package/dist/logging/silent-logger.d.ts.map +1 -0
- package/dist/logging/silent-logger.js +21 -0
- package/dist/logging/silent-logger.js.map +1 -0
- package/dist/strategies/copy-contents.d.ts +14 -0
- package/dist/strategies/copy-contents.d.ts.map +1 -0
- package/dist/strategies/copy-contents.js +69 -0
- package/dist/strategies/copy-contents.js.map +1 -0
- package/dist/strategies/copy-overwrite.d.ts +14 -0
- package/dist/strategies/copy-overwrite.d.ts.map +1 -0
- package/dist/strategies/copy-overwrite.js +47 -0
- package/dist/strategies/copy-overwrite.js.map +1 -0
- package/dist/strategies/create-only.d.ts +13 -0
- package/dist/strategies/create-only.d.ts.map +1 -0
- package/dist/strategies/create-only.js +30 -0
- package/dist/strategies/create-only.js.map +1 -0
- package/dist/strategies/index.d.ts +31 -0
- package/dist/strategies/index.d.ts.map +1 -0
- package/dist/strategies/index.js +52 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/strategies/merge.d.ts +13 -0
- package/dist/strategies/merge.d.ts.map +1 -0
- package/dist/strategies/merge.js +60 -0
- package/dist/strategies/merge.js.map +1 -0
- package/dist/strategies/strategy.interface.d.ts +31 -0
- package/dist/strategies/strategy.interface.d.ts.map +1 -0
- package/dist/strategies/strategy.interface.js +2 -0
- package/dist/strategies/strategy.interface.js.map +1 -0
- package/dist/transaction/backup.d.ts +38 -0
- package/dist/transaction/backup.d.ts.map +1 -0
- package/dist/transaction/backup.js +97 -0
- package/dist/transaction/backup.js.map +1 -0
- package/dist/transaction/index.d.ts +4 -0
- package/dist/transaction/index.d.ts.map +1 -0
- package/dist/transaction/index.js +3 -0
- package/dist/transaction/index.js.map +1 -0
- package/dist/transaction/transaction.d.ts +34 -0
- package/dist/transaction/transaction.d.ts.map +1 -0
- package/dist/transaction/transaction.js +68 -0
- package/dist/transaction/transaction.js.map +1 -0
- package/dist/utils/file-operations.d.ts +29 -0
- package/dist/utils/file-operations.d.ts.map +1 -0
- package/dist/utils/file-operations.js +84 -0
- package/dist/utils/file-operations.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json-utils.d.ts +22 -0
- package/dist/utils/json-utils.d.ts.map +1 -0
- package/dist/utils/json-utils.js +57 -0
- package/dist/utils/json-utils.js.map +1 -0
- package/dist/utils/path-utils.d.ts +21 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +35 -0
- package/dist/utils/path-utils.js.map +1 -0
- package/eslint-plugin-code-organization/README.md +149 -0
- package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
- package/eslint-plugin-code-organization/index.js +23 -0
- package/eslint-plugin-code-organization/package.json +10 -0
- package/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
- package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +238 -0
- package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +360 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +360 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +417 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +257 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +233 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +327 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +299 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +749 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +318 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +198 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +207 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +268 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +619 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +340 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +276 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +414 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +202 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +443 -0
- package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +309 -0
- package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +417 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +431 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +290 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +169 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +411 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +343 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +307 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +300 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +354 -0
- package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +362 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +505 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +711 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +446 -0
- package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +223 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +319 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +420 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +556 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +590 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +291 -0
- package/expo/copy-overwrite/.easignore.extra +2 -0
- package/expo/copy-overwrite/.mcp.json +33 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +234 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +84 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +196 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +289 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +32 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +10 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +230 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +91 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +178 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +238 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +260 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +29 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +10 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +51 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +55 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-inline-styles.js +73 -0
- package/expo/copy-overwrite/eslint.config.mjs +560 -0
- package/expo/copy-overwrite/lighthouserc.js +194 -0
- package/expo/create-only/lighthouserc-config.json +28 -0
- package/expo/merge/package.json +132 -0
- package/lisa.sh +35 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +176 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +527 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +483 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +257 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +413 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +513 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +536 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +275 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +487 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +450 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +536 -0
- package/nestjs/merge/package.json +75 -0
- package/package.json +124 -0
- package/typescript/copy-contents/.husky/commit-msg +91 -0
- package/typescript/copy-contents/.husky/pre-commit +96 -0
- package/typescript/copy-contents/.husky/pre-push +211 -0
- package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +74 -0
- package/typescript/copy-overwrite/.claude/hooks/install_pkgs.sh +59 -0
- package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +103 -0
- package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +388 -0
- package/typescript/copy-overwrite/.github/README.md +455 -0
- package/typescript/copy-overwrite/.github/dependabot.yml +40 -0
- package/typescript/copy-overwrite/.github/k6/BROWSER_TESTING_NOTE.md +129 -0
- package/typescript/copy-overwrite/.github/k6/INTEGRATION_GUIDE.md +354 -0
- package/typescript/copy-overwrite/.github/k6/README.md +386 -0
- package/typescript/copy-overwrite/.github/k6/SCENARIO_SELECTION_GUIDE.md +264 -0
- package/typescript/copy-overwrite/.github/k6/examples/customer-deploy-integration.yml +115 -0
- package/typescript/copy-overwrite/.github/k6/examples/data-driven-test.js +268 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/load.js +142 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/load.json +27 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/smoke.js +26 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/smoke.json +20 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/soak.js +244 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/soak.json +29 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/spike.js +180 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/spike.json +32 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/stress.js +206 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/stress.json +38 -0
- package/typescript/copy-overwrite/.github/k6/scripts/api-test.js +452 -0
- package/typescript/copy-overwrite/.github/k6/scripts/default-test.js +185 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/normal.json +30 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/relaxed.json +21 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/strict.json +29 -0
- package/typescript/copy-overwrite/.github/workflows/build.yml +72 -0
- package/typescript/copy-overwrite/.github/workflows/ci.yml +49 -0
- package/typescript/copy-overwrite/.github/workflows/claude.yml +51 -0
- package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +113 -0
- package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +195 -0
- package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +267 -0
- package/typescript/copy-overwrite/.github/workflows/deploy.yml +228 -0
- package/typescript/copy-overwrite/.github/workflows/k6-load-test-README.md +230 -0
- package/typescript/copy-overwrite/.github/workflows/lighthouse.yml +68 -0
- package/typescript/copy-overwrite/.github/workflows/load-test.yml +282 -0
- package/typescript/copy-overwrite/.github/workflows/quality.yml +1737 -0
- package/typescript/copy-overwrite/.github/workflows/release.yml +1599 -0
- package/typescript/copy-overwrite/.gitleaksignore +28 -0
- package/typescript/copy-overwrite/.nvmrc +1 -0
- package/typescript/copy-overwrite/.prettierignore +23 -0
- package/typescript/copy-overwrite/.prettierrc.json +22 -0
- package/typescript/copy-overwrite/.versionrc +42 -0
- package/typescript/copy-overwrite/.yamllint +20 -0
- package/typescript/copy-overwrite/commitlint.config.js +11 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +149 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +23 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +10 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
- package/typescript/copy-overwrite/eslint.config.mjs +390 -0
- package/typescript/copy-overwrite/eslint.ignore.config.json +57 -0
- package/typescript/copy-overwrite/eslint.thresholds.config.json +5 -0
- package/typescript/github-rulesets/base.json +106 -0
- package/typescript/merge/.claude/settings.json +28 -0
- package/typescript/merge/package.json +71 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-philosophy
|
|
3
|
+
description: Enforces immutable coding principles, function structure ordering, functional programming patterns, TDD, clean deletion, and YAGNI+SOLID+DRY+KISS principles for this codebase. This skill should be used when writing or reviewing TypeScript/React code in this project, particularly when creating hooks, utility functions, or components. Use this skill to ensure code follows the established patterns for immutability, proper ordering of statements, functional transformations, test-driven development, and simplicity (preferring Occam's Razor/KISS when principles conflict).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Coding Philosophy
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
This skill enforces the core coding philosophy for this project: **immutability**, **predictable structure**, **functional transformations**, **test-driven development**, **clean deletion**, and **simplicity**. All code should follow these principles to maintain consistency, testability, and clarity.
|
|
11
|
+
|
|
12
|
+
## Guiding Principles: YAGNI + SOLID + DRY + KISS
|
|
13
|
+
|
|
14
|
+
Follow these software engineering principles, **deferring to Occam's Razor/KISS whenever principles conflict**:
|
|
15
|
+
|
|
16
|
+
### KISS (Keep It Simple, Stupid) - The Tiebreaker
|
|
17
|
+
|
|
18
|
+
When principles conflict, **always choose the simpler solution**. Occam's Razor applies to code: the simplest solution that works is usually correct.
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// KISS: Simple direct approach
|
|
22
|
+
const isAdmin = user.role === "admin";
|
|
23
|
+
|
|
24
|
+
// Over-engineered: Abstraction without value
|
|
25
|
+
const isAdmin = RoleChecker.getInstance().checkRole(user, RoleTypes.ADMIN);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### YAGNI (You Ain't Gonna Need It)
|
|
29
|
+
|
|
30
|
+
Don't build features, abstractions, or flexibility you don't need **right now**.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Correct: Solve today's problem
|
|
34
|
+
const formatDate = (date: Date) => date.toISOString().split("T")[0];
|
|
35
|
+
|
|
36
|
+
// Wrong: Building for hypothetical future needs
|
|
37
|
+
const formatDate = (date: Date, format?: string, locale?: string, timezone?: string) => {
|
|
38
|
+
// 50 lines handling cases that may never be used
|
|
39
|
+
};
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### DRY (Don't Repeat Yourself) - With KISS Constraint
|
|
43
|
+
|
|
44
|
+
Extract duplication only when:
|
|
45
|
+
1. The same logic appears **3+ times**
|
|
46
|
+
2. The abstraction is **simpler** than the duplication
|
|
47
|
+
3. The extracted code has a **clear single purpose**
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// DRY + KISS: Extract when clearly beneficial
|
|
51
|
+
const formatPlayerName = (first: string, last: string) => `${first} ${last}`;
|
|
52
|
+
|
|
53
|
+
// Anti-pattern: Premature abstraction for 2 usages
|
|
54
|
+
// Keep inline if simpler and only used twice
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### SOLID Principles - Applied Pragmatically
|
|
58
|
+
|
|
59
|
+
Apply SOLID when it **reduces complexity**, not dogmatically:
|
|
60
|
+
|
|
61
|
+
| Principle | Apply When | Skip When |
|
|
62
|
+
| ------------------------- | --------------------------------------------- | --------------------------------------- |
|
|
63
|
+
| **S**ingle Responsibility | Function does 2+ unrelated things | Splitting adds complexity |
|
|
64
|
+
| **O**pen/Closed | Extension points have clear use cases | No foreseeable extensions |
|
|
65
|
+
| **L**iskov Substitution | Using inheritance hierarchies | Using composition (preferred) |
|
|
66
|
+
| **I**nterface Segregation | Consumers need different subsets | Interface is already small |
|
|
67
|
+
| **D**ependency Inversion | Testing requires mocking external services | Direct dependency is simpler |
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// Good SRP: Each function has one job
|
|
71
|
+
const validateEmail = (email: string) => EMAIL_REGEX.test(email);
|
|
72
|
+
const formatEmail = (email: string) => email.toLowerCase().trim();
|
|
73
|
+
|
|
74
|
+
// Over-applied SRP: Don't split a simple 3-line function into 3 files
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Decision Framework
|
|
78
|
+
|
|
79
|
+
When unsure, ask in order:
|
|
80
|
+
1. **Do I need this now?** (YAGNI) → If no, don't build it
|
|
81
|
+
2. **Is there a simpler way?** (KISS) → Choose the simpler option
|
|
82
|
+
3. **Am I repeating myself 3+ times?** (DRY) → Extract if the abstraction is simpler
|
|
83
|
+
4. **Does this function do one thing?** (SOLID-SRP) → Split only if clearer
|
|
84
|
+
|
|
85
|
+
## Core Principles
|
|
86
|
+
|
|
87
|
+
### 1. Immutability First
|
|
88
|
+
|
|
89
|
+
Never mutate data. Always create new references.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// Correct - spread creates new object
|
|
93
|
+
const updated = { ...user, name: "New Name" };
|
|
94
|
+
|
|
95
|
+
// Incorrect - mutation
|
|
96
|
+
user.name = "New Name";
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 2. Function Structure Ordering
|
|
100
|
+
|
|
101
|
+
All functions, hooks, and components follow a strict ordering:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
1. Variable definitions and derived state (const, useState, useMemo, useCallback)
|
|
105
|
+
2. Side effects (useEffect, function calls with no return value)
|
|
106
|
+
3. Return statement
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. Functional Transformations
|
|
110
|
+
|
|
111
|
+
Use `map`, `filter`, `reduce` instead of imperative loops and mutations.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// Correct - functional transformation
|
|
115
|
+
const names = users.map(u => u.name);
|
|
116
|
+
|
|
117
|
+
// Incorrect - imperative mutation
|
|
118
|
+
const names = [];
|
|
119
|
+
users.forEach(u => names.push(u.name));
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 4. Test-Driven Development (TDD)
|
|
123
|
+
|
|
124
|
+
**Always write failing tests before implementation code.** This is mandatory, not optional.
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
TDD Cycle:
|
|
128
|
+
1. RED: Write a failing test that defines expected behavior
|
|
129
|
+
2. GREEN: Write the minimum code to make the test pass
|
|
130
|
+
3. REFACTOR: Clean up while keeping tests green
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// Step 1: Write the failing test FIRST
|
|
135
|
+
describe("formatPlayerName", () => {
|
|
136
|
+
it("should format first and last name", () => {
|
|
137
|
+
expect(formatPlayerName("John", "Doe")).toBe("John Doe");
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("should handle empty last name", () => {
|
|
141
|
+
expect(formatPlayerName("John", "")).toBe("John");
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Step 2: THEN write implementation to make tests pass
|
|
146
|
+
const formatPlayerName = (first: string, last: string): string =>
|
|
147
|
+
last ? `${first} ${last}` : first;
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**TDD is non-negotiable because it:**
|
|
151
|
+
- Forces you to think about the API before implementation
|
|
152
|
+
- Ensures every feature has test coverage
|
|
153
|
+
- Prevents over-engineering (you only write what's needed to pass tests)
|
|
154
|
+
- Documents expected behavior
|
|
155
|
+
|
|
156
|
+
### 5. Clean Deletion
|
|
157
|
+
|
|
158
|
+
**Delete old code completely.** No deprecation warnings, migration shims, or backward-compatibility layers unless explicitly requested.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
// Correct: Remove the old code entirely
|
|
162
|
+
// (Old function is gone, new function exists)
|
|
163
|
+
const calculateScore = (player: Player): number => player.stats.overall;
|
|
164
|
+
|
|
165
|
+
// Wrong: Keeping deprecated versions around
|
|
166
|
+
/** @deprecated Use calculateScore instead */
|
|
167
|
+
const getPlayerScore = (player: Player): number => calculateScore(player);
|
|
168
|
+
const calculateScoreV2 = (player: Player): number => player.stats.overall;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Clean deletion rules:**
|
|
172
|
+
- When replacing code, delete the old version completely
|
|
173
|
+
- Never create `V2`, `New`, or `Old` suffixed functions/variables
|
|
174
|
+
- Never add `@deprecated` comments - just remove the code
|
|
175
|
+
- Never write migration code unless explicitly asked
|
|
176
|
+
- Trust git history for recovery if needed
|
|
177
|
+
|
|
178
|
+
**Why clean deletion:**
|
|
179
|
+
- Reduces cognitive load (one way to do things)
|
|
180
|
+
- Prevents confusion about which version to use
|
|
181
|
+
- Keeps bundle size small
|
|
182
|
+
- YAGNI: If no one is using it, delete it
|
|
183
|
+
|
|
184
|
+
## Detailed Guidelines
|
|
185
|
+
|
|
186
|
+
For comprehensive examples and patterns, see the reference files:
|
|
187
|
+
|
|
188
|
+
- **[references/immutable-patterns.md](references/immutable-patterns.md)** - Detailed immutable patterns with reduce, spread, and functional transformations
|
|
189
|
+
- **[references/function-structure.md](references/function-structure.md)** - Function ordering rules and examples for hooks, utilities, and components
|
|
190
|
+
|
|
191
|
+
## Quick Reference
|
|
192
|
+
|
|
193
|
+
### Variable Declaration
|
|
194
|
+
|
|
195
|
+
| Pattern | Status | Example |
|
|
196
|
+
| ------- | --------- | ----------------------------- |
|
|
197
|
+
| `const` | Required | `const value = calculate();` |
|
|
198
|
+
| `let` | Forbidden | Use ternary or reduce instead |
|
|
199
|
+
| `var` | Forbidden | Never use |
|
|
200
|
+
|
|
201
|
+
### Array Operations
|
|
202
|
+
|
|
203
|
+
| Instead of | Use |
|
|
204
|
+
| ----------------------- | -------------------------------------------- |
|
|
205
|
+
| `arr.push(item)` | `[...arr, item]` |
|
|
206
|
+
| `arr.pop()` | `arr.slice(0, -1)` |
|
|
207
|
+
| `arr.splice(i, 1)` | `arr.filter((_, idx) => idx !== i)` |
|
|
208
|
+
| `arr.sort()` | `[...arr].sort()` |
|
|
209
|
+
| `arr[i] = value` | `arr.map((v, idx) => idx === i ? value : v)` |
|
|
210
|
+
| `forEach` with mutation | `reduce` or `map` |
|
|
211
|
+
|
|
212
|
+
### Object Operations
|
|
213
|
+
|
|
214
|
+
| Instead of | Use |
|
|
215
|
+
| ------------------------- | ----------------------------- |
|
|
216
|
+
| `obj.key = value` | `{ ...obj, key: value }` |
|
|
217
|
+
| `delete obj.key` | `({ key: _, ...rest } = obj)` |
|
|
218
|
+
| `Object.assign(obj, ...)` | `{ ...obj, ...other }` |
|
|
219
|
+
|
|
220
|
+
### Building Lookup Objects
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// Correct - reduce with spread
|
|
224
|
+
const lookup = items.reduce(
|
|
225
|
+
(acc, item) => ({ ...acc, [item.id]: item }),
|
|
226
|
+
{} as Record<string, Item>
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
// Incorrect - forEach with Map.set
|
|
230
|
+
const lookup = new Map();
|
|
231
|
+
items.forEach(item => lookup.set(item.id, item));
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Conditional Values
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// Correct - ternary expression
|
|
238
|
+
const status = isComplete ? "done" : "pending";
|
|
239
|
+
|
|
240
|
+
// Incorrect - let with reassignment
|
|
241
|
+
let status = "pending";
|
|
242
|
+
if (isComplete) {
|
|
243
|
+
status = "done";
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Hook Structure Example
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
export const usePlayerData = (playerId: string) => {
|
|
251
|
+
// 1. VARIABLES & STATE (first)
|
|
252
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
253
|
+
const { data } = useQuery(GetPlayerDocument, { variables: { playerId } });
|
|
254
|
+
|
|
255
|
+
const playerName = useMemo(() => data?.player?.name ?? "Unknown", [data]);
|
|
256
|
+
|
|
257
|
+
const handleRefresh = useCallback(() => {
|
|
258
|
+
refetch();
|
|
259
|
+
}, [refetch]);
|
|
260
|
+
|
|
261
|
+
// 2. SIDE EFFECTS (second)
|
|
262
|
+
useEffect(() => {
|
|
263
|
+
console.log("Player loaded:", playerName);
|
|
264
|
+
}, [playerName]);
|
|
265
|
+
|
|
266
|
+
// 3. RETURN (last)
|
|
267
|
+
return { playerName, isLoading, handleRefresh };
|
|
268
|
+
};
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Container Component Example
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
const PlayerCardContainer: React.FC<Props> = ({ playerId }) => {
|
|
275
|
+
// 1. VARIABLES & STATE
|
|
276
|
+
const { data, loading } = useQuery(GetPlayerDocument, { variables: { playerId } });
|
|
277
|
+
const { colors } = useTheme();
|
|
278
|
+
|
|
279
|
+
const formattedStats = useMemo(
|
|
280
|
+
() => data?.stats?.map(s => ({ ...s, display: formatStat(s) })) ?? [],
|
|
281
|
+
[data?.stats]
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
const handlePress = useCallback(() => {
|
|
285
|
+
router.push(`/players/${playerId}`);
|
|
286
|
+
}, [playerId]);
|
|
287
|
+
|
|
288
|
+
// 2. SIDE EFFECTS (none in this example)
|
|
289
|
+
|
|
290
|
+
// 3. RETURN
|
|
291
|
+
return (
|
|
292
|
+
<PlayerCardView
|
|
293
|
+
stats={formattedStats}
|
|
294
|
+
colors={colors}
|
|
295
|
+
loading={loading}
|
|
296
|
+
onPress={handlePress}
|
|
297
|
+
/>
|
|
298
|
+
);
|
|
299
|
+
};
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Utility Function Example
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
export const calculateTeamRankings = (
|
|
306
|
+
players: readonly Player[]
|
|
307
|
+
): readonly TeamRanking[] => {
|
|
308
|
+
// 1. VARIABLES & DERIVED VALUES
|
|
309
|
+
const validPlayers = players.filter(p => p.team && p.score != null);
|
|
310
|
+
|
|
311
|
+
const teamScores = validPlayers.reduce(
|
|
312
|
+
(acc, player) => ({
|
|
313
|
+
...acc,
|
|
314
|
+
[player.team.id]: {
|
|
315
|
+
teamId: player.team.id,
|
|
316
|
+
totalScore: (acc[player.team.id]?.totalScore ?? 0) + player.score,
|
|
317
|
+
count: (acc[player.team.id]?.count ?? 0) + 1,
|
|
318
|
+
},
|
|
319
|
+
}),
|
|
320
|
+
{} as Record<string, { teamId: string; totalScore: number; count: number }>
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
const rankings = Object.values(teamScores).map(t => ({
|
|
324
|
+
teamId: t.teamId,
|
|
325
|
+
avgScore: t.totalScore / t.count,
|
|
326
|
+
}));
|
|
327
|
+
|
|
328
|
+
const sorted = [...rankings].sort((a, b) => b.avgScore - a.avgScore);
|
|
329
|
+
|
|
330
|
+
// 2. NO SIDE EFFECTS IN PURE FUNCTIONS
|
|
331
|
+
|
|
332
|
+
// 3. RETURN
|
|
333
|
+
return sorted;
|
|
334
|
+
};
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Anti-Patterns to Avoid
|
|
338
|
+
|
|
339
|
+
### Never use `let` for conditional assignment
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
// Wrong
|
|
343
|
+
let result;
|
|
344
|
+
if (condition) {
|
|
345
|
+
result = valueA;
|
|
346
|
+
} else {
|
|
347
|
+
result = valueB;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Correct
|
|
351
|
+
const result = condition ? valueA : valueB;
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Never mutate arrays
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
// Wrong
|
|
358
|
+
const items = [];
|
|
359
|
+
data.forEach(d => items.push(transform(d)));
|
|
360
|
+
|
|
361
|
+
// Correct
|
|
362
|
+
const items = data.map(d => transform(d));
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Never use Map when Record suffices
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
// Wrong
|
|
369
|
+
const lookup = new Map<string, User>();
|
|
370
|
+
users.forEach(u => lookup.set(u.id, u));
|
|
371
|
+
const user = lookup.get(userId);
|
|
372
|
+
|
|
373
|
+
// Correct
|
|
374
|
+
const lookup = users.reduce(
|
|
375
|
+
(acc, u) => ({ ...acc, [u.id]: u }),
|
|
376
|
+
{} as Record<string, User>
|
|
377
|
+
);
|
|
378
|
+
const user = lookup[userId];
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Never sort in place
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
// Wrong - mutates original
|
|
385
|
+
const sorted = items.sort((a, b) => a.value - b.value);
|
|
386
|
+
|
|
387
|
+
// Correct - creates new array
|
|
388
|
+
const sorted = [...items].sort((a, b) => a.value - b.value);
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Never place useEffect before variable definitions
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
// Wrong
|
|
395
|
+
useEffect(() => {
|
|
396
|
+
/* ... */
|
|
397
|
+
}, [value]);
|
|
398
|
+
const value = useMemo(() => calculate(), [dep]);
|
|
399
|
+
|
|
400
|
+
// Correct
|
|
401
|
+
const value = useMemo(() => calculate(), [dep]);
|
|
402
|
+
useEffect(() => {
|
|
403
|
+
/* ... */
|
|
404
|
+
}, [value]);
|
|
405
|
+
```
|