sumulige-claude 1.0.5 → 1.0.7
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/.claude/.kickoff-hint.txt +51 -0
- package/.claude/ANCHORS.md +40 -0
- package/.claude/MEMORY.md +34 -0
- package/.claude/PROJECT_LOG.md +101 -0
- package/.claude/THINKING_CHAIN_GUIDE.md +287 -0
- package/.claude/commands/commit-push-pr.md +59 -0
- package/.claude/commands/commit.md +53 -0
- package/.claude/commands/pr.md +76 -0
- package/.claude/commands/review.md +61 -0
- package/.claude/commands/sessions.md +62 -0
- package/.claude/commands/skill-create.md +131 -0
- package/.claude/commands/test.md +56 -0
- package/.claude/commands/todos.md +99 -0
- package/.claude/commands/verify-work.md +63 -0
- package/.claude/hooks/code-formatter.cjs +187 -0
- package/.claude/hooks/code-tracer.cjs +331 -0
- package/.claude/hooks/conversation-recorder.cjs +340 -0
- package/.claude/hooks/decision-tracker.cjs +398 -0
- package/.claude/hooks/export.cjs +329 -0
- package/.claude/hooks/multi-session.cjs +181 -0
- package/.claude/hooks/privacy-filter.js +224 -0
- package/.claude/hooks/project-kickoff.cjs +114 -0
- package/.claude/hooks/rag-skill-loader.cjs +159 -0
- package/.claude/hooks/session-end.sh +61 -0
- package/.claude/hooks/sync-to-log.sh +83 -0
- package/.claude/hooks/thinking-silent.cjs +145 -0
- package/.claude/hooks/tl-summary.sh +54 -0
- package/.claude/hooks/todo-manager.cjs +248 -0
- package/.claude/hooks/verify-work.cjs +134 -0
- package/.claude/sessions/active-sessions.json +444 -0
- package/.claude/settings.local.json +36 -2
- package/.claude/thinking-routes/.last-sync +1 -0
- package/.claude/thinking-routes/QUICKREF.md +98 -0
- package/CHANGELOG.md +56 -0
- package/DEV_TOOLS_GUIDE.md +190 -0
- package/PROJECT_STRUCTURE.md +10 -1
- package/README.md +20 -6
- package/cli.js +85 -824
- package/config/defaults.json +34 -0
- package/development/todos/INDEX.md +14 -58
- package/lib/commands.js +698 -0
- package/lib/config.js +71 -0
- package/lib/utils.js +62 -0
- package/package.json +2 -2
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Review current changes before committing
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Review the current uncommitted or staged changes.
|
|
6
|
+
|
|
7
|
+
## Step 1: Show Changes
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git status
|
|
11
|
+
|
|
12
|
+
# Show unstaged changes
|
|
13
|
+
git diff
|
|
14
|
+
|
|
15
|
+
# Show staged changes
|
|
16
|
+
git diff --staged
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Step 2: Code Review Checklist
|
|
20
|
+
|
|
21
|
+
Review the changes for:
|
|
22
|
+
|
|
23
|
+
### Functionality
|
|
24
|
+
- [ ] Does the change accomplish the intended goal?
|
|
25
|
+
- [ ] Are there any obvious bugs or logic errors?
|
|
26
|
+
- [ ] Are edge cases handled?
|
|
27
|
+
|
|
28
|
+
### Security
|
|
29
|
+
- [ ] No hardcoded credentials or API keys
|
|
30
|
+
- [ ] No SQL injection, XSS, or other vulnerabilities
|
|
31
|
+
- [ ] Proper input validation
|
|
32
|
+
|
|
33
|
+
### Code Quality
|
|
34
|
+
- [ ] Code is readable and self-documenting
|
|
35
|
+
- [ ] No unnecessary complexity
|
|
36
|
+
- [ ] Follows DRY (Don't Repeat Yourself)
|
|
37
|
+
- [ ] Proper error handling
|
|
38
|
+
|
|
39
|
+
### Testing
|
|
40
|
+
- [ ] Tests cover new functionality
|
|
41
|
+
- [ ] No tests are broken
|
|
42
|
+
- [ ] Edge cases are tested
|
|
43
|
+
|
|
44
|
+
### Performance
|
|
45
|
+
- [ ] No obvious performance issues
|
|
46
|
+
- [ ] No unnecessary database queries or API calls
|
|
47
|
+
- [ ] Proper use of caching (if applicable)
|
|
48
|
+
|
|
49
|
+
## Step 3: Provide Feedback
|
|
50
|
+
|
|
51
|
+
For each issue found:
|
|
52
|
+
1. Point out the specific file and line
|
|
53
|
+
2. Explain the issue
|
|
54
|
+
3. Suggest a fix
|
|
55
|
+
|
|
56
|
+
## Step 4: Summary
|
|
57
|
+
|
|
58
|
+
Provide an overall assessment:
|
|
59
|
+
- ✅ Ready to commit
|
|
60
|
+
- ⚠️ Minor issues to address
|
|
61
|
+
- ❌ Major issues that need fixing
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Manage and display parallel Claude sessions
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Manage and display information about parallel Claude sessions.
|
|
6
|
+
|
|
7
|
+
## Show Session Status
|
|
8
|
+
|
|
9
|
+
Display all active parallel sessions:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
node .claude/hooks/multi-session.cjs --status
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Session Management Best Practices
|
|
16
|
+
|
|
17
|
+
Based on Boris Cherny's workflow:
|
|
18
|
+
|
|
19
|
+
### Terminal Sessions (Local)
|
|
20
|
+
- Number your terminal tabs 1-5
|
|
21
|
+
- Use system notifications to know when Claude needs input
|
|
22
|
+
- Run different agents in different tabs:
|
|
23
|
+
- Tab 1: Conductor (planning/coordination)
|
|
24
|
+
- Tab 2: Architect (design/architecture)
|
|
25
|
+
- Tab 3: Builder (implementation)
|
|
26
|
+
- Tab 4: Reviewer (code review)
|
|
27
|
+
- Tab 5: Explorer (research)
|
|
28
|
+
|
|
29
|
+
### Web Sessions (claude.ai/code)
|
|
30
|
+
- Run 5-10 web sessions in parallel with local sessions
|
|
31
|
+
- Use `&` to hand off local sessions to web
|
|
32
|
+
- Use `--teleport` to switch between local and web
|
|
33
|
+
- Start sessions from mobile Claude app for async work
|
|
34
|
+
|
|
35
|
+
### Session Handoff
|
|
36
|
+
|
|
37
|
+
To hand off a session to web:
|
|
38
|
+
```bash
|
|
39
|
+
# End local session with summary
|
|
40
|
+
# The session context will be available in claude.ai/code
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## View Session History
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cat .claude/sessions/active-sessions.json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Clean Old Sessions
|
|
50
|
+
|
|
51
|
+
Sessions older than 1 hour are automatically cleaned up. To manually clean:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
rm .claude/sessions/active-sessions.json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Tips
|
|
58
|
+
|
|
59
|
+
1. **Use Plan mode** (Shift+Tab twice) for most sessions
|
|
60
|
+
2. **Switch to auto-accept** after approving a plan
|
|
61
|
+
3. **Let sessions run in parallel** - don't wait for one to finish
|
|
62
|
+
4. **Check notifications** to see when sessions need input
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a new skill with template
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Create a new skill using the standard template.
|
|
6
|
+
|
|
7
|
+
## Step 1: Get Skill Information
|
|
8
|
+
|
|
9
|
+
Ask the user for:
|
|
10
|
+
1. **Skill name** (kebab-case, e.g., `code-reviewer`)
|
|
11
|
+
2. **Description** (one-line summary)
|
|
12
|
+
3. **Category** (development, design, analysis, workflow, etc.)
|
|
13
|
+
4. **Difficulty** (beginner, intermediate, advanced)
|
|
14
|
+
|
|
15
|
+
## Step 2: Create Skill Directory
|
|
16
|
+
|
|
17
|
+
Create the skill directory structure:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
mkdir -p .claude/skills/{skill-name}/{templates,examples}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Step 3: Generate SKILL.md
|
|
24
|
+
|
|
25
|
+
Use this template:
|
|
26
|
+
|
|
27
|
+
```markdown
|
|
28
|
+
# {Skill Name}
|
|
29
|
+
|
|
30
|
+
> {Description}
|
|
31
|
+
|
|
32
|
+
**版本**: 1.0.0
|
|
33
|
+
**作者**: AI
|
|
34
|
+
**标签**: [{category}]
|
|
35
|
+
**难度**: {difficulty}
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 概述
|
|
40
|
+
|
|
41
|
+
{Detailed description of what this skill does}
|
|
42
|
+
|
|
43
|
+
## 适用场景
|
|
44
|
+
|
|
45
|
+
- {Scenario 1}
|
|
46
|
+
- {Scenario 2}
|
|
47
|
+
- {Scenario 3}
|
|
48
|
+
|
|
49
|
+
## 触发关键词
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
{trigger keywords}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 使用方法
|
|
56
|
+
|
|
57
|
+
### 基础用法
|
|
58
|
+
|
|
59
|
+
{Example usage}
|
|
60
|
+
|
|
61
|
+
## 输出格式
|
|
62
|
+
|
|
63
|
+
{Output format description}
|
|
64
|
+
|
|
65
|
+
## 注意事项
|
|
66
|
+
|
|
67
|
+
- {Note 1}
|
|
68
|
+
- {Note 2}
|
|
69
|
+
|
|
70
|
+
## 相关技能
|
|
71
|
+
|
|
72
|
+
- [Related Skill](../related-skill/)
|
|
73
|
+
|
|
74
|
+
## 更新日志
|
|
75
|
+
|
|
76
|
+
### 1.0.0 ({current-date})
|
|
77
|
+
- 初始版本
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Step 4: Generate metadata.yaml
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
name: {skill-name}
|
|
84
|
+
version: 1.0.0
|
|
85
|
+
author: AI
|
|
86
|
+
description: {description}
|
|
87
|
+
|
|
88
|
+
tags:
|
|
89
|
+
- {category}
|
|
90
|
+
|
|
91
|
+
triggers:
|
|
92
|
+
- {trigger1}
|
|
93
|
+
- {trigger2}
|
|
94
|
+
|
|
95
|
+
dependencies: []
|
|
96
|
+
difficulty: {difficulty}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Step 5: Add to RAG Index
|
|
100
|
+
|
|
101
|
+
Update `.claude/rag/skill-index.json`:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"skills": [
|
|
106
|
+
{
|
|
107
|
+
"name": "{skill-name}",
|
|
108
|
+
"description": "{description}",
|
|
109
|
+
"keywords": ["{trigger1}", "{trigger2}"],
|
|
110
|
+
"path": ".claude/skills/{skill-name}/SKILL.md"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Step 6: Verify
|
|
117
|
+
|
|
118
|
+
Confirm with user:
|
|
119
|
+
- Skill created at `.claude/skills/{skill-name}/`
|
|
120
|
+
- Added to RAG index
|
|
121
|
+
- Ready to use
|
|
122
|
+
|
|
123
|
+
## Example
|
|
124
|
+
|
|
125
|
+
User: "Create a skill called api-tester for testing REST APIs"
|
|
126
|
+
|
|
127
|
+
→ Create `.claude/skills/api-tester/` with:
|
|
128
|
+
- SKILL.md (filled with API testing content)
|
|
129
|
+
- metadata.yaml
|
|
130
|
+
- templates/request.md
|
|
131
|
+
- examples/basic-test.md
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Run tests and show coverage report
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run the test suite and provide comprehensive results.
|
|
6
|
+
|
|
7
|
+
## Step 1: Detect Test Framework
|
|
8
|
+
|
|
9
|
+
Check what test framework is being used:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cat package.json | grep -E '"test"|"jest"|"vitest"|"mocha"|"pytest"'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Step 2: Run Tests
|
|
16
|
+
|
|
17
|
+
Run the appropriate test command:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Node.js / JavaScript
|
|
21
|
+
npm test
|
|
22
|
+
|
|
23
|
+
# Python
|
|
24
|
+
pytest
|
|
25
|
+
|
|
26
|
+
# Rust
|
|
27
|
+
cargo test
|
|
28
|
+
|
|
29
|
+
# Go
|
|
30
|
+
go test ./...
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Step 3: Show Coverage
|
|
34
|
+
|
|
35
|
+
If coverage is available, run:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm run test:coverage
|
|
39
|
+
# or
|
|
40
|
+
pytest --cov
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Step 4: Analyze Results
|
|
44
|
+
|
|
45
|
+
Provide a summary:
|
|
46
|
+
- Total tests run
|
|
47
|
+
- Pass/fail counts
|
|
48
|
+
- Coverage percentage
|
|
49
|
+
- Any failing tests with details
|
|
50
|
+
|
|
51
|
+
## Step 5: Fix Failures (if any)
|
|
52
|
+
|
|
53
|
+
If tests fail, help the user:
|
|
54
|
+
1. Identify the root cause
|
|
55
|
+
2. Fix the issue
|
|
56
|
+
3. Re-run tests to verify
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Manage project todos and tasks
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Manage project tasks in the development/todos directory.
|
|
6
|
+
|
|
7
|
+
## Show Task Overview
|
|
8
|
+
|
|
9
|
+
Display the task overview:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cat development/todos/INDEX.md
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Task Operations
|
|
16
|
+
|
|
17
|
+
### Create a New Task
|
|
18
|
+
|
|
19
|
+
When user asks to create a task:
|
|
20
|
+
1. Create file in `development/todos/active/`
|
|
21
|
+
2. Use kebab-case for filename (e.g., `user-login.md`)
|
|
22
|
+
3. Use the template format:
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
# [Task Name]
|
|
26
|
+
|
|
27
|
+
**状态**: 🚧 进行中
|
|
28
|
+
**优先级**: P0/P1/P2/P3
|
|
29
|
+
**负责人**: AI/Human
|
|
30
|
+
**分支**: `feature/xxx`
|
|
31
|
+
**创建时间**: YYYY-MM-DD
|
|
32
|
+
**预计完成**: YYYY-MM-DD
|
|
33
|
+
|
|
34
|
+
## 描述
|
|
35
|
+
|
|
36
|
+
[Task description]
|
|
37
|
+
|
|
38
|
+
## 子任务
|
|
39
|
+
|
|
40
|
+
- [ ] Subtask 1
|
|
41
|
+
- [ ] Subtask 2
|
|
42
|
+
|
|
43
|
+
## 依赖
|
|
44
|
+
|
|
45
|
+
- [Dependencies]
|
|
46
|
+
|
|
47
|
+
## 进度
|
|
48
|
+
|
|
49
|
+
- [x] Planning
|
|
50
|
+
- [ ] In progress
|
|
51
|
+
- [ ] Testing
|
|
52
|
+
- [ ] Review
|
|
53
|
+
|
|
54
|
+
## 备注
|
|
55
|
+
|
|
56
|
+
[Notes]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Update Task Status
|
|
60
|
+
|
|
61
|
+
To move a task:
|
|
62
|
+
- **Complete**: Move from `active/` to `completed/`
|
|
63
|
+
- **Backlog**: Move from `active/` to `backlog/`
|
|
64
|
+
- **Archive**: Move from `completed/` to `archived/`
|
|
65
|
+
|
|
66
|
+
### Update Task Progress
|
|
67
|
+
|
|
68
|
+
Edit the task file and update:
|
|
69
|
+
- Subtask checkboxes
|
|
70
|
+
- Progress checklist
|
|
71
|
+
- Add notes
|
|
72
|
+
|
|
73
|
+
## Refresh Task Index
|
|
74
|
+
|
|
75
|
+
After any task changes, refresh the index:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
node .claude/hooks/todo-manager.cjs --force
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Task Priority Levels
|
|
82
|
+
|
|
83
|
+
| Priority | Usage |
|
|
84
|
+
|----------|-------|
|
|
85
|
+
| P0 | Critical - blocks release |
|
|
86
|
+
| P1 | High - important for next milestone |
|
|
87
|
+
| P2 | Medium - normal feature work |
|
|
88
|
+
| P3 | Low - nice to have |
|
|
89
|
+
|
|
90
|
+
## Examples
|
|
91
|
+
|
|
92
|
+
User says: "Create a task for implementing user authentication"
|
|
93
|
+
→ Create `active/user-authentication.md`
|
|
94
|
+
|
|
95
|
+
User says: "Mark the login task as complete"
|
|
96
|
+
→ Move `active/login.md` to `completed/login.md`
|
|
97
|
+
|
|
98
|
+
User says: "Show all active tasks"
|
|
99
|
+
→ List all files in `development/todos/active/`
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: View and manage pending verification tasks
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are helping the user review and verify completed work.
|
|
6
|
+
|
|
7
|
+
## Check Pending Tasks
|
|
8
|
+
|
|
9
|
+
First, read the verification log:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cat .claude/verify/verify-log.md 2>/dev/null || echo "No verification log found"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
And check pending tasks:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cat .claude/verify/.pending-verify.json 2>/dev/null || echo "No pending tasks"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Verification Process
|
|
22
|
+
|
|
23
|
+
For each pending task, guide the user through:
|
|
24
|
+
|
|
25
|
+
1. **What was done** - Summarize the action
|
|
26
|
+
2. **How to verify** - Run appropriate verification commands:
|
|
27
|
+
- For code changes: run tests, linters
|
|
28
|
+
- For deployments: check staging environment
|
|
29
|
+
- For commits: verify CI/CD status
|
|
30
|
+
|
|
31
|
+
## Common Verification Commands
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Run tests
|
|
35
|
+
npm test
|
|
36
|
+
|
|
37
|
+
# Check test coverage
|
|
38
|
+
npm run test:coverage
|
|
39
|
+
|
|
40
|
+
# Run linter
|
|
41
|
+
npm run lint
|
|
42
|
+
|
|
43
|
+
# Type check
|
|
44
|
+
npm run type-check
|
|
45
|
+
|
|
46
|
+
# Build verification
|
|
47
|
+
npm run build
|
|
48
|
+
|
|
49
|
+
# Check CI status (if using GitHub)
|
|
50
|
+
gh run list --limit 5
|
|
51
|
+
|
|
52
|
+
# Check PR status
|
|
53
|
+
gh pr status
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Mark as Complete
|
|
57
|
+
|
|
58
|
+
After verification is successful, ask the user if they want to:
|
|
59
|
+
- Mark the task as verified (remove from pending)
|
|
60
|
+
- Keep it for later verification
|
|
61
|
+
- Add additional verification steps
|
|
62
|
+
|
|
63
|
+
To mark as complete, edit `.claude/verify/.pending-verify.json` to remove the completed task.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Code Formatter Hook - 自动代码格式化
|
|
4
|
+
*
|
|
5
|
+
* 根据 Boris Cherny 的最佳实践,Claude 通常能生成格式良好的代码,
|
|
6
|
+
* 但这个 hook 处理最后 10% 的格式问题,避免 CI 中的格式错误。
|
|
7
|
+
*
|
|
8
|
+
* 触发时机:PostToolUse 事件
|
|
9
|
+
* 支持语言:JavaScript, TypeScript, Python, Rust, Go, JSON, Markdown
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const { spawn } = require('child_process');
|
|
15
|
+
|
|
16
|
+
const PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
17
|
+
|
|
18
|
+
// 支持的格式化器配置
|
|
19
|
+
const FORMATTERS = {
|
|
20
|
+
// JavaScript/TypeScript
|
|
21
|
+
'.js': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
22
|
+
'.jsx': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
23
|
+
'.ts': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
24
|
+
'.tsx': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
25
|
+
'.mjs': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
26
|
+
'.cjs': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
27
|
+
|
|
28
|
+
// Python
|
|
29
|
+
'.py': { cmd: 'black', args: ['--quiet'] },
|
|
30
|
+
|
|
31
|
+
// Rust
|
|
32
|
+
'.rs': { cmd: 'rustfmt', args: [] },
|
|
33
|
+
|
|
34
|
+
// Go
|
|
35
|
+
'.go': { cmd: 'gofmt', args: ['-w'] },
|
|
36
|
+
|
|
37
|
+
// JSON
|
|
38
|
+
'.json': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
39
|
+
|
|
40
|
+
// Markdown
|
|
41
|
+
'.md': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
42
|
+
|
|
43
|
+
// CSS/SCSS
|
|
44
|
+
'.css': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
45
|
+
'.scss': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
46
|
+
'.less': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
47
|
+
|
|
48
|
+
// HTML
|
|
49
|
+
'.html': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
50
|
+
'.htm': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
51
|
+
|
|
52
|
+
// YAML
|
|
53
|
+
'.yaml': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
54
|
+
'.yml': { cmd: 'prettier', args: ['--write', '--log-level', 'warn'] },
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// 检查命令是否可用
|
|
58
|
+
function isCommandAvailable(cmd) {
|
|
59
|
+
try {
|
|
60
|
+
// 首先尝试 which
|
|
61
|
+
spawn('which', [cmd], { stdio: 'ignore' });
|
|
62
|
+
|
|
63
|
+
// 对于 prettier,额外检查 npx
|
|
64
|
+
if (cmd === 'prettier') {
|
|
65
|
+
spawn('npx', [cmd, '--version'], { stdio: 'ignore' });
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
} catch (e) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 获取工具修改的文件
|
|
74
|
+
function getModifiedFiles() {
|
|
75
|
+
const toolName = process.env.CLAUDE_TOOL_NAME || '';
|
|
76
|
+
const toolInput = process.env.CLAUDE_TOOL_INPUT || '';
|
|
77
|
+
|
|
78
|
+
// 从工具输入中提取文件路径
|
|
79
|
+
const filePaths = [];
|
|
80
|
+
|
|
81
|
+
// Edit 工具
|
|
82
|
+
if (toolName === 'Edit') {
|
|
83
|
+
// Edit 工具的文件路径在 file_path 参数中
|
|
84
|
+
const match = toolInput.match(/"filePath":\s*"([^"]+)"/);
|
|
85
|
+
if (match) {
|
|
86
|
+
filePaths.push(match[1]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Write 工具
|
|
91
|
+
if (toolName === 'Write') {
|
|
92
|
+
const match = toolInput.match(/"file_path":\s*"([^"]+)"/);
|
|
93
|
+
if (match) {
|
|
94
|
+
filePaths.push(match[1]);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// NotebookEdit 工具
|
|
99
|
+
if (toolName === 'NotebookEdit') {
|
|
100
|
+
const match = toolInput.match(/"notebook_path":\s*"([^"]+)"/);
|
|
101
|
+
if (match) {
|
|
102
|
+
filePaths.push(match[1]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return filePaths;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 格式化文件
|
|
110
|
+
function formatFile(filePath) {
|
|
111
|
+
const ext = path.extname(filePath);
|
|
112
|
+
|
|
113
|
+
// 跳过不需要格式化的目录
|
|
114
|
+
const skipDirs = ['node_modules', '.git', 'dist', 'build', 'target', 'vendor', '.venv'];
|
|
115
|
+
if (skipDirs.some(dir => filePath.includes(`/${dir}/`) || filePath.includes(`\\${dir}\\`))) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const formatter = FORMATTERS[ext];
|
|
120
|
+
if (!formatter) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 检查格式化器是否可用
|
|
125
|
+
if (!isCommandAvailable(formatter.cmd)) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 检查文件是否存在
|
|
130
|
+
if (!fs.existsSync(filePath)) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
// 对于 prettier,使用 npx 来支持本地安装
|
|
136
|
+
const cmd = formatter.cmd === 'prettier' ? 'npx' : formatter.cmd;
|
|
137
|
+
const args = formatter.cmd === 'prettier'
|
|
138
|
+
? ['prettier', ...formatter.args, filePath]
|
|
139
|
+
: [...formatter.args, filePath];
|
|
140
|
+
|
|
141
|
+
// 运行格式化器
|
|
142
|
+
spawn(cmd, args, {
|
|
143
|
+
stdio: 'ignore',
|
|
144
|
+
cwd: PROJECT_DIR,
|
|
145
|
+
detached: true
|
|
146
|
+
}).unref();
|
|
147
|
+
return { file: filePath, formatter: formatter.cmd };
|
|
148
|
+
} catch (e) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 主函数
|
|
154
|
+
function main() {
|
|
155
|
+
try {
|
|
156
|
+
const eventType = process.env.CLAUDE_EVENT_TYPE || '';
|
|
157
|
+
|
|
158
|
+
// 只在 PostToolUse 事件时运行
|
|
159
|
+
if (eventType !== 'PostToolUse') {
|
|
160
|
+
process.exit(0);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const modifiedFiles = getModifiedFiles();
|
|
164
|
+
|
|
165
|
+
if (modifiedFiles.length === 0) {
|
|
166
|
+
process.exit(0);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 格式化所有修改的文件
|
|
170
|
+
const formatted = modifiedFiles
|
|
171
|
+
.map(formatFile)
|
|
172
|
+
.filter(result => result !== null);
|
|
173
|
+
|
|
174
|
+
// 输出格式化结果(可选,用于调试)
|
|
175
|
+
if (formatted.length > 0 && process.env.DEBUG_FORMATTER) {
|
|
176
|
+
console.log(`\n🎨 [格式化] 已格式化 ${formatted.length} 个文件:`);
|
|
177
|
+
formatted.forEach(f => console.log(` - ${f.file} (${f.formatter})`));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
} catch (e) {
|
|
181
|
+
// 完全静默,不输出任何错误
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
process.exit(0);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
main();
|