# Welcome to ClaudeTools — Onboarding Guide

Hey! This guide explains how our Claude Code setup works, WHY it's built the way it is, and how to use it effectively for daily MSP work. Read this once, then use it as reference when something feels unfamiliar.

---

## What is this?

ClaudeTools is our shared workspace for **Claude Code** — the AI coding + automation assistant. It's a git repo that syncs across our workstations via Gitea (our self-hosted Git server). Everything Claude learns, every session log, every automation script, every project we build — it all lives here and stays in sync.

**Why a repo instead of just using Claude directly?**
- Claude Code loses context between sessions. This repo IS the memory.
- Session logs preserve what we did, what creds we used, what decisions we made.
- CLAUDE.md tells Claude HOW to behave specifically for our org (not generic defaults).
- Skills and commands give us reusable shortcuts for common MSP tasks.
- The vault (separate repo) stores all credentials encrypted so Claude can access them without us typing passwords every session.

---

## First time setup

When you open Claude Code for the first time on a new machine, Claude will ask who you are. Just answer with your name. Claude then:

1. Creates a local identity file (so it knows who's at the keyboard)
2. Sets your git name/email for commits
3. Registers your machine in the shared users list

After that, every session log and git commit is attributed to you.

### Machine-local configuration

Some configuration files are **machine-local** (gitignored, not synced) because they contain machine-specific paths or settings:

| File | Purpose | Auto-created? |
|------|---------|---------------|
| `.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
- In other modes: Hooks enforce coordination protocol more strictly

You never need to manually create this file — the UserPromptSubmit hook initializes it automatically on first run. Claude updates it when switching modes (e.g., when you say "work on Dataforth" switches to client mode).

### GuruRMM repo — one-time setup per machine

The GuruRMM repo (`projects/msp-tools/guru-rmm/`) requires one extra step after cloning or first use. Run this from the repo root:

```bash
bash scripts/install-hooks.sh
```

This does three things permanently:
- Points git at `scripts/hooks/` so pre-commit checks run automatically (and stay current as hooks evolve — no re-install after updates)
- Sets `core.autocrlf=false` and `core.eol=lf` for this repo (prevents sqlx migration checksum drift from Windows CRLF line endings)
- Sets `core.autocrlf=false` globally on this machine

**Why this matters:** sqlx verifies migration files by sha384 hash. A file committed with CRLF line endings hashes differently than the same file with LF — the server sees the mismatch and refuses to start. The `.gitattributes` file handles new commits automatically; this command configures the git client for existing checkouts.

### Claude Code Hooks — where each hook lives

Claude Code fires hooks on specific events (before tool use, on message submit, etc.). We have two active hooks:

| Hook | File | What it does |
|------|------|--------------|
| `PreToolUse` (Bash) | `~/.claude/settings.json` (global, per-machine) | Blocks `powershell -Command` inline invocations from Git Bash — prevents a class of shell escaping bugs |
| `UserPromptSubmit` | `.claude/settings.json` (project-level, committed) | Checks the coord API for unread cross-session messages on every prompt; fires Windows toast notifications |

**The `UserPromptSubmit` hook is in the project `.claude/settings.json` and uses `$CLAUDE_PROJECT_DIR`** — a variable Claude Code sets automatically to the project root. This makes it portable across all machines without any machine-specific paths.

**If you have an old UserPromptSubmit entry in `~/.claude/settings.json` or `.claude/settings.local.json`, remove it.** The project-level hook fires correctly and the old entry causes double-firing. Symptoms of double-firing: two toast notifications per prompt, or messages marked read before you see them.

To clean up on any machine:

1. Check `~/.claude/settings.json` — the `hooks` section should contain ONLY `PreToolUse` (the pwsh-script block). If there's a `UserPromptSubmit` block there, delete it.
2. Check `.claude/settings.local.json` — if there's a `hooks` section with `UserPromptSubmit`, delete the entire `hooks` block.
3. The `PreToolUse` hook path in `~/.claude/settings.json` uses `$CLAUDETOOLS_ROOT/.claude/hooks/pre-bash-pwsh-script.sh` — update this if your claudetools clone is at a different path.

**The `PreToolUse` hook path is still machine-specific** (hardcoded path in `~/.claude/settings.json`) because global user settings don't have access to `$CLAUDE_PROJECT_DIR`. If you're on Windows with claudetools at `D:/claudetools`, the entry is:
```json
"command": "\"D:/claudetools/.claude/hooks/pre-bash-pwsh-script.sh\""
```
On Mac (claudetools at `~/claudetools`):
```json
"command": "\"~/claudetools/.claude/hooks/pre-bash-pwsh-script.sh\""
```

---

## The slash commands (most important daily tools)

Type these in Claude Code's prompt. They're shortcuts for common operations.

| Command | What it does | When to use |
|---------|-------------|-------------|
| `/save` | Saves a comprehensive session log (what you did, creds used, decisions made) | **End of every significant work session.** This is how future-you (or future-me) recovers context. |
| `/sync` | Pull + push changes to/from Gitea | Start of session (get latest), end of session (push yours) |
| `/context` | Searches session logs and credentials for previous work | "What did we do for Dataforth last week?" or "What's the password for AD2?" |
| `/checkpoint` | Git commit + database context save | After completing a feature or fix |
| `/scc` | Save + Commit + Push (all three in one shot) | Quick end-of-session wrap-up |
| `/1password` | Access secrets from 1Password | When vault doesn't have a credential |

### Why these exist

Without `/save`, you'd lose everything when a session ends. Without `/sync`, your work stays on one machine. Without `/context`, you'd re-discover the same information every session. These three commands are 90% of daily usage.

---

## The SOPS vault (how credentials work)

We store ALL credentials in an encrypted vault (separate git repo). Files are YAML encrypted with age/SOPS. Claude can decrypt them on the fly.

**How Claude accesses a credential:**
```bash
# Always via the ClaudeTools wrapper — never a hardcoded path
bash "$CLAUDETOOLS_ROOT/.claude/scripts/vault.sh" get-field clients/dataforth/ad2.sops.yaml credentials.password
```

**Why this matters:**
- We never hardcode passwords in scripts or session logs (they're vault references)
- The vault syncs across machines via Gitea (same as claudetools)
- Encryption uses an age key — this key needs to be on each machine that decrypts

**Setup required on each machine:**

1. **Clone the vault repo** somewhere convenient (e.g., `~/vault` on Mac/Linux, `D:\vault` on Windows)

2. **Add `vault_path` to `.claude/identity.json`** (created during onboarding):
   ```json
   {
     "user": "howard",
     "vault_path": "/Users/howard/vault"
   }
   ```
   This is the only place the path lives — no hardcoded paths in any shared file.

3. **Install your age key.** Mike will give you the key file. Drop it at:
   - **Windows:** `C:\Users\<you>\AppData\Roaming\sops\age\keys.txt`
   - **Mac/Linux:** `~/.config/sops/age/keys.txt`

Without the age key, vault commands fail. Everything else works fine.

---

## How Claude knows about our infrastructure

### CLAUDE.md (the brain)

`.claude/CLAUDE.md` is the master instructions file. Claude reads it at the start of every session. It tells Claude:

- **Who we are** (AZ Computer Guru, MSP)
- **How to behave** (delegate to agents, no emojis, use vault for creds)
- **What projects exist** (GuruRMM, Dataforth, ClaudeTools API)
- **How to load context** automatically when you mention a project keyword

**Key behavior:** If you say "work on Dataforth", Claude automatically reads `projects/dataforth-dos/CONTEXT.md` before responding. Same for "GuruRMM" → reads `projects/msp-tools/guru-rmm/CONTEXT.md`. This means Claude starts every project conversation with full context — server IPs, current state, recent work, anti-patterns to avoid.

### CONTEXT.md files (per-project state)

Each major project has a `CONTEXT.md` that captures:
- Server IPs, ports, credentials references
- Current deployment state
- Recent session logs (what was done last)
- Anti-patterns (things NOT to do, learned from past mistakes)
- What to work on next

These files are the **single source of truth** for "where are we on this project."

### Session logs (the history)

Every significant work session gets a log saved to `session-logs/` (root for general, or `projects/*/session-logs/` for project-specific). These include:
- What was accomplished
- Full credentials used (unredacted — needed for future sessions)
- Infrastructure changes made
- Commands that worked and errors that didn't
- What's still pending

**This is why `/save` matters.** Without it, the next person (or the next Claude session) starts from scratch.

---

## Skills (auto-invoked behaviors)

Skills are more powerful than commands — some trigger automatically.

| Skill | Auto-invokes? | What it does |
|-------|--------------|-------------|
| `frontend-design` | YES — after any UI change | Validates visual correctness, accessibility, design quality |
| `stop-slop` | YES — always active | Prevents generic/lazy AI output. Enforces quality. |
| `remediation-tool` | When you say "remediation tool" or "365" | M365 tenant investigation via our Graph API app |
| `skill-creator` | On request | Helps build new custom skills |
| `theme-factory` | On request | Apply visual themes to HTML artifacts |

### Why "stop-slop" exists

Without it, Claude defaults to generic patterns (purple gradients, Inter font, emoji-heavy prose). Our `stop-slop` skill enforces our standards: ASCII markers instead of emojis, specific rather than vague, no filler phrases.

---

## Agents (specialized workers)

Claude Code can spawn sub-agents for specific tasks. These are defined in `.claude/agents/`. The main ones you'll encounter:

| Agent | What it does | When Claude uses it |
|-------|-------------|-------------------|
| **Database Agent** | Runs SQL queries on our databases | Any database operation — Claude should NEVER query directly |
| **Code Review Agent** | Reviews code changes for quality/security | After any code modification |
| **Coding Agent** | Writes production code | When Claude needs to generate code (not just edit) |
| **Explore Agent** | Searches codebases quickly | When looking for files, patterns, or understanding code |
| **Gitea Agent** | Git commits, pushes, branch operations | Commit workflow |
| **Backup Agent** | Backup operations | Before destructive changes |

**Why agents?** Claude has a limited context window. If it does everything itself, it runs out of memory mid-conversation. Agents handle heavy work in isolation and return just the summary. Also: separation of concerns — the Code Review Agent can independently evaluate code the Coding Agent wrote.

---

## Local AI tools (when available)

### Ollama (local LLM)

Ollama runs AI models locally on your GPU. Used for tasks that don't need Claude's full reasoning power — summarization, classification, data extraction.

**Models we use:**
- `qwen3:14b` — general purpose (summarization, drafting)
- `codestral:22b` — code generation assistance
- `nomic-embed-text` — embeddings for semantic search

**Ollama runs on Mike's workstation** and is shared via Tailscale. You don't need to install it locally.

**To use from your machine (Tailscale must be connected):**
```bash
curl -s http://100.92.127.64:11434/api/tags
```

If that returns models, you're connected. Claude automatically uses the right URL based on which machine you're on (reads from `identity.json`).

If it fails: check that Tailscale is connected (`tailscale status`) and Mike's workstation is online.

### GrepAI (semantic code search)

Searches code by MEANING rather than exact text. "How does auth work?" finds authentication code even if the word "auth" doesn't appear.

**Status:** Requires setup per-machine (index build). The `deep-explore` agent uses it. If it's not installed, Claude uses regular grep (still works, just less smart).

---

## Project structure

```
D:\claudetools\
  .claude/           — Claude's brain (CLAUDE.md, agents, skills, memory, commands)
  session-logs/      — General work logs
  projects/
    dataforth-dos/   — Dataforth test datasheet pipeline (AD2, testdatadb)
    msp-tools/
      guru-rmm/      — GuruRMM agent + server (Rust, our product)
    newsletter/      — Marketing newsletters
  clients/
    dataforth/       — Dataforth-specific client docs
    pavon/           — Pavon/client docs
    ...              — Other clients
  credentials.md     — Quick-reference credentials (vault is source of truth)
  CONTEXT.md         — Root-level project context

D:\vault\            — SOPS-encrypted credentials (separate repo)
  infrastructure/    — Our servers (Jupiter, Uranus, pfSense, etc.)
  clients/           — Client credentials
  services/          — Service credentials (Cloudflare, Azure, Gitea, etc.)
  projects/          — Project-specific secrets
```

---

## Daily workflow

### Starting a work session
1. Open Claude Code in the project directory
2. Claude greets you by name (reads identity.json)
3. Tell Claude what you're working on — it auto-loads the right context
4. Work normally — ask questions, make changes, run commands

### Ending a work session
1. `/save` — creates the session log (DO THIS EVERY TIME)
2. `/sync` — pushes everything to Gitea
3. Close Claude Code

### When switching projects mid-session
Just say "let's work on GuruRMM" or "switch to Dataforth" — Claude reads the relevant CONTEXT.md and picks up where the last session left off.

---

## Things to know

**Claude remembers across sessions** — via session logs and memory files, not magic. If you don't `/save`, the next session starts cold.

**Credentials are in the vault** — don't ask Mike for passwords; ask Claude. It decrypts from the vault.

**Git commits are attributed to YOU** — your name and email appear on every commit from your machine.

**Production deployments need care** — Claude will warn before destructive operations (git push --force, database drops, service restarts). Read the warnings.

**If Claude seems confused about a project** — say `/context` and ask it to search for recent work. Or read the project's CONTEXT.md yourself.

**If something breaks** — session logs have the full history. `git log` shows what changed and who changed it. Gitea keeps everything.

---

## Getting help

- Ask Claude: "What commands do I have?" or "How do I access credentials?"
- Read `.claude/CLAUDE.md` for the full rulebook
- Check `session-logs/` for recent work examples
- Ask Mike

---

*Last updated: 2026-04-16*
