From a6b6b4e80a113450c664762de7cbf9dcfc5b6cd2 Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Sun, 14 Jun 2026 09:07:18 -0700 Subject: [PATCH] sync: auto-sync from GURU-BEAST-ROG at 2026-06-14 09:07:13 Author: Mike Swanson Machine: GURU-BEAST-ROG Timestamp: 2026-06-14 09:07:13 --- .claude/ONBOARDING.md | 14 +++++++ .claude/scripts/ensure-settings-env.py | 56 ++++++++++++++++++++++++++ errorlog.md | 4 ++ 3 files changed, 74 insertions(+) create mode 100644 .claude/scripts/ensure-settings-env.py diff --git a/.claude/ONBOARDING.md b/.claude/ONBOARDING.md index ac67fbf..fc9a1aa 100644 --- a/.claude/ONBOARDING.md +++ b/.claude/ONBOARDING.md @@ -35,6 +35,20 @@ Some configuration files are **machine-local** (gitignored, not synced) because |------|---------|---------------| | `.claude/identity.json` | Your name, email, vault path | YES — during onboarding | | `.claude/current-mode` | Work mode (dev, infra, client, etc.) | YES — defaults to "general" | +| `.claude/settings.local.json` | Per-machine env (`CLAUDETOOLS_ROOT`) + local permissions | env via provisioner (below) | + +**`CLAUDETOOLS_ROOT` env — run once per machine after `identity.json` exists:** + +```bash +py .claude/scripts/ensure-settings-env.py +``` + +This seeds `env.CLAUDETOOLS_ROOT` in `.claude/settings.local.json` from +`identity.json.claudetools_root`. Many skill docs invoke +`py "$CLAUDETOOLS_ROOT/.claude/skills/.../x.py"`; Claude Code injects the settings `env` +block into every Bash call, so without this the var is empty and those commands resolve to +the wrong path (the failure logged in `errorlog.md` on 2026-06-14). Idempotent; takes effect +at the next session start. The script is also safe to re-run any time the clone moves. **`.claude/current-mode`** is used by coordination hooks to determine behavior: - In `dev` mode: Hooks show active locks as warnings but don't block diff --git a/.claude/scripts/ensure-settings-env.py b/.claude/scripts/ensure-settings-env.py new file mode 100644 index 0000000..0fab437 --- /dev/null +++ b/.claude/scripts/ensure-settings-env.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +"""Ensure .claude/settings.local.json env.CLAUDETOOLS_ROOT matches identity.json. + +Why: many skill docs invoke `py "$CLAUDETOOLS_ROOT/.claude/skills/.../x.py"`. That +env var is per-machine and was never exported, so the commands resolved to the wrong +path in fresh Git-bash shells (logged in errorlog.md 2026-06-14). Claude Code injects +the `env` block from settings(.local).json into every Bash tool call, so seeding +CLAUDETOOLS_ROOT there from identity.json fixes it fleet-wide. Per-machine value, so it +lives in the gitignored settings.local.json — sourced here from identity.json. + +Idempotent. Run from the repo root (or anywhere — paths are resolved off this file). +Takes effect at the NEXT Claude Code session start (env is injected at session init). +""" +import json +import os +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +ROOT = os.path.normpath(os.path.join(HERE, "..", "..")) +IDENT = os.path.join(ROOT, ".claude", "identity.json") +LOCAL = os.path.join(ROOT, ".claude", "settings.local.json") + + +def main(): + if not os.path.isfile(IDENT): + print("[ERROR] .claude/identity.json missing — run onboarding first", file=sys.stderr) + return 1 + ident = json.load(open(IDENT, encoding="utf-8")) + root = ident.get("claudetools_root") + if not root: + print("[ERROR] identity.json has no 'claudetools_root'", file=sys.stderr) + return 1 + + settings = {} + if os.path.isfile(LOCAL): + try: + settings = json.load(open(LOCAL, encoding="utf-8")) + except Exception as e: + print(f"[ERROR] settings.local.json is not valid JSON: {e}", file=sys.stderr) + return 1 + + env = settings.setdefault("env", {}) + if env.get("CLAUDETOOLS_ROOT") == root: + print(f"[OK] CLAUDETOOLS_ROOT already set to {root}") + return 0 + + env["CLAUDETOOLS_ROOT"] = root + with open(LOCAL, "w", encoding="utf-8") as f: + json.dump(settings, f, indent=2) + f.write("\n") + print(f"[OK] Set CLAUDETOOLS_ROOT={root} in settings.local.json (effective next session)") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/errorlog.md b/errorlog.md index 943f47b..090215d 100644 --- a/errorlog.md +++ b/errorlog.md @@ -8,3 +8,7 @@ Format: `YYYY-MM-DD | MACHINE | command/skill | error (brief)` --- + +2026-06-14 | GURU-BEAST-ROG | coord skill (coord.py msg send) | `py "$CLAUDETOOLS_ROOT/.claude/skills/coord/scripts/coord.py"` failed — `$CLAUDETOOLS_ROOT` is not exported in fresh Git-bash shells here, so the path resolved under `C:\Program Files\Git\`. [RESOLVED 2026-06-14] Added `.claude/scripts/ensure-settings-env.py` (seeds `env.CLAUDETOOLS_ROOT` in per-machine `settings.local.json` from `identity.json`); Claude Code injects it into every Bash call. Wired into ONBOARDING.md + broadcast to fleet. Effective next session start. + +2026-06-14 | GURU-BEAST-ROG | /sync (sync.sh Phase 3, submodule update) | submodule `projects/msp-tools/guru-rmm` checkout of f38da05 aborted: untracked `docs/RMM_THOUGHTS.md` would be overwritten. Parent repo synced fine; submodule pointer left lagging. Recurring transient — candidate for sync.sh to stash/skip untracked submodule files.