dw-kit 1.2.0 → 1.2.1
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/hooks/session-init.sh +85 -74
- package/.claude/rules/code-style.md +37 -37
- package/.claude/rules/commit-standards.md +37 -37
- package/.claude/settings.json +101 -99
- package/.dw/config/dw.config.yml +82 -82
- package/README.md +9 -1
- package/package.json +84 -84
- package/src/cli.mjs +16 -8
- package/src/commands/upgrade.mjs +297 -262
- package/src/lib/copy.mjs +118 -110
|
@@ -1,74 +1,85 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# .claude/hooks/session-init.sh — dw-kit v1.2
|
|
3
|
-
# Inject active task context vào đầu session, giải quyết "session amnesia".
|
|
4
|
-
# Chỉ chạy một lần mỗi session (track bằng session_id).
|
|
5
|
-
#
|
|
6
|
-
# UserPromptSubmit hook
|
|
7
|
-
# Stdout output → được inject vào context của user prompt
|
|
8
|
-
# exit 0 = allow
|
|
9
|
-
|
|
10
|
-
INPUT=$(cat)
|
|
11
|
-
|
|
12
|
-
SESSION_ID=$(echo "$INPUT" | node -e "
|
|
13
|
-
let d='';
|
|
14
|
-
process.stdin.on('data',c=>d+=c).on('end',()=>{
|
|
15
|
-
try{ process.stdout.write(JSON.parse(d).session_id||''); }catch(e){}
|
|
16
|
-
});
|
|
17
|
-
" 2>/dev/null || true)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
echo "
|
|
72
|
-
echo ""
|
|
73
|
-
|
|
74
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# .claude/hooks/session-init.sh — dw-kit v1.2
|
|
3
|
+
# Inject active task context vào đầu session, giải quyết "session amnesia".
|
|
4
|
+
# Chỉ chạy một lần mỗi session (track bằng session_id).
|
|
5
|
+
#
|
|
6
|
+
# UserPromptSubmit hook
|
|
7
|
+
# Stdout output → được inject vào context của user prompt
|
|
8
|
+
# exit 0 = allow
|
|
9
|
+
|
|
10
|
+
INPUT=$(cat)
|
|
11
|
+
|
|
12
|
+
SESSION_ID=$(echo "$INPUT" | node -e "
|
|
13
|
+
let d='';
|
|
14
|
+
process.stdin.on('data',c=>d+=c).on('end',()=>{
|
|
15
|
+
try{ process.stdout.write(JSON.parse(d).session_id||''); }catch(e){}
|
|
16
|
+
});
|
|
17
|
+
" 2>/dev/null || true)
|
|
18
|
+
|
|
19
|
+
# Tier 2: pure-bash grep fallback — works without node (e.g. node absent or CRLF-corrupt shebang)
|
|
20
|
+
if [ -z "$SESSION_ID" ]; then
|
|
21
|
+
SESSION_ID=$(echo "$INPUT" | grep -o '"session_id":"[^"]*"' | cut -d'"' -f4 2>/dev/null || true)
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Tier 3: project-scoped + hour-scoped stable ID
|
|
25
|
+
# cksum is POSIX — available on Linux, macOS, and Git Bash on Windows.
|
|
26
|
+
# Ensures marker is always created so re-injection is suppressed even when tiers 1+2 fail.
|
|
27
|
+
if [ -z "$SESSION_ID" ]; then
|
|
28
|
+
_dir_hash=$(pwd | cksum | cut -d' ' -f1)
|
|
29
|
+
SESSION_ID="fallback-${_dir_hash}-$(date +%Y%m%d-%H)"
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# ── Track session: chỉ chạy một lần mỗi session ───────────────────────────────
|
|
33
|
+
SESSION_MARKER="/tmp/dw-session-${SESSION_ID}"
|
|
34
|
+
if [ -f "$SESSION_MARKER" ]; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
touch "$SESSION_MARKER" 2>/dev/null || true
|
|
38
|
+
|
|
39
|
+
# ── Scan .dw/tasks/ tìm tasks In Progress ─────────────────────────────────────
|
|
40
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
41
|
+
TASKS_DIR="$PROJECT_DIR/.dw/tasks"
|
|
42
|
+
|
|
43
|
+
[ ! -d "$TASKS_DIR" ] && exit 0
|
|
44
|
+
|
|
45
|
+
ACTIVE_TASKS=()
|
|
46
|
+
ACTIVE_SUMMARIES=()
|
|
47
|
+
|
|
48
|
+
while IFS= read -r progress_file; do
|
|
49
|
+
if grep -q "Trạng thái: In Progress" "$progress_file" 2>/dev/null; then
|
|
50
|
+
task_name=$(basename "$(dirname "$progress_file")")
|
|
51
|
+
|
|
52
|
+
# Extract current subtask (dòng "In Progress" trong table)
|
|
53
|
+
current_st=$(grep -m1 "In Progress" "$progress_file" 2>/dev/null \
|
|
54
|
+
| grep -oP '\| ST-\d+ \| [^|]+' | sed 's/|//g' | xargs 2>/dev/null || echo "")
|
|
55
|
+
|
|
56
|
+
# Extract last handoff note nếu có
|
|
57
|
+
last_handoff=$(awk '/## Handoff Notes/{found=1} found{print}' "$progress_file" 2>/dev/null \
|
|
58
|
+
| grep -m1 "Bước tiếp theo:" | sed 's/.*Bước tiếp theo://' | xargs 2>/dev/null || echo "")
|
|
59
|
+
|
|
60
|
+
ACTIVE_TASKS+=("$task_name")
|
|
61
|
+
summary="$task_name"
|
|
62
|
+
[ -n "$current_st" ] && summary="$summary — $current_st"
|
|
63
|
+
[ -n "$last_handoff" ] && summary="$summary | Next: $last_handoff"
|
|
64
|
+
ACTIVE_SUMMARIES+=("$summary")
|
|
65
|
+
fi
|
|
66
|
+
done < <(find "$TASKS_DIR" -name "*-progress.md" 2>/dev/null)
|
|
67
|
+
|
|
68
|
+
[ ${#ACTIVE_TASKS[@]} -eq 0 ] && exit 0
|
|
69
|
+
|
|
70
|
+
# ── Output context vào stdout (injected vào conversation) ─────────────────────
|
|
71
|
+
echo ""
|
|
72
|
+
echo "---"
|
|
73
|
+
echo "[dw-kit session-init] Task đang in-progress:"
|
|
74
|
+
for summary in "${ACTIVE_SUMMARIES[@]}"; do
|
|
75
|
+
echo " • $summary"
|
|
76
|
+
done
|
|
77
|
+
if [ ${#ACTIVE_TASKS[@]} -eq 1 ]; then
|
|
78
|
+
echo "Context: .dw/tasks/${ACTIVE_TASKS[0]}/"
|
|
79
|
+
else
|
|
80
|
+
echo "Nhiều tasks đang active — hỏi user task nào cần tiếp tục."
|
|
81
|
+
fi
|
|
82
|
+
echo "---"
|
|
83
|
+
echo ""
|
|
84
|
+
|
|
85
|
+
exit 0
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
# Code Style & Conventions
|
|
2
|
-
|
|
3
|
-
## Nguyên tắc chung
|
|
4
|
-
- Đặt tên biến/hàm rõ ràng, tự giải thích (self-documenting)
|
|
5
|
-
- Ưu tiên đơn giản, dễ đọc hơn clever code
|
|
6
|
-
- Mỗi function làm MỘT việc
|
|
7
|
-
- Comments giải thích WHY, không phải WHAT
|
|
8
|
-
- Xử lý errors ở đầu function (guard clauses / early return)
|
|
9
|
-
|
|
10
|
-
## Naming Conventions
|
|
11
|
-
- Variables/Functions: camelCase
|
|
12
|
-
- Classes/Components: PascalCase
|
|
13
|
-
- Constants: UPPER_SNAKE_CASE
|
|
14
|
-
- Files: kebab-case hoặc theo convention của framework
|
|
15
|
-
- Directories: kebab-case
|
|
16
|
-
|
|
17
|
-
## File Organization
|
|
18
|
-
- 1 component/class per file (trừ khi strongly related)
|
|
19
|
-
- Group imports: external → internal → relative
|
|
20
|
-
- Export ở cuối file hoặc inline (nhất quán trong project)
|
|
21
|
-
|
|
22
|
-
## Error Handling
|
|
23
|
-
- KHÔNG swallow errors (catch rỗng)
|
|
24
|
-
- Log đủ context để debug (error message, input data, stack)
|
|
25
|
-
- Dùng custom error types cho domain errors
|
|
26
|
-
- Validate input ở boundary (API, form, external data)
|
|
27
|
-
|
|
28
|
-
## Testing
|
|
29
|
-
- Test file cùng tên với source: `foo.ts` → `foo.test.ts` hoặc `foo.spec.ts`
|
|
30
|
-
- Mỗi test case kiểm tra MỘT behavior
|
|
31
|
-
- Test name mô tả expected behavior: "should return error when input is empty"
|
|
32
|
-
- Arrange → Act → Assert pattern
|
|
33
|
-
- KHÔNG mock internal implementation details
|
|
34
|
-
|
|
35
|
-
## NOTE
|
|
36
|
-
Đây là quy tắc mặc định. Team tùy chỉnh theo stack cụ thể của dự án.
|
|
37
|
-
Thêm framework-specific rules vào file này hoặc tạo file riêng trong `.claude/rules/`.
|
|
1
|
+
# Code Style & Conventions
|
|
2
|
+
|
|
3
|
+
## Nguyên tắc chung
|
|
4
|
+
- Đặt tên biến/hàm rõ ràng, tự giải thích (self-documenting)
|
|
5
|
+
- Ưu tiên đơn giản, dễ đọc hơn clever code
|
|
6
|
+
- Mỗi function làm MỘT việc
|
|
7
|
+
- Comments giải thích WHY, không phải WHAT
|
|
8
|
+
- Xử lý errors ở đầu function (guard clauses / early return)
|
|
9
|
+
|
|
10
|
+
## Naming Conventions
|
|
11
|
+
- Variables/Functions: camelCase
|
|
12
|
+
- Classes/Components: PascalCase
|
|
13
|
+
- Constants: UPPER_SNAKE_CASE
|
|
14
|
+
- Files: kebab-case hoặc theo convention của framework
|
|
15
|
+
- Directories: kebab-case
|
|
16
|
+
|
|
17
|
+
## File Organization
|
|
18
|
+
- 1 component/class per file (trừ khi strongly related)
|
|
19
|
+
- Group imports: external → internal → relative
|
|
20
|
+
- Export ở cuối file hoặc inline (nhất quán trong project)
|
|
21
|
+
|
|
22
|
+
## Error Handling
|
|
23
|
+
- KHÔNG swallow errors (catch rỗng)
|
|
24
|
+
- Log đủ context để debug (error message, input data, stack)
|
|
25
|
+
- Dùng custom error types cho domain errors
|
|
26
|
+
- Validate input ở boundary (API, form, external data)
|
|
27
|
+
|
|
28
|
+
## Testing
|
|
29
|
+
- Test file cùng tên với source: `foo.ts` → `foo.test.ts` hoặc `foo.spec.ts`
|
|
30
|
+
- Mỗi test case kiểm tra MỘT behavior
|
|
31
|
+
- Test name mô tả expected behavior: "should return error when input is empty"
|
|
32
|
+
- Arrange → Act → Assert pattern
|
|
33
|
+
- KHÔNG mock internal implementation details
|
|
34
|
+
|
|
35
|
+
## NOTE
|
|
36
|
+
Đây là quy tắc mặc định. Team tùy chỉnh theo stack cụ thể của dự án.
|
|
37
|
+
Thêm framework-specific rules vào file này hoặc tạo file riêng trong `.claude/rules/`.
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
# Commit Standards
|
|
2
|
-
|
|
3
|
-
## Format
|
|
4
|
-
```
|
|
5
|
-
<type>(<scope>): <mô tả tiếng Việt hoặc tiếng Anh>
|
|
6
|
-
|
|
7
|
-
[Body - chi tiết thay đổi, lý do]
|
|
8
|
-
[Blank line]
|
|
9
|
-
[Footer - breaking changes, references]
|
|
10
|
-
|
|
11
|
-
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## Types
|
|
15
|
-
| Type | Khi nào dùng |
|
|
16
|
-
|------|-------------|
|
|
17
|
-
| `feat` | Tính năng mới |
|
|
18
|
-
| `fix` | Sửa lỗi |
|
|
19
|
-
| `refactor` | Tái cấu trúc, không thay đổi behavior |
|
|
20
|
-
| `test` | Thêm/sửa tests |
|
|
21
|
-
| `docs` | Tài liệu, comments |
|
|
22
|
-
| `chore` | Build, config, dependencies |
|
|
23
|
-
| `style` | Format, whitespace (không thay đổi logic) |
|
|
24
|
-
| `perf` | Cải thiện performance |
|
|
25
|
-
|
|
26
|
-
## Quy tắc
|
|
27
|
-
- Mỗi commit = 1 subtask hoặc 1 đơn vị logic hoàn chỉnh
|
|
28
|
-
- Mô tả ngắn <= 72 ký tự
|
|
29
|
-
- Dùng thì hiện tại: "thêm", "sửa", "cập nhật" (không phải "đã thêm")
|
|
30
|
-
- KHÔNG commit files chứa secrets (.env, credentials, tokens)
|
|
31
|
-
- KHÔNG commit console.log/debugger còn sót
|
|
32
|
-
|
|
33
|
-
## Branch Naming
|
|
34
|
-
```
|
|
35
|
-
<type>/<task-name>
|
|
36
|
-
```
|
|
37
|
-
Ví dụ: `feat/user-auth`, `fix/login-redirect`, `refactor/api-structure`
|
|
1
|
+
# Commit Standards
|
|
2
|
+
|
|
3
|
+
## Format
|
|
4
|
+
```
|
|
5
|
+
<type>(<scope>): <mô tả tiếng Việt hoặc tiếng Anh>
|
|
6
|
+
|
|
7
|
+
[Body - chi tiết thay đổi, lý do]
|
|
8
|
+
[Blank line]
|
|
9
|
+
[Footer - breaking changes, references]
|
|
10
|
+
|
|
11
|
+
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Types
|
|
15
|
+
| Type | Khi nào dùng |
|
|
16
|
+
|------|-------------|
|
|
17
|
+
| `feat` | Tính năng mới |
|
|
18
|
+
| `fix` | Sửa lỗi |
|
|
19
|
+
| `refactor` | Tái cấu trúc, không thay đổi behavior |
|
|
20
|
+
| `test` | Thêm/sửa tests |
|
|
21
|
+
| `docs` | Tài liệu, comments |
|
|
22
|
+
| `chore` | Build, config, dependencies |
|
|
23
|
+
| `style` | Format, whitespace (không thay đổi logic) |
|
|
24
|
+
| `perf` | Cải thiện performance |
|
|
25
|
+
|
|
26
|
+
## Quy tắc
|
|
27
|
+
- Mỗi commit = 1 subtask hoặc 1 đơn vị logic hoàn chỉnh
|
|
28
|
+
- Mô tả ngắn <= 72 ký tự
|
|
29
|
+
- Dùng thì hiện tại: "thêm", "sửa", "cập nhật" (không phải "đã thêm")
|
|
30
|
+
- KHÔNG commit files chứa secrets (.env, credentials, tokens)
|
|
31
|
+
- KHÔNG commit console.log/debugger còn sót
|
|
32
|
+
|
|
33
|
+
## Branch Naming
|
|
34
|
+
```
|
|
35
|
+
<type>/<task-name>
|
|
36
|
+
```
|
|
37
|
+
Ví dụ: `feat/user-auth`, `fix/login-redirect`, `refactor/api-structure`
|
package/.claude/settings.json
CHANGED
|
@@ -1,99 +1,101 @@
|
|
|
1
|
-
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"Bash(git
|
|
9
|
-
"Bash(git
|
|
10
|
-
"Bash(git
|
|
11
|
-
"Bash(git
|
|
12
|
-
"Bash(git
|
|
13
|
-
"Bash(
|
|
14
|
-
"Bash(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"includeCoAuthoredBy": false,
|
|
3
|
+
"permissions": {
|
|
4
|
+
"allow": [
|
|
5
|
+
"Read(*)",
|
|
6
|
+
"Grep(*)",
|
|
7
|
+
"Glob(*)",
|
|
8
|
+
"Bash(git log *)",
|
|
9
|
+
"Bash(git diff *)",
|
|
10
|
+
"Bash(git show *)",
|
|
11
|
+
"Bash(git status)",
|
|
12
|
+
"Bash(git blame *)",
|
|
13
|
+
"Bash(git stash list)",
|
|
14
|
+
"Bash(ls *)",
|
|
15
|
+
"Bash(wc *)",
|
|
16
|
+
"Bash(node src/smoke-test.mjs)"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"hooks": {
|
|
20
|
+
"UserPromptSubmit": [
|
|
21
|
+
{
|
|
22
|
+
"hooks": [
|
|
23
|
+
{
|
|
24
|
+
"type": "command",
|
|
25
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/session-init.sh\""
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"PreToolUse": [
|
|
31
|
+
{
|
|
32
|
+
"matcher": "Read|Glob",
|
|
33
|
+
"hooks": [
|
|
34
|
+
{
|
|
35
|
+
"type": "command",
|
|
36
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/scout-block.sh\""
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"matcher": "Read",
|
|
42
|
+
"hooks": [
|
|
43
|
+
{
|
|
44
|
+
"type": "command",
|
|
45
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/privacy-block.sh\""
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"matcher": "Bash",
|
|
51
|
+
"hooks": [
|
|
52
|
+
{
|
|
53
|
+
"type": "command",
|
|
54
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/pre-commit-gate.sh\""
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"matcher": "Bash",
|
|
60
|
+
"hooks": [
|
|
61
|
+
{
|
|
62
|
+
"type": "command",
|
|
63
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/safety-guard.sh\""
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"PostToolUse": [
|
|
69
|
+
{
|
|
70
|
+
"matcher": "Write|Edit",
|
|
71
|
+
"hooks": [
|
|
72
|
+
{
|
|
73
|
+
"type": "command",
|
|
74
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/post-write.sh\""
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"Stop": [
|
|
80
|
+
{
|
|
81
|
+
"hooks": [
|
|
82
|
+
{
|
|
83
|
+
"type": "command",
|
|
84
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/stop-check.sh\""
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"Notification": [
|
|
90
|
+
{
|
|
91
|
+
"hooks": [
|
|
92
|
+
{
|
|
93
|
+
"type": "command",
|
|
94
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/progress-ping.sh\""
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"mcpServers": {}
|
|
101
|
+
}
|