-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.py
More file actions
127 lines (102 loc) · 3.91 KB
/
install.py
File metadata and controls
127 lines (102 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env python3
"""
Install claude-session-logger hooks and commands to ~/.claude/
Usage:
python install.py # Install to ~/.claude/
python install.py --check # Check what would be installed
python install.py --force # Overwrite existing files
"""
import argparse
import shutil
import subprocess
import sys
from pathlib import Path
def get_claude_dir() -> Path:
"""Get the ~/.claude directory path."""
return Path.home() / ".claude"
def install(check_only: bool = False, force: bool = False) -> bool:
"""Install hooks and commands to ~/.claude/"""
script_dir = Path(__file__).parent
claude_dir = get_claude_dir()
# Files to install (source path relative to this script, destination relative to ~/.claude/)
files = [
("hooks/scripts/log-command.py", "hooks/log-command.py"),
("hooks/scripts/run-hook.mjs", "hooks/run-hook.mjs"),
("hooks/scripts/rename_session.py", "hooks/rename_session.py"),
("commands/renameAI.md", "commands/renameAI.md"),
("commands/sessioninfo.md", "commands/sessioninfo.md"),
]
print(f"Claude directory: {claude_dir}")
print()
if check_only:
print("Files to install:")
for src_rel, dst_rel in files:
src = script_dir / src_rel
dst = claude_dir / dst_rel
exists = dst.exists()
status = " (exists, will skip)" if exists and not force else ""
status = " (exists, will overwrite)" if exists and force else status
print(f" {src_rel} -> {dst_rel}{status}")
print()
print("Run without --check to install.")
return True
# Create directories
(claude_dir / "hooks").mkdir(parents=True, exist_ok=True)
(claude_dir / "commands").mkdir(parents=True, exist_ok=True)
installed = 0
skipped = 0
for src_rel, dst_rel in files:
src = script_dir / src_rel
dst = claude_dir / dst_rel
if not src.exists():
print(f" ERROR: Source file not found: {src}")
continue
if dst.exists() and not force:
print(f" SKIP: {dst_rel} (exists, use --force to overwrite)")
skipped += 1
continue
shutil.copy2(src, dst)
print(f" OK: {dst_rel}")
installed += 1
print()
print(f"Installed: {installed}, Skipped: {skipped}")
# Install required Python dependency
if not check_only and installed > 0:
print()
print("Installing dazzle-filekit...")
pkg = "dazzle-filekit>=0.2.1"
strategies = [
[sys.executable, "-m", "pip", "install", pkg],
[sys.executable, "-m", "pip", "install", "--user", pkg],
[sys.executable, "-m", "pip", "install", "--break-system-packages", pkg],
]
dep_installed = False
for cmd in strategies:
try:
subprocess.check_call(cmd, timeout=30)
dep_installed = True
break
except Exception:
continue
if not dep_installed:
print(" WARNING: Could not install dazzle-filekit automatically.")
print(" Please install manually: pip install dazzle-filekit")
if installed > 0:
print()
print("Next steps:")
print(" 1. Add hooks to ~/.claude/settings.json (see README.md)")
print(" 2. Restart Claude Code")
return True
def main():
parser = argparse.ArgumentParser(description="Install claude-session-logger")
parser.add_argument("--check", action="store_true", help="Check what would be installed")
parser.add_argument("--force", action="store_true", help="Overwrite existing files")
args = parser.parse_args()
try:
success = install(check_only=args.check, force=args.force)
sys.exit(0 if success else 1)
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()