uv-suite 0.5.0 → 0.7.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/bin/cli.js +96 -38
- package/hooks/session-end.sh +51 -0
- package/hooks/session-start.sh +18 -0
- package/hooks/session-timer.sh +56 -0
- package/hooks/status-line.sh +46 -0
- package/install.sh +6 -3
- package/package.json +2 -1
- package/personas/auto.json +27 -0
- package/personas/professional.json +29 -2
- package/personas/spike.json +21 -0
- package/personas/sport.json +21 -0
package/bin/cli.js
CHANGED
|
@@ -1,49 +1,52 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { execSync } = require('child_process');
|
|
3
|
+
const { execSync, spawn } = require('child_process');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
|
|
7
7
|
const UV_SUITE_DIR = path.resolve(__dirname, '..');
|
|
8
8
|
const args = process.argv.slice(2);
|
|
9
9
|
const command = args[0];
|
|
10
|
+
const pkg = require(path.join(UV_SUITE_DIR, 'package.json'));
|
|
11
|
+
|
|
12
|
+
const PERSONAS = ['spike', 'sport', 'pro', 'professional', 'auto'];
|
|
13
|
+
const TOOLS = ['claude', 'codex'];
|
|
10
14
|
|
|
11
15
|
function usage() {
|
|
12
16
|
console.log(`
|
|
13
|
-
uv
|
|
17
|
+
uv v${pkg.version} — AI-assisted development framework
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
Launch a session:
|
|
20
|
+
uv claude pro Claude Code, Professional persona
|
|
21
|
+
uv claude auto Claude Code, Auto persona
|
|
22
|
+
uv codex pro Codex, Professional persona
|
|
23
|
+
uv codex sport Codex, Sport persona
|
|
24
|
+
uv pro Shorthand (defaults to Claude Code)
|
|
25
|
+
uv Claude Code, Professional
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
install
|
|
21
|
-
|
|
27
|
+
Setup:
|
|
28
|
+
uv install Install UV Suite into current project
|
|
29
|
+
uv install --persona sport
|
|
30
|
+
uv info Show what's installed
|
|
22
31
|
|
|
23
32
|
Personas:
|
|
24
|
-
spike
|
|
25
|
-
sport
|
|
26
|
-
|
|
27
|
-
auto
|
|
28
|
-
|
|
29
|
-
Examples:
|
|
30
|
-
npx uv-suite install Install with Professional persona
|
|
31
|
-
npx uv-suite install --persona sport Install with Sport persona
|
|
32
|
-
npx uv-suite install --global Install to ~/.claude/
|
|
33
|
+
spike Research & docs (Opus, max effort)
|
|
34
|
+
sport New projects (Sonnet, high effort)
|
|
35
|
+
pro Production code (all hooks, all guardrails)
|
|
36
|
+
auto Fully autonomous (max effort, everything approved)
|
|
33
37
|
`);
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
function info() {
|
|
37
41
|
console.log(`
|
|
38
|
-
UV Suite
|
|
42
|
+
UV Suite v${pkg.version}
|
|
39
43
|
|
|
40
44
|
Contents:
|
|
41
45
|
10 agents Claude Code (.md), Cursor (.mdc), Codex (.toml)
|
|
42
46
|
9 skills Slash commands for Claude Code
|
|
43
|
-
|
|
44
|
-
6 guardrails Anti-slop rules
|
|
47
|
+
5 hooks auto-lint, slop-check, danger-zone, block-destructive, review-reminder
|
|
48
|
+
6 guardrails Anti-slop rules
|
|
45
49
|
4 personas Spike, Sport, Professional, Auto
|
|
46
|
-
1 launcher uv.sh (session launcher with persona selection)
|
|
47
50
|
|
|
48
51
|
Source: ${UV_SUITE_DIR}
|
|
49
52
|
`);
|
|
@@ -55,8 +58,6 @@ function install() {
|
|
|
55
58
|
console.error('Error: install.sh not found at', installScript);
|
|
56
59
|
process.exit(1);
|
|
57
60
|
}
|
|
58
|
-
|
|
59
|
-
// Pass through all args after "install"
|
|
60
61
|
const installArgs = args.slice(1).join(' ');
|
|
61
62
|
try {
|
|
62
63
|
execSync(`bash "${installScript}" ${installArgs}`, { stdio: 'inherit' });
|
|
@@ -65,20 +66,77 @@ function install() {
|
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
69
|
+
function normPersona(p) {
|
|
70
|
+
if (p === 'pro' || p === 'professional') return 'professional';
|
|
71
|
+
if (PERSONAS.includes(p)) return p;
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function personaLabel(p) {
|
|
76
|
+
const labels = {
|
|
77
|
+
spike: 'Spike — research & docs (Opus, max)',
|
|
78
|
+
sport: 'Sport — lightweight (Sonnet, high)',
|
|
79
|
+
professional: 'Professional — full rigor (all hooks, all guardrails)',
|
|
80
|
+
auto: 'Auto — autonomous (max, everything approved)',
|
|
81
|
+
};
|
|
82
|
+
return labels[p] || p;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function launchClaude(persona, extra) {
|
|
86
|
+
const settings = path.resolve('.claude/personas', `${persona}.json`);
|
|
87
|
+
if (!fs.existsSync(settings)) {
|
|
88
|
+
console.error(`Error: ${settings} not found. Run 'uv install' first.`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
console.log(`UV Suite | Claude Code | ${personaLabel(persona)}`);
|
|
92
|
+
console.log('');
|
|
93
|
+
const child = spawn('claude', ['--settings', settings, ...extra], { stdio: 'inherit' });
|
|
94
|
+
child.on('exit', (code) => process.exit(code || 0));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function launchCodex(persona, extra) {
|
|
98
|
+
const approvalMap = {
|
|
99
|
+
spike: ['--model', 'o3', '--approval-mode', 'suggest'],
|
|
100
|
+
sport: ['--approval-mode', 'auto-edit'],
|
|
101
|
+
professional: ['--approval-mode', 'suggest'],
|
|
102
|
+
auto: ['--approval-mode', 'full-auto'],
|
|
103
|
+
};
|
|
104
|
+
const codexArgs = approvalMap[persona] || ['--approval-mode', 'suggest'];
|
|
105
|
+
console.log(`UV Suite | Codex | ${personaLabel(persona)}`);
|
|
106
|
+
console.log('');
|
|
107
|
+
const child = spawn('codex', [...codexArgs, ...extra], { stdio: 'inherit' });
|
|
108
|
+
child.on('exit', (code) => process.exit(code || 0));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// --- Parse and route ---
|
|
112
|
+
|
|
113
|
+
if (!command || command === '--help' || command === '-h') {
|
|
114
|
+
usage();
|
|
115
|
+
process.exit(0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (command === 'install') {
|
|
119
|
+
install();
|
|
120
|
+
} else if (command === 'info') {
|
|
121
|
+
info();
|
|
122
|
+
} else if (TOOLS.includes(command)) {
|
|
123
|
+
// uv claude pro, uv codex auto
|
|
124
|
+
const persona = normPersona(args[1] || 'pro');
|
|
125
|
+
if (!persona) {
|
|
126
|
+
console.error(`Unknown persona: ${args[1]}`);
|
|
127
|
+
console.error('Available: spike, sport, pro, auto');
|
|
83
128
|
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
const extra = args.slice(2);
|
|
131
|
+
if (command === 'claude') launchClaude(persona, extra);
|
|
132
|
+
else launchCodex(persona, extra);
|
|
133
|
+
} else if (normPersona(command)) {
|
|
134
|
+
// uv pro (shorthand for uv claude pro)
|
|
135
|
+
const persona = normPersona(command);
|
|
136
|
+
const extra = args.slice(1);
|
|
137
|
+
launchClaude(persona, extra);
|
|
138
|
+
} else {
|
|
139
|
+
console.error(`Unknown command: ${command}`);
|
|
140
|
+
usage();
|
|
141
|
+
process.exit(1);
|
|
84
142
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# UV Suite Hook: Session end — reflection and total time
|
|
3
|
+
# Event: Stop (replaces session-review-reminder.sh with richer behavior)
|
|
4
|
+
|
|
5
|
+
STATE_DIR="${CLAUDE_PROJECT_DIR:-.}/.uv-suite-state"
|
|
6
|
+
START_FILE="$STATE_DIR/session-start.txt"
|
|
7
|
+
|
|
8
|
+
# Compute session duration
|
|
9
|
+
DURATION_MSG=""
|
|
10
|
+
if [ -f "$START_FILE" ]; then
|
|
11
|
+
START=$(cat "$START_FILE")
|
|
12
|
+
NOW=$(date +%s)
|
|
13
|
+
ELAPSED=$((NOW - START))
|
|
14
|
+
MINUTES=$((ELAPSED / 60))
|
|
15
|
+
|
|
16
|
+
# Add to today's total
|
|
17
|
+
TODAY=$(date +%Y-%m-%d)
|
|
18
|
+
TODAY_FILE="$STATE_DIR/active-$TODAY.txt"
|
|
19
|
+
TODAY_TOTAL=$(cat "$TODAY_FILE" 2>/dev/null || echo "0")
|
|
20
|
+
TODAY_TOTAL=$((TODAY_TOTAL + MINUTES))
|
|
21
|
+
echo "$TODAY_TOTAL" > "$TODAY_FILE"
|
|
22
|
+
|
|
23
|
+
DURATION_MSG="Session: ${MINUTES} min. Today: ${TODAY_TOTAL} min. "
|
|
24
|
+
|
|
25
|
+
# Reset session state
|
|
26
|
+
rm -f "$START_FILE" "$STATE_DIR/tool-count.txt" "$STATE_DIR/last-warning.txt"
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Check for uncommitted changes
|
|
30
|
+
STAGED=$(git diff --cached --stat 2>/dev/null)
|
|
31
|
+
UNSTAGED=$(git diff --stat 2>/dev/null)
|
|
32
|
+
UNTRACKED=$(git ls-files --others --exclude-standard 2>/dev/null | head -5)
|
|
33
|
+
|
|
34
|
+
REVIEW_MSG=""
|
|
35
|
+
if [ -n "$STAGED" ] || [ -n "$UNSTAGED" ] || [ -n "$UNTRACKED" ]; then
|
|
36
|
+
REVIEW_MSG="Uncommitted changes — consider /review and /slop-check before committing. "
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Reflection prompt
|
|
40
|
+
REFLECTION_MSG="Before closing: What shipped? What did you learn? What would you teach the agent for next time (add to CLAUDE.md or DANGER-ZONES.md)?"
|
|
41
|
+
|
|
42
|
+
FULL_MSG="${DURATION_MSG}${REVIEW_MSG}${REFLECTION_MSG}"
|
|
43
|
+
|
|
44
|
+
cat <<EOF
|
|
45
|
+
{
|
|
46
|
+
"continue": true,
|
|
47
|
+
"systemMessage": "$FULL_MSG"
|
|
48
|
+
}
|
|
49
|
+
EOF
|
|
50
|
+
|
|
51
|
+
exit 0
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# UV Suite Hook: Session start — record start time
|
|
3
|
+
# Event: SessionStart
|
|
4
|
+
|
|
5
|
+
STATE_DIR="${CLAUDE_PROJECT_DIR:-.}/.uv-suite-state"
|
|
6
|
+
mkdir -p "$STATE_DIR"
|
|
7
|
+
|
|
8
|
+
# Record session start time
|
|
9
|
+
date +%s > "$STATE_DIR/session-start.txt"
|
|
10
|
+
|
|
11
|
+
# Track today's total active time
|
|
12
|
+
TODAY=$(date +%Y-%m-%d)
|
|
13
|
+
TODAY_FILE="$STATE_DIR/active-$TODAY.txt"
|
|
14
|
+
if [ ! -f "$TODAY_FILE" ]; then
|
|
15
|
+
echo "0" > "$TODAY_FILE"
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
exit 0
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# UV Suite Hook: Session timer — warn about session duration
|
|
3
|
+
# Event: PostToolUse (runs every Nth tool call)
|
|
4
|
+
# Escalates: 45min → gentle, 90min → firm, 180min → strong
|
|
5
|
+
|
|
6
|
+
STATE_DIR="${CLAUDE_PROJECT_DIR:-.}/.uv-suite-state"
|
|
7
|
+
START_FILE="$STATE_DIR/session-start.txt"
|
|
8
|
+
|
|
9
|
+
# Only check every 20th tool call to avoid noise
|
|
10
|
+
COUNT_FILE="$STATE_DIR/tool-count.txt"
|
|
11
|
+
COUNT=$(cat "$COUNT_FILE" 2>/dev/null || echo "0")
|
|
12
|
+
COUNT=$((COUNT + 1))
|
|
13
|
+
echo "$COUNT" > "$COUNT_FILE"
|
|
14
|
+
|
|
15
|
+
if [ $((COUNT % 20)) -ne 0 ]; then
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
if [ ! -f "$START_FILE" ]; then
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
START=$(cat "$START_FILE")
|
|
24
|
+
NOW=$(date +%s)
|
|
25
|
+
ELAPSED=$((NOW - START))
|
|
26
|
+
MINUTES=$((ELAPSED / 60))
|
|
27
|
+
|
|
28
|
+
# Check if we've already shown a warning for this threshold
|
|
29
|
+
LAST_WARN_FILE="$STATE_DIR/last-warning.txt"
|
|
30
|
+
LAST_WARN=$(cat "$LAST_WARN_FILE" 2>/dev/null || echo "0")
|
|
31
|
+
|
|
32
|
+
MESSAGE=""
|
|
33
|
+
WARN_LEVEL=0
|
|
34
|
+
|
|
35
|
+
if [ "$MINUTES" -ge 180 ] && [ "$LAST_WARN" -lt 3 ]; then
|
|
36
|
+
MESSAGE="SESSION HEALTH (3+ hours): You've been in this session for ${MINUTES} minutes. This is a long stretch. Strongly consider: (1) commit what you have, (2) close this session, (3) take a real break away from the screen. Long uninterrupted agent sessions lead to goal drift, lower judgment quality, and burnout. /compact if you must continue, but a break is better."
|
|
37
|
+
WARN_LEVEL=3
|
|
38
|
+
elif [ "$MINUTES" -ge 90 ] && [ "$LAST_WARN" -lt 2 ]; then
|
|
39
|
+
MESSAGE="SESSION HEALTH (90+ min): You've been in this session for ${MINUTES} minutes. Consider taking a 10-minute break — stretch, water, walk. Come back with fresh eyes. Also a good time to commit progress."
|
|
40
|
+
WARN_LEVEL=2
|
|
41
|
+
elif [ "$MINUTES" -ge 45 ] && [ "$LAST_WARN" -lt 1 ]; then
|
|
42
|
+
MESSAGE="SESSION HEALTH (45 min): You've been in this session for ${MINUTES} minutes. Good time for a quick break and to commit any progress."
|
|
43
|
+
WARN_LEVEL=1
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [ -n "$MESSAGE" ]; then
|
|
47
|
+
echo "$WARN_LEVEL" > "$LAST_WARN_FILE"
|
|
48
|
+
cat <<EOF
|
|
49
|
+
{
|
|
50
|
+
"continue": true,
|
|
51
|
+
"systemMessage": "$MESSAGE"
|
|
52
|
+
}
|
|
53
|
+
EOF
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
exit 0
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# UV Suite Hook: Status line — show session duration and persona
|
|
3
|
+
# Event: statusLine (rendered continuously)
|
|
4
|
+
|
|
5
|
+
STATE_DIR="${CLAUDE_PROJECT_DIR:-.}/.uv-suite-state"
|
|
6
|
+
START_FILE="$STATE_DIR/session-start.txt"
|
|
7
|
+
|
|
8
|
+
# Session duration
|
|
9
|
+
if [ -f "$START_FILE" ]; then
|
|
10
|
+
START=$(cat "$START_FILE")
|
|
11
|
+
NOW=$(date +%s)
|
|
12
|
+
ELAPSED=$((NOW - START))
|
|
13
|
+
MINS=$((ELAPSED / 60))
|
|
14
|
+
|
|
15
|
+
if [ "$MINS" -ge 180 ]; then
|
|
16
|
+
SESSION="session ${MINS}m (!! take a break)"
|
|
17
|
+
elif [ "$MINS" -ge 90 ]; then
|
|
18
|
+
SESSION="session ${MINS}m (break soon)"
|
|
19
|
+
elif [ "$MINS" -ge 45 ]; then
|
|
20
|
+
SESSION="session ${MINS}m"
|
|
21
|
+
else
|
|
22
|
+
SESSION="session ${MINS}m"
|
|
23
|
+
fi
|
|
24
|
+
else
|
|
25
|
+
SESSION="session 0m"
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Today's total active time
|
|
29
|
+
TODAY=$(date +%Y-%m-%d)
|
|
30
|
+
TODAY_FILE="$STATE_DIR/active-$TODAY.txt"
|
|
31
|
+
if [ -f "$TODAY_FILE" ]; then
|
|
32
|
+
TODAY_TOTAL=$(cat "$TODAY_FILE")
|
|
33
|
+
CURRENT_MINS=${MINS:-0}
|
|
34
|
+
TODAY_NOW=$((TODAY_TOTAL + CURRENT_MINS))
|
|
35
|
+
TODAY_STR=" · today ${TODAY_NOW}m"
|
|
36
|
+
else
|
|
37
|
+
TODAY_STR=""
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Persona from settings path (best-effort detection)
|
|
41
|
+
PERSONA=""
|
|
42
|
+
if [ -f "$CLAUDE_PROJECT_DIR/.claude/settings.local.json" ]; then
|
|
43
|
+
PERSONA=$(grep -o '"effort"[^,]*' "$CLAUDE_PROJECT_DIR/.claude/settings.local.json" 2>/dev/null | head -1)
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
echo "UV Suite · $SESSION$TODAY_STR"
|
package/install.sh
CHANGED
|
@@ -112,13 +112,16 @@ echo " ✓ /map-codebase, /spec, /architect, /review, /write-tests"
|
|
|
112
112
|
echo " ✓ /write-evals, /slop-check, /prototype, /security-review"
|
|
113
113
|
|
|
114
114
|
# --- Install hooks ---
|
|
115
|
-
echo "Installing
|
|
115
|
+
echo "Installing hook scripts..."
|
|
116
116
|
cp "$UV_SUITE_DIR/hooks/"*.sh "$TARGET_DIR/hooks/"
|
|
117
117
|
chmod +x "$TARGET_DIR/hooks/"*.sh
|
|
118
|
-
echo " ✓ auto-lint.sh (PostToolUse: auto-format
|
|
118
|
+
echo " ✓ auto-lint.sh (PostToolUse: auto-format)"
|
|
119
119
|
echo " ✓ danger-zone-check.sh (PreToolUse: warn on danger zone files)"
|
|
120
120
|
echo " ✓ block-destructive.sh (PreToolUse: block rm -rf, force push, etc.)"
|
|
121
|
-
echo " ✓ session-
|
|
121
|
+
echo " ✓ session-start.sh (SessionStart: track session start time)"
|
|
122
|
+
echo " ✓ session-timer.sh (PostToolUse: warn at 45/90/180 min)"
|
|
123
|
+
echo " ✓ session-end.sh (Stop: reflection + duration + review reminder)"
|
|
124
|
+
echo " ✓ status-line.sh (statusLine: show session time continuously)"
|
|
122
125
|
echo " + Real-time slop check (Haiku prompt hook, wired in settings.json)"
|
|
123
126
|
|
|
124
127
|
# --- Install guardrail rules (Sport only) ---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uv-suite",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Portable framework for AI-assisted software development. 10 agents, 9 skills, 5 hooks, 4 personas. Works with Claude Code, Cursor, and Codex.",
|
|
5
5
|
"author": "Utsav Anand",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"repomix": "^0.3.0"
|
|
25
25
|
},
|
|
26
26
|
"bin": {
|
|
27
|
+
"uv": "./bin/cli.js",
|
|
27
28
|
"uv-suite": "./bin/cli.js"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
package/personas/auto.json
CHANGED
|
@@ -50,6 +50,14 @@
|
|
|
50
50
|
},
|
|
51
51
|
|
|
52
52
|
"hooks": {
|
|
53
|
+
"SessionStart": [
|
|
54
|
+
{
|
|
55
|
+
"matcher": "*",
|
|
56
|
+
"hooks": [
|
|
57
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-start.sh", "timeout": 5 }
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
],
|
|
53
61
|
"PreToolUse": [
|
|
54
62
|
{
|
|
55
63
|
"matcher": "Bash",
|
|
@@ -64,6 +72,12 @@
|
|
|
64
72
|
}
|
|
65
73
|
],
|
|
66
74
|
"PostToolUse": [
|
|
75
|
+
{
|
|
76
|
+
"matcher": "*",
|
|
77
|
+
"hooks": [
|
|
78
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-timer.sh", "timeout": 5 }
|
|
79
|
+
]
|
|
80
|
+
},
|
|
67
81
|
{
|
|
68
82
|
"matcher": "Edit|Write",
|
|
69
83
|
"hooks": [
|
|
@@ -75,6 +89,19 @@
|
|
|
75
89
|
}
|
|
76
90
|
]
|
|
77
91
|
}
|
|
92
|
+
],
|
|
93
|
+
"Stop": [
|
|
94
|
+
{
|
|
95
|
+
"matcher": "*",
|
|
96
|
+
"hooks": [
|
|
97
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-end.sh", "timeout": 10 }
|
|
98
|
+
]
|
|
99
|
+
}
|
|
78
100
|
]
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
"statusLine": {
|
|
104
|
+
"type": "command",
|
|
105
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/status-line.sh"
|
|
79
106
|
}
|
|
80
107
|
}
|
|
@@ -48,6 +48,18 @@
|
|
|
48
48
|
},
|
|
49
49
|
|
|
50
50
|
"hooks": {
|
|
51
|
+
"SessionStart": [
|
|
52
|
+
{
|
|
53
|
+
"matcher": "*",
|
|
54
|
+
"hooks": [
|
|
55
|
+
{
|
|
56
|
+
"type": "command",
|
|
57
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-start.sh",
|
|
58
|
+
"timeout": 5
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
],
|
|
51
63
|
"PreToolUse": [
|
|
52
64
|
{
|
|
53
65
|
"matcher": "Bash",
|
|
@@ -73,6 +85,16 @@
|
|
|
73
85
|
}
|
|
74
86
|
],
|
|
75
87
|
"PostToolUse": [
|
|
88
|
+
{
|
|
89
|
+
"matcher": "*",
|
|
90
|
+
"hooks": [
|
|
91
|
+
{
|
|
92
|
+
"type": "command",
|
|
93
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-timer.sh",
|
|
94
|
+
"timeout": 5
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
},
|
|
76
98
|
{
|
|
77
99
|
"matcher": "Edit|Write",
|
|
78
100
|
"hooks": [
|
|
@@ -98,12 +120,17 @@
|
|
|
98
120
|
"hooks": [
|
|
99
121
|
{
|
|
100
122
|
"type": "command",
|
|
101
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-
|
|
123
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-end.sh",
|
|
102
124
|
"timeout": 10,
|
|
103
|
-
"statusMessage": "
|
|
125
|
+
"statusMessage": "Wrapping up session..."
|
|
104
126
|
}
|
|
105
127
|
]
|
|
106
128
|
}
|
|
107
129
|
]
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
"statusLine": {
|
|
133
|
+
"type": "command",
|
|
134
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/status-line.sh"
|
|
108
135
|
}
|
|
109
136
|
}
|
package/personas/spike.json
CHANGED
|
@@ -36,6 +36,14 @@
|
|
|
36
36
|
},
|
|
37
37
|
|
|
38
38
|
"hooks": {
|
|
39
|
+
"SessionStart": [
|
|
40
|
+
{
|
|
41
|
+
"matcher": "*",
|
|
42
|
+
"hooks": [
|
|
43
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-start.sh", "timeout": 5 }
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
],
|
|
39
47
|
"PostToolUse": [
|
|
40
48
|
{
|
|
41
49
|
"matcher": "Write",
|
|
@@ -49,6 +57,19 @@
|
|
|
49
57
|
}
|
|
50
58
|
]
|
|
51
59
|
}
|
|
60
|
+
],
|
|
61
|
+
"Stop": [
|
|
62
|
+
{
|
|
63
|
+
"matcher": "*",
|
|
64
|
+
"hooks": [
|
|
65
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-end.sh", "timeout": 10 }
|
|
66
|
+
]
|
|
67
|
+
}
|
|
52
68
|
]
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
"statusLine": {
|
|
72
|
+
"type": "command",
|
|
73
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/status-line.sh"
|
|
53
74
|
}
|
|
54
75
|
}
|
package/personas/sport.json
CHANGED
|
@@ -22,6 +22,14 @@
|
|
|
22
22
|
},
|
|
23
23
|
|
|
24
24
|
"hooks": {
|
|
25
|
+
"SessionStart": [
|
|
26
|
+
{
|
|
27
|
+
"matcher": "*",
|
|
28
|
+
"hooks": [
|
|
29
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-start.sh", "timeout": 5 }
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
],
|
|
25
33
|
"PostToolUse": [
|
|
26
34
|
{
|
|
27
35
|
"matcher": "Edit|Write",
|
|
@@ -34,6 +42,19 @@
|
|
|
34
42
|
}
|
|
35
43
|
]
|
|
36
44
|
}
|
|
45
|
+
],
|
|
46
|
+
"Stop": [
|
|
47
|
+
{
|
|
48
|
+
"matcher": "*",
|
|
49
|
+
"hooks": [
|
|
50
|
+
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-end.sh", "timeout": 10 }
|
|
51
|
+
]
|
|
52
|
+
}
|
|
37
53
|
]
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
"statusLine": {
|
|
57
|
+
"type": "command",
|
|
58
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/status-line.sh"
|
|
38
59
|
}
|
|
39
60
|
}
|