Full standards audit traced every doc through its checker into the codebase. All 20 standards rated NEEDS UPDATE. This PR fixes the systemic issues: Checker bugs fixed: - encapsulation_check: continue/break bug falsely flagging allowed handlers - error_handling_check: now accepts canonical prax import (not just shorthand) - cli_check: import detection now matches aipass.cli prefix (was bare cli.) - meta_check: AIPass header accepted (was only META), legacy compat preserved Doc fixes: - Checker paths corrected in 10 docs (added standards/aipass/ segment) - naming.md rewritten: marketplace removed, json_handler.py promoted to standard, verbs descriptive not prescriptive, module naming section added - imports.md: both prax import forms now valid (canonical + shorthand) - architecture/testing/trigger/encapsulation/json_structure/cli_flags/ log_handler: stale paths, Dev-Pass refs, outdated data fixed Code fixes: - parents[4]→parents[3] in 16 handler files (backup/daemon/memory) - AIPass header marker in all 42 checker .py files - pyproject.toml: added pyright to dev deps - Removed agent_mock_branch template (replaced by builder/birthright) - Removed stale branch_system_prompt.md files (renamed to aipass_local_prompt.md) - New devpulse local prompt + FPLAN-0010 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
197 lines
5.5 KiB
Bash
Executable File
197 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# AIPass setup script
|
|
# Creates a venv, installs the package in editable mode, and verifies CLI entry points.
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
# cd to repo root (where this script lives) so it works from anywhere
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
echo "=== AIPass Setup ==="
|
|
echo "Repo root: $SCRIPT_DIR"
|
|
echo ""
|
|
|
|
# --- Check python3 exists ---
|
|
if ! command -v python3 &>/dev/null; then
|
|
echo "FAIL: python3 not found. Install Python 3.10+ and try again."
|
|
exit 1
|
|
fi
|
|
|
|
PY_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
|
|
echo "Found python3 $PY_VERSION"
|
|
|
|
# --- Check minimum version ---
|
|
PY_OK=$(python3 -c 'import sys; print(int(sys.version_info >= (3, 10)))')
|
|
if [ "$PY_OK" != "1" ]; then
|
|
echo "FAIL: Python 3.10+ required, found $PY_VERSION"
|
|
exit 1
|
|
fi
|
|
|
|
# --- Create venv ---
|
|
if [ -d ".venv" ]; then
|
|
echo "Existing .venv found — removing it for a clean install."
|
|
rm -rf .venv
|
|
fi
|
|
|
|
echo "Creating virtual environment at .venv ..."
|
|
python3 -m venv .venv
|
|
|
|
# --- Activate and install ---
|
|
source .venv/bin/activate
|
|
|
|
echo "Upgrading pip ..."
|
|
pip install --upgrade pip --quiet
|
|
|
|
echo "Installing aipass in editable mode (with dev extras) ..."
|
|
pip install -e ".[dev]" --quiet
|
|
|
|
# --- Verify CLI entry points ---
|
|
FAIL=0
|
|
|
|
echo ""
|
|
echo "Verifying entry points ..."
|
|
|
|
if drone --help &>/dev/null; then
|
|
echo " drone ... ok"
|
|
else
|
|
echo " drone ... FAILED"
|
|
FAIL=1
|
|
fi
|
|
|
|
if seedgo --help &>/dev/null; then
|
|
echo " seedgo ... ok"
|
|
else
|
|
echo " seedgo ... FAILED"
|
|
FAIL=1
|
|
fi
|
|
|
|
# --- Create secrets directory ---
|
|
SECRETS_DIR="$HOME/.secrets/aipass"
|
|
if [ ! -d "$SECRETS_DIR" ]; then
|
|
echo "Creating secrets directory at $SECRETS_DIR ..."
|
|
mkdir -p "$SECRETS_DIR"
|
|
chmod 700 "$HOME/.secrets"
|
|
echo " ~/.secrets/aipass/ ... created"
|
|
else
|
|
echo "Secrets directory already exists — skipping"
|
|
fi
|
|
|
|
# --- Generate branch registry ---
|
|
if [ ! -f "AIPASS_REGISTRY.json" ]; then
|
|
echo "Generating AIPASS_REGISTRY.json ..."
|
|
python3 - "$SCRIPT_DIR" << 'PYEOF'
|
|
import json, sys, os
|
|
from pathlib import Path
|
|
from datetime import date
|
|
|
|
repo_root = sys.argv[1]
|
|
src_dir = Path(repo_root) / "src" / "aipass"
|
|
today = date.today().isoformat()
|
|
|
|
branches = {}
|
|
for d in sorted(src_dir.iterdir()):
|
|
if d.is_dir() and not d.name.startswith(("_", ".")):
|
|
branches[d.name] = {
|
|
"name": d.name,
|
|
"path": str(d),
|
|
"profile": "library",
|
|
"description": "",
|
|
"email": f"@{d.name}",
|
|
"status": "active",
|
|
"created": today,
|
|
"last_active": today,
|
|
}
|
|
|
|
registry = {
|
|
"metadata": {
|
|
"version": "1.0.0",
|
|
"last_updated": today,
|
|
"total_branches": len(branches),
|
|
},
|
|
"branches": branches,
|
|
}
|
|
|
|
out = Path(repo_root) / "AIPASS_REGISTRY.json"
|
|
out.write_text(json.dumps(registry, indent=2) + "\n")
|
|
print(f" {len(branches)} branches registered")
|
|
PYEOF
|
|
else
|
|
echo "AIPASS_REGISTRY.json already exists — skipping"
|
|
fi
|
|
|
|
# --- Install Claude Code hooks ---
|
|
CLAUDE_SETTINGS="$HOME/.claude/settings.json"
|
|
|
|
if [ -d "$SCRIPT_DIR/.claude/hooks" ]; then
|
|
echo "Installing Claude Code hooks ..."
|
|
mkdir -p "$HOME/.claude"
|
|
|
|
python3 - "$SCRIPT_DIR" "$CLAUDE_SETTINGS" << 'PYEOF'
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
repo_root = sys.argv[1]
|
|
settings_path = Path(sys.argv[2])
|
|
hooks_dir = f"{repo_root}/.claude/hooks"
|
|
|
|
# Load existing settings or start fresh
|
|
if settings_path.exists():
|
|
settings = json.loads(settings_path.read_text())
|
|
else:
|
|
settings = {}
|
|
|
|
# Build hooks config with absolute paths
|
|
settings["hooks"] = {
|
|
"UserPromptSubmit": [
|
|
{"hooks": [{"type": "command", "command": f"cat {repo_root}/.aipass/aipass_global_prompt.md 2>/dev/null || true"}]},
|
|
{"hooks": [{"type": "command", "command": f"python3 {hooks_dir}/branch_prompt_loader.py"}]},
|
|
{"hooks": [{"type": "command", "command": f"python3 {hooks_dir}/identity_injector.py"}]},
|
|
{"hooks": [{"type": "command", "command": f"python3 {hooks_dir}/email_notification.py"}]},
|
|
],
|
|
"PreToolUse": [
|
|
{"matcher": "Bash|Edit|MultiEdit|Write|Read|Grep|Glob|WebSearch|WebFetch|Task",
|
|
"hooks": [{"type": "command", "command": f"python3 {hooks_dir}/tool_use_sound.py"}]},
|
|
],
|
|
"PostToolUse": [
|
|
{"matcher": "Edit|MultiEdit|Write|NotebookEdit",
|
|
"hooks": [{"type": "command", "command": f"python3 {hooks_dir}/auto_fix_diagnostics.py"}]},
|
|
],
|
|
"Stop": [
|
|
{"hooks": [{"type": "command", "command": f"python3 {hooks_dir}/stop_sound.py"}]},
|
|
],
|
|
"Notification": [
|
|
{"hooks": [{"type": "command", "command": f"python3 {hooks_dir}/notification_sound.py"}]},
|
|
],
|
|
"PreCompact": [
|
|
{"matcher": "manual", "hooks": [{"type": "command", "command": f"python3 {hooks_dir}/pre_compact.py", "timeout": 60}]},
|
|
{"matcher": "auto", "hooks": [{"type": "command", "command": f"python3 {hooks_dir}/pre_compact.py", "timeout": 60}]},
|
|
],
|
|
}
|
|
|
|
settings_path.write_text(json.dumps(settings, indent=2) + "\n")
|
|
print(f" hooks -> {settings_path}")
|
|
PYEOF
|
|
else
|
|
echo "Skipping hooks (no .claude/hooks/ directory found)"
|
|
fi
|
|
|
|
# --- Result ---
|
|
echo ""
|
|
if [ "$FAIL" -eq 0 ]; then
|
|
echo "=== Setup complete ==="
|
|
echo ""
|
|
echo "To activate the environment, run:"
|
|
echo ""
|
|
echo " source .venv/bin/activate"
|
|
echo ""
|
|
else
|
|
echo "=== Setup finished with errors ==="
|
|
echo "The venv was created and the package was installed, but one or more"
|
|
echo "CLI entry points failed verification. Check the output above."
|
|
exit 1
|
|
fi
|