@theglitchking/babel-fish 2.5.0 → 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.
@@ -102,6 +102,11 @@ POST-INSTALL COMMANDS
102
102
  python .claude/project-map/context-check.py
103
103
  python .claude/project-map/context-check.py --budget 80000 --map-style
104
104
 
105
+ Check files land where .claude/structure.toml says (opt-in; see --help):
106
+ python .claude/project-map/structure-check.py # no manifest: explains the options
107
+ python .claude/project-map/structure-check.py --detect # repo facts: mode, environments, folders
108
+ python .claude/project-map/structure-check.py --bootstrap # write a starting manifest (never overwrites)
109
+
105
110
  Re-install git hooks (if you cloned a fresh copy):
106
111
  bash .githooks/install.sh
107
112
 
@@ -125,7 +130,8 @@ KEY FILES AFTER INSTALL
125
130
  .claude/rules/project-vocabulary.md — Auto-loaded every session
126
131
  .claude/rules/operational-runbook.md — Edit manually to grow over time
127
132
  .claude/skills/<slug>-developer-skill/ — Your developer skill
128
- .githooks/pre-commit — Regenerates map; checks auto-loaded context
133
+ .githooks/pre-commit — Regenerates map; checks auto-loaded context + structure
134
+ .claude/templates/structure/*.toml — Layout templates (single, monorepo, multi-repo)
129
135
 
130
136
  GRADING CATEGORIES (90% to pass)
131
137
  Section completeness 25% — All 19 sections generated
@@ -403,6 +409,28 @@ if git diff --cached --name-only 2>/dev/null | grep -qE '^(\.claude/)?CLAUDE(\.l
403
409
  fi
404
410
  # ── End Context Check ────────────────────────────────────────────────────────
405
411
  SNIPPET
412
+ )
413
+
414
+ local structure_snippet
415
+ structure_snippet=$(cat <<'SNIPPET'
416
+ # ── Structure Check: files land where .claude/structure.toml says (#22) ──────
417
+ # Opt-in: runs only once the repo has a manifest. On Python < 3.11 it warns and passes.
418
+ if [ -f ".claude/structure.toml" ]; then
419
+ CHECK_SCRIPT=".claude/project-map/structure-check.py"
420
+ if [ -f "$CHECK_SCRIPT" ]; then
421
+ PYTHON=""
422
+ if [ -f ".venv/bin/python3" ]; then PYTHON=".venv/bin/python3"
423
+ elif command -v python3 &>/dev/null; then PYTHON="python3"
424
+ elif command -v python &>/dev/null; then PYTHON="python"
425
+ fi
426
+ if [ -n "$PYTHON" ] && ! $PYTHON "$CHECK_SCRIPT" --staged; then
427
+ echo "[structure-check] Commit blocked. Each FAIL above has a fix: line -- or change .claude/structure.toml if the structure should change." >&2
428
+ exit 1
429
+ fi
430
+ fi
431
+ fi
432
+ # ── End Structure Check ──────────────────────────────────────────────────────
433
+ SNIPPET
406
434
  )
407
435
 
408
436
  if [ ! -f "$pre_commit" ]; then
@@ -421,6 +449,12 @@ SNIPPET
421
449
  else
422
450
  ok "pre-commit hook already contains Context Check snippet"
423
451
  fi
452
+ if ! grep -q 'Structure Check' "$pre_commit" 2>/dev/null; then
453
+ { echo ""; echo "$structure_snippet"; } >> "$pre_commit"
454
+ ok "Added Structure Check to pre-commit hook"
455
+ else
456
+ ok "pre-commit hook already contains Structure Check snippet"
457
+ fi
424
458
 
425
459
  chmod +x "$pre_commit"
426
460
 
@@ -512,7 +546,7 @@ if $DRY_RUN; then
512
546
  _dry "mkdir -p $CLAUDE_DIR/rules"
513
547
  _dry "mkdir -p $CLAUDE_DIR/skills/<project>-developer-skill/"
514
548
  _dry "copy scripts/*.sh → $CLAUDE_DIR/scripts/"
515
- _dry "copy templates/*.template → $CLAUDE_DIR/templates/"
549
+ _dry "copy templates/*.template, templates/structure/*.toml → $CLAUDE_DIR/templates/"
516
550
  _dry "copy project-map/*.py → $CLAUDE_DIR/project-map/"
517
551
  _dry "write $CLAUDE_DIR/project-map/PROJECT_MAP.md"
518
552
  _dry "write $CLAUDE_DIR/project-map/sections/01-vocabulary.md (+ 18 more sections)"
@@ -545,6 +579,8 @@ if [ "$PLUGIN_SOURCE_DIR" != "$CLAUDE_DIR" ]; then
545
579
  cp -r "$PLUGIN_SOURCE_DIR/project-map/grader.py" "$CLAUDE_DIR/project-map/" 2>/dev/null || true
546
580
  cp -r "$PLUGIN_SOURCE_DIR/project-map/mine-sessions.py" "$CLAUDE_DIR/project-map/" 2>/dev/null || true
547
581
  cp -r "$PLUGIN_SOURCE_DIR/project-map/context-check.py" "$CLAUDE_DIR/project-map/" 2>/dev/null || true
582
+ cp -r "$PLUGIN_SOURCE_DIR/project-map/structure-check.py" "$CLAUDE_DIR/project-map/" 2>/dev/null || true
583
+ # Never copies .claude/structure.toml: the manifest is the repo's own data (#22).
548
584
  fi
549
585
 
550
586
  # ── Step 1: Ensure Python ─────────────────────────────────────────────────────
@@ -1522,6 +1522,30 @@ def write_glossary(vocab: list[dict], stack: dict) -> Path:
1522
1522
  # ║ PROJECT MAP TOC ║
1523
1523
  # ╚══════════════════════════════════════════════════════════════════════════╝
1524
1524
 
1525
+ def build_structure_pointer() -> list[str]:
1526
+ """Where files go (#22): a pointer to the manifest, never a copy of it."""
1527
+ manifest = PROJECT_ROOT / '.claude' / 'structure.toml'
1528
+ if not manifest.is_file():
1529
+ return []
1530
+ lines = [
1531
+ "",
1532
+ "## Repo Structure\n",
1533
+ "Where files go — approved folders, environments, related repos: "
1534
+ "`.claude/structure.toml`. Checked on commit by `structure-check.py`.",
1535
+ ]
1536
+ try:
1537
+ import tomllib
1538
+ m = tomllib.loads(manifest.read_text(encoding='utf-8'))
1539
+ except Exception: # Python < 3.11 or a broken manifest: the pointer alone still helps
1540
+ return lines
1541
+ repos = [r for r in m.get('repo', []) if isinstance(r, dict)]
1542
+ if repos:
1543
+ lines.append("\nRelated repos — each keeps its own map:\n")
1544
+ lines += [f"- **{r.get('name', '?')}** `{r.get('path') or r.get('url', '')}`"
1545
+ + (f" — {r['purpose']}" if r.get('purpose') else '') for r in repos]
1546
+ return lines
1547
+
1548
+
1525
1549
  def build_project_map(
1526
1550
  stack: dict,
1527
1551
  routes: list[dict],
@@ -1596,6 +1620,7 @@ def build_project_map(
1596
1620
  when = WHEN_TO_READ.get(num, '')
1597
1621
  lines.append(f"| [{num}](sections/{path.name}) | {display} | {size_kb:.1f} KB | {when} |")
1598
1622
 
1623
+ lines += build_structure_pointer()
1599
1624
  lines += [
1600
1625
  "",
1601
1626
  "## Quick Routing\n",