@codyswann/lisa 1.0.0 → 1.0.5
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/README.md +244 -36
- package/all/copy-overwrite/.claude/README.md +1 -3
- package/all/copy-overwrite/.claude/REFERENCE.md +519 -0
- package/all/copy-overwrite/.claude/agents/skill-evaluator.md +7 -7
- package/all/copy-overwrite/.claude/agents/test-coverage-agent.md +17 -0
- package/all/copy-overwrite/.claude/commands/git/commit.md +9 -5
- package/all/copy-overwrite/.claude/commands/git/submit-pr.md +1 -1
- package/all/copy-overwrite/.claude/commands/lisa/review-implementation.md +209 -0
- package/all/copy-overwrite/.claude/commands/project/add-test-coverage.md +58 -0
- package/all/copy-overwrite/.claude/commands/project/archive.md +1 -1
- package/all/copy-overwrite/.claude/commands/project/complete-task.md +53 -1
- package/all/copy-overwrite/.claude/commands/project/debrief.md +12 -23
- package/all/copy-overwrite/.claude/commands/project/execute.md +33 -77
- package/all/copy-overwrite/.claude/commands/project/fix-linter-error.md +87 -0
- package/all/copy-overwrite/.claude/commands/project/implement.md +24 -28
- package/all/copy-overwrite/.claude/commands/project/lower-code-complexity.md +30 -55
- package/all/copy-overwrite/.claude/commands/project/plan.md +87 -242
- package/all/copy-overwrite/.claude/commands/project/reduce-max-lines-per-function.md +76 -0
- package/all/copy-overwrite/.claude/commands/project/reduce-max-lines.md +75 -0
- package/all/copy-overwrite/.claude/commands/project/research.md +86 -188
- package/all/copy-overwrite/.claude/commands/project/review.md +19 -38
- package/all/copy-overwrite/.claude/commands/project/setup.md +1 -1
- package/all/copy-overwrite/.claude/commands/project/verify.md +62 -25
- package/all/copy-overwrite/.claude/commands/pull-request/review.md +25 -7
- package/all/copy-overwrite/.claude/commands/tasks/load.md +63 -0
- package/all/copy-overwrite/.claude/commands/tasks/sync.md +84 -0
- package/all/copy-overwrite/.claude/hooks/README.md +75 -0
- package/all/copy-overwrite/.claude/hooks/check-tired-boss.sh +61 -0
- package/all/copy-overwrite/.claude/hooks/debug-hook.sh +47 -0
- package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +2 -0
- package/all/copy-overwrite/.claude/hooks/sync-tasks.sh +95 -0
- package/all/copy-overwrite/.claude/{skills/coding-philosophy/SKILL.md → rules/coding-philosophy.md} +93 -70
- package/all/copy-overwrite/.claude/settings.json +35 -14
- package/all/copy-overwrite/.claude/skills/prompt-complexity-scorer/SKILL.md +41 -9
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +2 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +2 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +2 -0
- package/all/copy-overwrite/.safety-net.json +25 -0
- package/all/copy-overwrite/CLAUDE.md +8 -30
- package/all/copy-overwrite/HUMAN.md +517 -17
- package/all/create-only/.claude/rules/PROJECT_RULES.md +9 -0
- package/all/create-only/scripts/setup-deploy-key.sh +190 -0
- package/all/deletions.json +5 -0
- package/cdk/copy-overwrite/.github/workflows/ci.yml +142 -0
- package/cdk/copy-overwrite/.github/workflows/deploy.yml +59 -0
- package/cdk/copy-overwrite/eslint.cdk.ts +175 -0
- package/cdk/copy-overwrite/eslint.config.ts +51 -0
- package/cdk/copy-overwrite/eslint.slow.config.ts +80 -0
- package/cdk/copy-overwrite/knip.json +53 -0
- package/cdk/copy-overwrite/tsconfig.eslint.json +11 -0
- package/cdk/merge/package.json +17 -1
- package/dist/cli/index.d.ts +3 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +83 -64
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/prompts.d.ts +17 -3
- package/dist/cli/prompts.d.ts.map +1 -1
- package/dist/cli/prompts.js +52 -16
- package/dist/cli/prompts.js.map +1 -1
- package/dist/core/config.d.ts +13 -4
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +17 -9
- package/dist/core/config.js.map +1 -1
- package/dist/core/git-service.d.ts +40 -0
- package/dist/core/git-service.d.ts.map +1 -0
- package/dist/core/git-service.js +52 -0
- package/dist/core/git-service.js.map +1 -0
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +3 -3
- package/dist/core/lisa.d.ts +124 -7
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +423 -221
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/manifest.d.ts +5 -1
- package/dist/core/manifest.d.ts.map +1 -1
- package/dist/core/manifest.js +22 -16
- package/dist/core/manifest.js.map +1 -1
- package/dist/detection/detector.interface.d.ts +1 -1
- package/dist/detection/detectors/cdk.d.ts +6 -1
- package/dist/detection/detectors/cdk.d.ts.map +1 -1
- package/dist/detection/detectors/cdk.js +16 -8
- package/dist/detection/detectors/cdk.js.map +1 -1
- package/dist/detection/detectors/expo.d.ts +6 -1
- package/dist/detection/detectors/expo.d.ts.map +1 -1
- package/dist/detection/detectors/expo.js +13 -8
- package/dist/detection/detectors/expo.js.map +1 -1
- package/dist/detection/detectors/nestjs.d.ts +7 -2
- package/dist/detection/detectors/nestjs.d.ts.map +1 -1
- package/dist/detection/detectors/nestjs.js +17 -9
- package/dist/detection/detectors/nestjs.js.map +1 -1
- package/dist/detection/detectors/npm-package.d.ts +6 -1
- package/dist/detection/detectors/npm-package.d.ts.map +1 -1
- package/dist/detection/detectors/npm-package.js +9 -4
- package/dist/detection/detectors/npm-package.js.map +1 -1
- package/dist/detection/detectors/typescript.d.ts +6 -1
- package/dist/detection/detectors/typescript.d.ts.map +1 -1
- package/dist/detection/detectors/typescript.js +12 -7
- package/dist/detection/detectors/typescript.js.map +1 -1
- package/dist/detection/index.d.ts +13 -3
- package/dist/detection/index.d.ts.map +1 -1
- package/dist/detection/index.js +17 -7
- package/dist/detection/index.js.map +1 -1
- package/dist/errors/index.d.ts +66 -2
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +89 -17
- package/dist/errors/index.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/logging/console-logger.d.ts +21 -1
- package/dist/logging/console-logger.d.ts.map +1 -1
- package/dist/logging/console-logger.js +26 -6
- package/dist/logging/console-logger.js.map +1 -1
- package/dist/logging/index.d.ts +3 -3
- package/dist/logging/index.js +2 -2
- package/dist/logging/logger.interface.d.ts +1 -1
- package/dist/logging/silent-logger.d.ts +21 -1
- package/dist/logging/silent-logger.d.ts.map +1 -1
- package/dist/logging/silent-logger.js +20 -0
- package/dist/logging/silent-logger.js.map +1 -1
- package/dist/strategies/copy-contents.d.ts +47 -6
- package/dist/strategies/copy-contents.d.ts.map +1 -1
- package/dist/strategies/copy-contents.js +99 -49
- package/dist/strategies/copy-contents.js.map +1 -1
- package/dist/strategies/copy-overwrite.d.ts +10 -2
- package/dist/strategies/copy-overwrite.d.ts.map +1 -1
- package/dist/strategies/copy-overwrite.js +17 -9
- package/dist/strategies/copy-overwrite.js.map +1 -1
- package/dist/strategies/create-only.d.ts +10 -2
- package/dist/strategies/create-only.d.ts.map +1 -1
- package/dist/strategies/create-only.js +14 -6
- package/dist/strategies/create-only.js.map +1 -1
- package/dist/strategies/index.d.ts +17 -7
- package/dist/strategies/index.d.ts.map +1 -1
- package/dist/strategies/index.js +19 -9
- package/dist/strategies/index.js.map +1 -1
- package/dist/strategies/merge.d.ts +10 -2
- package/dist/strategies/merge.d.ts.map +1 -1
- package/dist/strategies/merge.js +21 -21
- package/dist/strategies/merge.js.map +1 -1
- package/dist/strategies/strategy.interface.d.ts +1 -1
- package/dist/strategies/strategy.interface.d.ts.map +1 -1
- package/dist/transaction/backup.d.ts +15 -1
- package/dist/transaction/backup.d.ts.map +1 -1
- package/dist/transaction/backup.js +47 -12
- package/dist/transaction/backup.js.map +1 -1
- package/dist/transaction/index.d.ts +3 -3
- package/dist/transaction/index.js +2 -2
- package/dist/transaction/transaction.d.ts +25 -2
- package/dist/transaction/transaction.d.ts.map +1 -1
- package/dist/transaction/transaction.js +25 -2
- package/dist/transaction/transaction.js.map +1 -1
- package/dist/utils/file-operations.d.ts +21 -0
- package/dist/utils/file-operations.d.ts.map +1 -1
- package/dist/utils/file-operations.js +48 -12
- package/dist/utils/file-operations.js.map +1 -1
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +3 -3
- package/dist/utils/json-utils.d.ts +12 -0
- package/dist/utils/json-utils.d.ts.map +1 -1
- package/dist/utils/json-utils.js +17 -5
- package/dist/utils/json-utils.js.map +1 -1
- package/dist/utils/path-utils.d.ts +11 -0
- package/dist/utils/path-utils.d.ts.map +1 -1
- package/dist/utils/path-utils.js +12 -1
- package/dist/utils/path-utils.js.map +1 -1
- package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +5 -0
- package/eslint-plugin-code-organization/index.js +5 -0
- package/eslint-plugin-code-organization/rules/enforce-statement-order.js +5 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +2 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +2 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +2 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +2 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +2 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +2 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +2 -41
- package/{typescript → expo}/copy-overwrite/.github/workflows/build.yml +3 -0
- package/expo/copy-overwrite/.github/workflows/ci.yml +36 -0
- package/{typescript → expo}/copy-overwrite/.github/workflows/deploy.yml +22 -26
- package/{typescript → expo}/copy-overwrite/.github/workflows/lighthouse.yml +4 -1
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +5 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +5 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +5 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +5 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +5 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +6 -1
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +5 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +5 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +0 -68
- package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +5 -3
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +5 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +5 -0
- package/expo/copy-overwrite/eslint.config.ts +53 -0
- package/expo/copy-overwrite/eslint.expo.ts +330 -0
- package/expo/copy-overwrite/eslint.slow.config.ts +86 -0
- package/expo/copy-overwrite/knip.json +132 -0
- package/expo/copy-overwrite/lighthouserc.js +27 -0
- package/expo/copy-overwrite/tsconfig.eslint.json +25 -0
- package/expo/create-only/lighthouserc-config.json +6 -1
- package/expo/merge/package.json +16 -3
- package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +1 -1
- package/{typescript → nestjs}/copy-overwrite/.github/k6/README.md +2 -2
- package/{typescript → nestjs}/copy-overwrite/.github/k6/examples/customer-deploy-integration.yml +3 -0
- package/{typescript → nestjs}/copy-overwrite/.github/k6/examples/data-driven-test.js +5 -0
- package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/load.js +6 -2
- package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/smoke.js +5 -0
- package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/soak.js +5 -0
- package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/spike.js +5 -0
- package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/stress.js +5 -0
- package/{typescript → nestjs}/copy-overwrite/.github/k6/scripts/api-test.js +5 -0
- package/{typescript → nestjs}/copy-overwrite/.github/k6/scripts/default-test.js +5 -0
- package/nestjs/copy-overwrite/.github/workflows/ci.yml +29 -0
- package/nestjs/copy-overwrite/.github/workflows/deploy.yml +291 -0
- package/{typescript → nestjs}/copy-overwrite/.github/workflows/load-test.yml +3 -0
- package/nestjs/copy-overwrite/eslint.config.ts +53 -0
- package/nestjs/copy-overwrite/eslint.nestjs.ts +178 -0
- package/nestjs/merge/package.json +11 -3
- package/package.json +34 -40
- package/typescript/copy-contents/.husky/pre-commit +1 -1
- package/typescript/copy-contents/.husky/pre-push +99 -118
- package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +2 -0
- package/typescript/copy-overwrite/.claude/hooks/install_pkgs.sh +3 -11
- package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +2 -0
- package/typescript/copy-overwrite/.claude/hooks/sg-scan-on-edit.sh +68 -0
- package/typescript/copy-overwrite/.claude/settings.json +79 -0
- package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +44 -0
- package/typescript/copy-overwrite/.github/README.md +49 -1
- package/typescript/copy-overwrite/.github/dependabot.yml +3 -0
- package/typescript/copy-overwrite/.github/workflows/ci.yml +7 -29
- package/typescript/copy-overwrite/.github/workflows/claude.yml +3 -0
- package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +6 -4
- package/typescript/copy-overwrite/.github/workflows/create-issue-on-failure.yml +176 -0
- package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +3 -1
- package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +3 -1
- package/typescript/copy-overwrite/.github/workflows/lint-slow.yml +40 -0
- package/typescript/copy-overwrite/.github/workflows/quality.yml +151 -38
- package/typescript/copy-overwrite/.github/workflows/release.yml +3 -0
- package/typescript/copy-overwrite/.gitleaksignore +3 -0
- package/typescript/copy-overwrite/.lintstagedrc.json +6 -0
- package/typescript/copy-overwrite/.prettierignore +2 -1
- package/typescript/copy-overwrite/.yamllint +2 -0
- package/typescript/copy-overwrite/ast-grep/rule-tests/.gitkeep +3 -0
- package/typescript/copy-overwrite/ast-grep/rules/.gitkeep +3 -0
- package/typescript/copy-overwrite/ast-grep/utils/.gitkeep +3 -0
- package/typescript/copy-overwrite/{commitlint.config.js → commitlint.config.cjs} +5 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +5 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +5 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +5 -0
- package/typescript/copy-overwrite/eslint.base.ts +430 -0
- package/typescript/copy-overwrite/eslint.config.ts +52 -0
- package/typescript/copy-overwrite/eslint.ignore.config.json +19 -2
- package/typescript/copy-overwrite/eslint.slow.config.ts +69 -0
- package/typescript/copy-overwrite/eslint.typescript.ts +142 -0
- package/typescript/copy-overwrite/knip.json +64 -0
- package/typescript/copy-overwrite/sgconfig.yml +11 -0
- package/typescript/copy-overwrite/tsconfig.eslint.json +9 -0
- package/typescript/create-only/eslint.config.local.ts +24 -0
- package/typescript/{copy-overwrite/eslint.thresholds.config.json → create-only/eslint.thresholds.json} +1 -1
- package/typescript/github-rulesets/base.json +2 -75
- package/typescript/merge/.claude/settings.json +160 -0
- package/typescript/merge/package.json +35 -34
- package/all/copy-overwrite/.claude/commands/rules/format-md.md +0 -72
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md +0 -416
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/immutable-patterns.md +0 -316
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-inline-styles.js +0 -73
- package/expo/copy-overwrite/eslint.config.mjs +0 -560
- package/lisa.sh +0 -35
- package/typescript/copy-overwrite/eslint.config.mjs +0 -390
- /package/{all/create-only/PROJECT_RULES.md → cdk/copy-overwrite/.github/workflows/.keep} +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/BROWSER_TESTING_NOTE.md +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/INTEGRATION_GUIDE.md +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/SCENARIO_SELECTION_GUIDE.md +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/load.json +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/smoke.json +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/soak.json +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/spike.json +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/stress.json +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/thresholds/normal.json +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/thresholds/relaxed.json +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/k6/thresholds/strict.json +0 -0
- /package/{typescript → nestjs}/copy-overwrite/.github/workflows/k6-load-test-README.md +0 -0
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Format any markdown file according to brief.md standard template"
|
|
3
|
-
argument-hint: "[markdown-file-path]"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Format Markdown File
|
|
7
|
-
|
|
8
|
-
Format any markdown file according to the brief.md standard template structure. Provide the markdown file path as argument.
|
|
9
|
-
|
|
10
|
-
## Usage
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
/format-md path/to/file.md
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Standard Template Format
|
|
17
|
-
|
|
18
|
-
The command will reorganize markdown content into this standard structure:
|
|
19
|
-
|
|
20
|
-
```markdown
|
|
21
|
-
# [Document Title]
|
|
22
|
-
|
|
23
|
-
## Context
|
|
24
|
-
|
|
25
|
-
[Brief description of the problem or situation]
|
|
26
|
-
|
|
27
|
-
## Goal
|
|
28
|
-
|
|
29
|
-
[What needs to be achieved]
|
|
30
|
-
|
|
31
|
-
## Changes
|
|
32
|
-
|
|
33
|
-
[List of specific changes needed]
|
|
34
|
-
|
|
35
|
-
## Implementation
|
|
36
|
-
|
|
37
|
-
[Detailed steps or technical implementation details]
|
|
38
|
-
|
|
39
|
-
## Notes
|
|
40
|
-
|
|
41
|
-
[Additional information, constraints, or special considerations]
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Instructions
|
|
45
|
-
|
|
46
|
-
1. **Read the file**: Read the markdown file provided in $ARGUMENTS
|
|
47
|
-
2. **Extract title**:
|
|
48
|
-
- Use the first # heading as title
|
|
49
|
-
- If no # title found, create one that fits the content
|
|
50
|
-
3. **Categorize content**:
|
|
51
|
-
- **Context**: Problem/Background/Issue/Current state descriptions
|
|
52
|
-
- **Goal**: Solution/Objective/Purpose/Target statements
|
|
53
|
-
- **Changes**: Requirements/Features/Scope/What's needed items
|
|
54
|
-
- **Implementation**: Steps/Technical details/How to do it/Code blocks
|
|
55
|
-
- **Notes**: Additional info/Warnings/Considerations/Important notes
|
|
56
|
-
4. **Reformat**:
|
|
57
|
-
- Move all content into appropriate standard sections
|
|
58
|
-
- Unify language like English
|
|
59
|
-
- Keep code blocks, lists, and formatting intact
|
|
60
|
-
5. **Write back**: Save the formatted content to the same file
|
|
61
|
-
|
|
62
|
-
## Content Mapping Rules
|
|
63
|
-
|
|
64
|
-
### Headers that map to sections:
|
|
65
|
-
|
|
66
|
-
- **Context**: Context, Problem, Background, Issue, Current State, Description
|
|
67
|
-
- **Goal**: Goal, Objective, Solution, Purpose, Target, What, Solution Overview
|
|
68
|
-
- **Changes**: Changes, Requirements, Features, Scope, Deliverables, What's Needed
|
|
69
|
-
- **Implementation**: Implementation, Steps, Technical Details, How, Approach, Process
|
|
70
|
-
- **Notes**: Notes, Considerations, Constraints, Additional Information, Warnings, Important
|
|
71
|
-
|
|
72
|
-
Execute this formatting process on the markdown file specified in $ARGUMENTS.
|
package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md
DELETED
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
# Function Structure Reference
|
|
2
|
-
|
|
3
|
-
This document defines the required ordering of statements within functions, hooks, and components.
|
|
4
|
-
|
|
5
|
-
## The Three Sections
|
|
6
|
-
|
|
7
|
-
Every function body follows this order:
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
1. VARIABLES & STATE
|
|
11
|
-
- Variable declarations (const)
|
|
12
|
-
- useState hooks
|
|
13
|
-
- useQuery/useMutation hooks
|
|
14
|
-
- useMemo computations
|
|
15
|
-
- useCallback handlers
|
|
16
|
-
- Regular function definitions
|
|
17
|
-
|
|
18
|
-
2. SIDE EFFECTS
|
|
19
|
-
- useEffect hooks
|
|
20
|
-
- Function calls with no return value
|
|
21
|
-
|
|
22
|
-
3. RETURN
|
|
23
|
-
- Return statement (always last)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## ESLint Enforcement
|
|
27
|
-
|
|
28
|
-
This ordering is enforced by the `code-organization/enforce-hook-order` ESLint rule.
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
Expected order: variables/state/functions → useEffects → return statement
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Hook Structure
|
|
35
|
-
|
|
36
|
-
### Complete Example
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
export const usePlayerData = (playerId: string): UsePlayerDataReturn => {
|
|
40
|
-
// ========================================
|
|
41
|
-
// 1. VARIABLES & STATE
|
|
42
|
-
// ========================================
|
|
43
|
-
|
|
44
|
-
// UI state
|
|
45
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
46
|
-
const [searchQuery, setSearchQuery] = useState("");
|
|
47
|
-
|
|
48
|
-
// External hooks
|
|
49
|
-
const { colors } = useTheme();
|
|
50
|
-
const router = useRouter();
|
|
51
|
-
|
|
52
|
-
// GraphQL queries
|
|
53
|
-
const { data, loading, refetch } = useQuery(GetPlayerDocument, {
|
|
54
|
-
variables: { playerId },
|
|
55
|
-
skip: !playerId,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Derived state with useMemo
|
|
59
|
-
const playerName = useMemo(
|
|
60
|
-
() => data?.player?.name ?? "Unknown",
|
|
61
|
-
[data?.player?.name]
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
const filteredStats = useMemo(
|
|
65
|
-
() => data?.stats?.filter(s => s.name.includes(searchQuery)) ?? [],
|
|
66
|
-
[data?.stats, searchQuery]
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
// Handlers with useCallback
|
|
70
|
-
const handleRefresh = useCallback(() => {
|
|
71
|
-
refetch();
|
|
72
|
-
}, [refetch]);
|
|
73
|
-
|
|
74
|
-
const handleNavigate = useCallback(() => {
|
|
75
|
-
if (!playerId) {
|
|
76
|
-
console.error("Cannot navigate: player ID is missing");
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
router.push(`/players/${playerId}/details`);
|
|
80
|
-
}, [playerId, router]);
|
|
81
|
-
|
|
82
|
-
// Helper functions (defined as const arrow functions or regular functions)
|
|
83
|
-
const formatPlayerLabel = (name: string, position: string): string => {
|
|
84
|
-
return `${name} (${position})`;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// ========================================
|
|
88
|
-
// 2. SIDE EFFECTS
|
|
89
|
-
// ========================================
|
|
90
|
-
|
|
91
|
-
useEffect(() => {
|
|
92
|
-
console.log("Player loaded:", playerName);
|
|
93
|
-
}, [playerName]);
|
|
94
|
-
|
|
95
|
-
useEffect(() => {
|
|
96
|
-
if (data?.player) {
|
|
97
|
-
trackAnalytics("player_viewed", { playerId });
|
|
98
|
-
}
|
|
99
|
-
}, [data?.player, playerId]);
|
|
100
|
-
|
|
101
|
-
// ========================================
|
|
102
|
-
// 3. RETURN
|
|
103
|
-
// ========================================
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
playerName,
|
|
107
|
-
filteredStats,
|
|
108
|
-
isExpanded,
|
|
109
|
-
loading,
|
|
110
|
-
handleRefresh,
|
|
111
|
-
handleNavigate,
|
|
112
|
-
formatPlayerLabel,
|
|
113
|
-
setIsExpanded,
|
|
114
|
-
setSearchQuery,
|
|
115
|
-
};
|
|
116
|
-
};
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## Container Component Structure
|
|
120
|
-
|
|
121
|
-
### Complete Example
|
|
122
|
-
|
|
123
|
-
```typescript
|
|
124
|
-
const PlayerCardContainer: React.FC<PlayerCardContainerProps> = ({
|
|
125
|
-
playerId,
|
|
126
|
-
onPress,
|
|
127
|
-
showDetails = false,
|
|
128
|
-
}) => {
|
|
129
|
-
// ========================================
|
|
130
|
-
// 1. VARIABLES & STATE
|
|
131
|
-
// ========================================
|
|
132
|
-
|
|
133
|
-
// Theme and styling
|
|
134
|
-
const { colors } = useTheme();
|
|
135
|
-
const { width } = useWindowDimensions();
|
|
136
|
-
const isDark = useColorScheme() === "dark";
|
|
137
|
-
|
|
138
|
-
// Local state
|
|
139
|
-
const [isHovered, setIsHovered] = useState(false);
|
|
140
|
-
|
|
141
|
-
// Data fetching
|
|
142
|
-
const { data, loading, error } = useQuery(GetPlayerDocument, {
|
|
143
|
-
variables: { playerId },
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Derived values
|
|
147
|
-
const player = data?.player;
|
|
148
|
-
|
|
149
|
-
const cardStyle = useMemo(
|
|
150
|
-
() => ({
|
|
151
|
-
backgroundColor: isDark ? colors.cardDark : colors.cardLight,
|
|
152
|
-
maxWidth: width > 768 ? 400 : width - 32,
|
|
153
|
-
}),
|
|
154
|
-
[isDark, colors, width]
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
const formattedStats = useMemo(
|
|
158
|
-
() => player?.stats?.map(s => ({
|
|
159
|
-
...s,
|
|
160
|
-
displayValue: formatStatValue(s.value, s.type),
|
|
161
|
-
})) ?? [],
|
|
162
|
-
[player?.stats]
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
// Handlers
|
|
166
|
-
const handlePress = useCallback(() => {
|
|
167
|
-
if (!playerId) {
|
|
168
|
-
console.error("Cannot navigate: player ID is missing");
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
onPress?.(playerId);
|
|
172
|
-
}, [playerId, onPress]);
|
|
173
|
-
|
|
174
|
-
const handleHoverIn = useCallback(() => {
|
|
175
|
-
setIsHovered(true);
|
|
176
|
-
}, []);
|
|
177
|
-
|
|
178
|
-
const handleHoverOut = useCallback(() => {
|
|
179
|
-
setIsHovered(false);
|
|
180
|
-
}, []);
|
|
181
|
-
|
|
182
|
-
// ========================================
|
|
183
|
-
// 2. SIDE EFFECTS
|
|
184
|
-
// ========================================
|
|
185
|
-
|
|
186
|
-
useEffect(() => {
|
|
187
|
-
if (player) {
|
|
188
|
-
console.log("Player card rendered:", player.name);
|
|
189
|
-
}
|
|
190
|
-
}, [player]);
|
|
191
|
-
|
|
192
|
-
// ========================================
|
|
193
|
-
// 3. RETURN
|
|
194
|
-
// ========================================
|
|
195
|
-
|
|
196
|
-
// Early returns are acceptable after side effects
|
|
197
|
-
if (loading) {
|
|
198
|
-
return <LoadingSkeleton />;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (error) {
|
|
202
|
-
return <ErrorCard message={error.message} />;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return (
|
|
206
|
-
<PlayerCardView
|
|
207
|
-
player={player}
|
|
208
|
-
stats={formattedStats}
|
|
209
|
-
cardStyle={cardStyle}
|
|
210
|
-
isHovered={isHovered}
|
|
211
|
-
showDetails={showDetails}
|
|
212
|
-
onPress={handlePress}
|
|
213
|
-
onHoverIn={handleHoverIn}
|
|
214
|
-
onHoverOut={handleHoverOut}
|
|
215
|
-
/>
|
|
216
|
-
);
|
|
217
|
-
};
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## Utility Function Structure
|
|
221
|
-
|
|
222
|
-
### Pure Function Example
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
export const calculateTeamRankings = (
|
|
226
|
-
players: readonly Player[],
|
|
227
|
-
teamId: string
|
|
228
|
-
): TeamRanking => {
|
|
229
|
-
// ========================================
|
|
230
|
-
// 1. VARIABLES & DERIVED VALUES
|
|
231
|
-
// ========================================
|
|
232
|
-
|
|
233
|
-
const validPlayers = players.filter(p => p.team && p.score != null);
|
|
234
|
-
|
|
235
|
-
const teamScores = validPlayers.reduce(
|
|
236
|
-
(acc, player) => {
|
|
237
|
-
const id = player.team.id;
|
|
238
|
-
const existing = acc[id];
|
|
239
|
-
return {
|
|
240
|
-
...acc,
|
|
241
|
-
[id]: {
|
|
242
|
-
teamId: id,
|
|
243
|
-
totalScore: (existing?.totalScore ?? 0) + player.score,
|
|
244
|
-
count: (existing?.count ?? 0) + 1,
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
},
|
|
248
|
-
{} as Record<string, { teamId: string; totalScore: number; count: number }>
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
const rankings = Object.values(teamScores).map(t => ({
|
|
252
|
-
teamId: t.teamId,
|
|
253
|
-
avgScore: t.totalScore / t.count,
|
|
254
|
-
}));
|
|
255
|
-
|
|
256
|
-
const sorted = [...rankings].sort((a, b) => b.avgScore - a.avgScore);
|
|
257
|
-
|
|
258
|
-
const targetRank = sorted.findIndex(r => r.teamId === teamId) + 1;
|
|
259
|
-
|
|
260
|
-
// ========================================
|
|
261
|
-
// 2. NO SIDE EFFECTS IN PURE FUNCTIONS
|
|
262
|
-
// ========================================
|
|
263
|
-
|
|
264
|
-
// ========================================
|
|
265
|
-
// 3. RETURN
|
|
266
|
-
// ========================================
|
|
267
|
-
|
|
268
|
-
return {
|
|
269
|
-
rank: targetRank || null,
|
|
270
|
-
totalTeams: sorted.length,
|
|
271
|
-
avgScore: teamScores[teamId]?.totalScore / teamScores[teamId]?.count ?? 0,
|
|
272
|
-
};
|
|
273
|
-
};
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
## Helper Function Extraction
|
|
277
|
-
|
|
278
|
-
When reducing cognitive complexity, extract helper functions and place them between types and the main component.
|
|
279
|
-
|
|
280
|
-
### File Structure
|
|
281
|
-
|
|
282
|
-
```typescript
|
|
283
|
-
// ========================================
|
|
284
|
-
// TYPES
|
|
285
|
-
// ========================================
|
|
286
|
-
|
|
287
|
-
interface Props {
|
|
288
|
-
readonly players: readonly Player[];
|
|
289
|
-
readonly isDark: boolean;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// ========================================
|
|
293
|
-
// HELPER FUNCTIONS
|
|
294
|
-
// ========================================
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Renders the loading skeleton state.
|
|
298
|
-
* @param props - Component properties
|
|
299
|
-
* @param props.isDark - Whether dark mode is active
|
|
300
|
-
* @returns Loading skeleton UI
|
|
301
|
-
*/
|
|
302
|
-
function renderLoadingState(props: { readonly isDark: boolean }) {
|
|
303
|
-
const { isDark } = props;
|
|
304
|
-
return <LoadingSkeleton isDark={isDark} />;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Renders the empty state when no players exist.
|
|
309
|
-
* @param props - Component properties
|
|
310
|
-
* @param props.message - Message to display
|
|
311
|
-
* @returns Empty state UI
|
|
312
|
-
*/
|
|
313
|
-
function renderEmptyState(props: { readonly message: string }) {
|
|
314
|
-
const { message } = props;
|
|
315
|
-
return <EmptyState message={message} />;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// ========================================
|
|
319
|
-
// MAIN COMPONENT
|
|
320
|
-
// ========================================
|
|
321
|
-
|
|
322
|
-
export const PlayerListView = memo(function PlayerListView({
|
|
323
|
-
players,
|
|
324
|
-
isDark,
|
|
325
|
-
}: Props) {
|
|
326
|
-
if (!players.length) {
|
|
327
|
-
return renderEmptyState({ message: "No players found" });
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return (
|
|
331
|
-
<Box>
|
|
332
|
-
{players.map(player => (
|
|
333
|
-
<PlayerCard key={player.id} player={player} />
|
|
334
|
-
))}
|
|
335
|
-
</Box>
|
|
336
|
-
);
|
|
337
|
-
});
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
## Common Mistakes
|
|
341
|
-
|
|
342
|
-
### Wrong: useEffect Before useMemo
|
|
343
|
-
|
|
344
|
-
```typescript
|
|
345
|
-
// WRONG
|
|
346
|
-
useEffect(() => {
|
|
347
|
-
console.log("Value:", computedValue);
|
|
348
|
-
}, [computedValue]);
|
|
349
|
-
|
|
350
|
-
const computedValue = useMemo(() => calculate(data), [data]);
|
|
351
|
-
|
|
352
|
-
// CORRECT
|
|
353
|
-
const computedValue = useMemo(() => calculate(data), [data]);
|
|
354
|
-
|
|
355
|
-
useEffect(() => {
|
|
356
|
-
console.log("Value:", computedValue);
|
|
357
|
-
}, [computedValue]);
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
### Wrong: Return Before useEffect
|
|
361
|
-
|
|
362
|
-
```typescript
|
|
363
|
-
// WRONG
|
|
364
|
-
const Component = () => {
|
|
365
|
-
const data = useData();
|
|
366
|
-
|
|
367
|
-
if (!data) {
|
|
368
|
-
return null; // Early return before useEffect!
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
useEffect(() => {
|
|
372
|
-
// This breaks the rules of hooks
|
|
373
|
-
}, []);
|
|
374
|
-
|
|
375
|
-
return <View />;
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
// CORRECT
|
|
379
|
-
const Component = () => {
|
|
380
|
-
const data = useData();
|
|
381
|
-
|
|
382
|
-
useEffect(() => {
|
|
383
|
-
if (data) {
|
|
384
|
-
// Handle data
|
|
385
|
-
}
|
|
386
|
-
}, [data]);
|
|
387
|
-
|
|
388
|
-
if (!data) {
|
|
389
|
-
return null;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
return <View />;
|
|
393
|
-
};
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### Wrong: Handler Definition After useEffect
|
|
397
|
-
|
|
398
|
-
```typescript
|
|
399
|
-
// WRONG
|
|
400
|
-
useEffect(() => {
|
|
401
|
-
handleInit();
|
|
402
|
-
}, [handleInit]);
|
|
403
|
-
|
|
404
|
-
const handleInit = useCallback(() => {
|
|
405
|
-
// ...
|
|
406
|
-
}, []);
|
|
407
|
-
|
|
408
|
-
// CORRECT
|
|
409
|
-
const handleInit = useCallback(() => {
|
|
410
|
-
// ...
|
|
411
|
-
}, []);
|
|
412
|
-
|
|
413
|
-
useEffect(() => {
|
|
414
|
-
handleInit();
|
|
415
|
-
}, [handleInit]);
|
|
416
|
-
```
|