@theglitchking/babel-fish 2.4.3 → 2.6.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 +79 -10
- package/.claude/project-map/context-check.py +156 -0
- package/.claude/project-map/generate.py +25 -0
- package/.claude/project-map/structure-check.py +773 -0
- package/.claude/project-map/test_context_check.py +221 -0
- package/.claude/project-map/test_generate.py +13 -0
- package/.claude/project-map/test_structure_check.py +864 -0
- package/.claude/templates/structure/monorepo.toml +76 -0
- package/.claude/templates/structure/multi-repo.toml +85 -0
- package/.claude/templates/structure/single.toml +73 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.githooks/install.sh +0 -0
- package/.githooks/pre-commit +35 -0
- package/CHANGELOG.md +96 -0
- package/README.md +49 -3
- package/checksums.json +1 -1
- package/package.json +6 -2
- package/scripts/link-skills.js +3 -3
- package/skills/structure-bootstrap/SKILL.md +209 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Layout: monorepo -- several apps and shared packages in one repo, dev (localhost) -> stg -> prod (cloud).
|
|
2
|
+
#
|
|
3
|
+
# A reference, not a rule. `structure-check.py --bootstrap --layout monorepo` copies it,
|
|
4
|
+
# marks each folder active (exists) or planned (not yet), adds a folder for anything
|
|
5
|
+
# it doesn't cover, and lists the remaining differences in `exceptions` by exact
|
|
6
|
+
# path -- adopting it blocks nothing. The
|
|
7
|
+
# structure-bootstrap skill reads it to suggest purposes and changes.
|
|
8
|
+
mode = "monorepo"
|
|
9
|
+
env_file = "infra/env/.env.example" # the ONE committed env template (every key, every env and app)
|
|
10
|
+
root_files = [
|
|
11
|
+
"README.md", "LICENSE", "CHANGELOG.md", "CLAUDE.md", "AGENTS.md",
|
|
12
|
+
".gitignore", ".gitattributes", ".editorconfig", ".dockerignore", ".mcp.json",
|
|
13
|
+
"package.json", "package-lock.json", "*.lock", "tsconfig*.json", "*.config.js", "*.config.ts",
|
|
14
|
+
"pyproject.toml", "requirements*.txt", "go.mod", "go.sum", "Cargo.toml",
|
|
15
|
+
"Makefile", "Dockerfile",
|
|
16
|
+
"pnpm-workspace.yaml", "turbo.json", "nx.json", "lerna.json", "go.work",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[[folder]]
|
|
20
|
+
path = "apps"
|
|
21
|
+
purpose = "One folder per deployable app: apps/<name>/ with its own source, tests, manifest and migrations"
|
|
22
|
+
holds = ["*/**", "README.md"]
|
|
23
|
+
|
|
24
|
+
[[folder]]
|
|
25
|
+
path = "packages"
|
|
26
|
+
purpose = "Shared libraries: packages/<name>/, imported by apps, never deployed alone"
|
|
27
|
+
holds = ["*/**", "README.md"]
|
|
28
|
+
|
|
29
|
+
[[folder]]
|
|
30
|
+
path = "tests"
|
|
31
|
+
purpose = "Cross-app tests (end-to-end, contract); unit tests live with each app"
|
|
32
|
+
|
|
33
|
+
[[folder]]
|
|
34
|
+
path = "scripts"
|
|
35
|
+
purpose = "Repo-wide developer and ops scripts"
|
|
36
|
+
|
|
37
|
+
[[folder]]
|
|
38
|
+
path = "infra/compose"
|
|
39
|
+
purpose = "Compose files: base.yml shared, dev.yml for localhost, remote.yml for the cloud environments"
|
|
40
|
+
holds = ["*.yml", "*.yaml"]
|
|
41
|
+
|
|
42
|
+
[[folder]]
|
|
43
|
+
path = "infra/env"
|
|
44
|
+
purpose = "Env config: .env.example is the one template (every key, placeholders) and your local .env sits beside it, gitignored. Stg/prod values come from the secret manager or CI, never from files here; <env>/ holds only non-secret per-env deltas"
|
|
45
|
+
holds = [".env.example", "README.md", "*/**"]
|
|
46
|
+
|
|
47
|
+
[[folder]]
|
|
48
|
+
path = "infra/deploy"
|
|
49
|
+
purpose = "Cloud deploy config: base/ shared, <env>/ holds only what differs (Terraform, k8s, platform files)"
|
|
50
|
+
|
|
51
|
+
[[folder]]
|
|
52
|
+
path = ".github"
|
|
53
|
+
purpose = "CI workflows -- one deploy workflow that takes the environment as input"
|
|
54
|
+
|
|
55
|
+
[[folder]]
|
|
56
|
+
path = ".claude"
|
|
57
|
+
purpose = "Claude Code config: rules, skills, the project map and this manifest"
|
|
58
|
+
|
|
59
|
+
[[folder]]
|
|
60
|
+
path = ".documentation"
|
|
61
|
+
purpose = "Prose docs (hit-em-with-the-docs)"
|
|
62
|
+
|
|
63
|
+
[[environment]]
|
|
64
|
+
name = "dev"
|
|
65
|
+
target = "local"
|
|
66
|
+
promotes_to = "stg"
|
|
67
|
+
|
|
68
|
+
[[environment]]
|
|
69
|
+
name = "stg"
|
|
70
|
+
target = "cloud"
|
|
71
|
+
promotes_to = "prod"
|
|
72
|
+
mirrors = "prod"
|
|
73
|
+
|
|
74
|
+
[[environment]]
|
|
75
|
+
name = "prod"
|
|
76
|
+
target = "cloud"
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Layout: multi-repo -- this repo is one of several. Same flat layout as `single`;
|
|
2
|
+
# [[repo]] entries point at the others. Each of those runs its own babel-fish (map,
|
|
3
|
+
# drift, structure check) -- nothing here reaches into them.
|
|
4
|
+
#
|
|
5
|
+
# Environments: dev (localhost) -> stg -> prod (cloud).
|
|
6
|
+
#
|
|
7
|
+
# A reference, not a rule. `structure-check.py --bootstrap --layout multi-repo` copies it,
|
|
8
|
+
# marks each folder active (exists) or planned (not yet), adds a folder for anything
|
|
9
|
+
# it doesn't cover, and lists the remaining differences in `exceptions` by exact
|
|
10
|
+
# path -- adopting it blocks nothing. The
|
|
11
|
+
# structure-bootstrap skill reads it to suggest purposes and changes.
|
|
12
|
+
mode = "multi-repo"
|
|
13
|
+
env_file = "infra/env/.env.example" # the ONE committed env template (every key, every env and app)
|
|
14
|
+
root_files = [
|
|
15
|
+
"README.md", "LICENSE", "CHANGELOG.md", "CLAUDE.md", "AGENTS.md",
|
|
16
|
+
".gitignore", ".gitattributes", ".editorconfig", ".dockerignore", ".mcp.json",
|
|
17
|
+
"package.json", "package-lock.json", "*.lock", "tsconfig*.json", "*.config.js", "*.config.ts",
|
|
18
|
+
"pyproject.toml", "requirements*.txt", "go.mod", "go.sum", "Cargo.toml",
|
|
19
|
+
"Makefile", "Dockerfile",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[[folder]]
|
|
23
|
+
path = "src"
|
|
24
|
+
purpose = "Application source"
|
|
25
|
+
|
|
26
|
+
[[folder]]
|
|
27
|
+
path = "tests"
|
|
28
|
+
purpose = "Tests"
|
|
29
|
+
|
|
30
|
+
[[folder]]
|
|
31
|
+
path = "scripts"
|
|
32
|
+
purpose = "Developer and ops scripts"
|
|
33
|
+
|
|
34
|
+
[[folder]]
|
|
35
|
+
path = "migrations"
|
|
36
|
+
purpose = "Database migrations -- one folder, the same path forward in every environment"
|
|
37
|
+
|
|
38
|
+
[[folder]]
|
|
39
|
+
path = "infra/compose"
|
|
40
|
+
purpose = "Compose files: base.yml shared, dev.yml for localhost, remote.yml for the cloud environments"
|
|
41
|
+
holds = ["*.yml", "*.yaml"]
|
|
42
|
+
|
|
43
|
+
[[folder]]
|
|
44
|
+
path = "infra/env"
|
|
45
|
+
purpose = "Env config: .env.example is the one template (every key, placeholders) and your local .env sits beside it, gitignored. Stg/prod values come from the secret manager or CI, never from files here; <env>/ holds only non-secret per-env deltas"
|
|
46
|
+
holds = [".env.example", "README.md", "*/**"]
|
|
47
|
+
|
|
48
|
+
[[folder]]
|
|
49
|
+
path = "infra/deploy"
|
|
50
|
+
purpose = "Cloud deploy config: base/ shared, <env>/ holds only what differs (Terraform, k8s, platform files)"
|
|
51
|
+
|
|
52
|
+
[[folder]]
|
|
53
|
+
path = ".github"
|
|
54
|
+
purpose = "CI workflows -- one deploy workflow that takes the environment as input"
|
|
55
|
+
|
|
56
|
+
[[folder]]
|
|
57
|
+
path = ".claude"
|
|
58
|
+
purpose = "Claude Code config: rules, skills, the project map and this manifest"
|
|
59
|
+
|
|
60
|
+
[[folder]]
|
|
61
|
+
path = ".documentation"
|
|
62
|
+
purpose = "Prose docs (hit-em-with-the-docs)"
|
|
63
|
+
|
|
64
|
+
[[environment]]
|
|
65
|
+
name = "dev"
|
|
66
|
+
target = "local"
|
|
67
|
+
promotes_to = "stg"
|
|
68
|
+
|
|
69
|
+
[[environment]]
|
|
70
|
+
name = "stg"
|
|
71
|
+
target = "cloud"
|
|
72
|
+
promotes_to = "prod"
|
|
73
|
+
mirrors = "prod"
|
|
74
|
+
|
|
75
|
+
[[environment]]
|
|
76
|
+
name = "prod"
|
|
77
|
+
target = "cloud"
|
|
78
|
+
|
|
79
|
+
# One entry per repo this one works with. `path` is a local checkout (warned if
|
|
80
|
+
# missing), `url` the remote; at least one is required.
|
|
81
|
+
# [[repo]]
|
|
82
|
+
# name = "api"
|
|
83
|
+
# path = "../api"
|
|
84
|
+
# url = "https://github.com/<org>/api"
|
|
85
|
+
# purpose = "Backend API"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Layout: single -- one project, flat layout, dev (localhost) -> stg -> prod (cloud).
|
|
2
|
+
#
|
|
3
|
+
# A reference, not a rule. `structure-check.py --bootstrap --layout single` copies it,
|
|
4
|
+
# marks each folder active (exists) or planned (not yet), adds a folder for anything
|
|
5
|
+
# it doesn't cover, and lists the remaining differences in `exceptions` by exact
|
|
6
|
+
# path -- adopting it blocks nothing. The
|
|
7
|
+
# structure-bootstrap skill reads it to suggest purposes and changes.
|
|
8
|
+
mode = "single"
|
|
9
|
+
env_file = "infra/env/.env.example" # the ONE committed env template (every key, every env and app)
|
|
10
|
+
root_files = [
|
|
11
|
+
"README.md", "LICENSE", "CHANGELOG.md", "CLAUDE.md", "AGENTS.md",
|
|
12
|
+
".gitignore", ".gitattributes", ".editorconfig", ".dockerignore", ".mcp.json",
|
|
13
|
+
"package.json", "package-lock.json", "*.lock", "tsconfig*.json", "*.config.js", "*.config.ts",
|
|
14
|
+
"pyproject.toml", "requirements*.txt", "go.mod", "go.sum", "Cargo.toml",
|
|
15
|
+
"Makefile", "Dockerfile",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[[folder]]
|
|
19
|
+
path = "src"
|
|
20
|
+
purpose = "Application source"
|
|
21
|
+
|
|
22
|
+
[[folder]]
|
|
23
|
+
path = "tests"
|
|
24
|
+
purpose = "Tests"
|
|
25
|
+
|
|
26
|
+
[[folder]]
|
|
27
|
+
path = "scripts"
|
|
28
|
+
purpose = "Developer and ops scripts"
|
|
29
|
+
|
|
30
|
+
[[folder]]
|
|
31
|
+
path = "migrations"
|
|
32
|
+
purpose = "Database migrations -- one folder, the same path forward in every environment"
|
|
33
|
+
|
|
34
|
+
[[folder]]
|
|
35
|
+
path = "infra/compose"
|
|
36
|
+
purpose = "Compose files: base.yml shared, dev.yml for localhost, remote.yml for the cloud environments"
|
|
37
|
+
holds = ["*.yml", "*.yaml"]
|
|
38
|
+
|
|
39
|
+
[[folder]]
|
|
40
|
+
path = "infra/env"
|
|
41
|
+
purpose = "Env config: .env.example is the one template (every key, placeholders) and your local .env sits beside it, gitignored. Stg/prod values come from the secret manager or CI, never from files here; <env>/ holds only non-secret per-env deltas"
|
|
42
|
+
holds = [".env.example", "README.md", "*/**"]
|
|
43
|
+
|
|
44
|
+
[[folder]]
|
|
45
|
+
path = "infra/deploy"
|
|
46
|
+
purpose = "Cloud deploy config: base/ shared, <env>/ holds only what differs (Terraform, k8s, platform files)"
|
|
47
|
+
|
|
48
|
+
[[folder]]
|
|
49
|
+
path = ".github"
|
|
50
|
+
purpose = "CI workflows -- one deploy workflow that takes the environment as input"
|
|
51
|
+
|
|
52
|
+
[[folder]]
|
|
53
|
+
path = ".claude"
|
|
54
|
+
purpose = "Claude Code config: rules, skills, the project map and this manifest"
|
|
55
|
+
|
|
56
|
+
[[folder]]
|
|
57
|
+
path = ".documentation"
|
|
58
|
+
purpose = "Prose docs (hit-em-with-the-docs)"
|
|
59
|
+
|
|
60
|
+
[[environment]]
|
|
61
|
+
name = "dev"
|
|
62
|
+
target = "local"
|
|
63
|
+
promotes_to = "stg"
|
|
64
|
+
|
|
65
|
+
[[environment]]
|
|
66
|
+
name = "stg"
|
|
67
|
+
target = "cloud"
|
|
68
|
+
promotes_to = "prod"
|
|
69
|
+
mirrors = "prod"
|
|
70
|
+
|
|
71
|
+
[[environment]]
|
|
72
|
+
name = "prod"
|
|
73
|
+
target = "cloud"
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Official marketplace for babel-fish - Codebase introspection and vocabulary translation for AI coding assistants",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.6.0"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "babel-fish",
|
|
14
14
|
"description": "Auto-generates a project map, vocabulary translation layer, and developer skill for any codebase. Introspects routes, models, services, features, infrastructure, and session history to give Claude instant full-stack context. Self-updates via pre-commit hook.",
|
|
15
|
-
"version": "2.
|
|
15
|
+
"version": "2.6.0",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "TheGlitchKing"
|
|
18
18
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babel-fish",
|
|
3
3
|
"description": "Auto-generates a project map, vocabulary translation layer, and developer skill for any codebase. Introspects routes, models, services, features, infrastructure, and session history to give Claude instant full-stack context. Self-updates via pre-commit hook.",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.6.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TheGlitchKing",
|
|
7
7
|
"email": "theglitchking@users.noreply.github.com"
|
package/.githooks/install.sh
CHANGED
|
File without changes
|
package/.githooks/pre-commit
CHANGED
|
@@ -21,3 +21,38 @@ if echo "$STAGED_FILES" | grep -qE "$EXTENSIONS_PATTERN" 2>/dev/null; then
|
|
|
21
21
|
fi
|
|
22
22
|
fi
|
|
23
23
|
# ── End Codebase Mapper ──────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
# ── Context Check: auto-loaded instructions stay in budget, pointers resolve ──
|
|
26
|
+
if git diff --cached --name-only 2>/dev/null | grep -qE '^(\.claude/)?CLAUDE(\.local)?\.md$|^\.claude/rules/.*\.md$'; then
|
|
27
|
+
CHECK_SCRIPT=".claude/project-map/context-check.py"
|
|
28
|
+
if [ -f "$CHECK_SCRIPT" ]; then
|
|
29
|
+
PYTHON=""
|
|
30
|
+
if [ -f ".venv/bin/python3" ]; then PYTHON=".venv/bin/python3"
|
|
31
|
+
elif command -v python3 &>/dev/null; then PYTHON="python3"
|
|
32
|
+
elif command -v python &>/dev/null; then PYTHON="python"
|
|
33
|
+
fi
|
|
34
|
+
if [ -n "$PYTHON" ] && ! $PYTHON "$CHECK_SCRIPT"; then
|
|
35
|
+
echo "[context-check] Commit blocked. Fix the FAIL lines above, or add flags (--budget N, --map-style) to this call in .githooks/pre-commit." >&2
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
40
|
+
# ── End Context Check ────────────────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
# ── Structure Check: files land where .claude/structure.toml says (#22) ──────
|
|
43
|
+
# Opt-in: runs only once the repo has a manifest. On Python < 3.11 it warns and passes.
|
|
44
|
+
if [ -f ".claude/structure.toml" ]; then
|
|
45
|
+
CHECK_SCRIPT=".claude/project-map/structure-check.py"
|
|
46
|
+
if [ -f "$CHECK_SCRIPT" ]; then
|
|
47
|
+
PYTHON=""
|
|
48
|
+
if [ -f ".venv/bin/python3" ]; then PYTHON=".venv/bin/python3"
|
|
49
|
+
elif command -v python3 &>/dev/null; then PYTHON="python3"
|
|
50
|
+
elif command -v python &>/dev/null; then PYTHON="python"
|
|
51
|
+
fi
|
|
52
|
+
if [ -n "$PYTHON" ] && ! $PYTHON "$CHECK_SCRIPT" --staged; then
|
|
53
|
+
echo "[structure-check] Commit blocked. Each FAIL above has a fix: line -- or change .claude/structure.toml if the structure should change." >&2
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
# ── End Structure Check ──────────────────────────────────────────────────────
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,102 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.6.0] - 2026-09-30
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`structure-check.py`: files land where the repo says they go**
|
|
10
|
+
([#22](https://github.com/the-glitch-kingdom/babel-fish/issues/22)). The project map
|
|
11
|
+
describes where things *are*. The new, opt-in `.claude/structure.toml` says where
|
|
12
|
+
they *should go*, and the check enforces it at commit time and in CI.
|
|
13
|
+
|
|
14
|
+
**Manifest.** Each approved folder declares a `purpose`, optional `holds` globs and
|
|
15
|
+
a lifecycle status: `planned` (approved, may be created), `active`, or `deprecated`
|
|
16
|
+
(new files blocked while existing ones move out). The manifest also lists
|
|
17
|
+
`root_files`, an `exceptions` baseline so adopting the check blocks nothing (only
|
|
18
|
+
*new* violations fail), and `[[repo]]` pointers for multi-repo setups. Each pointed-to
|
|
19
|
+
repo runs its own babel-fish; nothing crosses repos. The mode is `single`,
|
|
20
|
+
`monorepo` or `multi-repo`.
|
|
21
|
+
|
|
22
|
+
**Environment lifecycle.** Declared `[[environment]]`s (`target` local or cloud,
|
|
23
|
+
`promotes_to`, `mirrors`) enforce dev → stg → prod: undeclared environment folders
|
|
24
|
+
fail, stg must hold the same files as prod, local-only files (Compose, seeds, certs)
|
|
25
|
+
stay out of cloud environments and deploy config stays out of local ones,
|
|
26
|
+
environment folders hold deltas only (an identical copy of a shared file fails),
|
|
27
|
+
migrations are never per-environment, and per-app environment folders outside
|
|
28
|
+
`env_roots` fail. A tracked `.env` fails in every mode. Only an exact-path
|
|
29
|
+
exception, added by hand for a committed test fixture, can allow one.
|
|
30
|
+
|
|
31
|
+
**One `.env`, as close as the structure allows.** A single committed template
|
|
32
|
+
(`env_file`, default `infra/env/.env.example`) holds every key for every
|
|
33
|
+
environment and app; the one real `.env` sits beside it, gitignored; stg/prod values
|
|
34
|
+
come from the secret manager. Any other template (per-app, per-environment,
|
|
35
|
+
`.env.sample`, `example.env`) fails with "merge its keys into env_file". A real
|
|
36
|
+
env file that git would commit fails before it is staged, and scattered local ones
|
|
37
|
+
warn. Bootstrap keeps an existing single template where it is and puts extra
|
|
38
|
+
templates in the backlog.
|
|
39
|
+
|
|
40
|
+
**Detection and adoption.** `--detect [--json]` reports facts: best-guess mode with
|
|
41
|
+
reasons, environments seen, top-level folders, sibling repos, and whether the repo is
|
|
42
|
+
new. `--bootstrap [--layout single|monorepo|multi-repo]` writes a starting manifest
|
|
43
|
+
and never overwrites an existing one. Uncovered top-level folders become their own
|
|
44
|
+
entries, leftover violations seed `exceptions` as exact paths, and tracked secrets
|
|
45
|
+
are never seeded. With
|
|
46
|
+
no manifest, running the script explains the options and exits 0. Flags for commit
|
|
47
|
+
and CI: `--staged` and `--since REF`.
|
|
48
|
+
|
|
49
|
+
**`structure-bootstrap` skill.** It makes the judgment calls the script can't:
|
|
50
|
+
folder purposes and `holds` from real contents, which layout fits, planning a new
|
|
51
|
+
repo from a project description, recipes for adding and retiring folders, apps and
|
|
52
|
+
environments, and, only on request, for Flow C, or for a new repo, a rules file and
|
|
53
|
+
a procedure doc.
|
|
54
|
+
|
|
55
|
+
The pre-commit hook gets a `Structure Check` block (own marker, so re-running
|
|
56
|
+
`bash .claude/install.sh` adds it to existing hooks). It runs only when the manifest
|
|
57
|
+
exists. The installer copies the script and the layouts and never touches
|
|
58
|
+
`structure.toml`. On Python < 3.11 (no `tomllib`) the check prints a readable warning
|
|
59
|
+
and passes; the rest of babel-fish still runs on 3.8. When a manifest exists,
|
|
60
|
+
`PROJECT_MAP.md` gets a one-line pointer to it plus the related repos.
|
|
61
|
+
|
|
62
|
+
## [2.5.0] - 2026-09-25
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- **`context-check.py` — keeps auto-loaded context small and its pointers live**
|
|
67
|
+
([#20](https://github.com/TheGlitchKing/babel-fish/issues/20)). `CLAUDE.md` and
|
|
68
|
+
every `.claude/rules/*.md` load into every session; past Claude Code's 150k-char
|
|
69
|
+
limit rules stop binding, and nothing reports it. glitch-stock-trading-rig had
|
|
70
|
+
reached 225.6k before forking `generate.py` to enforce a budget.
|
|
71
|
+
|
|
72
|
+
The new script checks three things. **Budget:** total chars under `--budget`
|
|
73
|
+
(default 60,000). **Pointers:** every `` → `path` ``, backticked `.documentation/`
|
|
74
|
+
path and relative markdown link resolves. hewtd link-checks only inside
|
|
75
|
+
`.documentation/`, so a renamed doc used to break a rule's pointer silently.
|
|
76
|
+
**Rule lines** (opt-in, `--map-style`): each rule bullet reads
|
|
77
|
+
`` - ALWAYS|NEVER <rule> — <why> → `doc` ``. That form is one repo's convention,
|
|
78
|
+
and the hook ships to every install, so it is off by default.
|
|
79
|
+
|
|
80
|
+
The pre-commit hook runs it when `CLAUDE.md` or `.claude/rules/` is staged, and a
|
|
81
|
+
failure blocks the commit. It is a separate script rather than part of
|
|
82
|
+
`generate.py`: the hook runs `generate.py` only for code changes, `.claude/` is
|
|
83
|
+
outside the watch set, and the hook discards `generate.py`'s errors. The block
|
|
84
|
+
has its own marker, so re-running `bash .claude/install.sh` adds it to hooks
|
|
85
|
+
installed by older versions.
|
|
86
|
+
|
|
87
|
+
Registry drift (item 4 of #20) stays in the downstream fork; babel-fish has no
|
|
88
|
+
tool registry.
|
|
89
|
+
|
|
90
|
+
### Fixed
|
|
91
|
+
|
|
92
|
+
- **This repo's pre-commit hook never ran.** Both `.githooks/` files were
|
|
93
|
+
committed `100644`, and git skips a non-executable hook without a word, so no
|
|
94
|
+
clone ever regenerated its map on commit. Both are `100755` now, and
|
|
95
|
+
`test_hooks_are_committed_executable` holds them there.
|
|
96
|
+
|
|
97
|
+
57 tests pass across four suites. Each context check was mutation-tested: breaking
|
|
98
|
+
it fails at least one test. A fresh install and an upgrade over a pre-2.5.0 hook
|
|
99
|
+
were both run end to end.
|
|
100
|
+
|
|
5
101
|
## [2.4.3] - 2026-09-05
|
|
6
102
|
|
|
7
103
|
### Fixed
|
package/README.md
CHANGED
|
@@ -146,7 +146,7 @@ See [CHANGELOG.md](./CHANGELOG.md) for the full 2.0.0 release notes, breaking-ch
|
|
|
146
146
|
2. Detects your stack (language, framework, database, ORM, auth, infra)
|
|
147
147
|
3. Runs `generate.py` → grades with `grader.py` (iterates up to 3× until 90%+ quality)
|
|
148
148
|
4. Renders your developer skill and rules files
|
|
149
|
-
5. Installs the pre-commit hook (auto-regenerates map on source file changes)
|
|
149
|
+
5. Installs the pre-commit hook (auto-regenerates map on source file changes; checks auto-loaded context when `CLAUDE.md` or `.claude/rules/` changes)
|
|
150
150
|
6. Updates `CLAUDE.md` with a project map pointer
|
|
151
151
|
7. Prints a full quality report
|
|
152
152
|
|
|
@@ -227,6 +227,46 @@ Entries follow a simple format: symptom → cause → fix. This is the anti-drif
|
|
|
227
227
|
|
|
228
228
|
---
|
|
229
229
|
|
|
230
|
+
## Auto-loaded Context Check *(2.5.0+)*
|
|
231
|
+
|
|
232
|
+
Everything in `CLAUDE.md` and `.claude/rules/` loads into every session, and past Claude Code's 150k-char limit rules stop binding silently. When those files are staged, the pre-commit hook runs `context-check.py` and blocks the commit if:
|
|
233
|
+
|
|
234
|
+
- the total exceeds the budget (default 60,000 chars), or
|
|
235
|
+
- a pointer names a file that doesn't exist. hewtd only link-checks inside `.documentation/`, so a renamed doc breaks a rule's pointer unnoticed.
|
|
236
|
+
|
|
237
|
+
Opt in to `--map-style` to also require every rule bullet to read `` - ALWAYS|NEVER <rule> — <why> → `doc` ``. See [auto-loaded context check](./.documentation/standards/auto-loaded-context-check.md).
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
python .claude/project-map/context-check.py --budget 80000 --map-style
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Repo Structure Check *(2.6.0+)*
|
|
246
|
+
|
|
247
|
+
The map shows where things **are**. An opt-in `.claude/structure.toml` says where they **should go**, and `structure-check.py` blocks the commit (and fails CI) when a file lands somewhere else.
|
|
248
|
+
|
|
249
|
+
- **Folders with a lifecycle:** each approved folder has a purpose, optional `holds` globs, and a status of `planned`, `active` or `deprecated`. A deprecated folder takes no new files while the old ones move out.
|
|
250
|
+
- **dev → stg → prod:** declared environments must stay separate:
|
|
251
|
+
- stg holds the same files as prod
|
|
252
|
+
- environment folders hold only what differs
|
|
253
|
+
- local tooling stays out of the cloud environments, and deploy config out of local ones
|
|
254
|
+
- migrations are shared across environments
|
|
255
|
+
- a real `.env` is never committed
|
|
256
|
+
- **One `.env`, not twenty:** a single committed `.env.example` holds every key for every environment and app, and the one real `.env` sits beside it, gitignored. Stray templates, per-app `.env` files and a `.env` that git would commit all get caught.
|
|
257
|
+
- **Modes:** `single`, `monorepo`, or `multi-repo`. In multi-repo, `[[repo]]` entries point at sibling repos, each running its own babel-fish.
|
|
258
|
+
- **Adoption blocks nothing:** `--bootstrap` seeds an `exceptions` baseline from today's tree, so only *new* violations fail.
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
python .claude/project-map/structure-check.py --detect # mode, environments, folders
|
|
262
|
+
python .claude/project-map/structure-check.py --bootstrap --layout monorepo # start a manifest (never overwrites)
|
|
263
|
+
python .claude/project-map/structure-check.py --since origin/main # CI
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Or ask Claude to *"set up the repo structure"*. The `structure-bootstrap` skill reads the tree, fills in each folder's purpose, can plan a new repo from a description, and asks only what it can't infer. Needs Python 3.11+ (on older Python it warns and passes). See [repo structure check](./.documentation/standards/repo-structure-check.md) and [changing repo structure](./.documentation/procedures/changing-repo-structure.md).
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
230
270
|
## File Structure
|
|
231
271
|
|
|
232
272
|
```
|
|
@@ -235,11 +275,15 @@ Entries follow a simple format: symptom → cause → fix. This is the anti-drif
|
|
|
235
275
|
│ ├── generate.py # Introspection script
|
|
236
276
|
│ ├── grader.py # Quality grader
|
|
237
277
|
│ ├── mine-sessions.py # Session vocabulary miner
|
|
278
|
+
│ ├── context-check.py # Budget + pointer check for auto-loaded files
|
|
279
|
+
│ ├── structure-check.py # Files vs .claude/structure.toml (opt-in)
|
|
238
280
|
│ ├── PROJECT_MAP.md # TOC + quick routing guide
|
|
239
281
|
│ ├── sections/ # 19 focused section files
|
|
240
282
|
│ ├── reports/ # Install and iteration reports
|
|
241
283
|
│ ├── checksums.json # Skip regeneration if unchanged
|
|
242
284
|
│ └── learned-vocabulary.json # Persisted session aliases
|
|
285
|
+
├── structure.toml # Your repo's structure manifest (you own it; never overwritten)
|
|
286
|
+
├── templates/structure/ # Layouts: single, monorepo, multi-repo
|
|
243
287
|
├── rules/
|
|
244
288
|
│ ├── project-vocabulary.md # Auto-loaded every session
|
|
245
289
|
│ └── operational-runbook.md # Auto-loaded every session
|
|
@@ -247,7 +291,7 @@ Entries follow a simple format: symptom → cause → fix. This is the anti-drif
|
|
|
247
291
|
└── <project>-developer-skill/
|
|
248
292
|
└── SKILL.md
|
|
249
293
|
.githooks/
|
|
250
|
-
├── pre-commit #
|
|
294
|
+
├── pre-commit # Regenerates map; runs the context + structure checks
|
|
251
295
|
└── install.sh # Register hooks: bash .githooks/install.sh
|
|
252
296
|
```
|
|
253
297
|
|
|
@@ -268,7 +312,7 @@ Entries follow a simple format: symptom → cause → fix. This is the anti-drif
|
|
|
268
312
|
## Requirements
|
|
269
313
|
|
|
270
314
|
- AI coding assistant (Claude Code, Cursor, or compatible)
|
|
271
|
-
- Python ≥ 3.8 (auto-installed if missing)
|
|
315
|
+
- Python ≥ 3.8 (auto-installed if missing); the structure check needs ≥ 3.11
|
|
272
316
|
- Bash
|
|
273
317
|
- Optional: `pip install pyyaml` for docker-compose YAML parsing (regex fallback included)
|
|
274
318
|
|
|
@@ -281,6 +325,8 @@ Entries follow a simple format: symptom → cause → fix. This is the anti-drif
|
|
|
281
325
|
| `python .claude/project-map/generate.py --force` | Force-regenerate project map |
|
|
282
326
|
| `python .claude/project-map/grader.py` | Grade map quality (0–100%) |
|
|
283
327
|
| `python .claude/project-map/mine-sessions.py` | Mine session vocabulary |
|
|
328
|
+
| `python .claude/project-map/context-check.py` | Check auto-loaded context: budget, pointers |
|
|
329
|
+
| `python .claude/project-map/structure-check.py` | Check files against `.claude/structure.toml` (`--detect`, `--bootstrap`) |
|
|
284
330
|
| `bash .githooks/install.sh` | (Re)install git hooks |
|
|
285
331
|
| `bash .claude/install.sh` | Re-run full plugin installer |
|
|
286
332
|
|
package/checksums.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theglitchking/babel-fish",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Gives your AI coding assistant instant, accurate knowledge of every route, model, service, feature, and infrastructure element in your codebase.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"postinstall": "node scripts/link-skills.js",
|
|
11
|
-
"test": "python3 .claude/project-map/test_generate.py && python3 .claude/project-map/test_mine_sessions.py && python3 .claude/project-map/test_grader.py"
|
|
11
|
+
"test": "python3 .claude/project-map/test_generate.py && python3 .claude/project-map/test_mine_sessions.py && python3 .claude/project-map/test_grader.py && python3 .claude/project-map/test_context_check.py && python3 .claude/project-map/test_structure_check.py"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"bin/",
|
|
@@ -22,9 +22,13 @@
|
|
|
22
22
|
".claude/project-map/generate.py",
|
|
23
23
|
".claude/project-map/grader.py",
|
|
24
24
|
".claude/project-map/mine-sessions.py",
|
|
25
|
+
".claude/project-map/context-check.py",
|
|
26
|
+
".claude/project-map/structure-check.py",
|
|
25
27
|
".claude/project-map/test_generate.py",
|
|
26
28
|
".claude/project-map/test_mine_sessions.py",
|
|
27
29
|
".claude/project-map/test_grader.py",
|
|
30
|
+
".claude/project-map/test_context_check.py",
|
|
31
|
+
".claude/project-map/test_structure_check.py",
|
|
28
32
|
".githooks/",
|
|
29
33
|
"skills/",
|
|
30
34
|
"install.sh",
|
package/scripts/link-skills.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Postinstall — delegates to @theglitchking/claude-plugin-runtime.
|
|
3
|
-
// babel-fish ships
|
|
4
|
-
// the runtime symlinks into
|
|
5
|
-
// can discover
|
|
3
|
+
// babel-fish ships two skills (skills/babel-fish-developer-skill/ and
|
|
4
|
+
// skills/structure-bootstrap/) which the runtime symlinks into
|
|
5
|
+
// <project>/.claude/skills/ so Claude Code can discover them. Runtime also writes the default update-policy config
|
|
6
6
|
// and registers the SessionStart hook (with plugin-vs-npm dedup).
|
|
7
7
|
//
|
|
8
8
|
// NOTE: npm install only handles the skill + update policy. To get the
|