
Brewcode:Grepai
- 19 installs
- 29 repo stars
- Updated August 2, 2026
- kochetkov-ma/claude-brewcode
Helps with ai & agent building tasks.
About
brewcode:grepai is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- brewcode:grepai
- AI & Agent Building
- AI-coding skill
Brewcode:Grepai by the numbers
- 19 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #10,587 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kochetkov-ma/claude-brewcode --skill brewcodegrepaiAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 19 |
|---|---|
| repo stars | ★ 29 |
| Last updated | August 2, 2026 |
| Repository | kochetkov-ma/claude-brewcode ↗ |
What it does
Helps with ai & agent building tasks.
Files
grepai Skill
Environment: Ollama + bge-m3 | GOB storage | Java/Kotlin/JS/TS
<instructions>
Mode Detection
Step 1: Detect Mode (MANDATORY FIRST STEP)
EXECUTE using Bash tool — detect mode from skill arguments:
bash "${CLAUDE_SKILL_DIR}/scripts/detect-mode.sh" "$ARGUMENTS"Use $ARGUMENTS directly - it contains the skill invocation arguments.
Output format:
ARGS: [arguments received]
MODE: [detected mode]Use the MODE value and GOTO that section below.
Mode Reference
| Keyword in args | MODE |
|---|---|
| upgrade, апгрейд | upgrade |
| optimize, update, улучши, обнови | optimize |
| stop, halt, kill | stop |
| start, watch | start |
| status, doctor, check, health | status |
| setup, configure, init | setup |
| reindex, rebuild, refresh | reindex |
| (empty) + .grepai/ exists | start |
| (empty) + no .grepai/ | setup |
| (unrecognized text) | prompt |
Prerequisites: Run /brewcode:setup first to install brew, ollama, grepai, etc.---
Mode: setup
Full grepai installation and project setup.
Phase 1: Infrastructure Check
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/infra-check.sh" && echo "✅ infra-check" || echo "❌ infra-check FAILED"STOP if ❌ — install missing components before continuing.
Phase 2: MCP Configuration & Permissions
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/mcp-check.sh" && echo "✅ mcp-check" || echo "❌ mcp-check FAILED"This script configures MCP server and allowedTools permissions.
STOP if ❌ — fix MCP configuration before continuing.
Phase 3: Generate Config
SPAWN the bc-grepai-configurator agent using Task tool:
| Parameter | Value |
|---|---|
subagent_type | brewcode:bc-grepai-configurator |
prompt | Configure grepai for this project. Analyze all build files, test patterns, source structure. Generate optimal .grepai/config.yaml. |
model | opus |
Context: BC_PLUGIN_ROOT is available in agent context (injected by pre-task.mjs hook).WAIT for agent to complete before proceeding.
Phase 4: Initialize Index
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/init-index.sh" && echo "✅ init-index" || echo "❌ init-index FAILED"STOP if ❌ — check .grepai/logs/grepai-watch.log for errors.⏳ Synchronous — Large projects (5k+ files) take 10-30+ min. Monitor: tail -f .grepai/logs/grepai-watch.logPhase 5: Create Rule
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/create-rule.sh" && echo "✅ create-rule" || echo "❌ create-rule FAILED"STOP if ❌ — manually create rule in .claude/rules/.Phase 6: Verification
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/verify.sh" && echo "✅ verify" || echo "❌ verify FAILED"---
Mode: status
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/status.sh" && echo "✅ status" || echo "❌ status FAILED"---
Mode: start
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/start.sh" && echo "✅ start" || echo "❌ start FAILED"---
Mode: stop
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/stop.sh" && echo "✅ stop" || echo "❌ stop FAILED"---
Mode: reindex
Full index rebuild: stop watch → clean → rebuild → restart.
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/reindex.sh" && echo "✅ reindex" || echo "❌ reindex FAILED"⏳ Synchronous — Monitor: `tail -f .grepai/logs/grepai-watch.log`
---
Mode: optimize
Re-analyze project and regenerate config with backup.
Step 1: Backup current config
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/optimize.sh" && echo "✅ optimize-backup" || echo "❌ optimize-backup FAILED"STOP if ❌ — check if .grepai/config.yaml exists.
Step 2: Regenerate config
SPAWN the bc-grepai-configurator agent using Task tool:
| Parameter | Value |
|---|---|
subagent_type | brewcode:bc-grepai-configurator |
prompt | Re-analyze project and regenerate .grepai/config.yaml. Compare with existing config, optimize boost patterns, update trace languages. |
model | opus |
Context: BC_PLUGIN_ROOT is available in agent context (injected by pre-task.mjs hook).WAIT for agent to complete.
Step 3: Reindex with new config
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/reindex.sh" && echo "✅ reindex" || echo "❌ reindex FAILED"---
Mode: upgrade
Update grepai CLI via Homebrew.
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/upgrade.sh" && echo "✅ upgrade" || echo "❌ upgrade FAILED"---
Mode: prompt
Use AskUserQuestion to ask which operation to run:
header: "grepai"
question: "Which grepai operation do you want to run?"
options:
- label: "setup"
description: "Initialize and configure semantic search for this project"
- label: "status"
description: "Check health, index stats, doctor"
- label: "start / watch"
description: "Start watch mode (auto-index on file changes)"
- label: "optimize"
description: "Update and rebuild the search index"For stop, reindex, upgrade — user types via Other. After answer, GOTO that mode section.
</instructions>
---
Output Format
# grepai [MODE]
## Detection
| Field | Value |
|-------|-------|
| Arguments | `$ARGUMENTS` |
| Mode | `[detected mode]` |
## Status
| Component | Status |
|-----------|--------|
| grepai CLI | [✅/❌] |
| ollama | [✅/❌] |
| bge-m3 model | [✅/❌] |
| MCP | [✅/❌] |
| Permissions | [✅/❌] allowedTools |
| .grepai/ | [✅/❌] |
| index | [size/indexing] |
| watch | [running/stopped] |
| rule | [✅/⚠️] |
## Actions Taken
- [action 1]
- [action 2]
## Next Steps
- [if any issues, list resolution steps]# grepai config example
# Copy to .grepai/config.yaml and adapt to your project
version: 1
embedder:
provider: ollama
model: bge-m3 # Best multilingual model, 1.2GB
endpoint: http://localhost:11434
dimensions: 1024 # bge-m3 native dimension
# CRITICAL: Ollama does NOT support parallel embeddings!
# See: https://github.com/ollama/ollama/issues/12591
# Always keep parallelism: 1 for Ollama provider
parallelism: 1
store:
backend: gob # Fast local storage
chunking:
size: 512 # Chars per chunk (smaller = more precise)
overlap: 50 # Overlap between chunks
watch:
debounce_ms: 500 # Wait before re-indexing on file change
search:
boost:
enabled: true
# Penalties: reduce score for test/mock/generated files
penalties:
- pattern: /tests/
factor: 0.5
- pattern: /test/
factor: 0.5
- pattern: _test.
factor: 0.5
- pattern: .test.
factor: 0.5
- pattern: .spec.
factor: 0.5
- pattern: /mocks/
factor: 0.4
- pattern: /fixtures/
factor: 0.4
- pattern: /generated/
factor: 0.4
- pattern: .gen.
factor: 0.4
- pattern: .md
factor: 0.6
- pattern: /docs/
factor: 0.6
# Bonuses: boost score for main source directories
bonuses:
- pattern: /src/
factor: 1.1
- pattern: /lib/
factor: 1.1
- pattern: /app/
factor: 1.1
hybrid:
enabled: false # Hybrid search (semantic + keyword)
k: 60
trace:
mode: fast # Call graph tracing mode
enabled_languages: # Languages for trace analysis
- .go
- .js
- .ts
- .tsx
- .py
- .java
- .rs
exclude_patterns: # Exclude test files from trace
- '*_test.go'
- '*.spec.ts'
- '*.test.ts'
- __tests__/*
update:
check_on_startup: false # Don't check for grepai updates
# Directories to ignore (never index)
ignore:
- .git
- .grepai
- node_modules
- vendor
- dist
- build
- target
- __pycache__
- .venv
- .idea
- .vscode
MIT License
Copyright (c) 2025-2026 Maxim Kochetkov (kochetkov-ma)
https://github.com/kochetkov-ma/claude-brewcode
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Grepai
Sets up and manages semantic code search powered by grepai (Ollama + bge-m3 embeddings). Lets Claude find code by meaning rather than exact keywords -- search for "user authentication" and find validateCredentials().
Quick Start
/brewcode:grepai setupFirst-time setup takes 5-30+ minutes depending on project size. It checks infrastructure, configures MCP, generates an optimal config, builds the index, and creates a Claude rule.
Modes
| Mode | Trigger keywords | What it does |
|---|---|---|
setup | setup, configure, init | Full installation: infra check, MCP config, config generation (via bc-grepai-configurator agent), initial indexing, rule creation |
status | status, doctor, check, health | Reports health of all components: CLI, Ollama, bge-m3, MCP, index, watcher |
start | start, watch | Starts the file watcher -- auto-indexes on code changes |
stop | stop, halt, kill | Stops the file watcher |
reindex | reindex, rebuild, refresh | Full index rebuild: stops watcher, cleans index, rebuilds from scratch, restarts watcher |
optimize | optimize, update | Backs up current config, re-analyzes the project, regenerates config, then reindexes |
upgrade | upgrade | Updates grepai CLI to the latest version via Homebrew |
prompt | (unrecognized text) | Interactive menu -- asks which operation to run |
Auto-detection: Running /brewcode:grepai with no arguments defaults to start if .grepai/ exists, or setup if it does not.
Examples
Good Usage
# First-time setup on a new project
/brewcode:grepai setup
# Check if everything is healthy after a restart
/brewcode:grepai status
# Start the watcher at the beginning of a work session
/brewcode:grepai start
# Rebuild the index after a large merge or branch switch
/brewcode:grepai reindex
# Re-analyze and regenerate config after adding a new module
/brewcode:grepai optimizeCommon Mistakes
# Searching before the index is built -- run setup first
/brewcode:grepai start <-- watcher starts but index is empty
# Running setup again when grepai is already configured -- use reindex or optimize instead
/brewcode:grepai setup <-- overwrites existing config
# Forgetting prerequisites -- run /brewcode:setup before grepai setup
/brewcode:grepai setup <-- fails on missing Ollama or bge-m3Output
After setup completes, the following is created in your project:
| Path | Purpose |
|---|---|
.grepai/config.yaml | Project-specific search configuration (languages, boost patterns, exclusions) |
.grepai/logs/grepai-watch.log | Watcher and indexing logs |
.grepai/index/ | Embedded search index (GOB storage) |
.claude/rules/grepai-*.md | Rule reminding Claude to use grepai for code exploration |
MCP server is configured with grepai_search and related tools (trace_callers, trace_callees, trace_graph).
Tips
- Monitor long indexing runs with
tail -f .grepai/logs/grepai-watch.log-- large projects (5k+ files) can take 10-30+ minutes. - Run `/brewcode:setup` first if you do not have Homebrew, Ollama, or the grepai CLI installed.
- Use `optimize` after structural changes (new modules, renamed packages, changed build config) to regenerate the config with fresh project analysis.
- Check `status` when search results seem off -- it validates every component from CLI to index integrity.
Documentation
Full docs: grepai
#!/bin/bash
set -euo pipefail
# grepai Create Rule + CLAUDE.md entry
echo "=== Create Rule ==="
RULE_FILE=".claude/rules/grepai-first.md"
CLAUDE_MD="CLAUDE.md"
GREPAI_MARKER="grepai_search"
mkdir -p .claude/rules
# TODO: Extract shared CLAUDE.md logic to common function (duplicated in start.sh)
# Add grepai entry to CLAUDE.md (create if not exists)
if [ ! -f "$CLAUDE_MD" ]; then
echo "# CLAUDE.md" > "$CLAUDE_MD"
echo "" >> "$CLAUDE_MD"
echo "## Code Search" >> "$CLAUDE_MD"
echo "" >> "$CLAUDE_MD"
echo "> **CRITICAL:** Use \`grepai_search\` FIRST for code exploration." >> "$CLAUDE_MD"
echo "✅ CLAUDE.md created with grepai entry"
elif ! grep -q "$GREPAI_MARKER" "$CLAUDE_MD" 2>/dev/null; then
echo "" >> "$CLAUDE_MD"
echo "## Code Search" >> "$CLAUDE_MD"
echo "" >> "$CLAUDE_MD"
echo "> **CRITICAL:** Use \`grepai_search\` FIRST for code exploration." >> "$CLAUDE_MD"
echo "✅ CLAUDE.md updated with grepai entry"
else
echo "⏭️ CLAUDE.md already has grepai entry"
fi
# Self-location: derive plugin root from script path
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# Path: scripts/create-rule.sh -> skills/grepai/scripts -> skills/grepai -> skills -> PLUGIN_ROOT
PLUGIN_ROOT="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")"
PLUGIN_TEMPLATES="$PLUGIN_ROOT/templates"
if [ -f "$PLUGIN_TEMPLATES/rules/grepai-first.md.template" ]; then
cp "$PLUGIN_TEMPLATES/rules/grepai-first.md.template" "$RULE_FILE"
echo "✅ Rule updated: $RULE_FILE"
else
echo "⚠️ Template not found, creating default rule"
cat > "$RULE_FILE" << 'RULE'
---
paths:
- "**/*"
description: grepai-first - semantic search FIRST for code exploration
---
# grepai-first
Use grepai as PRIMARY search tool for semantic code search.
| Task | Tool |
|------|------|
| Search by intent | grepai_search |
| Exact text match | Grep |
| File path patterns | Glob |
**Decision:** "Need exact text/pattern?" → YES: Grep/Glob, NO: grepai
RULE
echo "✅ Rule updated (default): $RULE_FILE"
fi
#!/bin/bash
set -euo pipefail
# Detect grepai mode from arguments
# Usage: detect-mode.sh "$ARGUMENTS"
# Output: ARGS and MODE for debugging
ARGS="${1:-}"
ARGS_LOWER=$(echo "$ARGS" | tr '[:upper:]' '[:lower:]')
# Debug output
echo "ARGS: [$ARGS]"
# Determine mode
MODE=""
# Check keywords (order matters - first match wins)
if [[ "$ARGS_LOWER" =~ (upgrade|апгрейд) ]]; then
MODE="upgrade"
elif [[ "$ARGS_LOWER" =~ (optimize|update|улучши|обнови) ]]; then
MODE="optimize"
elif [[ "$ARGS_LOWER" =~ (stop|halt|kill) ]]; then
MODE="stop"
elif [[ "$ARGS_LOWER" =~ (start|watch) ]]; then
MODE="start"
elif [[ "$ARGS_LOWER" =~ (status|doctor|check|health) ]]; then
MODE="status"
elif [[ "$ARGS_LOWER" =~ (setup|configure|init) ]]; then
MODE="setup"
elif [[ "$ARGS_LOWER" =~ (reindex|rebuild|refresh) ]]; then
MODE="reindex"
elif [[ -z "$ARGS" ]]; then
# No arguments - check filesystem
if [[ -d ".grepai" ]]; then
MODE="start"
else
MODE="setup"
fi
else
# Has args but no keyword match
MODE="prompt"
fi
echo "MODE: $MODE"
#!/bin/bash
set -euo pipefail
# grepai Infrastructure Check
echo "=== Infrastructure Check ==="
ERRORS=0
# grepai CLI
if command -v grepai >/dev/null 2>&1; then
echo "✅ grepai: $(grepai version 2>/dev/null || echo 'installed')"
else
echo "❌ grepai: NOT FOUND"
echo " Install: brew install yoanbernabeu/tap/grepai"
ERRORS=$((ERRORS + 1))
fi
# Ollama
if curl -s --connect-timeout 3 --max-time 5 localhost:11434/api/tags >/dev/null 2>&1; then
echo "✅ ollama: running"
else
echo "❌ ollama: not running"
echo " Install: brew install ollama && brew services start ollama"
ERRORS=$((ERRORS + 1))
fi
# bge-m3 model
if ollama list 2>/dev/null | grep -q bge-m3; then
echo "✅ bge-m3: installed"
else
echo "❌ bge-m3: not installed"
echo " Install: ollama pull bge-m3"
ERRORS=$((ERRORS + 1))
fi
exit $ERRORS
#!/bin/bash
set -euo pipefail
# grepai Initialize Index
echo "=== Initialize Index ==="
# Check .grepai exists
if [ ! -d .grepai ]; then
echo "❌ .grepai/ not found. Run setup first: /grepai setup"
exit 1
fi
# Create logs directory
mkdir -p .grepai/logs
# Count indexable files (estimate)
echo ""
echo "--- File Count ---"
FILE_COUNT=$(find . -type f \( -name "*.java" -o -name "*.kt" -o -name "*.kts" -o -name "*.js" -o -name "*.ts" -o -name "*.tsx" -o -name "*.jsx" -o -name "*.go" -o -name "*.py" -o -name "*.rs" -o -name "*.sh" -o -name "*.md" -o -name "*.yaml" -o -name "*.yml" -o -name "*.json" \) -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/target/*" -not -path "*/build/*" -not -path "*/dist/*" -not -path "*/.grepai/*" 2>/dev/null | wc -l | tr -d ' ')
echo "Files to index: ~$FILE_COUNT"
# Estimate time and set timeout
if [ "$FILE_COUNT" -lt 100 ]; then
EST_TIME="<1 min"
TIMEOUT=120
elif [ "$FILE_COUNT" -lt 500 ]; then
EST_TIME="1-3 min"
TIMEOUT=300
elif [ "$FILE_COUNT" -lt 1000 ]; then
EST_TIME="3-7 min"
TIMEOUT=600
elif [ "$FILE_COUNT" -lt 5000 ]; then
EST_TIME="10-30 min"
TIMEOUT=1800
else
EST_TIME="30+ min"
TIMEOUT=3600
fi
echo "Estimated time: $EST_TIME"
echo ""
# Check if index already exists
if [ -f .grepai/index.gob ]; then
echo "⏭️ index.gob already exists ($(du -h .grepai/index.gob | cut -f1))"
echo ""
echo "--- Starting Watch ---"
# Just start watch if not running
if pgrep -f "grepai watch" >/dev/null; then
echo "✅ grepai watch: already running (PID: $(pgrep -f 'grepai watch'))"
else
grepai watch --background --log-dir .grepai/logs 2>/dev/null
sleep 1
if pgrep -f "grepai watch" >/dev/null; then
echo "✅ grepai watch: started (PID: $(pgrep -f 'grepai watch'))"
else
echo "⚠️ grepai watch: not started - check manually"
fi
fi
echo ""
echo "=== Init Complete ==="
echo "✅ index.gob: $(du -h .grepai/index.gob | cut -f1)"
pgrep -f "grepai watch" >/dev/null && echo "✅ watch: running" || echo "⚠️ watch: not running"
exit 0
fi
# No index exists - build it via grepai watch
echo "--- Building Index ---"
WATCH_LOG=".grepai/logs/grepai-watch.log"
> "$WATCH_LOG" # truncate
echo ""
echo " Log: $WATCH_LOG"
echo " Monitor: tail -f $WATCH_LOG"
echo ""
# Start watch in BACKGROUND with logging
grepai watch --background --log-dir .grepai/logs 2>/dev/null
sleep 1
if ! pgrep -f "grepai watch" >/dev/null; then
echo "❌ Failed to start grepai watch"
cat "$WATCH_LOG" 2>/dev/null
exit 1
fi
echo "✅ Watch started (PID: $(pgrep -f 'grepai watch'))"
# Poll for "Initial scan complete" in log
ELAPSED=0
echo "⏳ Waiting for indexing to complete..."
while [ "$ELAPSED" -lt "$TIMEOUT" ]; do
# Check completion marker in log
if grep -q "Initial scan complete" "$WATCH_LOG" 2>/dev/null; then
echo ""
echo "✅ Initial scan complete"
break
fi
# Check watch still running
if ! pgrep -f "grepai watch" >/dev/null; then
echo ""
echo "❌ Watch process died unexpectedly"
cat "$WATCH_LOG" 2>/dev/null
exit 1
fi
# Progress every 5s with file sizes
if [ $((ELAPSED % 5)) -eq 0 ] && [ "$ELAPSED" -gt 0 ]; then
IDX_SIZE=$(du -h .grepai/index.gob 2>/dev/null | cut -f1 || echo "0")
SYM_SIZE=$(du -h .grepai/symbols.gob 2>/dev/null | cut -f1 || echo "0")
LAST_LINE=$(grep -E "Indexing|Processing" "$WATCH_LOG" 2>/dev/null | tail -1 | head -c 80 || true)
echo "⏳ ${ELAPSED}s | index: ${IDX_SIZE} | symbols: ${SYM_SIZE}"
[ -n "$LAST_LINE" ] && echo " $LAST_LINE"
fi
sleep 1
ELAPSED=$((ELAPSED + 1))
done
if [ "$ELAPSED" -ge "$TIMEOUT" ]; then
echo ""
echo "❌ Timeout after ${TIMEOUT}s"
grepai watch --stop 2>/dev/null || true
exit 1
fi
# Extract stats from log
STATS=$(grep "Initial scan complete" "$WATCH_LOG" | tail -1 || true)
echo " $STATS"
echo ""
echo "=== Init Complete ==="
test -f .grepai/index.gob && echo "✅ index.gob: $(du -h .grepai/index.gob | cut -f1)" || echo "❌ index.gob missing"
test -f .grepai/symbols.gob && echo "✅ symbols.gob: $(du -h .grepai/symbols.gob | cut -f1)" || echo "⚠️ symbols.gob missing"
pgrep -f "grepai watch" >/dev/null && echo "✅ watch: running (PID: $(pgrep -f 'grepai watch'))" || echo "⚠️ watch: not running"
echo "✅ Duration: ${ELAPSED}s"
exit 0
#!/bin/bash
set -euo pipefail
# Install grepai prerequisites via Homebrew
echo "=== grepai Prerequisites Install ==="
INSTALLED=()
FAILED=()
# 1. Homebrew
echo ""
echo "--- Homebrew ---"
if command -v brew &>/dev/null; then
echo "✅ brew: $(brew --version | head -1)"
else
echo "⚠️ brew: not found, installing..."
if /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then # nosemgrep: curl-pipe-bash
eval "$(/opt/homebrew/bin/brew shellenv)" 2>/dev/null || eval "$(/usr/local/bin/brew shellenv)" 2>/dev/null || true
echo "✅ brew: installed"
INSTALLED+=("brew")
else
echo "❌ brew: install failed"
FAILED+=("brew")
fi
fi
# Exit early if no brew
if ! command -v brew &>/dev/null; then
echo ""
echo "=== Install Failed ==="
echo "❌ Homebrew is required for all other dependencies"
echo "Manual install: https://brew.sh"
exit 1
fi
# 2. timeout (from coreutils)
echo ""
echo "--- timeout ---"
if command -v timeout &>/dev/null; then
echo "✅ timeout: $(timeout --version 2>&1 | head -1)"
else
echo "⚠️ timeout: not found, installing coreutils..."
if brew install coreutils &>/dev/null; then
echo "✅ coreutils: installed"
INSTALLED+=("coreutils")
# Create symlink for timeout command
BREW_BIN=$(brew --prefix)/bin
if [ -w "$BREW_BIN" ]; then
ln -sf "$(brew --prefix)/opt/coreutils/libexec/gnubin/timeout" "$BREW_BIN/timeout"
echo "✅ timeout: symlink created"
fi
else
echo "❌ coreutils: install failed"
FAILED+=("coreutils")
fi
fi
# 3. jq (JSON processor)
echo ""
echo "--- jq ---"
if command -v jq &>/dev/null; then
echo "✅ jq: $(jq --version)"
else
echo "⚠️ jq: not found, installing..."
if brew install jq &>/dev/null; then
echo "✅ jq: installed"
INSTALLED+=("jq")
else
echo "❌ jq: install failed"
FAILED+=("jq")
fi
fi
# 4. ollama (embedding server)
echo ""
echo "--- ollama ---"
if command -v ollama &>/dev/null; then
echo "✅ ollama: $(ollama --version 2>&1 | head -1)"
# Check if running
if curl -s --connect-timeout 3 --max-time 5 localhost:11434/api/tags &>/dev/null; then
echo "✅ ollama: running"
else
echo "⚠️ ollama: installed but not running"
echo " Starting ollama service..."
brew services start ollama &>/dev/null || ollama serve &>/dev/null &
sleep 2
if curl -s --connect-timeout 3 --max-time 5 localhost:11434/api/tags &>/dev/null; then
echo "✅ ollama: started"
else
echo "⚠️ ollama: start manually with 'ollama serve'"
fi
fi
else
echo "⚠️ ollama: not found, installing..."
if brew install ollama &>/dev/null; then
echo "✅ ollama: installed"
INSTALLED+=("ollama")
echo " Starting ollama service..."
brew services start ollama &>/dev/null || true
sleep 2
else
echo "❌ ollama: install failed"
FAILED+=("ollama")
fi
fi
# 5. bge-m3 model (for ollama)
echo ""
echo "--- bge-m3 model ---"
if command -v ollama &>/dev/null && curl -s --connect-timeout 3 --max-time 5 localhost:11434/api/tags &>/dev/null; then
if ollama list 2>/dev/null | grep -q bge-m3; then
echo "✅ bge-m3: installed"
else
echo "⚠️ bge-m3: not found, pulling..."
if ollama pull bge-m3; then
echo "✅ bge-m3: installed"
INSTALLED+=("bge-m3")
else
echo "❌ bge-m3: pull failed"
FAILED+=("bge-m3")
fi
fi
else
echo "⏭️ bge-m3: skipped (ollama not available)"
fi
# 6. grepai CLI
echo ""
echo "--- grepai ---"
if command -v grepai &>/dev/null; then
echo "✅ grepai: $(grepai version 2>&1)"
else
echo "⚠️ grepai: not found, installing..."
if brew install yoanbernabeu/tap/grepai &>/dev/null; then
echo "✅ grepai: installed"
INSTALLED+=("grepai")
else
echo "❌ grepai: install failed"
FAILED+=("grepai")
fi
fi
# Summary
echo ""
echo "=== Install Summary ==="
echo ""
echo "| Component | Status |"
echo "|-----------|--------|"
# Check each component
check_status() {
local name=$1
local cmd=$2
if command -v "$cmd" &>/dev/null; then
echo "| $name | ✅ |"
else
echo "| $name | ❌ |"
fi
}
check_status "brew" "brew"
check_status "timeout" "timeout"
check_status "jq" "jq"
check_status "ollama" "ollama"
check_status "grepai" "grepai"
# bge-m3 special check
if command -v ollama &>/dev/null && ollama list 2>/dev/null | grep -q bge-m3; then
echo "| bge-m3 | ✅ |"
else
echo "| bge-m3 | ❌ |"
fi
# ollama running check
if curl -s --connect-timeout 3 --max-time 5 localhost:11434/api/tags &>/dev/null; then
echo "| ollama running | ✅ |"
else
echo "| ollama running | ❌ |"
fi
echo ""
if [ ${#INSTALLED[@]} -gt 0 ]; then
echo "Installed: ${INSTALLED[*]}"
fi
if [ ${#FAILED[@]} -gt 0 ]; then
echo "Failed: ${FAILED[*]}"
exit 1
fi
echo ""
echo "✅ All prerequisites installed"
exit 0
#!/bin/bash
set -euo pipefail
# grepai MCP Configuration Check
# Ensures grepai MCP is registered AND alwaysLoad=true (CC 2.1.115+)
# Falls back to JSON patching if --always-load flag unsupported.
echo "=== MCP Check ==="
CLAUDE_JSON="$HOME/.claude.json"
TMP_FILE=""
TMP_FILE2=""
# Single trap for all temp files (variables can be empty/unset - rm -f is safe)
trap 'rm -f "${TMP_FILE:-}" "${TMP_FILE2:-}"' EXIT
# Helper: check if alwaysLoad already true for grepai
already_always_load() {
command -v jq &>/dev/null || return 1
[ -f "$CLAUDE_JSON" ] || return 1
jq -e '.mcpServers.grepai.alwaysLoad == true' "$CLAUDE_JSON" >/dev/null 2>&1
}
# Helper: detect --always-load flag support
supports_always_load() {
claude mcp add --help 2>&1 | grep -q -- '--always-load'
}
# Helper: backup ~/.claude.json once per invocation if we are about to mutate
backup_claude_json() {
[ -f "$CLAUDE_JSON" ] || return 0
local bak
bak="$CLAUDE_JSON.bak.$(date +%s)"
cp "$CLAUDE_JSON" "$bak" && echo " Backup: $bak"
}
# Phase 1: Check/Add MCP Server
echo ""
echo "--- MCP Server ---"
GREPAI_PRESENT=0
if [ -f "$CLAUDE_JSON" ] && grep -q '"grepai"' "$CLAUDE_JSON" 2>/dev/null; then
GREPAI_PRESENT=1
echo "✅ MCP grepai: already configured"
else
echo "⚠️ MCP grepai: not configured"
echo " Adding via claude CLI..."
if supports_always_load; then
if claude mcp add grepai --always-load --transport stdio --scope user -- grepai mcp-serve; then
echo "✅ MCP grepai: added (alwaysLoad via CLI)"
GREPAI_PRESENT=1
else
echo "❌ MCP grepai: failed to add"
exit 1
fi
else
if claude mcp add --scope user grepai -- grepai mcp-serve; then
echo "✅ MCP grepai: added (legacy CLI, will patch alwaysLoad)"
GREPAI_PRESENT=1
else
echo "❌ MCP grepai: failed to add"
exit 1
fi
fi
fi
# Phase 1b: Ensure alwaysLoad=true for grepai
echo ""
echo "--- alwaysLoad Flag ---"
if [ "$GREPAI_PRESENT" -eq 1 ]; then
if already_always_load; then
echo "✅ alwaysLoad: already true (no changes)"
else
# Try CLI re-registration with --always-load first (idempotent in newer CC)
PATCHED=0
if supports_always_load; then
# `claude mcp add` may refuse to overwrite; try and if it fails, fall through to JSON patch
if claude mcp add grepai --always-load --transport stdio --scope user -- grepai mcp-serve 2>/dev/null; then
if already_always_load; then
echo "✅ alwaysLoad: set via CLI re-register"
PATCHED=1
fi
fi
fi
if [ "$PATCHED" -eq 0 ]; then
# Fallback: JSON patch
if [ ! -f "$CLAUDE_JSON" ]; then
echo "❌ $CLAUDE_JSON does not exist; cannot patch"
exit 1
fi
if ! command -v jq &>/dev/null; then
echo "❌ jq required for fallback patch"
exit 1
fi
backup_claude_json
TMP_FILE=$(mktemp)
jq '.mcpServers.grepai.alwaysLoad = true' "$CLAUDE_JSON" > "$TMP_FILE" && mv "$TMP_FILE" "$CLAUDE_JSON"
# Validate JSON
jq empty "$CLAUDE_JSON" >/dev/null 2>&1 || { echo "❌ Invalid JSON after patch"; exit 1; }
if already_always_load; then
echo "✅ alwaysLoad: set via JSON patch"
else
echo "❌ alwaysLoad: patch did not take effect"
exit 1
fi
fi
fi
else
echo "⏭️ alwaysLoad: skipped (grepai not present)"
fi
# Phase 2: Check/Add allowedTools (prevents [destructive] permission prompts)
echo ""
echo "--- Allowed Tools ---"
SETTINGS_FILE="$HOME/.claude/settings.json"
# Create settings.json if not exists
if [ ! -f "$SETTINGS_FILE" ]; then
mkdir -p "$(dirname "$SETTINGS_FILE")"
echo '{}' > "$SETTINGS_FILE"
echo " Created $SETTINGS_FILE"
fi
# Check if mcp__grepai__ already allowed
if grep -q 'mcp__grepai__' "$SETTINGS_FILE" 2>/dev/null; then
echo "✅ allowedTools: mcp__grepai__* already configured"
else
echo "⚠️ allowedTools: mcp__grepai__* not configured"
echo " Adding to $SETTINGS_FILE..."
# Use jq if available, otherwise use python
if command -v jq &>/dev/null; then
# jq approach
TMP_FILE2=$(mktemp)
jq '.allowedTools = ((.allowedTools // []) + ["mcp__grepai__*"] | unique)' "$SETTINGS_FILE" > "$TMP_FILE2" && mv "$TMP_FILE2" "$SETTINGS_FILE"
jq . "$SETTINGS_FILE" >/dev/null 2>&1 || { echo "❌ Invalid JSON"; exit 1; }
elif command -v python3 &>/dev/null; then
# python approach
SETTINGS_FILE="$SETTINGS_FILE" python3 -c "
import json, os
settings_file = os.environ['SETTINGS_FILE']
with open(settings_file, 'r') as f:
data = json.load(f)
allowed = data.get('allowedTools', [])
if 'mcp__grepai__*' not in allowed:
allowed.append('mcp__grepai__*')
data['allowedTools'] = allowed
with open(settings_file, 'w') as f:
json.dump(data, f, indent=2)
"
python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$SETTINGS_FILE" 2>/dev/null || { echo "❌ Invalid JSON in $SETTINGS_FILE"; exit 1; }
else
echo "❌ Neither jq nor python3 available"
echo " Manually add to $SETTINGS_FILE:"
echo ' {"allowedTools": ["mcp__grepai__*"]}'
exit 1
fi
if grep -q 'mcp__grepai__' "$SETTINGS_FILE" 2>/dev/null; then
echo "✅ allowedTools: mcp__grepai__* added"
else
echo "❌ Failed to add allowedTools"
exit 1
fi
fi
echo ""
echo "=== MCP Check Complete ==="
echo "✅ MCP server: configured"
echo "✅ alwaysLoad: enabled (no ToolSearch preflight needed)"
echo "✅ Permissions: auto-allowed (no prompts)"
echo ""
echo "ℹ️ Restart Claude Code to apply MCP changes"
exit 0
#!/bin/bash
set -euo pipefail
# grepai Config Optimization (backup + reindex)
echo "=== Config Optimization ==="
# Check .grepai exists
if [ ! -d .grepai ]; then
echo "❌ .grepai/ not found. Run setup first: /grepai setup"
exit 1
fi
if [ ! -f .grepai/config.yaml ]; then
echo "❌ config.yaml not found. Run setup first: /grepai setup"
exit 1
fi
# Create backup
BACKUP_DIR=".grepai/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
cp .grepai/config.yaml "$BACKUP_DIR/config_$TIMESTAMP.yaml"
echo "✅ Backup: $BACKUP_DIR/config_$TIMESTAMP.yaml"
# Remove stale last_index_time to prepare for fresh config
if grep -q "last_index_time:" .grepai/config.yaml 2>/dev/null; then
grep -v 'last_index_time:' .grepai/config.yaml > .grepai/config.yaml.tmp && mv .grepai/config.yaml.tmp .grepai/config.yaml
echo "✅ Removed stale last_index_time"
fi
echo ""
echo "Config backed up. Agent will now analyze and regenerate config."
echo "After config update, run: /grepai reindex"
#!/bin/bash
set -euo pipefail
# grepai Full Reindex: stop, clean, rebuild (sync), start background
echo "=== Reindex: Stop Watch ==="
grepai watch --stop 2>/dev/null || true
pkill -f "grepai watch" 2>/dev/null || true
sleep 1
# Force kill if still running
if pgrep -f "grepai watch" >/dev/null; then
echo "⚠️ watch still running - force kill"
pgrep -f "grepai watch" | xargs kill -9 2>/dev/null || true
sleep 1
fi
echo "✅ Watch stopped"
# Check .grepai exists
if [ ! -d .grepai ]; then
echo "❌ .grepai/ not found. Run setup first: /grepai setup"
exit 1
fi
echo ""
echo "=== Reindex: Clean ==="
mkdir -p .grepai/logs
rm -f .grepai/index.gob && echo " ✅ removed index.gob" || echo " ⏭️ index.gob not found"
rm -f .grepai/symbols.gob && echo " ✅ removed symbols.gob" || echo " ⏭️ symbols.gob not found"
rm -f .grepai/logs/*.log 2>/dev/null && echo " ✅ cleaned old logs" || true
# CRITICAL: Remove last_index_time to force full reindex
if grep -q "last_index_time:" .grepai/config.yaml 2>/dev/null; then
grep -v 'last_index_time:' .grepai/config.yaml > .grepai/config.yaml.tmp && mv .grepai/config.yaml.tmp .grepai/config.yaml
echo " ✅ removed last_index_time (prevents skip bug)"
fi
echo "✅ Cleanup complete"
echo ""
echo "=== Reindex: File Count ==="
# Count indexable files (estimate)
FILE_COUNT=$(find . -type f \( -name "*.java" -o -name "*.kt" -o -name "*.kts" -o -name "*.js" -o -name "*.ts" -o -name "*.tsx" -o -name "*.jsx" -o -name "*.go" -o -name "*.py" -o -name "*.rs" -o -name "*.sh" -o -name "*.md" -o -name "*.yaml" -o -name "*.yml" -o -name "*.json" \) -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/target/*" -not -path "*/build/*" -not -path "*/dist/*" -not -path "*/.grepai/*" 2>/dev/null | wc -l | tr -d ' ')
echo "Files to index: ~$FILE_COUNT"
# Estimate time and set timeout
if [ "$FILE_COUNT" -lt 100 ]; then
EST_TIME="<1 min"
TIMEOUT=120
elif [ "$FILE_COUNT" -lt 500 ]; then
EST_TIME="1-3 min"
TIMEOUT=300
elif [ "$FILE_COUNT" -lt 1000 ]; then
EST_TIME="3-7 min"
TIMEOUT=600
elif [ "$FILE_COUNT" -lt 5000 ]; then
EST_TIME="10-30 min"
TIMEOUT=1800
else
EST_TIME="30+ min"
TIMEOUT=3600
fi
echo "Estimated time: $EST_TIME"
echo ""
echo "=== Reindex: Build Index ==="
WATCH_LOG=".grepai/logs/grepai-watch.log"
> "$WATCH_LOG" # truncate
echo "Log: $WATCH_LOG"
echo "Monitor: tail -f $WATCH_LOG"
echo ""
# Start watch in BACKGROUND with logging
# grepai watch --background writes to grepai-watch.log automatically
grepai watch --background --log-dir .grepai/logs 2>/dev/null
sleep 1
if ! pgrep -f "grepai watch" >/dev/null; then
echo "❌ Failed to start grepai watch"
cat "$WATCH_LOG" 2>/dev/null
exit 1
fi
echo "✅ Watch started in background (PID: $(pgrep -f 'grepai watch'))"
# Poll for "Initial scan complete" in log
ELAPSED=0
echo "⏳ Waiting for indexing to complete..."
while [ "$ELAPSED" -lt "$TIMEOUT" ]; do
# Check completion marker in log
if grep -q "Initial scan complete" "$WATCH_LOG" 2>/dev/null; then
echo ""
echo "✅ Initial scan complete"
break
fi
# Check watch still running
if ! pgrep -f "grepai watch" >/dev/null; then
echo ""
echo "❌ Watch process died unexpectedly"
cat "$WATCH_LOG" 2>/dev/null
exit 1
fi
# Progress every 5s with file sizes
if [ $((ELAPSED % 5)) -eq 0 ] && [ "$ELAPSED" -gt 0 ]; then
IDX_SIZE=$(du -h .grepai/index.gob 2>/dev/null | cut -f1 || echo "0")
SYM_SIZE=$(du -h .grepai/symbols.gob 2>/dev/null | cut -f1 || echo "0")
# Show last indexing line from log
LAST_LINE=$(grep -E "Indexing|Processing" "$WATCH_LOG" 2>/dev/null | tail -1 | head -c 80 || true)
echo "⏳ ${ELAPSED}s | index: ${IDX_SIZE} | symbols: ${SYM_SIZE}"
[ -n "$LAST_LINE" ] && echo " $LAST_LINE"
fi
sleep 1
ELAPSED=$((ELAPSED + 1))
done
if [ "$ELAPSED" -ge "$TIMEOUT" ]; then
echo ""
echo "❌ Timeout after ${TIMEOUT}s"
grepai watch --stop 2>/dev/null || true
exit 1
fi
# Extract stats from log
STATS=$(grep "Initial scan complete" "$WATCH_LOG" | tail -1 || true)
echo " $STATS"
# Watch is already running in background - no need to restart
echo ""
echo "=== Reindex Complete ==="
test -f .grepai/index.gob && echo "✅ index.gob: $(du -h .grepai/index.gob | cut -f1)" || echo "❌ index.gob missing"
test -f .grepai/symbols.gob && echo "✅ symbols.gob: $(du -h .grepai/symbols.gob | cut -f1)" || echo "⚠️ symbols.gob missing"
pgrep -f "grepai watch" >/dev/null && echo "✅ watch: running (PID: $(pgrep -f 'grepai watch'))" || echo "⚠️ watch: not running"
echo "✅ Duration: ${ELAPSED}s"
#!/bin/bash
set -euo pipefail
# grepai Start Watch
echo "=== Starting grepai watch ==="
# Check prerequisites
if [ ! -d .grepai ]; then
echo "❌ .grepai/ not found. Run setup first: /grepai setup"
exit 1
fi
# Check if already running
if pgrep -f "grepai watch" >/dev/null; then
echo "⚠️ watch already running (PID: $(pgrep -f 'grepai watch'))"
exit 0
fi
# Create logs directory
mkdir -p .grepai/logs
# Start watch
grepai watch --background --log-dir .grepai/logs 2>/dev/null
# Verify
sleep 1
if pgrep -f "grepai watch" >/dev/null; then
echo "✅ watch started (PID: $(pgrep -f 'grepai watch'))"
echo " Logs: .grepai/logs/"
else
echo "❌ watch failed to start"
echo " Check: grepai watch (foreground) for errors"
exit 1
fi
# TODO: Extract shared CLAUDE.md logic to common function (duplicated in create-rule.sh)
# Ensure CLAUDE.md has grepai entry
CLAUDE_MD="CLAUDE.md"
GREPAI_MARKER="grepai_search"
if [ ! -f "$CLAUDE_MD" ]; then
echo "# CLAUDE.md" > "$CLAUDE_MD"
echo "" >> "$CLAUDE_MD"
echo "## Code Search" >> "$CLAUDE_MD"
echo "" >> "$CLAUDE_MD"
echo "> **CRITICAL:** Use \`grepai_search\` FIRST for code exploration." >> "$CLAUDE_MD"
echo "✅ CLAUDE.md created with grepai entry"
elif ! grep -q "$GREPAI_MARKER" "$CLAUDE_MD" 2>/dev/null; then
echo "" >> "$CLAUDE_MD"
echo "## Code Search" >> "$CLAUDE_MD"
echo "" >> "$CLAUDE_MD"
echo "> **CRITICAL:** Use \`grepai_search\` FIRST for code exploration." >> "$CLAUDE_MD"
echo "✅ CLAUDE.md updated with grepai entry"
fi
#!/bin/bash
set -euo pipefail
# grepai Status Check
echo "=== grepai Status ==="
echo ""
echo "--- Infrastructure ---"
if command -v grepai &>/dev/null; then
CURRENT=$(grepai version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
LATEST=$(brew info yoanbernabeu/tap/grepai 2>/dev/null | grep -oE 'stable [0-9]+\.[0-9]+\.[0-9]+' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || true)
if [ -n "$CURRENT" ] && [ -n "$LATEST" ]; then
# Compare versions (newer installed = ok, older = update available)
if [ "$(printf '%s\n' "$LATEST" "$CURRENT" | sort -V | tail -1)" = "$LATEST" ] && [ "$CURRENT" != "$LATEST" ]; then
echo "⚠️ grepai: v$CURRENT → v$LATEST available — run: /grepai upgrade"
else
echo "✅ grepai: v$CURRENT (brew: v$LATEST)"
fi
elif [ -n "$CURRENT" ]; then
echo "✅ grepai: v$CURRENT"
else
echo "✅ grepai: installed"
fi
else
echo "❌ grepai: NOT FOUND"
fi
curl -s --connect-timeout 3 --max-time 5 localhost:11434/api/tags >/dev/null && echo "✅ ollama: running" || echo "❌ ollama: stopped"
ollama list 2>/dev/null | grep -q bge-m3 && echo "✅ bge-m3: installed" || echo "❌ bge-m3: missing"
echo ""
echo "--- Project ---"
test -d .grepai && echo "✅ .grepai/: exists" || echo "❌ .grepai/: missing"
test -f .grepai/config.yaml && echo "✅ config.yaml: exists" || echo "❌ config.yaml: missing"
test -f .grepai/index.gob && echo "✅ index.gob: $(du -h .grepai/index.gob 2>/dev/null | cut -f1)" || echo "⚠️ index.gob: missing"
echo ""
echo "--- Watch ---"
if pgrep -f "grepai watch" >/dev/null; then
echo "✅ watch: running (PID: $(pgrep -f 'grepai watch'))"
# Check if actively indexing (recent log activity)
if [ -f .grepai/logs/grepai-watch.log ]; then
LAST_LOG=$(tail -1 .grepai/logs/grepai-watch.log 2>/dev/null | head -c 100)
if echo "$LAST_LOG" | grep -qiE "index|embed|chunk"; then
echo " ⏳ indexing in progress..."
echo " last: $(echo "$LAST_LOG" | cut -c1-60)..."
fi
fi
else
echo "⚠️ watch: not running"
fi
echo ""
echo "--- Integration ---"
grep -q '"grepai"' ~/.claude.json 2>/dev/null && echo "✅ MCP: configured" || echo "❌ MCP: not configured"
grep -q 'mcp__grepai__' ~/.claude/settings.json 2>/dev/null && echo "✅ Permissions: auto-allowed" || echo "⚠️ Permissions: will prompt (run /grepai setup)"
test -f .claude/rules/grepai-first.md && echo "✅ rule: grepai-first.md" || echo "⚠️ rule: missing"
echo ""
echo "--- Hook ---"
# Self-location
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PLUGIN_ROOT="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")"
test -f "$PLUGIN_ROOT/hooks/grepai-session.mjs" && echo "✅ hook: built-in (plugin)" || echo "⚠️ hook: missing in plugin"
echo ""
echo "--- MCP Tools ---"
if grep -q '"grepai"' ~/.claude.json 2>/dev/null; then
echo "Available: grepai_search, grepai_trace_callers, grepai_trace_callees, grepai_trace_graph, grepai_index_status"
fi
#!/bin/bash
set -euo pipefail
# grepai Stop Watch
echo "=== Stopping grepai watch ==="
# Try graceful stop first
grepai watch --stop 2>/dev/null || true
# Force kill if still running
if pgrep -f "grepai watch" >/dev/null; then
pkill -f "grepai watch" || true
sleep 1
fi
# Verify
if pgrep -f "grepai watch" >/dev/null; then
echo "❌ watch still running (PID: $(pgrep -f 'grepai watch'))"
echo " Try: kill -9 $(pgrep -f 'grepai watch')"
exit 1
else
echo "✅ watch stopped"
fi
#!/bin/bash
set -euo pipefail
# grepai CLI Upgrade via Homebrew
echo "=== grepai Upgrade ==="
# Check brew available
if ! command -v brew &>/dev/null; then
echo "❌ Homebrew not found"
exit 1
fi
# Get current version
CURRENT=$(grepai version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
if [ -z "$CURRENT" ]; then
echo "⚠️ grepai not installed, installing..."
brew install yoanbernabeu/tap/grepai && echo "✅ Installed" || { echo "❌ Install failed"; exit 1; }
exit 0
fi
echo "Current: v$CURRENT"
# Get latest from brew
TIMEOUT_CMD=$(command -v timeout || echo "")
if [ -n "$TIMEOUT_CMD" ]; then
LATEST=$($TIMEOUT_CMD 10 brew info yoanbernabeu/tap/grepai 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
else
LATEST=$(brew info yoanbernabeu/tap/grepai 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
fi
if [ -z "$LATEST" ]; then
echo "⚠️ Cannot fetch latest version (network issue?)"
echo "Manual check: brew info yoanbernabeu/tap/grepai"
exit 0
fi
echo "Latest: v$LATEST"
# Compare versions
if [ "$CURRENT" = "$LATEST" ]; then
echo "✅ Already up to date"
exit 0
fi
# Upgrade
echo "Upgrading..."
if brew upgrade yoanbernabeu/tap/grepai 2>&1; then
NEW=$(grepai version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
echo "✅ Upgraded: v$CURRENT → v$NEW"
else
echo "❌ Upgrade failed"
exit 1
fi
exit 0
#!/bin/bash
set -euo pipefail
# grepai Final Verification
echo "=== Final Verification ==="
# Infrastructure
command -v grepai >/dev/null && echo "✅ grepai CLI" || echo "❌ grepai CLI"
curl -s --connect-timeout 3 --max-time 5 localhost:11434/api/tags >/dev/null && echo "✅ ollama running" || echo "❌ ollama stopped"
ollama list 2>/dev/null | grep -q bge-m3 && echo "✅ bge-m3 model" || echo "❌ bge-m3 missing"
grep -q '"grepai"' ~/.claude.json 2>/dev/null && echo "✅ MCP configured" || echo "❌ MCP missing"
grep -q 'mcp__grepai__' ~/.claude/settings.json 2>/dev/null && echo "✅ Permissions: auto-allowed" || echo "⚠️ Permissions: will prompt"
# Project config
test -d .grepai && echo "✅ .grepai/ directory" || echo "❌ .grepai/ missing"
test -f .grepai/config.yaml && echo "✅ config.yaml" || echo "❌ config.yaml missing"
test -f .grepai/index.gob && echo "✅ index.gob ($(du -h .grepai/index.gob | cut -f1))" || echo "⚠️ index.gob (indexing...)"
test -f .claude/rules/grepai-first.md && echo "✅ grepai-first.md rule" || echo "❌ rule missing"
# Plugin hook (self-location)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PLUGIN_ROOT="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")"
test -f "$PLUGIN_ROOT/hooks/grepai-session.mjs" && echo "✅ hook: built-in (plugin)" || echo "❌ hook: missing in plugin"
# Watch status
pgrep -f "grepai watch" >/dev/null && echo "✅ watch running" || echo "⚠️ watch not running"
echo ""
echo "=== Setup Complete ==="