-
Notifications
You must be signed in to change notification settings - Fork 58
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·314 lines (258 loc) · 10.4 KB
/
install.sh
File metadata and controls
executable file
·314 lines (258 loc) · 10.4 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#!/bin/bash
set -eo pipefail
# Claude Code PROJECT_INDEX Installer
# Installs PROJECT_INDEX to ~/.claude-code-project-index
echo "Claude Code PROJECT_INDEX Installer"
echo "===================================="
echo ""
# Fixed installation location
INSTALL_DIR="$HOME/.claude-code-project-index"
# Detect OS type
if [[ "$OSTYPE" == "darwin"* ]]; then
OS_TYPE="macos"
echo "✓ Detected macOS"
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
OS_TYPE="linux"
echo "✓ Detected Linux"
else
echo "❌ Error: Unsupported OS type: $OSTYPE"
echo "This installer supports macOS and Linux only"
exit 1
fi
# Check dependencies
echo ""
echo "Checking dependencies..."
# Check for git and jq
for cmd in git jq; do
if ! command -v "$cmd" &> /dev/null; then
echo "❌ Error: $cmd is required but not installed"
echo "Please install $cmd and try again"
exit 1
fi
done
# Find Python intelligently
# When running via curl | bash, BASH_SOURCE is not set
if [[ -n "${BASH_SOURCE[0]:-}" ]]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
else
# Running via curl | bash - scripts won't be available yet
SCRIPT_DIR=""
fi
if [[ -n "$SCRIPT_DIR" && -f "$SCRIPT_DIR/scripts/find_python.sh" ]]; then
PYTHON_CMD=$(bash "$SCRIPT_DIR/scripts/find_python.sh")
else
# Fallback to simple check if find_python.sh doesn't exist yet
if command -v python3 &> /dev/null; then
PYTHON_CMD="python3"
elif command -v python &> /dev/null; then
PYTHON_CMD="python"
else
echo "❌ Error: Python 3.8+ is required but not found"
echo "Please install Python 3.8+ and try again"
exit 1
fi
fi
if [[ -z "$PYTHON_CMD" ]]; then
exit 1
fi
echo "✓ All dependencies satisfied"
# Check if already installed
if [[ -d "$INSTALL_DIR" ]]; then
echo ""
echo "⚠️ Found existing installation at $INSTALL_DIR"
# Check if we're running interactively or via pipe
if [ -t 0 ]; then
# Interactive mode - can use read
read -p "Remove and reinstall? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Installation cancelled"
exit 0
fi
else
# Non-interactive mode (curl | bash) - auto-reinstall
echo "Running in non-interactive mode, removing and reinstalling..."
fi
echo "Removing existing installation..."
rm -rf "$INSTALL_DIR"
fi
# Clone or copy repository
echo ""
echo "Installing PROJECT_INDEX..."
# If we're running from the repo, copy files
# (SCRIPT_DIR already set above during Python detection)
if [[ -f "$SCRIPT_DIR/scripts/project_index.py" || -f "$SCRIPT_DIR/README.md" ]]; then
echo "Installing from local repository..."
# Create install directory
mkdir -p "$INSTALL_DIR"
# Copy essential files
cp "$SCRIPT_DIR/install.sh" "$INSTALL_DIR/"
cp "$SCRIPT_DIR/uninstall.sh" "$INSTALL_DIR/" 2>/dev/null || true
cp "$SCRIPT_DIR/scripts/project-index-helper.sh" "$INSTALL_DIR/scripts/" 2>/dev/null || true
cp "$SCRIPT_DIR/README.md" "$INSTALL_DIR/" 2>/dev/null || true
cp "$SCRIPT_DIR/LICENSE" "$INSTALL_DIR/" 2>/dev/null || true
cp "$SCRIPT_DIR/.gitignore" "$INSTALL_DIR/" 2>/dev/null || true
# Create scripts directory and copy all scripts
mkdir -p "$INSTALL_DIR/scripts"
cp "$SCRIPT_DIR"/*.py "$INSTALL_DIR/scripts/" 2>/dev/null || true
cp "$SCRIPT_DIR/scripts"/*.py "$INSTALL_DIR/scripts/" 2>/dev/null || true
cp "$SCRIPT_DIR/scripts"/*.sh "$INSTALL_DIR/scripts/" 2>/dev/null || true
# Copy agent files to Claude's agents directory
if [[ -d "$SCRIPT_DIR/agents" ]]; then
mkdir -p "$HOME/.claude/agents"
cp "$SCRIPT_DIR/agents"/*.md "$HOME/.claude/agents/" 2>/dev/null || true
echo " ✓ Agent files installed to ~/.claude/agents/"
fi
# Remove the old setup script if it was copied
rm -f "$INSTALL_DIR/scripts/setup_hooks.py"
echo "✓ Files copied to $INSTALL_DIR"
else
# Clone from GitHub
echo "Cloning from GitHub..."
git clone https://github.com/ericbuess/claude-code-project-index.git "$INSTALL_DIR"
# Move Python files to scripts directory
mkdir -p "$INSTALL_DIR/scripts"
mv "$INSTALL_DIR"/*.py "$INSTALL_DIR/scripts/" 2>/dev/null || true
rm -f "$INSTALL_DIR/scripts/setup_hooks.py"
# Copy agent files to Claude's agents directory
if [[ -d "$INSTALL_DIR/agents" ]]; then
mkdir -p "$HOME/.claude/agents"
cp "$INSTALL_DIR/agents"/*.md "$HOME/.claude/agents/" 2>/dev/null || true
echo " ✓ Agent files installed to ~/.claude/agents/"
fi
echo "✓ Repository cloned to $INSTALL_DIR"
fi
# Make scripts executable
chmod +x "$INSTALL_DIR/install.sh" 2>/dev/null || true
chmod +x "$INSTALL_DIR/uninstall.sh" 2>/dev/null || true
chmod +x "$INSTALL_DIR/scripts/project-index-helper.sh" 2>/dev/null || true
chmod +x "$INSTALL_DIR/scripts/find_python.sh" 2>/dev/null || true
chmod +x "$INSTALL_DIR/scripts/run_python.sh" 2>/dev/null || true
# Save the Python command for later use
echo "$PYTHON_CMD" > "$INSTALL_DIR/.python_cmd"
echo " ✓ Python command saved: $PYTHON_CMD"
# Create /index command
echo ""
echo "Creating /index command..."
mkdir -p "$HOME/.claude/commands"
cat > "$HOME/.claude/commands/index.md" << 'EOF'
---
name: index
description: Create or update PROJECT_INDEX.json for the current project
---
# PROJECT_INDEX Command
This command creates or updates a PROJECT_INDEX.json file that gives Claude architectural awareness of your codebase.
The indexer script is located at:
`~/.claude-code-project-index/scripts/project_index.py`
## What it does
The PROJECT_INDEX creates a comprehensive map of your project including:
- Directory structure and file organization
- Function and class signatures with type annotations
- Call graphs showing what calls what
- Import dependencies
- Documentation structure
- Directory purposes
## Usage
Simply type `/index` in any project directory to create or update the index.
## About the Tool
**PROJECT_INDEX** is a community tool created by Eric Buess that helps Claude Code understand your project structure better.
- **GitHub**: https://github.com/ericbuess/claude-code-project-index
- **Purpose**: Prevents code duplication, ensures proper file placement, maintains architectural consistency
- **Philosophy**: Fork and customize for your needs - Claude can modify it instantly
## How to Use the Index
After running `/index`, you can:
1. Reference it directly: `@PROJECT_INDEX.json what functions call authenticate_user?`
2. Use with -i flag: `refactor the auth system -i`
3. Add to CLAUDE.md for auto-loading: `@PROJECT_INDEX.json`
## Implementation
When you run `/index`, Claude will:
1. Check if PROJECT_INDEX is installed at ~/.claude-code-project-index
2. Run the indexer script at ~/.claude-code-project-index/scripts/project_index.py to create/update PROJECT_INDEX.json
3. Provide feedback on what was indexed
4. The index is then available as PROJECT_INDEX.json
## Troubleshooting
If the index is too large for your project, ask Claude:
"The indexer creates too large an index. Please modify it to only index src/ and lib/ directories"
For other issues, the tool is designed to be customized - just describe your problem to Claude!
EOF
echo "✓ Created /index command"
# Update hooks in settings.json
echo ""
echo "Configuring hooks..."
SETTINGS_FILE="$HOME/.claude/settings.json"
# Ensure settings.json exists
if [[ ! -f "$SETTINGS_FILE" ]]; then
echo "{}" > "$SETTINGS_FILE"
fi
# Create a backup
cp "$SETTINGS_FILE" "${SETTINGS_FILE}.backup"
# Update hooks using jq - removes old PROJECT_INDEX hooks and adds new ones
jq '
# Initialize hooks if not present
if .hooks == null then .hooks = {} else . end |
# Initialize UserPromptSubmit if not present (for index-aware mode)
if .hooks.UserPromptSubmit == null then .hooks.UserPromptSubmit = [] else . end |
# Filter out any existing PROJECT_INDEX UserPromptSubmit hooks, then add the new one
.hooks.UserPromptSubmit = ([.hooks.UserPromptSubmit[] | select(
all(.hooks[]?.command // "";
contains("i_flag_hook.py") | not) and
all(.hooks[]?.command // "";
contains("project_index") | not)
)] + [{
"hooks": [{
"type": "command",
"command": "'"$HOME"'/.claude-code-project-index/scripts/run_python.sh '"$HOME"'/.claude-code-project-index/scripts/i_flag_hook.py",
"timeout": 20
}]
}]) |
# Initialize Stop if not present
if .hooks.Stop == null then .hooks.Stop = [] else . end |
# Filter out any existing PROJECT_INDEX Stop hooks, then add the new one
.hooks.Stop = ([.hooks.Stop[] | select(
all(.hooks[]?.command // "";
contains("stop_hook.py") | not) and
all(.hooks[]?.command // "";
contains("reindex_if_needed.py") | not) and
all(.hooks[]?.command // "";
contains("project_index") | not)
)] + [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "'"$HOME"'/.claude-code-project-index/scripts/run_python.sh '"$HOME"'/.claude-code-project-index/scripts/stop_hook.py",
"timeout": 10
}]
}])
' "$SETTINGS_FILE" > "${SETTINGS_FILE}.tmp" && mv "${SETTINGS_FILE}.tmp" "$SETTINGS_FILE"
echo "✓ Hooks configured in settings.json"
# Test installation
echo ""
echo "Testing installation..."
if $PYTHON_CMD "$INSTALL_DIR/scripts/project_index.py" --version 2>/dev/null | grep -q "PROJECT_INDEX"; then
echo "✓ Installation test passed"
else
echo "⚠️ Version check failed, but installation completed"
echo " You can still use /index command normally"
fi
echo ""
echo "=========================================="
echo "✅ PROJECT_INDEX installed successfully!"
echo "=========================================="
echo ""
echo "📁 Installation location: $INSTALL_DIR"
echo ""
echo "📝 Manual cleanup needed:"
echo " Please remove these old files from ~/.claude/scripts/ if they exist:"
echo " • project_index.py"
echo " • update_index.py"
echo " • reindex_if_needed.py"
echo " • index_utils.py"
echo " • detect_external_changes.py"
echo ""
echo "🚀 Usage:"
echo " • Add -i flag to any prompt for index-aware mode (e.g., 'fix auth bug -i')"
echo " • Use -ic flag to export to clipboard for large context AI models"
echo " • Reference with @PROJECT_INDEX.json when you need architectural awareness"
echo " • The index is created automatically when you use -i flag"
echo ""
echo "📚 For more information, see: $INSTALL_DIR/README.md"