claude-code-starter 0.2.0 → 0.3.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/README.md +24 -10
- package/dist/cli.js +723 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Claude Code Starter
|
|
2
2
|
|
|
3
|
+
[](https://github.com/cassmtnr/claude-code-starter/actions/workflows/pr-check.yml)
|
|
4
|
+
[](https://codecov.io/gh/cassmtnr/claude-code-starter)
|
|
5
|
+
[](https://www.npmjs.com/package/claude-code-starter)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
[](https://bun.sh/)
|
|
9
|
+
|
|
3
10
|
Intelligent CLI that bootstraps Claude Code configurations tailored to your project's tech stack.
|
|
4
11
|
|
|
5
12
|
## Quick Start
|
|
@@ -39,12 +46,13 @@ Based on your stack, creates:
|
|
|
39
46
|
|
|
40
47
|
## Commands
|
|
41
48
|
|
|
42
|
-
| Command | Description
|
|
43
|
-
| ----------------- |
|
|
44
|
-
| `/task <desc>` | Start a new task
|
|
45
|
-
| `/status` | Show current task
|
|
46
|
-
| `/done` | Mark task complete
|
|
47
|
-
| `/analyze <area>` | Deep dive into code
|
|
49
|
+
| Command | Description |
|
|
50
|
+
| ----------------- | ---------------------------------------- |
|
|
51
|
+
| `/task <desc>` | Start a new task |
|
|
52
|
+
| `/status` | Show current task |
|
|
53
|
+
| `/done` | Mark task complete |
|
|
54
|
+
| `/analyze <area>` | Deep dive into code |
|
|
55
|
+
| `/code-review` | Review changes for quality and security |
|
|
48
56
|
|
|
49
57
|
## CLI Options
|
|
50
58
|
|
|
@@ -75,7 +83,7 @@ npx claude-code-starter --help # Show help
|
|
|
75
83
|
✅ Configuration complete! (14 files)
|
|
76
84
|
|
|
77
85
|
Generated for your stack:
|
|
78
|
-
📚
|
|
86
|
+
📚 9 skills (pattern-discovery, iterative-development, security, nextjs-patterns, ...)
|
|
79
87
|
🤖 2 agents (code-reviewer, test-writer)
|
|
80
88
|
📏 2 rules
|
|
81
89
|
```
|
|
@@ -95,15 +103,21 @@ After running, your project will have:
|
|
|
95
103
|
│ ├── task.md
|
|
96
104
|
│ ├── status.md
|
|
97
105
|
│ ├── done.md
|
|
98
|
-
│
|
|
106
|
+
│ ├── analyze.md
|
|
107
|
+
│ └── code-review.md
|
|
99
108
|
├── rules/ # Code style rules
|
|
100
109
|
│ ├── typescript.md # (or python.md, etc.)
|
|
101
110
|
│ └── code-style.md
|
|
102
|
-
├── skills/ #
|
|
111
|
+
├── skills/ # Methodology guides + patterns
|
|
103
112
|
│ ├── pattern-discovery.md
|
|
104
113
|
│ ├── systematic-debugging.md
|
|
105
114
|
│ ├── testing-methodology.md
|
|
106
|
-
│
|
|
115
|
+
│ ├── iterative-development.md
|
|
116
|
+
│ ├── commit-hygiene.md
|
|
117
|
+
│ ├── code-deduplication.md
|
|
118
|
+
│ ├── simplicity-rules.md
|
|
119
|
+
│ ├── security.md
|
|
120
|
+
│ └── nextjs-patterns.md # (framework-specific)
|
|
107
121
|
└── state/
|
|
108
122
|
└── task.md # Current task tracking
|
|
109
123
|
```
|
package/dist/cli.js
CHANGED
|
@@ -539,6 +539,7 @@ function generateClaudeMd(projectInfo) {
|
|
|
539
539
|
sections.push("| `/status` | Show current task state |");
|
|
540
540
|
sections.push("| `/done` | Mark current task complete |");
|
|
541
541
|
sections.push("| `/analyze <area>` | Deep-dive into specific code |");
|
|
542
|
+
sections.push("| `/code-review` | Review changes for quality and security |");
|
|
542
543
|
sections.push("");
|
|
543
544
|
sections.push("## Common Operations");
|
|
544
545
|
sections.push("");
|
|
@@ -553,6 +554,18 @@ function generateClaudeMd(projectInfo) {
|
|
|
553
554
|
sections.push("3. **Test Before Done** - Run tests before marking complete");
|
|
554
555
|
sections.push("4. **Update State** - Keep task.md current as you work");
|
|
555
556
|
sections.push("5. **Match Patterns** - Follow existing code conventions");
|
|
557
|
+
sections.push("6. **TDD Workflow** - Write failing tests first, then implement");
|
|
558
|
+
sections.push("");
|
|
559
|
+
sections.push("## Quality Gates");
|
|
560
|
+
sections.push("");
|
|
561
|
+
sections.push("Enforced constraints for code quality:");
|
|
562
|
+
sections.push("");
|
|
563
|
+
sections.push("| Constraint | Limit | Action |");
|
|
564
|
+
sections.push("|------------|-------|--------|");
|
|
565
|
+
sections.push("| Lines per function | 20 max | Decompose immediately |");
|
|
566
|
+
sections.push("| Parameters per function | 3 max | Use options object |");
|
|
567
|
+
sections.push("| Lines per file | 200 max | Split by responsibility |");
|
|
568
|
+
sections.push("| Test coverage | 80% min | Add tests before merge |");
|
|
556
569
|
sections.push("");
|
|
557
570
|
sections.push("## Skills");
|
|
558
571
|
sections.push("");
|
|
@@ -757,9 +770,16 @@ function generateSettings(stack) {
|
|
|
757
770
|
}
|
|
758
771
|
function getSkillsForStack(stack) {
|
|
759
772
|
const skills = [
|
|
773
|
+
// Core methodology skills
|
|
760
774
|
{ name: "pattern-discovery", description: "Finding codebase patterns" },
|
|
761
775
|
{ name: "systematic-debugging", description: "Debugging approach" },
|
|
762
|
-
{ name: "testing-methodology", description: "Testing strategy" }
|
|
776
|
+
{ name: "testing-methodology", description: "Testing strategy" },
|
|
777
|
+
// Process discipline skills
|
|
778
|
+
{ name: "iterative-development", description: "TDD loops until tests pass" },
|
|
779
|
+
{ name: "commit-hygiene", description: "Atomic commits and PR size limits" },
|
|
780
|
+
{ name: "code-deduplication", description: "Prevent semantic code duplication" },
|
|
781
|
+
{ name: "simplicity-rules", description: "Code complexity constraints" },
|
|
782
|
+
{ name: "security", description: "Security patterns and secrets management" }
|
|
763
783
|
];
|
|
764
784
|
if (stack.frameworks.includes("nextjs")) {
|
|
765
785
|
skills.push({ name: "nextjs-patterns", description: "Next.js App Router patterns" });
|
|
@@ -783,6 +803,11 @@ function generateSkills(stack) {
|
|
|
783
803
|
artifacts.push(generatePatternDiscoverySkill());
|
|
784
804
|
artifacts.push(generateSystematicDebuggingSkill());
|
|
785
805
|
artifacts.push(generateTestingMethodologySkill(stack));
|
|
806
|
+
artifacts.push(generateIterativeDevelopmentSkill(stack));
|
|
807
|
+
artifacts.push(generateCommitHygieneSkill());
|
|
808
|
+
artifacts.push(generateCodeDeduplicationSkill());
|
|
809
|
+
artifacts.push(generateSimplicityRulesSkill());
|
|
810
|
+
artifacts.push(generateSecuritySkill(stack));
|
|
786
811
|
if (stack.frameworks.includes("nextjs")) {
|
|
787
812
|
artifacts.push(generateNextJsSkill());
|
|
788
813
|
}
|
|
@@ -1634,6 +1659,615 @@ describe('UsersService', () => {
|
|
|
1634
1659
|
isNew: true
|
|
1635
1660
|
};
|
|
1636
1661
|
}
|
|
1662
|
+
function generateIterativeDevelopmentSkill(stack) {
|
|
1663
|
+
const testCmd = getTestCommand(stack);
|
|
1664
|
+
const lintCmd = getLintCommand(stack);
|
|
1665
|
+
return {
|
|
1666
|
+
type: "skill",
|
|
1667
|
+
path: ".claude/skills/iterative-development.md",
|
|
1668
|
+
content: `---
|
|
1669
|
+
name: iterative-development
|
|
1670
|
+
description: TDD-driven iterative loops until tests pass
|
|
1671
|
+
globs:
|
|
1672
|
+
- "**/*.ts"
|
|
1673
|
+
- "**/*.tsx"
|
|
1674
|
+
- "**/*.js"
|
|
1675
|
+
- "**/*.py"
|
|
1676
|
+
- "**/*.go"
|
|
1677
|
+
---
|
|
1678
|
+
|
|
1679
|
+
# Iterative Development (TDD Loops)
|
|
1680
|
+
|
|
1681
|
+
Self-referential development loops where you iterate until completion criteria are met.
|
|
1682
|
+
|
|
1683
|
+
## Core Philosophy
|
|
1684
|
+
|
|
1685
|
+
\`\`\`
|
|
1686
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
1687
|
+
\u2502 ITERATION > PERFECTION \u2502
|
|
1688
|
+
\u2502 Don't aim for perfect on first try. \u2502
|
|
1689
|
+
\u2502 Let the loop refine the work. \u2502
|
|
1690
|
+
\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
|
|
1691
|
+
\u2502 FAILURES ARE DATA \u2502
|
|
1692
|
+
\u2502 Failed tests, lint errors, type mismatches are signals. \u2502
|
|
1693
|
+
\u2502 Use them to guide the next iteration. \u2502
|
|
1694
|
+
\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
|
|
1695
|
+
\u2502 CLEAR COMPLETION CRITERIA \u2502
|
|
1696
|
+
\u2502 Define exactly what "done" looks like. \u2502
|
|
1697
|
+
\u2502 Tests passing. Coverage met. Lint clean. \u2502
|
|
1698
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
1699
|
+
\`\`\`
|
|
1700
|
+
|
|
1701
|
+
## TDD Workflow (Mandatory)
|
|
1702
|
+
|
|
1703
|
+
Every implementation task MUST follow this workflow:
|
|
1704
|
+
|
|
1705
|
+
### 1. RED: Write Tests First
|
|
1706
|
+
\`\`\`bash
|
|
1707
|
+
# Write tests based on requirements
|
|
1708
|
+
# Run tests - they MUST FAIL
|
|
1709
|
+
${testCmd}
|
|
1710
|
+
\`\`\`
|
|
1711
|
+
|
|
1712
|
+
### 2. GREEN: Implement Feature
|
|
1713
|
+
\`\`\`bash
|
|
1714
|
+
# Write minimum code to pass tests
|
|
1715
|
+
# Run tests - they MUST PASS
|
|
1716
|
+
${testCmd}
|
|
1717
|
+
\`\`\`
|
|
1718
|
+
|
|
1719
|
+
### 3. VALIDATE: Quality Gates
|
|
1720
|
+
\`\`\`bash
|
|
1721
|
+
# Full quality check
|
|
1722
|
+
${lintCmd ? `${lintCmd} && ` : ""}${testCmd}
|
|
1723
|
+
\`\`\`
|
|
1724
|
+
|
|
1725
|
+
## Completion Criteria Template
|
|
1726
|
+
|
|
1727
|
+
For any implementation task, define:
|
|
1728
|
+
|
|
1729
|
+
\`\`\`markdown
|
|
1730
|
+
### Completion Criteria
|
|
1731
|
+
- [ ] All tests passing
|
|
1732
|
+
- [ ] Coverage >= 80% (on new code)
|
|
1733
|
+
- [ ] Lint clean (no errors)
|
|
1734
|
+
- [ ] Type check passing
|
|
1735
|
+
\`\`\`
|
|
1736
|
+
|
|
1737
|
+
## When to Use This Workflow
|
|
1738
|
+
|
|
1739
|
+
| Task Type | Use TDD Loop? |
|
|
1740
|
+
|-----------|---------------|
|
|
1741
|
+
| New feature | \u2705 Always |
|
|
1742
|
+
| Bug fix | \u2705 Always (write test that reproduces bug first) |
|
|
1743
|
+
| Refactoring | \u2705 Always (existing tests must stay green) |
|
|
1744
|
+
| Spike/exploration | \u274C Skip (but document findings) |
|
|
1745
|
+
| Documentation | \u274C Skip |
|
|
1746
|
+
|
|
1747
|
+
## Anti-Patterns
|
|
1748
|
+
|
|
1749
|
+
- \u274C Writing code before tests
|
|
1750
|
+
- \u274C Skipping the RED phase (tests that never fail are useless)
|
|
1751
|
+
- \u274C Moving on when tests fail
|
|
1752
|
+
- \u274C Large batches (prefer small, focused iterations)
|
|
1753
|
+
`,
|
|
1754
|
+
isNew: true
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
function generateCommitHygieneSkill() {
|
|
1758
|
+
return {
|
|
1759
|
+
type: "skill",
|
|
1760
|
+
path: ".claude/skills/commit-hygiene.md",
|
|
1761
|
+
content: `---
|
|
1762
|
+
name: commit-hygiene
|
|
1763
|
+
description: Atomic commits, PR size limits, commit thresholds
|
|
1764
|
+
globs:
|
|
1765
|
+
- "**/*"
|
|
1766
|
+
---
|
|
1767
|
+
|
|
1768
|
+
# Commit Hygiene
|
|
1769
|
+
|
|
1770
|
+
Keep commits atomic, PRs reviewable, and git history clean.
|
|
1771
|
+
|
|
1772
|
+
## Size Thresholds
|
|
1773
|
+
|
|
1774
|
+
| Metric | \u{1F7E2} Good | \u{1F7E1} Warning | \u{1F534} Commit Now |
|
|
1775
|
+
|--------|---------|------------|---------------|
|
|
1776
|
+
| Files changed | 1-5 | 6-10 | > 10 |
|
|
1777
|
+
| Lines added | < 150 | 150-300 | > 300 |
|
|
1778
|
+
| Total changes | < 250 | 250-400 | > 400 |
|
|
1779
|
+
|
|
1780
|
+
**Research shows:** PRs > 400 lines have 40%+ defect rates vs 15% for smaller changes.
|
|
1781
|
+
|
|
1782
|
+
## When to Commit
|
|
1783
|
+
|
|
1784
|
+
### Commit Triggers (Any = Commit)
|
|
1785
|
+
|
|
1786
|
+
| Trigger | Action |
|
|
1787
|
+
|---------|--------|
|
|
1788
|
+
| Test passes | Just got a test green \u2192 commit |
|
|
1789
|
+
| Feature complete | Finished a function \u2192 commit |
|
|
1790
|
+
| Refactor done | Renamed across files \u2192 commit |
|
|
1791
|
+
| Bug fixed | Fixed the issue \u2192 commit |
|
|
1792
|
+
| Threshold hit | > 5 files or > 200 lines \u2192 commit |
|
|
1793
|
+
|
|
1794
|
+
### Commit Immediately If
|
|
1795
|
+
|
|
1796
|
+
- \u2705 Tests are passing after being red
|
|
1797
|
+
- \u2705 You're about to make a "big change"
|
|
1798
|
+
- \u2705 You've been coding for 30+ minutes
|
|
1799
|
+
- \u2705 You're about to try something risky
|
|
1800
|
+
- \u2705 The current state is "working"
|
|
1801
|
+
|
|
1802
|
+
## Atomic Commit Patterns
|
|
1803
|
+
|
|
1804
|
+
### Good Commits \u2705
|
|
1805
|
+
|
|
1806
|
+
\`\`\`
|
|
1807
|
+
"Add email validation to signup form"
|
|
1808
|
+
- 3 files: validator.ts, signup.tsx, signup.test.ts
|
|
1809
|
+
- 120 lines changed
|
|
1810
|
+
- Single purpose: email validation
|
|
1811
|
+
|
|
1812
|
+
"Fix null pointer in user lookup"
|
|
1813
|
+
- 2 files: userService.ts, userService.test.ts
|
|
1814
|
+
- 25 lines changed
|
|
1815
|
+
- Single purpose: fix one bug
|
|
1816
|
+
\`\`\`
|
|
1817
|
+
|
|
1818
|
+
### Bad Commits \u274C
|
|
1819
|
+
|
|
1820
|
+
\`\`\`
|
|
1821
|
+
"Add authentication, fix bugs, update styles"
|
|
1822
|
+
- 25 files changed, 800 lines
|
|
1823
|
+
- Multiple unrelated purposes
|
|
1824
|
+
|
|
1825
|
+
"WIP" / "Updates" / "Fix stuff"
|
|
1826
|
+
- Unknown scope, no clear purpose
|
|
1827
|
+
\`\`\`
|
|
1828
|
+
|
|
1829
|
+
## Quick Status Check
|
|
1830
|
+
|
|
1831
|
+
Run frequently to check current state:
|
|
1832
|
+
|
|
1833
|
+
\`\`\`bash
|
|
1834
|
+
# See what's changed
|
|
1835
|
+
git status --short
|
|
1836
|
+
|
|
1837
|
+
# Count changes
|
|
1838
|
+
git diff --shortstat
|
|
1839
|
+
|
|
1840
|
+
# Full summary
|
|
1841
|
+
git diff --stat HEAD
|
|
1842
|
+
\`\`\`
|
|
1843
|
+
|
|
1844
|
+
## PR Size Rules
|
|
1845
|
+
|
|
1846
|
+
| PR Size | Review Time | Quality |
|
|
1847
|
+
|---------|-------------|---------|
|
|
1848
|
+
| < 200 lines | < 30 min | High confidence |
|
|
1849
|
+
| 200-400 lines | 30-60 min | Good confidence |
|
|
1850
|
+
| 400-1000 lines | 1-2 hours | Declining quality |
|
|
1851
|
+
| > 1000 lines | Often skipped | Rubber-stamped |
|
|
1852
|
+
|
|
1853
|
+
**Best practice:** If a PR will be > 400 lines, split into stacked PRs.
|
|
1854
|
+
`,
|
|
1855
|
+
isNew: true
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1858
|
+
function generateCodeDeduplicationSkill() {
|
|
1859
|
+
return {
|
|
1860
|
+
type: "skill",
|
|
1861
|
+
path: ".claude/skills/code-deduplication.md",
|
|
1862
|
+
content: `---
|
|
1863
|
+
name: code-deduplication
|
|
1864
|
+
description: Prevent semantic code duplication with capability index
|
|
1865
|
+
globs:
|
|
1866
|
+
- "**/*.ts"
|
|
1867
|
+
- "**/*.tsx"
|
|
1868
|
+
- "**/*.js"
|
|
1869
|
+
- "**/*.py"
|
|
1870
|
+
---
|
|
1871
|
+
|
|
1872
|
+
# Code Deduplication
|
|
1873
|
+
|
|
1874
|
+
Prevent semantic duplication by maintaining awareness of existing capabilities.
|
|
1875
|
+
|
|
1876
|
+
## Core Principle
|
|
1877
|
+
|
|
1878
|
+
\`\`\`
|
|
1879
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
1880
|
+
\u2502 CHECK BEFORE YOU WRITE \u2502
|
|
1881
|
+
\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2502
|
|
1882
|
+
\u2502 AI doesn't copy/paste - it reimplements. \u2502
|
|
1883
|
+
\u2502 The problem isn't duplicate code, it's duplicate PURPOSE. \u2502
|
|
1884
|
+
\u2502 \u2502
|
|
1885
|
+
\u2502 Before writing ANY new function: \u2502
|
|
1886
|
+
\u2502 1. Search codebase for similar functionality \u2502
|
|
1887
|
+
\u2502 2. Check utils/, helpers/, lib/ for existing implementations \u2502
|
|
1888
|
+
\u2502 3. Extend existing code if possible \u2502
|
|
1889
|
+
\u2502 4. Only create new if nothing suitable exists \u2502
|
|
1890
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
1891
|
+
\`\`\`
|
|
1892
|
+
|
|
1893
|
+
## Before Writing New Code
|
|
1894
|
+
|
|
1895
|
+
### Search Checklist
|
|
1896
|
+
|
|
1897
|
+
1. **Search by purpose**: "format date", "validate email", "fetch user"
|
|
1898
|
+
2. **Search common locations**:
|
|
1899
|
+
- \`src/utils/\` or \`lib/\`
|
|
1900
|
+
- \`src/helpers/\`
|
|
1901
|
+
- \`src/common/\`
|
|
1902
|
+
- \`src/shared/\`
|
|
1903
|
+
3. **Search by function signature**: Similar inputs/outputs
|
|
1904
|
+
|
|
1905
|
+
### Common Duplicate Candidates
|
|
1906
|
+
|
|
1907
|
+
| Category | Look For |
|
|
1908
|
+
|----------|----------|
|
|
1909
|
+
| Date/Time | formatDate, parseDate, isExpired, addDays |
|
|
1910
|
+
| Validation | isEmail, isPhone, isURL, isUUID |
|
|
1911
|
+
| Strings | slugify, truncate, capitalize, pluralize |
|
|
1912
|
+
| API | fetchUser, createItem, handleError |
|
|
1913
|
+
| Auth | validateToken, requireAuth, getCurrentUser |
|
|
1914
|
+
|
|
1915
|
+
## If Similar Code Exists
|
|
1916
|
+
|
|
1917
|
+
### Option 1: Reuse directly
|
|
1918
|
+
\`\`\`typescript
|
|
1919
|
+
// Import and use existing function
|
|
1920
|
+
import { formatDate } from '@/utils/dates';
|
|
1921
|
+
\`\`\`
|
|
1922
|
+
|
|
1923
|
+
### Option 2: Extend with options
|
|
1924
|
+
\`\`\`typescript
|
|
1925
|
+
// Add optional parameter to existing function
|
|
1926
|
+
export function formatDate(
|
|
1927
|
+
date: Date,
|
|
1928
|
+
format: string = 'short',
|
|
1929
|
+
locale?: string // NEW: added locale support
|
|
1930
|
+
): string { ... }
|
|
1931
|
+
\`\`\`
|
|
1932
|
+
|
|
1933
|
+
### Option 3: Compose from existing
|
|
1934
|
+
\`\`\`typescript
|
|
1935
|
+
// Build on existing utilities
|
|
1936
|
+
export function formatDateRange(start: Date, end: Date) {
|
|
1937
|
+
return \`\${formatDate(start)} - \${formatDate(end)}\`;
|
|
1938
|
+
}
|
|
1939
|
+
\`\`\`
|
|
1940
|
+
|
|
1941
|
+
## File Header Pattern
|
|
1942
|
+
|
|
1943
|
+
Document what each file provides:
|
|
1944
|
+
|
|
1945
|
+
\`\`\`typescript
|
|
1946
|
+
/**
|
|
1947
|
+
* @file User validation utilities
|
|
1948
|
+
* @description Email, phone, and identity validation functions.
|
|
1949
|
+
*
|
|
1950
|
+
* Key exports:
|
|
1951
|
+
* - isEmail(email) - Validates email format
|
|
1952
|
+
* - isPhone(phone, country?) - Validates phone with country
|
|
1953
|
+
* - isValidUsername(username) - Checks username rules
|
|
1954
|
+
*/
|
|
1955
|
+
\`\`\`
|
|
1956
|
+
|
|
1957
|
+
## Anti-Patterns
|
|
1958
|
+
|
|
1959
|
+
- \u274C Writing date formatter without checking utils/
|
|
1960
|
+
- \u274C Creating new API client when one exists
|
|
1961
|
+
- \u274C Duplicating validation logic across files
|
|
1962
|
+
- \u274C Copy-pasting functions between files
|
|
1963
|
+
- \u274C "I'll refactor later" (you won't)
|
|
1964
|
+
`,
|
|
1965
|
+
isNew: true
|
|
1966
|
+
};
|
|
1967
|
+
}
|
|
1968
|
+
function generateSimplicityRulesSkill() {
|
|
1969
|
+
return {
|
|
1970
|
+
type: "skill",
|
|
1971
|
+
path: ".claude/skills/simplicity-rules.md",
|
|
1972
|
+
content: `---
|
|
1973
|
+
name: simplicity-rules
|
|
1974
|
+
description: Enforced code complexity constraints
|
|
1975
|
+
globs:
|
|
1976
|
+
- "**/*.ts"
|
|
1977
|
+
- "**/*.tsx"
|
|
1978
|
+
- "**/*.js"
|
|
1979
|
+
- "**/*.py"
|
|
1980
|
+
- "**/*.go"
|
|
1981
|
+
---
|
|
1982
|
+
|
|
1983
|
+
# Simplicity Rules
|
|
1984
|
+
|
|
1985
|
+
Complexity is the enemy. Every line of code is a liability.
|
|
1986
|
+
|
|
1987
|
+
## Enforced Limits
|
|
1988
|
+
|
|
1989
|
+
**CRITICAL: These limits are non-negotiable. Check and enforce for EVERY file.**
|
|
1990
|
+
|
|
1991
|
+
### Function Level
|
|
1992
|
+
|
|
1993
|
+
| Constraint | Limit | Action if Exceeded |
|
|
1994
|
+
|------------|-------|-------------------|
|
|
1995
|
+
| Lines per function | 20 max | Decompose immediately |
|
|
1996
|
+
| Parameters | 3 max | Use options object |
|
|
1997
|
+
| Nesting levels | 2 max | Flatten with early returns |
|
|
1998
|
+
|
|
1999
|
+
### File Level
|
|
2000
|
+
|
|
2001
|
+
| Constraint | Limit | Action if Exceeded |
|
|
2002
|
+
|------------|-------|-------------------|
|
|
2003
|
+
| Lines per file | 200 max | Split by responsibility |
|
|
2004
|
+
| Functions per file | 10 max | Split into modules |
|
|
2005
|
+
|
|
2006
|
+
### Module Level
|
|
2007
|
+
|
|
2008
|
+
| Constraint | Limit | Reason |
|
|
2009
|
+
|------------|-------|--------|
|
|
2010
|
+
| Directory nesting | 3 levels max | Flat is better |
|
|
2011
|
+
| Circular deps | 0 | Never acceptable |
|
|
2012
|
+
|
|
2013
|
+
## Enforcement Protocol
|
|
2014
|
+
|
|
2015
|
+
**Before completing ANY file:**
|
|
2016
|
+
|
|
2017
|
+
\`\`\`
|
|
2018
|
+
1. Count total lines \u2192 if > 200, STOP and split
|
|
2019
|
+
2. Count functions \u2192 if > 10, STOP and split
|
|
2020
|
+
3. Check function length \u2192 if any > 20 lines, decompose
|
|
2021
|
+
4. Check parameters \u2192 if any > 3, refactor to options object
|
|
2022
|
+
\`\`\`
|
|
2023
|
+
|
|
2024
|
+
## Violation Response
|
|
2025
|
+
|
|
2026
|
+
When limits are exceeded:
|
|
2027
|
+
|
|
2028
|
+
\`\`\`
|
|
2029
|
+
\u26A0\uFE0F FILE SIZE VIOLATION DETECTED
|
|
2030
|
+
|
|
2031
|
+
[filename] has [X] lines (limit: 200)
|
|
2032
|
+
|
|
2033
|
+
Splitting into:
|
|
2034
|
+
- [filename-a].ts - [responsibility A]
|
|
2035
|
+
- [filename-b].ts - [responsibility B]
|
|
2036
|
+
\`\`\`
|
|
2037
|
+
|
|
2038
|
+
**Never defer refactoring.** Fix violations immediately.
|
|
2039
|
+
|
|
2040
|
+
## Decomposition Patterns
|
|
2041
|
+
|
|
2042
|
+
### Long Function \u2192 Multiple Functions
|
|
2043
|
+
|
|
2044
|
+
\`\`\`typescript
|
|
2045
|
+
// BEFORE: 40 lines
|
|
2046
|
+
function processOrder(order) {
|
|
2047
|
+
// validate... 10 lines
|
|
2048
|
+
// calculate totals... 15 lines
|
|
2049
|
+
// apply discounts... 10 lines
|
|
2050
|
+
// save... 5 lines
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
// AFTER: 4 functions, each < 15 lines
|
|
2054
|
+
function processOrder(order) {
|
|
2055
|
+
validateOrder(order);
|
|
2056
|
+
const totals = calculateTotals(order);
|
|
2057
|
+
const finalPrice = applyDiscounts(totals, order.coupons);
|
|
2058
|
+
return saveOrder({ ...order, finalPrice });
|
|
2059
|
+
}
|
|
2060
|
+
\`\`\`
|
|
2061
|
+
|
|
2062
|
+
### Many Parameters \u2192 Options Object
|
|
2063
|
+
|
|
2064
|
+
\`\`\`typescript
|
|
2065
|
+
// BEFORE: 6 parameters
|
|
2066
|
+
function createUser(name, email, password, role, team, settings) { }
|
|
2067
|
+
|
|
2068
|
+
// AFTER: 1 options object
|
|
2069
|
+
interface CreateUserOptions {
|
|
2070
|
+
name: string;
|
|
2071
|
+
email: string;
|
|
2072
|
+
password: string;
|
|
2073
|
+
role?: string;
|
|
2074
|
+
team?: string;
|
|
2075
|
+
settings?: UserSettings;
|
|
2076
|
+
}
|
|
2077
|
+
function createUser(options: CreateUserOptions) { }
|
|
2078
|
+
\`\`\`
|
|
2079
|
+
|
|
2080
|
+
### Deep Nesting \u2192 Early Returns
|
|
2081
|
+
|
|
2082
|
+
\`\`\`typescript
|
|
2083
|
+
// BEFORE: 4 levels deep
|
|
2084
|
+
function process(data) {
|
|
2085
|
+
if (data) {
|
|
2086
|
+
if (data.valid) {
|
|
2087
|
+
if (data.items) {
|
|
2088
|
+
for (const item of data.items) {
|
|
2089
|
+
// actual logic here
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
// AFTER: 1 level deep
|
|
2097
|
+
function process(data) {
|
|
2098
|
+
if (!data?.valid || !data.items) return;
|
|
2099
|
+
|
|
2100
|
+
for (const item of data.items) {
|
|
2101
|
+
// actual logic here
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
\`\`\`
|
|
2105
|
+
|
|
2106
|
+
## Anti-Patterns
|
|
2107
|
+
|
|
2108
|
+
- \u274C God objects/files (do everything)
|
|
2109
|
+
- \u274C "Just one more line" (compound violations)
|
|
2110
|
+
- \u274C "I'll split it later" (you won't)
|
|
2111
|
+
- \u274C Deep inheritance hierarchies
|
|
2112
|
+
- \u274C Complex conditionals without extraction
|
|
2113
|
+
`,
|
|
2114
|
+
isNew: true
|
|
2115
|
+
};
|
|
2116
|
+
}
|
|
2117
|
+
function generateSecuritySkill(stack) {
|
|
2118
|
+
const isJS = stack.languages.includes("typescript") || stack.languages.includes("javascript");
|
|
2119
|
+
const isPython = stack.languages.includes("python");
|
|
2120
|
+
return {
|
|
2121
|
+
type: "skill",
|
|
2122
|
+
path: ".claude/skills/security.md",
|
|
2123
|
+
content: `---
|
|
2124
|
+
name: security
|
|
2125
|
+
description: Security best practices, secrets management, OWASP patterns
|
|
2126
|
+
globs:
|
|
2127
|
+
- "**/*"
|
|
2128
|
+
---
|
|
2129
|
+
|
|
2130
|
+
# Security Best Practices
|
|
2131
|
+
|
|
2132
|
+
Security is not optional. Every project must pass security checks.
|
|
2133
|
+
|
|
2134
|
+
## Required .gitignore Entries
|
|
2135
|
+
|
|
2136
|
+
**NEVER commit these:**
|
|
2137
|
+
|
|
2138
|
+
\`\`\`gitignore
|
|
2139
|
+
# Environment files
|
|
2140
|
+
.env
|
|
2141
|
+
.env.*
|
|
2142
|
+
!.env.example
|
|
2143
|
+
|
|
2144
|
+
# Secrets and credentials
|
|
2145
|
+
*.pem
|
|
2146
|
+
*.key
|
|
2147
|
+
*.p12
|
|
2148
|
+
credentials.json
|
|
2149
|
+
secrets.json
|
|
2150
|
+
*-credentials.json
|
|
2151
|
+
service-account*.json
|
|
2152
|
+
|
|
2153
|
+
# IDE secrets
|
|
2154
|
+
.idea/
|
|
2155
|
+
.vscode/settings.json
|
|
2156
|
+
\`\`\`
|
|
2157
|
+
|
|
2158
|
+
## Environment Variables
|
|
2159
|
+
|
|
2160
|
+
### Create .env.example
|
|
2161
|
+
|
|
2162
|
+
Document required vars without values:
|
|
2163
|
+
|
|
2164
|
+
\`\`\`bash
|
|
2165
|
+
# Server-side only (never expose to client)
|
|
2166
|
+
DATABASE_URL=
|
|
2167
|
+
API_SECRET_KEY=
|
|
2168
|
+
ANTHROPIC_API_KEY=
|
|
2169
|
+
|
|
2170
|
+
# Client-side safe (public, non-sensitive)
|
|
2171
|
+
${isJS ? "VITE_API_URL=\nNEXT_PUBLIC_SITE_URL=" : "API_BASE_URL="}
|
|
2172
|
+
\`\`\`
|
|
2173
|
+
|
|
2174
|
+
${isJS ? `### Frontend Exposure Rules
|
|
2175
|
+
|
|
2176
|
+
| Framework | Client-Exposed Prefix | Server-Only |
|
|
2177
|
+
|-----------|----------------------|-------------|
|
|
2178
|
+
| Vite | \`VITE_*\` | No prefix |
|
|
2179
|
+
| Next.js | \`NEXT_PUBLIC_*\` | No prefix |
|
|
2180
|
+
| CRA | \`REACT_APP_*\` | N/A |
|
|
2181
|
+
|
|
2182
|
+
**CRITICAL:** Never put secrets in client-exposed env vars!
|
|
2183
|
+
|
|
2184
|
+
\`\`\`typescript
|
|
2185
|
+
// \u274C WRONG - Secret exposed to browser
|
|
2186
|
+
const key = import.meta.env.VITE_API_SECRET;
|
|
2187
|
+
|
|
2188
|
+
// \u2705 CORRECT - Secret stays server-side
|
|
2189
|
+
const key = process.env.API_SECRET; // in API route only
|
|
2190
|
+
\`\`\`
|
|
2191
|
+
` : ""}
|
|
2192
|
+
|
|
2193
|
+
### Validate at Startup
|
|
2194
|
+
|
|
2195
|
+
${isJS ? `\`\`\`typescript
|
|
2196
|
+
import { z } from 'zod';
|
|
2197
|
+
|
|
2198
|
+
const envSchema = z.object({
|
|
2199
|
+
DATABASE_URL: z.string().url(),
|
|
2200
|
+
API_SECRET_KEY: z.string().min(32),
|
|
2201
|
+
NODE_ENV: z.enum(['development', 'production', 'test']),
|
|
2202
|
+
});
|
|
2203
|
+
|
|
2204
|
+
export const env = envSchema.parse(process.env);
|
|
2205
|
+
\`\`\`` : ""}
|
|
2206
|
+
${isPython ? `\`\`\`python
|
|
2207
|
+
from pydantic_settings import BaseSettings
|
|
2208
|
+
|
|
2209
|
+
class Settings(BaseSettings):
|
|
2210
|
+
database_url: str
|
|
2211
|
+
api_secret_key: str
|
|
2212
|
+
environment: str = "development"
|
|
2213
|
+
|
|
2214
|
+
class Config:
|
|
2215
|
+
env_file = ".env"
|
|
2216
|
+
|
|
2217
|
+
settings = Settings()
|
|
2218
|
+
\`\`\`` : ""}
|
|
2219
|
+
|
|
2220
|
+
## OWASP Top 10 Checklist
|
|
2221
|
+
|
|
2222
|
+
| Vulnerability | Prevention |
|
|
2223
|
+
|---------------|------------|
|
|
2224
|
+
| Injection (SQL, NoSQL, Command) | Parameterized queries, input validation |
|
|
2225
|
+
| Broken Auth | Secure session management, MFA |
|
|
2226
|
+
| Sensitive Data Exposure | Encryption at rest and in transit |
|
|
2227
|
+
| XXE | Disable external entity processing |
|
|
2228
|
+
| Broken Access Control | Verify permissions on every request |
|
|
2229
|
+
| Security Misconfiguration | Secure defaults, minimal permissions |
|
|
2230
|
+
| XSS | Output encoding, CSP headers |
|
|
2231
|
+
| Insecure Deserialization | Validate all serialized data |
|
|
2232
|
+
| Using Vulnerable Components | Keep dependencies updated |
|
|
2233
|
+
| Insufficient Logging | Log security events, monitor |
|
|
2234
|
+
|
|
2235
|
+
## Input Validation
|
|
2236
|
+
|
|
2237
|
+
\`\`\`
|
|
2238
|
+
RULE: Never trust user input. Validate everything.
|
|
2239
|
+
|
|
2240
|
+
- Validate type, length, format, range
|
|
2241
|
+
- Sanitize before storage
|
|
2242
|
+
- Encode before output
|
|
2243
|
+
- Use allowlists over denylists
|
|
2244
|
+
\`\`\`
|
|
2245
|
+
|
|
2246
|
+
## Secrets Detection
|
|
2247
|
+
|
|
2248
|
+
Before committing, check for:
|
|
2249
|
+
|
|
2250
|
+
- API keys (usually 32+ chars, specific patterns)
|
|
2251
|
+
- Passwords in code
|
|
2252
|
+
- Connection strings with credentials
|
|
2253
|
+
- Private keys (BEGIN RSA/EC/PRIVATE KEY)
|
|
2254
|
+
- Tokens (jwt, bearer, oauth)
|
|
2255
|
+
|
|
2256
|
+
## Security Review Checklist
|
|
2257
|
+
|
|
2258
|
+
Before PR merge:
|
|
2259
|
+
|
|
2260
|
+
- [ ] No secrets in code or config
|
|
2261
|
+
- [ ] Input validation on all user data
|
|
2262
|
+
- [ ] Output encoding where displayed
|
|
2263
|
+
- [ ] Authentication checked on protected routes
|
|
2264
|
+
- [ ] Authorization verified for resources
|
|
2265
|
+
- [ ] Dependencies scanned for vulnerabilities
|
|
2266
|
+
- [ ] Error messages don't leak internals
|
|
2267
|
+
`,
|
|
2268
|
+
isNew: true
|
|
2269
|
+
};
|
|
2270
|
+
}
|
|
1637
2271
|
function getAgentsForStack(stack) {
|
|
1638
2272
|
const agents = [
|
|
1639
2273
|
{ name: "code-reviewer", description: "Reviews code for quality and security" },
|
|
@@ -1948,7 +2582,8 @@ function generateCommands() {
|
|
|
1948
2582
|
generateTaskCommand(),
|
|
1949
2583
|
generateStatusCommand(),
|
|
1950
2584
|
generateDoneCommand(),
|
|
1951
|
-
generateAnalyzeCommand()
|
|
2585
|
+
generateAnalyzeCommand(),
|
|
2586
|
+
generateCodeReviewCommand()
|
|
1952
2587
|
];
|
|
1953
2588
|
}
|
|
1954
2589
|
function generateTaskCommand() {
|
|
@@ -2092,6 +2727,71 @@ Any improvements or concerns noted.
|
|
|
2092
2727
|
isNew: true
|
|
2093
2728
|
};
|
|
2094
2729
|
}
|
|
2730
|
+
function generateCodeReviewCommand() {
|
|
2731
|
+
return {
|
|
2732
|
+
type: "command",
|
|
2733
|
+
path: ".claude/commands/code-review.md",
|
|
2734
|
+
content: `---
|
|
2735
|
+
allowed-tools: Read, Glob, Grep, Bash(git diff), Bash(git status), Bash(git log)
|
|
2736
|
+
description: Review code changes for quality, security, and best practices
|
|
2737
|
+
---
|
|
2738
|
+
|
|
2739
|
+
# Code Review
|
|
2740
|
+
|
|
2741
|
+
## Changes to Review
|
|
2742
|
+
|
|
2743
|
+
!git diff --stat HEAD~1 2>/dev/null || git diff --stat
|
|
2744
|
+
|
|
2745
|
+
## Review Process
|
|
2746
|
+
|
|
2747
|
+
Analyze all changes for:
|
|
2748
|
+
|
|
2749
|
+
### 1. Security (Critical)
|
|
2750
|
+
- [ ] No secrets/credentials in code
|
|
2751
|
+
- [ ] Input validation present
|
|
2752
|
+
- [ ] Output encoding where needed
|
|
2753
|
+
- [ ] Auth/authz checks on protected routes
|
|
2754
|
+
|
|
2755
|
+
### 2. Quality
|
|
2756
|
+
- [ ] Functions \u2264 20 lines
|
|
2757
|
+
- [ ] Files \u2264 200 lines
|
|
2758
|
+
- [ ] No code duplication
|
|
2759
|
+
- [ ] Clear naming
|
|
2760
|
+
- [ ] Proper error handling
|
|
2761
|
+
|
|
2762
|
+
### 3. Testing
|
|
2763
|
+
- [ ] Tests exist for new code
|
|
2764
|
+
- [ ] Edge cases covered
|
|
2765
|
+
- [ ] Tests are meaningful (not just for coverage)
|
|
2766
|
+
|
|
2767
|
+
### 4. Style
|
|
2768
|
+
- [ ] Matches existing patterns
|
|
2769
|
+
- [ ] Consistent formatting
|
|
2770
|
+
- [ ] No commented-out code
|
|
2771
|
+
|
|
2772
|
+
## Output Format
|
|
2773
|
+
|
|
2774
|
+
For each finding, include file:line reference:
|
|
2775
|
+
|
|
2776
|
+
### Critical (Must Fix)
|
|
2777
|
+
Issues that block merge
|
|
2778
|
+
|
|
2779
|
+
### Warning (Should Fix)
|
|
2780
|
+
Issues that should be addressed
|
|
2781
|
+
|
|
2782
|
+
### Suggestion (Consider)
|
|
2783
|
+
Optional improvements
|
|
2784
|
+
|
|
2785
|
+
## Summary
|
|
2786
|
+
|
|
2787
|
+
Provide:
|
|
2788
|
+
1. Overall assessment (Ready / Changes Needed / Not Ready)
|
|
2789
|
+
2. Count of findings by severity
|
|
2790
|
+
3. Top priorities to address
|
|
2791
|
+
`,
|
|
2792
|
+
isNew: true
|
|
2793
|
+
};
|
|
2794
|
+
}
|
|
2095
2795
|
function formatLanguage(lang) {
|
|
2096
2796
|
const names = {
|
|
2097
2797
|
typescript: "TypeScript",
|
|
@@ -2203,15 +2903,14 @@ ${pc.bold("MORE INFO")}
|
|
|
2203
2903
|
`);
|
|
2204
2904
|
}
|
|
2205
2905
|
function showBanner() {
|
|
2206
|
-
console.log(
|
|
2207
|
-
console.log(pc.
|
|
2208
|
-
console.log(pc.
|
|
2209
|
-
console.log(pc.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
2906
|
+
console.log();
|
|
2907
|
+
console.log(pc.bold("Claude Code Starter") + pc.gray(` v${VERSION}`));
|
|
2908
|
+
console.log(pc.gray("Intelligent AI-Assisted Development Setup"));
|
|
2210
2909
|
console.log();
|
|
2211
2910
|
}
|
|
2212
2911
|
function showTechStack(projectInfo, verbose) {
|
|
2213
2912
|
const { techStack } = projectInfo;
|
|
2214
|
-
console.log(pc.
|
|
2913
|
+
console.log(pc.bold("Tech Stack"));
|
|
2215
2914
|
console.log();
|
|
2216
2915
|
if (techStack.primaryLanguage) {
|
|
2217
2916
|
console.log(` ${pc.bold("Language:")} ${formatLanguage2(techStack.primaryLanguage)}`);
|
|
@@ -2251,7 +2950,7 @@ async function promptNewProject(args) {
|
|
|
2251
2950
|
if (!args.interactive) {
|
|
2252
2951
|
return null;
|
|
2253
2952
|
}
|
|
2254
|
-
console.log(pc.yellow("
|
|
2953
|
+
console.log(pc.yellow("New project detected - let's set it up!"));
|
|
2255
2954
|
console.log();
|
|
2256
2955
|
const response = await prompts([
|
|
2257
2956
|
{
|
|
@@ -2441,7 +3140,7 @@ async function main() {
|
|
|
2441
3140
|
}
|
|
2442
3141
|
showBanner();
|
|
2443
3142
|
const projectDir = process.cwd();
|
|
2444
|
-
console.log(pc.
|
|
3143
|
+
console.log(pc.gray("Analyzing repository..."));
|
|
2445
3144
|
console.log();
|
|
2446
3145
|
const projectInfo = analyzeRepository(projectDir);
|
|
2447
3146
|
showTechStack(projectInfo, args.verbose);
|
|
@@ -2457,11 +3156,11 @@ async function main() {
|
|
|
2457
3156
|
projectInfo.description = preferences.description;
|
|
2458
3157
|
}
|
|
2459
3158
|
} else {
|
|
2460
|
-
console.log(pc.
|
|
3159
|
+
console.log(pc.gray(`Existing project with ${projectInfo.fileCount} source files`));
|
|
2461
3160
|
console.log();
|
|
2462
3161
|
}
|
|
2463
3162
|
if (projectInfo.techStack.hasClaudeConfig && !args.force) {
|
|
2464
|
-
console.log(pc.yellow("
|
|
3163
|
+
console.log(pc.yellow("Existing .claude/ configuration detected"));
|
|
2465
3164
|
console.log();
|
|
2466
3165
|
if (args.interactive) {
|
|
2467
3166
|
const { proceed } = await prompts({
|
|
@@ -2477,32 +3176,32 @@ async function main() {
|
|
|
2477
3176
|
}
|
|
2478
3177
|
console.log();
|
|
2479
3178
|
}
|
|
2480
|
-
console.log(pc.
|
|
3179
|
+
console.log(pc.gray("Generating configuration..."));
|
|
2481
3180
|
console.log();
|
|
2482
3181
|
const result = generateArtifacts(projectInfo);
|
|
2483
3182
|
const { created, updated, skipped } = writeArtifacts(result.artifacts, projectDir, args.force);
|
|
2484
3183
|
if (created.length > 0) {
|
|
2485
|
-
console.log(pc.green("
|
|
3184
|
+
console.log(pc.green("Created:"));
|
|
2486
3185
|
for (const file of created) {
|
|
2487
|
-
console.log(pc.green(`
|
|
3186
|
+
console.log(pc.green(` + ${file}`));
|
|
2488
3187
|
}
|
|
2489
3188
|
}
|
|
2490
3189
|
if (updated.length > 0) {
|
|
2491
|
-
console.log(pc.blue("
|
|
3190
|
+
console.log(pc.blue("Updated:"));
|
|
2492
3191
|
for (const file of updated) {
|
|
2493
|
-
console.log(pc.blue(`
|
|
3192
|
+
console.log(pc.blue(` ~ ${file}`));
|
|
2494
3193
|
}
|
|
2495
3194
|
}
|
|
2496
3195
|
if (skipped.length > 0 && args.verbose) {
|
|
2497
|
-
console.log(pc.gray("
|
|
3196
|
+
console.log(pc.gray("Preserved:"));
|
|
2498
3197
|
for (const file of skipped) {
|
|
2499
|
-
console.log(pc.gray(`
|
|
3198
|
+
console.log(pc.gray(` - ${file}`));
|
|
2500
3199
|
}
|
|
2501
3200
|
}
|
|
2502
3201
|
console.log();
|
|
2503
3202
|
createTaskFile(projectInfo, preferences);
|
|
2504
3203
|
const totalFiles = created.length + updated.length;
|
|
2505
|
-
console.log(pc.green(
|
|
3204
|
+
console.log(pc.green(`Done! (${totalFiles} files)`));
|
|
2506
3205
|
console.log();
|
|
2507
3206
|
console.log(pc.bold("Generated for your stack:"));
|
|
2508
3207
|
const skills = result.artifacts.filter((a) => a.type === "skill");
|
|
@@ -2510,24 +3209,24 @@ async function main() {
|
|
|
2510
3209
|
const rules = result.artifacts.filter((a) => a.type === "rule");
|
|
2511
3210
|
if (skills.length > 0) {
|
|
2512
3211
|
console.log(
|
|
2513
|
-
`
|
|
3212
|
+
` ${skills.length} skills (${skills.map((s) => path3.basename(s.path, ".md")).join(", ")})`
|
|
2514
3213
|
);
|
|
2515
3214
|
}
|
|
2516
3215
|
if (agents.length > 0) {
|
|
2517
3216
|
console.log(
|
|
2518
|
-
`
|
|
3217
|
+
` ${agents.length} agents (${agents.map((a) => path3.basename(a.path, ".md")).join(", ")})`
|
|
2519
3218
|
);
|
|
2520
3219
|
}
|
|
2521
3220
|
if (rules.length > 0) {
|
|
2522
|
-
console.log(`
|
|
3221
|
+
console.log(` ${rules.length} rules`);
|
|
2523
3222
|
}
|
|
2524
3223
|
console.log();
|
|
2525
3224
|
console.log(`${pc.cyan("Next step:")} Run ${pc.bold("claude")} to start working!`);
|
|
2526
3225
|
console.log();
|
|
2527
3226
|
if (!projectInfo.isExisting) {
|
|
2528
|
-
console.log(pc.gray("
|
|
3227
|
+
console.log(pc.gray("Tip: Use /task to define your first task"));
|
|
2529
3228
|
} else {
|
|
2530
|
-
console.log(pc.gray("
|
|
3229
|
+
console.log(pc.gray("Tip: Use /analyze to explore specific areas of your codebase"));
|
|
2531
3230
|
}
|
|
2532
3231
|
}
|
|
2533
3232
|
main().catch((err) => {
|