@theglitchking/babel-fish 1.0.1 → 2.0.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/.claude/install.sh +666 -0
- package/.claude/project-map/PROJECT_MAP.md +61 -0
- package/.claude/project-map/checksums.json +6 -0
- package/.claude/project-map/generate.py +1481 -0
- package/.claude/project-map/grader.py +583 -0
- package/.claude/project-map/learned-vocabulary.json +1 -0
- package/.claude/project-map/mine-sessions.py +419 -0
- package/.claude/project-map/reports/install-report.md +54 -0
- package/.claude/project-map/reports/iteration-01-report.md +54 -0
- package/.claude/project-map/reports/iteration-01-score.json +7 -0
- package/.claude/project-map/sections/01-vocabulary.md +8 -0
- package/.claude/project-map/sections/02-service-topology.md +6 -0
- package/.claude/project-map/sections/03-environment.md +6 -0
- package/.claude/project-map/sections/04-api-routes.md +6 -0
- package/.claude/project-map/sections/05-data-models.md +4 -0
- package/.claude/project-map/sections/06-schemas.md +4 -0
- package/.claude/project-map/sections/07-services.md +6 -0
- package/.claude/project-map/sections/08-background-jobs.md +5 -0
- package/.claude/project-map/sections/09-frontend-features.md +4 -0
- package/.claude/project-map/sections/10-tools-commands.md +8 -0
- package/.claude/project-map/sections/11-migrations.md +4 -0
- package/.claude/project-map/sections/12-import-chains.md +7 -0
- package/.claude/project-map/sections/13-frontend-backend-map.md +8 -0
- package/.claude/project-map/sections/14-reverse-proxy.md +4 -0
- package/.claude/project-map/sections/15-auth-config.md +6 -0
- package/.claude/project-map/sections/16-infra-profile.md +13 -0
- package/.claude/project-map/sections/17-learned-vocabulary.md +7 -0
- package/.claude/project-map/sections/18-dead-code.md +9 -0
- package/.claude/project-map/sections/19-doc-pointers.md +5 -0
- package/.claude/project-map/stack.json +12 -0
- package/.claude/rules/operational-runbook.md +40 -0
- package/.claude/rules/project-vocabulary.md +25 -0
- package/.claude/scripts/detect-stack.sh +222 -0
- package/.claude/scripts/ensure-python.sh +100 -0
- package/.claude/scripts/statusline.sh +27 -0
- package/.claude/scripts/validate.sh +59 -0
- package/.claude/settings.json +6 -0
- package/.claude/skills/babel-fish-developer-skill/SKILL.md +56 -0
- package/.claude/templates/SKILL.md.template +56 -0
- package/.claude/templates/operational-runbook.md.template +40 -0
- package/.claude/templates/project-vocabulary.md.template +25 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.githooks/install.sh +4 -0
- package/.githooks/pre-commit +22 -0
- package/CHANGELOG.md +72 -0
- package/README.md +18 -0
- package/bin/babel-fish.js +78 -71
- package/commands/policy.md +16 -0
- package/commands/relink.md +6 -0
- package/commands/status.md +6 -0
- package/commands/update.md +6 -0
- package/hooks/hooks.json +15 -0
- package/hooks/session-start.js +11 -0
- package/package.json +17 -4
- package/scripts/link-skills.js +31 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "babel-fish",
|
|
3
|
+
"slug": "babel-fish",
|
|
4
|
+
"language": "unknown",
|
|
5
|
+
"framework": "unknown",
|
|
6
|
+
"database": "unknown",
|
|
7
|
+
"orm": "unknown",
|
|
8
|
+
"auth": "unknown",
|
|
9
|
+
"package_manager": "unknown",
|
|
10
|
+
"infrastructure": "none",
|
|
11
|
+
"project_root": "/mnt/e/the-glitch-kingdom/babel-fish"
|
|
12
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# babel-fish — Operational Runbook
|
|
2
|
+
|
|
3
|
+
> Auto-loaded every session. Contains operational knowledge that cannot be derived from code.
|
|
4
|
+
> This file grows over time as the team discovers gotchas, quirks, and procedures.
|
|
5
|
+
> **Edit this file manually** — it is NOT overwritten on regeneration.
|
|
6
|
+
|
|
7
|
+
## Environment Differences
|
|
8
|
+
|
|
9
|
+
<!-- TODO: Document how dev/staging/prod differ (DB, deploy method, secrets, URLs) -->
|
|
10
|
+
|
|
11
|
+
| | Dev | Staging | Production |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| **URL** | | | |
|
|
14
|
+
| **Database** | | | |
|
|
15
|
+
| **Deploy** | | | |
|
|
16
|
+
| **Secrets** | | | |
|
|
17
|
+
|
|
18
|
+
## Known Issues & Workarounds
|
|
19
|
+
|
|
20
|
+
<!-- This section fills in naturally. When you hit a non-obvious issue, add it here. -->
|
|
21
|
+
<!-- Examples: "HMR doesn't work on WSL2", "port 6543 breaks migrations" -->
|
|
22
|
+
|
|
23
|
+
_No known issues documented yet. When you encounter a non-obvious problem and its solution, add it here so future sessions don't re-discover it._
|
|
24
|
+
|
|
25
|
+
## Deploy Procedures
|
|
26
|
+
|
|
27
|
+
<!-- TODO: Document how to deploy to each environment -->
|
|
28
|
+
|
|
29
|
+
## Key Commands
|
|
30
|
+
|
|
31
|
+
| Command | What It Does |
|
|
32
|
+
|---------|-------------|
|
|
33
|
+
| `python .claude/project-map/generate.py --force` | Force-regenerate project map |
|
|
34
|
+
| `python .claude/project-map/grader.py` | Grade map quality (0-100%) |
|
|
35
|
+
| `bash .githooks/install.sh` | (Re)install git hooks |
|
|
36
|
+
| `bash .claude/install.sh` | Re-run full plugin installer |
|
|
37
|
+
|
|
38
|
+
## Dev Credentials
|
|
39
|
+
|
|
40
|
+
<!-- Add test/dev credentials here (NEVER production secrets) -->
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# babel-fish — Project Vocabulary
|
|
2
|
+
|
|
3
|
+
> Auto-loaded every session. Maps human language to exact code locations.
|
|
4
|
+
> Regenerated automatically via pre-commit hook. Do not edit the auto-generated rows.
|
|
5
|
+
|
|
6
|
+
## Feature → Code Location
|
|
7
|
+
|
|
8
|
+
| You Say | Frontend | Backend | Model/Table |
|
|
9
|
+
|---------|----------|---------|-------------|
|
|
10
|
+
| _(vocabulary populates as source code is added)_ | | | |
|
|
11
|
+
|
|
12
|
+
## Infrastructure Vocabulary
|
|
13
|
+
|
|
14
|
+
| You Say | What It Is | Key Details |
|
|
15
|
+
|---------|-----------|-------------|
|
|
16
|
+
| project | babel-fish | unknown / unknown stack |
|
|
17
|
+
|
|
18
|
+
## Quick Actions
|
|
19
|
+
|
|
20
|
+
| You Say | What To Do |
|
|
21
|
+
|---------|-----------|
|
|
22
|
+
| regenerate map | `python .claude/project-map/generate.py --force` |
|
|
23
|
+
| grade map | `python .claude/project-map/grader.py` |
|
|
24
|
+
| view project map | `cat .claude/project-map/PROJECT_MAP.md` |
|
|
25
|
+
| install hooks | `bash .githooks/install.sh` |
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# detect-stack.sh — Auto-detect project stack
|
|
3
|
+
# Outputs a JSON object with detected stack info to stdout
|
|
4
|
+
# Usage: bash detect-stack.sh [project-root]
|
|
5
|
+
|
|
6
|
+
PROJECT_ROOT="${1:-$(pwd)}"
|
|
7
|
+
cd "$PROJECT_ROOT" || exit 1
|
|
8
|
+
|
|
9
|
+
CYAN='\033[36m'; RESET='\033[0m'
|
|
10
|
+
log() { printf '%b\n' "${CYAN}[detect]${RESET} $*" >&2; }
|
|
11
|
+
|
|
12
|
+
# ── Language Detection ──────────────────────────────────────────────────────
|
|
13
|
+
detect_language() {
|
|
14
|
+
local langs=()
|
|
15
|
+
|
|
16
|
+
[ -f "requirements.txt" ] || [ -f "pyproject.toml" ] || [ -f "setup.py" ] || [ -f "Pipfile" ] \
|
|
17
|
+
&& langs+=("python")
|
|
18
|
+
[ -f "package.json" ] \
|
|
19
|
+
&& langs+=("javascript")
|
|
20
|
+
find . -maxdepth 3 -name "*.ts" -o -name "*.tsx" 2>/dev/null | grep -q . \
|
|
21
|
+
&& langs+=("typescript")
|
|
22
|
+
[ -f "go.mod" ] \
|
|
23
|
+
&& langs+=("go")
|
|
24
|
+
[ -f "pom.xml" ] || [ -f "build.gradle" ] \
|
|
25
|
+
&& langs+=("java")
|
|
26
|
+
[ -f "Cargo.toml" ] \
|
|
27
|
+
&& langs+=("rust")
|
|
28
|
+
[ -f "composer.json" ] \
|
|
29
|
+
&& langs+=("php")
|
|
30
|
+
[ -f "Gemfile" ] \
|
|
31
|
+
&& langs+=("ruby")
|
|
32
|
+
|
|
33
|
+
# Primary = first detected, fallback = unknown
|
|
34
|
+
if [ ${#langs[@]} -eq 0 ]; then
|
|
35
|
+
echo "unknown"
|
|
36
|
+
else
|
|
37
|
+
echo "${langs[0]}"
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# ── Framework Detection ─────────────────────────────────────────────────────
|
|
42
|
+
detect_framework() {
|
|
43
|
+
local lang="$1"
|
|
44
|
+
|
|
45
|
+
case "$lang" in
|
|
46
|
+
python)
|
|
47
|
+
grep -r "fastapi\|FastAPI" requirements.txt pyproject.toml setup.py 2>/dev/null | grep -q . && echo "fastapi" && return
|
|
48
|
+
grep -r "django\|Django" requirements.txt pyproject.toml setup.py 2>/dev/null | grep -q . && echo "django" && return
|
|
49
|
+
grep -r "flask\|Flask" requirements.txt pyproject.toml setup.py 2>/dev/null | grep -q . && echo "flask" && return
|
|
50
|
+
echo "python-generic"
|
|
51
|
+
;;
|
|
52
|
+
javascript|typescript)
|
|
53
|
+
[ -f "next.config.js" ] || [ -f "next.config.ts" ] && echo "nextjs" && return
|
|
54
|
+
grep -q '"next"' package.json 2>/dev/null && echo "nextjs" && return
|
|
55
|
+
grep -q '"nuxt"' package.json 2>/dev/null && echo "nuxtjs" && return
|
|
56
|
+
grep -q '"@nestjs/core"' package.json 2>/dev/null && echo "nestjs" && return
|
|
57
|
+
grep -q '"express"' package.json 2>/dev/null && echo "express" && return
|
|
58
|
+
grep -q '"react"' package.json 2>/dev/null && echo "react" && return
|
|
59
|
+
grep -q '"vue"' package.json 2>/dev/null && echo "vue" && return
|
|
60
|
+
grep -q '"svelte"' package.json 2>/dev/null && echo "svelte" && return
|
|
61
|
+
echo "node-generic"
|
|
62
|
+
;;
|
|
63
|
+
go)
|
|
64
|
+
grep -r "gin-gonic\|github.com/gin" go.mod 2>/dev/null | grep -q . && echo "gin" && return
|
|
65
|
+
grep -r "echo\|labstack/echo" go.mod 2>/dev/null | grep -q . && echo "echo" && return
|
|
66
|
+
grep -r "chi\|go-chi" go.mod 2>/dev/null | grep -q . && echo "chi" && return
|
|
67
|
+
echo "go-stdlib"
|
|
68
|
+
;;
|
|
69
|
+
java)
|
|
70
|
+
grep -r "spring-boot\|springframework" pom.xml build.gradle 2>/dev/null | grep -q . && echo "spring-boot" && return
|
|
71
|
+
echo "java-generic"
|
|
72
|
+
;;
|
|
73
|
+
*)
|
|
74
|
+
echo "unknown"
|
|
75
|
+
;;
|
|
76
|
+
esac
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# ── Database Detection ──────────────────────────────────────────────────────
|
|
80
|
+
detect_database() {
|
|
81
|
+
# Check docker-compose
|
|
82
|
+
for f in docker-compose.yml docker-compose.yaml docker-compose.dev.yml; do
|
|
83
|
+
[ -f "$f" ] && {
|
|
84
|
+
grep -qi "postgres\|postgresql" "$f" && echo "postgresql" && return
|
|
85
|
+
grep -qi "mysql\|mariadb" "$f" && echo "mysql" && return
|
|
86
|
+
grep -qi "mongo\|mongodb" "$f" && echo "mongodb" && return
|
|
87
|
+
grep -qi "redis" "$f" && echo "redis" && return
|
|
88
|
+
grep -qi "sqlite" "$f" && echo "sqlite" && return
|
|
89
|
+
}
|
|
90
|
+
done
|
|
91
|
+
# Check env files
|
|
92
|
+
for f in .env .env.example .env.local .env.development; do
|
|
93
|
+
[ -f "$f" ] && {
|
|
94
|
+
grep -qi "DATABASE_URL.*postgres" "$f" && echo "postgresql" && return
|
|
95
|
+
grep -qi "DATABASE_URL.*mysql" "$f" && echo "mysql" && return
|
|
96
|
+
grep -qi "DATABASE_URL.*sqlite" "$f" && echo "sqlite" && return
|
|
97
|
+
grep -qi "MONGO_URL\|MONGODB" "$f" && echo "mongodb" && return
|
|
98
|
+
}
|
|
99
|
+
done
|
|
100
|
+
# Check requirements/package.json
|
|
101
|
+
grep -r "psycopg\|asyncpg\|pg\b" requirements.txt pyproject.toml package.json 2>/dev/null | grep -q . && echo "postgresql" && return
|
|
102
|
+
grep -r "pymysql\|mysql2\|mysql-connector" requirements.txt pyproject.toml package.json 2>/dev/null | grep -q . && echo "mysql" && return
|
|
103
|
+
grep -r "motor\|pymongo\|mongoose" requirements.txt pyproject.toml package.json 2>/dev/null | grep -q . && echo "mongodb" && return
|
|
104
|
+
echo "unknown"
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
# ── ORM Detection ───────────────────────────────────────────────────────────
|
|
108
|
+
detect_orm() {
|
|
109
|
+
grep -r "sqlalchemy\|SQLAlchemy" requirements.txt pyproject.toml 2>/dev/null | grep -q . && echo "sqlalchemy" && return
|
|
110
|
+
grep -r "alembic" requirements.txt pyproject.toml 2>/dev/null | grep -q . && echo "sqlalchemy+alembic" && return
|
|
111
|
+
[ -f "prisma/schema.prisma" ] || find . -maxdepth 3 -name "schema.prisma" 2>/dev/null | grep -q . && echo "prisma" && return
|
|
112
|
+
grep -r "typeorm\|TypeORM" package.json 2>/dev/null | grep -q . && echo "typeorm" && return
|
|
113
|
+
grep -r "sequelize\|Sequelize" package.json 2>/dev/null | grep -q . && echo "sequelize" && return
|
|
114
|
+
grep -r "django.db.models" requirements.txt pyproject.toml 2>/dev/null | grep -q . && echo "django-orm" && return
|
|
115
|
+
grep -r "drizzle-orm" package.json 2>/dev/null | grep -q . && echo "drizzle" && return
|
|
116
|
+
grep -r "mongoose" package.json 2>/dev/null | grep -q . && echo "mongoose" && return
|
|
117
|
+
echo "unknown"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# ── Infrastructure Detection ────────────────────────────────────────────────
|
|
121
|
+
detect_infra() {
|
|
122
|
+
local infra=()
|
|
123
|
+
for f in docker-compose.yml docker-compose.yaml docker-compose.dev.yml; do
|
|
124
|
+
[ -f "$f" ] && { infra+=("docker-compose"); break; }
|
|
125
|
+
done
|
|
126
|
+
[ -f "Dockerfile" ] || find . -maxdepth 2 -name "Dockerfile*" 2>/dev/null | grep -q . && infra+=("docker")
|
|
127
|
+
[ -f ".github/workflows" ] || find . -maxdepth 3 -path "*/.github/workflows/*.yml" 2>/dev/null | grep -q . && infra+=("github-actions")
|
|
128
|
+
find . -maxdepth 3 -name "nginx.conf" -o -name "*.nginx" 2>/dev/null | grep -q . && infra+=("nginx")
|
|
129
|
+
find . -maxdepth 3 -name "Caddyfile" 2>/dev/null | grep -q . && infra+=("caddy")
|
|
130
|
+
find . -maxdepth 3 -name "*.tf" 2>/dev/null | grep -q . && infra+=("terraform")
|
|
131
|
+
[ -f "fly.toml" ] && infra+=("fly.io")
|
|
132
|
+
[ -f "render.yaml" ] && infra+=("render")
|
|
133
|
+
[ -f "railway.json" ] || [ -f "railway.toml" ] && infra+=("railway")
|
|
134
|
+
[ -f "vercel.json" ] && infra+=("vercel")
|
|
135
|
+
[ -f "netlify.toml" ] && infra+=("netlify")
|
|
136
|
+
[ -f "heroku.yml" ] || [ -f "Procfile" ] && infra+=("heroku")
|
|
137
|
+
|
|
138
|
+
if [ ${#infra[@]} -eq 0 ]; then
|
|
139
|
+
echo "none"
|
|
140
|
+
else
|
|
141
|
+
local IFS=','
|
|
142
|
+
echo "${infra[*]}"
|
|
143
|
+
fi
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# ── Package Manager Detection ───────────────────────────────────────────────
|
|
147
|
+
detect_package_manager() {
|
|
148
|
+
[ -f "pnpm-lock.yaml" ] && echo "pnpm" && return
|
|
149
|
+
[ -f "yarn.lock" ] && echo "yarn" && return
|
|
150
|
+
[ -f "package-lock.json" ] && echo "npm" && return
|
|
151
|
+
[ -f "bun.lockb" ] && echo "bun" && return
|
|
152
|
+
[ -f "Pipfile.lock" ] && echo "pipenv" && return
|
|
153
|
+
[ -f "poetry.lock" ] && echo "poetry" && return
|
|
154
|
+
[ -f "requirements.txt" ] && echo "pip" && return
|
|
155
|
+
[ -f "go.mod" ] && echo "go-modules" && return
|
|
156
|
+
[ -f "Cargo.toml" ] && echo "cargo" && return
|
|
157
|
+
[ -f "Gemfile.lock" ] && echo "bundler" && return
|
|
158
|
+
echo "unknown"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# ── Auth Detection ──────────────────────────────────────────────────────────
|
|
162
|
+
detect_auth() {
|
|
163
|
+
grep -r "supabase\|@supabase" requirements.txt pyproject.toml package.json 2>/dev/null | grep -q . && echo "supabase" && return
|
|
164
|
+
grep -r "next-auth\|NextAuth\|auth\.js" package.json 2>/dev/null | grep -q . && echo "next-auth" && return
|
|
165
|
+
grep -r "passport\|passportjs" package.json 2>/dev/null | grep -q . && echo "passport" && return
|
|
166
|
+
grep -r "python-jose\|PyJWT\|fastapi-users" requirements.txt pyproject.toml 2>/dev/null | grep -q . && echo "jwt" && return
|
|
167
|
+
grep -r "clerk\|@clerk" package.json 2>/dev/null | grep -q . && echo "clerk" && return
|
|
168
|
+
grep -r "auth0\|@auth0" package.json 2>/dev/null | grep -q . && echo "auth0" && return
|
|
169
|
+
grep -r "keycloak" requirements.txt pyproject.toml package.json 2>/dev/null | grep -q . && echo "keycloak" && return
|
|
170
|
+
echo "unknown"
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
# ── Project Name ─────────────────────────────────────────────────────────────
|
|
174
|
+
detect_name() {
|
|
175
|
+
# package.json
|
|
176
|
+
if [ -f "package.json" ]; then
|
|
177
|
+
name=$(python3 -c "import json,sys; d=json.load(open('package.json')); print(d.get('name',''))" 2>/dev/null)
|
|
178
|
+
[ -n "$name" ] && echo "$name" && return
|
|
179
|
+
fi
|
|
180
|
+
# pyproject.toml
|
|
181
|
+
if [ -f "pyproject.toml" ]; then
|
|
182
|
+
name=$(grep -E '^name\s*=' pyproject.toml | head -1 | sed 's/.*=\s*"\(.*\)"/\1/')
|
|
183
|
+
[ -n "$name" ] && echo "$name" && return
|
|
184
|
+
fi
|
|
185
|
+
# Directory name
|
|
186
|
+
basename "$PROJECT_ROOT"
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
# ── Main ─────────────────────────────────────────────────────────────────────
|
|
190
|
+
main() {
|
|
191
|
+
log "Detecting stack in: $PROJECT_ROOT"
|
|
192
|
+
|
|
193
|
+
LANG=$(detect_language)
|
|
194
|
+
FRAMEWORK=$(detect_framework "$LANG")
|
|
195
|
+
DATABASE=$(detect_database)
|
|
196
|
+
ORM=$(detect_orm)
|
|
197
|
+
INFRA=$(detect_infra)
|
|
198
|
+
PKG_MGR=$(detect_package_manager)
|
|
199
|
+
AUTH=$(detect_auth)
|
|
200
|
+
NAME=$(detect_name)
|
|
201
|
+
SLUG=$(echo "$NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
|
|
202
|
+
|
|
203
|
+
log "Stack: $LANG / $FRAMEWORK / $DATABASE / $ORM"
|
|
204
|
+
|
|
205
|
+
# Output JSON
|
|
206
|
+
cat <<EOF
|
|
207
|
+
{
|
|
208
|
+
"name": "$NAME",
|
|
209
|
+
"slug": "$SLUG",
|
|
210
|
+
"language": "$LANG",
|
|
211
|
+
"framework": "$FRAMEWORK",
|
|
212
|
+
"database": "$DATABASE",
|
|
213
|
+
"orm": "$ORM",
|
|
214
|
+
"auth": "$AUTH",
|
|
215
|
+
"package_manager": "$PKG_MGR",
|
|
216
|
+
"infrastructure": "$INFRA",
|
|
217
|
+
"project_root": "$PROJECT_ROOT"
|
|
218
|
+
}
|
|
219
|
+
EOF
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
main
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ensure-python.sh — Check for Python >=3.8, install if missing
|
|
3
|
+
# Supports: Linux (apt/yum/dnf/pacman), macOS (brew), WSL2
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
MIN_MAJOR=3
|
|
8
|
+
MIN_MINOR=8
|
|
9
|
+
|
|
10
|
+
CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; RESET='\033[0m'
|
|
11
|
+
|
|
12
|
+
# All logging goes to stderr so stdout is clean for the command name
|
|
13
|
+
log() { printf '%b\n' "${CYAN}[python]${RESET} $*" >&2; }
|
|
14
|
+
ok() { printf '%b\n' "${GREEN}[python]${RESET} $*" >&2; }
|
|
15
|
+
warn() { printf '%b\n' "${YELLOW}[python]${RESET} $*" >&2; }
|
|
16
|
+
fail() { printf '%b\n' "${RED}[python]${RESET} $*" >&2; exit 1; }
|
|
17
|
+
|
|
18
|
+
version_ok() {
|
|
19
|
+
local cmd="$1"
|
|
20
|
+
if ! command -v "$cmd" &>/dev/null; then return 1; fi
|
|
21
|
+
local ver
|
|
22
|
+
ver=$("$cmd" --version 2>&1 | grep -oE '[0-9]+\.[0-9]+' | head -1)
|
|
23
|
+
local major minor
|
|
24
|
+
major=$(echo "$ver" | cut -d. -f1)
|
|
25
|
+
minor=$(echo "$ver" | cut -d. -f2)
|
|
26
|
+
[ "$major" -gt "$MIN_MAJOR" ] || { [ "$major" -eq "$MIN_MAJOR" ] && [ "$minor" -ge "$MIN_MINOR" ]; }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
find_python() {
|
|
30
|
+
for cmd in python3 python python3.12 python3.11 python3.10 python3.9 python3.8; do
|
|
31
|
+
if version_ok "$cmd"; then
|
|
32
|
+
echo "$cmd"
|
|
33
|
+
return 0
|
|
34
|
+
fi
|
|
35
|
+
done
|
|
36
|
+
return 1
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
install_linux() {
|
|
40
|
+
log "Detecting Linux package manager..."
|
|
41
|
+
if command -v apt-get &>/dev/null; then
|
|
42
|
+
log "Installing via apt..."
|
|
43
|
+
sudo apt-get update -qq && sudo apt-get install -y python3 python3-pip
|
|
44
|
+
elif command -v dnf &>/dev/null; then
|
|
45
|
+
log "Installing via dnf..."
|
|
46
|
+
sudo dnf install -y python3 python3-pip
|
|
47
|
+
elif command -v yum &>/dev/null; then
|
|
48
|
+
log "Installing via yum..."
|
|
49
|
+
sudo yum install -y python3 python3-pip
|
|
50
|
+
elif command -v pacman &>/dev/null; then
|
|
51
|
+
log "Installing via pacman..."
|
|
52
|
+
sudo pacman -Sy --noconfirm python python-pip
|
|
53
|
+
elif command -v zypper &>/dev/null; then
|
|
54
|
+
log "Installing via zypper..."
|
|
55
|
+
sudo zypper install -y python3 python3-pip
|
|
56
|
+
else
|
|
57
|
+
fail "No supported package manager found (tried apt, dnf, yum, pacman, zypper). Please install Python ${MIN_MAJOR}.${MIN_MINOR}+ manually."
|
|
58
|
+
fi
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
install_macos() {
|
|
62
|
+
if command -v brew &>/dev/null; then
|
|
63
|
+
log "Installing via Homebrew..."
|
|
64
|
+
brew install python3
|
|
65
|
+
else
|
|
66
|
+
warn "Homebrew not found. Attempting to install Homebrew first..."
|
|
67
|
+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
68
|
+
brew install python3
|
|
69
|
+
fi
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
main() {
|
|
73
|
+
log "Checking for Python >= ${MIN_MAJOR}.${MIN_MINOR}..."
|
|
74
|
+
|
|
75
|
+
if PYTHON_CMD=$(find_python); then
|
|
76
|
+
ver=$("$PYTHON_CMD" --version 2>&1)
|
|
77
|
+
ok "Found: $PYTHON_CMD ($ver)"
|
|
78
|
+
echo "$PYTHON_CMD"
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
warn "Python >= ${MIN_MAJOR}.${MIN_MINOR} not found. Attempting installation..."
|
|
83
|
+
|
|
84
|
+
OS="$(uname -s)"
|
|
85
|
+
case "$OS" in
|
|
86
|
+
Linux*) install_linux ;;
|
|
87
|
+
Darwin*) install_macos ;;
|
|
88
|
+
*) fail "Unsupported OS: $OS. Please install Python ${MIN_MAJOR}.${MIN_MINOR}+ manually." ;;
|
|
89
|
+
esac
|
|
90
|
+
|
|
91
|
+
if PYTHON_CMD=$(find_python); then
|
|
92
|
+
ver=$("$PYTHON_CMD" --version 2>&1)
|
|
93
|
+
ok "Installed successfully: $PYTHON_CMD ($ver)"
|
|
94
|
+
echo "$PYTHON_CMD"
|
|
95
|
+
else
|
|
96
|
+
fail "Installation appeared to succeed but Python ${MIN_MAJOR}.${MIN_MINOR}+ is still not accessible. Please check your PATH."
|
|
97
|
+
fi
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
main
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
input=$(cat)
|
|
3
|
+
|
|
4
|
+
MODEL=$(echo "$input" | jq -r '.model.display_name')
|
|
5
|
+
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
|
|
6
|
+
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
|
|
7
|
+
|
|
8
|
+
CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; RESET='\033[0m'
|
|
9
|
+
|
|
10
|
+
# Color based on context usage
|
|
11
|
+
if [ "$PCT" -ge 90 ]; then BAR_COLOR="$RED"
|
|
12
|
+
elif [ "$PCT" -ge 70 ]; then BAR_COLOR="$YELLOW"
|
|
13
|
+
else BAR_COLOR="$GREEN"; fi
|
|
14
|
+
|
|
15
|
+
# Build 10-segment progress bar
|
|
16
|
+
FILLED=$((PCT / 10)); EMPTY=$((10 - FILLED))
|
|
17
|
+
BAR=""
|
|
18
|
+
[ "$FILLED" -gt 0 ] && BAR=$(printf "%${FILLED}s" | tr ' ' '#')
|
|
19
|
+
[ "$EMPTY" -gt 0 ] && BAR="${BAR}$(printf "%${EMPTY}s" | tr ' ' '-')"
|
|
20
|
+
|
|
21
|
+
# Git branch
|
|
22
|
+
BRANCH=""
|
|
23
|
+
if git -C "$DIR" rev-parse --git-dir > /dev/null 2>&1; then
|
|
24
|
+
BRANCH=$(git -C "$DIR" branch --show-current 2>/dev/null)
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
printf '%b' "${CYAN}[$MODEL]${RESET} ${BRANCH:+🌿 $BRANCH | }${BAR_COLOR}${BAR}${RESET} ${PCT}%\n"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# validate.sh — Post-install validation
|
|
3
|
+
# Confirms generate.py ran successfully and sections exist
|
|
4
|
+
# Usage: bash validate.sh [project-root]
|
|
5
|
+
# Exit 0 = OK, Exit 1 = failed
|
|
6
|
+
|
|
7
|
+
PROJECT_ROOT="${1:-$(pwd)}"
|
|
8
|
+
MAP_DIR="$PROJECT_ROOT/.claude/project-map"
|
|
9
|
+
|
|
10
|
+
GREEN='\033[32m'; RED='\033[31m'; YELLOW='\033[33m'; CYAN='\033[36m'; RESET='\033[0m'
|
|
11
|
+
|
|
12
|
+
ok() { printf '%b\n' " ${GREEN}✓${RESET} $*"; }
|
|
13
|
+
fail() { printf '%b\n' " ${RED}✗${RESET} $*"; FAILED=1; }
|
|
14
|
+
warn() { printf '%b\n' " ${YELLOW}⚠${RESET} $*"; }
|
|
15
|
+
|
|
16
|
+
FAILED=0
|
|
17
|
+
|
|
18
|
+
printf '%b\n' "\n${CYAN}── Validation ──────────────────────────────────────${RESET}"
|
|
19
|
+
|
|
20
|
+
# Required files
|
|
21
|
+
[ -f "$MAP_DIR/generate.py" ] && ok "generate.py exists" || fail "generate.py missing"
|
|
22
|
+
[ -f "$MAP_DIR/grader.py" ] && ok "grader.py exists" || fail "grader.py missing"
|
|
23
|
+
[ -f "$MAP_DIR/PROJECT_MAP.md" ] && ok "PROJECT_MAP.md generated" || fail "PROJECT_MAP.md not generated — did generate.py run?"
|
|
24
|
+
[ -f "$MAP_DIR/checksums.json" ] && ok "checksums.json exists" || warn "checksums.json missing (ok for first run)"
|
|
25
|
+
[ -d "$MAP_DIR/sections" ] && ok "sections/ directory exists" || fail "sections/ directory missing"
|
|
26
|
+
|
|
27
|
+
# At least one section
|
|
28
|
+
SECTION_COUNT=$(find "$MAP_DIR/sections" -name "*.md" 2>/dev/null | wc -l)
|
|
29
|
+
if [ "$SECTION_COUNT" -gt 0 ]; then
|
|
30
|
+
ok "sections/ has $SECTION_COUNT file(s)"
|
|
31
|
+
else
|
|
32
|
+
warn "sections/ is empty (ok for greenfield — sections generate as code is added)"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Rules files
|
|
36
|
+
[ -f "$PROJECT_ROOT/.claude/rules/project-vocabulary.md" ] \
|
|
37
|
+
&& ok "project-vocabulary.md exists" || fail "project-vocabulary.md missing"
|
|
38
|
+
[ -f "$PROJECT_ROOT/.claude/rules/operational-runbook.md" ] \
|
|
39
|
+
&& ok "operational-runbook.md exists" || fail "operational-runbook.md missing"
|
|
40
|
+
|
|
41
|
+
# Skill
|
|
42
|
+
SKILL=$(find "$PROJECT_ROOT/.claude/skills" -name "SKILL.md" 2>/dev/null | head -1)
|
|
43
|
+
[ -n "$SKILL" ] && ok "Developer skill: $SKILL" || fail "No SKILL.md found in .claude/skills/"
|
|
44
|
+
|
|
45
|
+
# Git hooks
|
|
46
|
+
[ -f "$PROJECT_ROOT/.githooks/pre-commit" ] \
|
|
47
|
+
&& ok ".githooks/pre-commit exists" || warn ".githooks/pre-commit missing"
|
|
48
|
+
[ -x "$PROJECT_ROOT/.githooks/pre-commit" ] \
|
|
49
|
+
&& ok ".githooks/pre-commit is executable" || warn ".githooks/pre-commit is not executable"
|
|
50
|
+
|
|
51
|
+
printf '%b\n' "${CYAN}────────────────────────────────────────────────────${RESET}"
|
|
52
|
+
|
|
53
|
+
if [ "$FAILED" -eq 0 ]; then
|
|
54
|
+
printf '%b\n' "\n${GREEN}✓ Validation passed${RESET}\n"
|
|
55
|
+
exit 0
|
|
56
|
+
else
|
|
57
|
+
printf '%b\n' "\n${RED}✗ Validation failed — see issues above${RESET}\n"
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: babel-fish-developer-skill
|
|
3
|
+
description: |
|
|
4
|
+
Full-stack developer context for babel-fish (unknown/unknown).
|
|
5
|
+
Provides instant access to project map, vocabulary translation, and infrastructure details.
|
|
6
|
+
Invoke when working on any babel-fish feature, bug, or infrastructure task.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /babel-fish-developer — babel-fish Developer Context
|
|
10
|
+
|
|
11
|
+
You are a developer working on **babel-fish**. This skill gives you complete
|
|
12
|
+
knowledge of every route, model, service, feature, and infrastructure component
|
|
13
|
+
via an auto-generated project map.
|
|
14
|
+
|
|
15
|
+
## On Trigger — Load Only What You Need
|
|
16
|
+
|
|
17
|
+
The project map is split into section files at `.claude/project-map/sections/`.
|
|
18
|
+
Do NOT read them all. Start with:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Read: .claude/project-map/PROJECT_MAP.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Use the Quick Routing table to pick which 2-3 sections to load.
|
|
25
|
+
|
|
26
|
+
## Section Routing
|
|
27
|
+
|
|
28
|
+
| Task | Read These Sections |
|
|
29
|
+
|------|-------------------|
|
|
30
|
+
| Feature / UX work | 01-vocabulary → 09-frontend → 04-routes |
|
|
31
|
+
| Add a model or field | 05-models → 06-schemas → 12-import-chains |
|
|
32
|
+
| Troubleshoot error | 02-topology → 03-environment → 14-proxy |
|
|
33
|
+
| Infrastructure / scaling | 16-infra-profile → 02-topology |
|
|
34
|
+
| Auth / security | 15-auth-config → 19-doc-pointers |
|
|
35
|
+
| What tools exist | 10-tools-commands |
|
|
36
|
+
| Background jobs | 08-background-jobs |
|
|
37
|
+
|
|
38
|
+
## Platform Quick Reference
|
|
39
|
+
|
|
40
|
+
- **Stack**: unknown / unknown
|
|
41
|
+
- **Map**: `.claude/project-map/PROJECT_MAP.md`
|
|
42
|
+
|
|
43
|
+
## Keeping the Map Current
|
|
44
|
+
|
|
45
|
+
Regenerates automatically via pre-commit hook.
|
|
46
|
+
Force: `python .claude/project-map/generate.py --force`
|
|
47
|
+
|
|
48
|
+
## Growing the Runbook
|
|
49
|
+
|
|
50
|
+
When you encounter a non-obvious operational issue, suggest adding it:
|
|
51
|
+
|
|
52
|
+
> "This looks like operational knowledge worth documenting. Want me to add it
|
|
53
|
+
> to the runbook? (Y/n)"
|
|
54
|
+
|
|
55
|
+
If agreed, append a concise entry (symptom → cause → fix) to
|
|
56
|
+
`.claude/rules/operational-runbook.md`.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{PROJECT_SLUG}}-developer-skill
|
|
3
|
+
description: |
|
|
4
|
+
Full-stack developer context for {{PROJECT_NAME}} ({{LANGUAGE}}/{{FRAMEWORK}}).
|
|
5
|
+
Provides instant access to project map, vocabulary translation, and infrastructure details.
|
|
6
|
+
Invoke when working on any {{PROJECT_NAME}} feature, bug, or infrastructure task.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /{{PROJECT_SLUG}}-developer — {{PROJECT_NAME}} Developer Context
|
|
10
|
+
|
|
11
|
+
You are a developer working on **{{PROJECT_NAME}}**. This skill gives you complete
|
|
12
|
+
knowledge of every route, model, service, feature, and infrastructure component
|
|
13
|
+
via an auto-generated project map.
|
|
14
|
+
|
|
15
|
+
## On Trigger — Load Only What You Need
|
|
16
|
+
|
|
17
|
+
The project map is split into section files at `.claude/project-map/sections/`.
|
|
18
|
+
Do NOT read them all. Start with:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Read: .claude/project-map/PROJECT_MAP.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Use the Quick Routing table to pick which 2-3 sections to load.
|
|
25
|
+
|
|
26
|
+
## Section Routing
|
|
27
|
+
|
|
28
|
+
| Task | Read These Sections |
|
|
29
|
+
|------|-------------------|
|
|
30
|
+
| Feature / UX work | 01-vocabulary → 09-frontend → 04-routes |
|
|
31
|
+
| Add a model or field | 05-models → 06-schemas → 12-import-chains |
|
|
32
|
+
| Troubleshoot error | 02-topology → 03-environment → 14-proxy |
|
|
33
|
+
| Infrastructure / scaling | 16-infra-profile → 02-topology |
|
|
34
|
+
| Auth / security | 15-auth-config → 19-doc-pointers |
|
|
35
|
+
| What tools exist | 10-tools-commands |
|
|
36
|
+
| Background jobs | 08-background-jobs |
|
|
37
|
+
|
|
38
|
+
## Platform Quick Reference
|
|
39
|
+
|
|
40
|
+
- **Stack**: {{LANGUAGE}} / {{FRAMEWORK}}
|
|
41
|
+
- **Map**: `.claude/project-map/PROJECT_MAP.md`
|
|
42
|
+
|
|
43
|
+
## Keeping the Map Current
|
|
44
|
+
|
|
45
|
+
Regenerates automatically via pre-commit hook.
|
|
46
|
+
Force: `python .claude/project-map/generate.py --force`
|
|
47
|
+
|
|
48
|
+
## Growing the Runbook
|
|
49
|
+
|
|
50
|
+
When you encounter a non-obvious operational issue, suggest adding it:
|
|
51
|
+
|
|
52
|
+
> "This looks like operational knowledge worth documenting. Want me to add it
|
|
53
|
+
> to the runbook? (Y/n)"
|
|
54
|
+
|
|
55
|
+
If agreed, append a concise entry (symptom → cause → fix) to
|
|
56
|
+
`.claude/rules/operational-runbook.md`.
|