From 446a6c1b1c397ff0bb4012a6f35fc1a0112507c6 Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Tue, 2 Jun 2026 20:40:57 -0700 Subject: [PATCH] sync: auto-sync from GURU-5070 at 2026-06-02 20:40:54 Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-06-02 20:40:54 --- .claude/CLAUDE.md | 16 ++ .claude/commands/README.md | 6 +- .claude/commands/recover.md | 28 ++- .claude/hooks/block-backslash-winpath.sh | 30 ++- .claude/memory/MEMORY.md | 1 + .../memory/feedback_windows_bash_mapping.md | 54 ++++ .claude/scripts/check-messages.sh | 2 + .claude/scripts/ensure-git-bash.ps1 | 24 ++ .claude/scripts/recover_grok_session.py | 230 ++++++++++++++++++ .claude/scripts/sync-memory.sh | 5 +- .../skills/self-check/baseline/manifest.json | 6 + .grok/README.md | 109 +++++++++ .grok/hooks/claudetools.json | 42 ++++ .grok/skills/1password/SKILL.md | 22 ++ .grok/skills/autotask/SKILL.md | 9 + .grok/skills/checkpoint/SKILL.md | 32 +++ .grok/skills/context/SKILL.md | 27 ++ .grok/skills/create-spec/SKILL.md | 9 + .grok/skills/feature-request/SKILL.md | 19 ++ .grok/skills/forum-post/SKILL.md | 9 + .grok/skills/gc-feature-request/SKILL.md | 7 + .grok/skills/import/SKILL.md | 7 + .grok/skills/inject-standards/SKILL.md | 7 + .grok/skills/mailbox/SKILL.md | 7 + .grok/skills/mode/SKILL.md | 35 +++ .grok/skills/recover/SKILL.md | 26 ++ .grok/skills/remediation-tool/SKILL.md | 26 ++ .grok/skills/rmm/SKILL.md | 30 +++ .grok/skills/save/SKILL.md | 51 ++++ .grok/skills/scc/SKILL.md | 23 ++ .grok/skills/self-check/SKILL.md | 26 ++ .grok/skills/shape-spec/SKILL.md | 9 + .grok/skills/sync/SKILL.md | 28 +++ .../skills/syncro-emergency-billing/SKILL.md | 7 + .grok/skills/syncro/SKILL.md | 20 ++ .grok/skills/wiki-compile/SKILL.md | 18 ++ .grok/skills/wiki-lint/SKILL.md | 9 + .grok/skills/windows-bash/SKILL.md | 48 ++++ session-logs/2026-06-02-session.md | 44 ++++ 39 files changed, 1101 insertions(+), 7 deletions(-) create mode 100644 .claude/memory/feedback_windows_bash_mapping.md create mode 100644 .claude/scripts/ensure-git-bash.ps1 create mode 100644 .claude/scripts/recover_grok_session.py create mode 100644 .grok/README.md create mode 100644 .grok/hooks/claudetools.json create mode 100644 .grok/skills/1password/SKILL.md create mode 100644 .grok/skills/autotask/SKILL.md create mode 100644 .grok/skills/checkpoint/SKILL.md create mode 100644 .grok/skills/context/SKILL.md create mode 100644 .grok/skills/create-spec/SKILL.md create mode 100644 .grok/skills/feature-request/SKILL.md create mode 100644 .grok/skills/forum-post/SKILL.md create mode 100644 .grok/skills/gc-feature-request/SKILL.md create mode 100644 .grok/skills/import/SKILL.md create mode 100644 .grok/skills/inject-standards/SKILL.md create mode 100644 .grok/skills/mailbox/SKILL.md create mode 100644 .grok/skills/mode/SKILL.md create mode 100644 .grok/skills/recover/SKILL.md create mode 100644 .grok/skills/remediation-tool/SKILL.md create mode 100644 .grok/skills/rmm/SKILL.md create mode 100644 .grok/skills/save/SKILL.md create mode 100644 .grok/skills/scc/SKILL.md create mode 100644 .grok/skills/self-check/SKILL.md create mode 100644 .grok/skills/shape-spec/SKILL.md create mode 100644 .grok/skills/sync/SKILL.md create mode 100644 .grok/skills/syncro-emergency-billing/SKILL.md create mode 100644 .grok/skills/syncro/SKILL.md create mode 100644 .grok/skills/wiki-compile/SKILL.md create mode 100644 .grok/skills/wiki-lint/SKILL.md create mode 100644 .grok/skills/windows-bash/SKILL.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 138c7d1..b3e5125 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -71,6 +71,22 @@ This file is gitignored (machine-local). The `UserPromptSubmit` hook reads it to **Windows/Git Bash:** always use the relative path above (or forward slashes — `/d/claudetools/.claude/current-mode`). NEVER a backslashed Windows path like `D:\claudetools\.claude\current-mode`: Git Bash strips the backslashes and substitutes the illegal `:` with a Unicode PUA char, creating a garbled junk file instead of writing the path. A `PreToolUse(Bash)` hook (`.claude/hooks/block-backslash-winpath.sh`) blocks such redirects; `sync.sh` also strips any that slip through before staging. +**Windows bash command (the `bash` executable):** In PowerShell contexts (including the Grok/Claude tool run_terminal_command), `bash` often resolves to the WSL stub (`WindowsApps\bash.exe`) instead of the required Git for Windows/MSYS bash. This breaks vault.sh, sync.sh, hooks, etc. + +Fix (idempotent): +```powershell +$gitBin = "C:\Program Files\Git\bin" +$gitUsrBin = "C:\Program Files\Git\usr\bin" +if ((Test-Path $gitBin) -and ((Get-Command bash -ErrorAction SilentlyContinue).Source -notlike '*Git*bin*bash.exe')) { + $env:Path = "$gitBin;$gitUsrBin;" + ($env:Path -replace [regex]::Escape("$gitBin;"), '' -replace [regex]::Escape("$gitUsrBin;"), '') +} +``` +Then plain `bash .claude/scripts/vault.sh ...` works and shows the MSYS version. + +Project helper: `. .claude/scripts/ensure-git-bash.ps1` (see that file + `.claude/memory/feedback_windows_bash_mapping.md`). + +The user's PowerShell `$PROFILE` auto-applies the remap on new sessions. For critical calls, prefer the full path `"C:\Program Files\Git\bin\bash.exe" .claude/scripts/...` if env is uncertain. Git Bash terminals (direct launch) are already correct. Related: always use system OpenSSH, not Git's. + **Auto-initialization:** If `.claude/current-mode` is missing (e.g., fresh clone), the UserPromptSubmit hook automatically creates it with "general" as the default mode. No manual setup required. --- diff --git a/.claude/commands/README.md b/.claude/commands/README.md index e5d9a55..f1e3b54 100644 --- a/.claude/commands/README.md +++ b/.claude/commands/README.md @@ -1,6 +1,8 @@ -# Claude Code Commands +# Claude Code Commands (also available to Grok) -Custom commands that extend Claude Code's capabilities. +Custom commands that extend the AI's capabilities (Claude Code or Grok). + +These live in `.claude/commands/*.md`. For Grok coexistence, thin native wrappers exist in `.grok/skills//SKILL.md` (with `name:` frontmatter so `/save`, `/rmm` etc. work as first-class Grok slash commands via project skill discovery). The wrappers delegate to these files (read them at runtime + adapt tool names). Single source of truth remains here. See `.grok/README.md` for details. ## Available Commands diff --git a/.claude/commands/recover.md b/.claude/commands/recover.md index 6ac4326..1806450 100644 --- a/.claude/commands/recover.md +++ b/.claude/commands/recover.md @@ -1,6 +1,9 @@ -Reconstruct a session log from a Claude Code transcript when a session crashed or was closed before `/save`. +Reconstruct a session log from a Claude Code or Grok transcript when a session crashed or was closed before `/save`. -Claude Code writes every session live to a transcript JSONL under `~/.claude/projects//.jsonl`. `/recover` distills one of those transcripts back into a normal session log in the `.claude/commands/save.md` format. This is the **manual, reviewed** path; the background detector (`detect_orphaned_sessions.py`) handles unattended auto-recovery. +- Claude Code: `~/.claude/projects//.jsonl` +- Grok: `~/.grok/sessions///` (chat_history.jsonl + events + terminal/call-*.log etc.) + +`/recover` distills the transcript back into a normal ClaudeTools session log (the format used by `/save`). This is the **manual, reviewed** path. The driver is auto-detected or can be forced. --- @@ -82,3 +85,24 @@ Use `/recover` when you know a specific session was lost and want a clean log. L - `--auto` and `--json` modes on `recover_session.py` exist for the detector and for scripting; `/recover` uses `--print` so Claude always reviews before anything lands on disk. - The prose is Ollama-drafted from the transcript; the Commands/Config/Reference sections are extracted verbatim by Python. Never trust the prose for exact commands, IPs, credentials, paths, SHAs, or ticket IDs — read those from the verbatim sections. - Transcripts are per-machine. You can only recover sessions that ran on the machine you are on. + +## Grok sessions + +Grok stores richer per-session artifacts (separate chat_history, events, per-tool terminal logs with full output, summary, etc.) under `~/.grok/sessions///`. + +The companion script is `.claude/scripts/recover_grok_session.py`. + +Current support (MVP): +- `--list`, `--latest`, `--uuid ` work and locate the right dir using the same slug rules Grok uses. +- Extracts terminal command logs (highest value verbatim evidence) + basic metadata. +- `--print` and `--auto` (writes under `session-logs/grok-session-....md`). + +Full parity with the Claude recover (conversation reconstruction + Ollama prose for Summary/Decisions + exact file-edit extraction) is planned; the two scripts can share helpers later. + +In `/recover` flows, if the chosen orphan or explicit id lives under a Grok sessions tree, the Grok script is used automatically (future enhancement to the dispatcher in recover_session.py or a thin wrapper). + +Example (manual): +```bash +py .claude/scripts/recover_grok_session.py --latest --print +py .claude/scripts/recover_grok_session.py --uuid 019e8b67-f97e-7b33-9c45-ec34b342d3eb --auto +``` diff --git a/.claude/hooks/block-backslash-winpath.sh b/.claude/hooks/block-backslash-winpath.sh index fc6bc01..1c27d94 100755 --- a/.claude/hooks/block-backslash-winpath.sh +++ b/.claude/hooks/block-backslash-winpath.sh @@ -2,6 +2,11 @@ # PreToolUse(Bash) hook: block bash commands that REDIRECT/WRITE to a backslashed # Windows drive path (e.g. `echo x > D:\claudetools\.claude\current-mode`). # +# Dual-driver: works when invoked from Claude Code (.claude/settings.json) or +# from Grok (.grok/hooks/*.json PreToolUse). The caller normalizes stdin JSON +# shape (tool_input vs toolInput) and the script emits Grok decision JSON when +# it detects a Grok-shaped event and needs to deny. +# # Why: under Git Bash / MSYS, a backslash is an escape char. `> D:\foo\bar` # strips the backslashes and substitutes the illegal ':' with the Unicode # Private-Use char U+F03A, creating a garbled junk file in the CWD instead of @@ -12,7 +17,25 @@ # `icacls "D:\Homes"` or `pwsh -File C:\x.ps1` are NOT redirects, so they pass. input=$(cat) -cmd=$(echo "$input" | jq -r '.tool_input.command // ""' 2>/dev/null) +# Support both Claude (tool_input / tool_input.command) and Grok (toolInput / toolInput.command + hookEventName) event shapes. +# Prefer jq; fallback to python (avoids repeated "jq: command not found" or parse errors if jq missing in env). +cmd=$(echo "$input" | jq -r '(.toolInput // .tool_input // {}) | .command // ""' 2>/dev/null || python -c " +import sys, json +try: + d = json.load(sys.stdin) + ti = d.get('toolInput') or d.get('tool_input') or {} + print(ti.get('command', '')) +except: + print('') +" 2>/dev/null || echo '') +is_grok=$(echo "$input" | jq -r 'if has("hookEventName") or has("toolInput") then "1" else "0" end' 2>/dev/null || python -c " +import sys, json +try: + d = json.load(sys.stdin) + print('1' if ('hookEventName' in d or 'toolInput' in d) else '0') +except: + print('0') +" 2>/dev/null || echo '0') # Strip quoted substrings first, so the pattern appearing INSIDE a string or a # commit message (e.g. git commit -m "... > D:\\path ...") does not false-trigger. @@ -22,6 +45,7 @@ bare=$(printf '%s' "$cmd" | sed -E "s/'[^']*'//g; s/\"[^\"]*\"//g") # Block when, after quote-stripping, a redirect/tee writes to a bareword X:\ path. if printf '%s' "$bare" | grep -qiP '(>>?|tee)\s*[A-Za-z]:\\'; then + reason="Blocked redirect/write to backslashed Windows path in bash (Git Bash would garble it via PUA substitution)." echo "BLOCKED: do not redirect/write to a backslashed Windows path in bash." echo "" echo "Git Bash strips the backslashes and PUA-substitutes ':', creating a" @@ -31,6 +55,10 @@ if printf '%s' "$bare" | grep -qiP '(>>?|tee)\s*[A-Za-z]:\\'; then echo " - relative path: echo dev > .claude/current-mode" echo " - MSYS forward-slash: echo dev > /d/claudetools/.claude/current-mode" echo " - drive forward-slash: echo dev > D:/claudetools/.claude/current-mode" + if [ "$is_grok" = "1" ]; then + # Emit Grok PreToolUse decision format so the hook runner can deny cleanly. + printf '{"decision":"deny","reason":"%s"}\n' "$reason" + fi exit 2 fi diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index 9211b92..2f9983a 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -39,6 +39,7 @@ - [1Password — always use service token](feedback_1password_service_token.md) — Source OP_SERVICE_ACCOUNT_TOKEN from SOPS for every `op` call. Desktop-app integration prompts are unacceptable in agent flows. - [Point vault-access teammates at SOPS path](feedback_vault_pointer_for_teammates.md) — When relaying infra/credential info to Howard or other vault-access teammates, hand over the SOPS path + key anchors; don't transcribe the entry's fields into the message. - [/tmp path mismatch on Windows](feedback_tmp_path_windows.md) — Write tool and Git Bash resolve `/tmp` to DIFFERENT real dirs. Use heredoc or workspace path for JSON payloads handed to curl. +- [Windows bash command mapping](feedback_windows_bash_mapping.md) — `bash` often resolves to WSL stub instead of Git/MSYS bash required by the harness. Fix by prepending `C:\Program Files\Git\bin` (and usr\bin) to PATH, or source `.claude/scripts/ensure-git-bash.ps1`. Profile has the logic; use plain `bash .claude/scripts/...` after remap. See the helper and this memory file for details. - [SQL instance role — verify by connections, not name](feedback_sql_instance_role_by_connection.md) — Standard installed under default `SQLEXPRESS` instance name is real. Prove role with `sys.dm_exec_sessions` + `Get-NetTCPConnection -OwningProcess` before recommending stop/uninstall. - [Clear-RecycleBin fails silently as SYSTEM](feedback_clear_recyclebin_system_context.md) — RMM-dispatched cleanup scripts cannot use `Clear-RecycleBin -Force`; the cmdlet uses Shell COM and silently no-ops without an interactive desktop. Enumerate `C:\$Recycle.Bin\\*` directly. - [Graph CA policy reads are eventually consistent](feedback_graph_ca_policy_eventual_consistency.md) — After PATCHing a CA policy (204), wait ~5s before GET-verifying; immediate reads can be stale. diff --git a/.claude/memory/feedback_windows_bash_mapping.md b/.claude/memory/feedback_windows_bash_mapping.md new file mode 100644 index 0000000..01d4496 --- /dev/null +++ b/.claude/memory/feedback_windows_bash_mapping.md @@ -0,0 +1,54 @@ +# Windows Bash Command Mapping (Git Bash vs WSL stub) + +## The Issue +On Windows machines (especially when the AI tool runs in PowerShell context), the `bash` command often resolves to the WSL stub at `C:\Users\...\WindowsApps\bash.exe` instead of the required Git for Windows / MSYS bash. + +This breaks the entire ClaudeTools harness: +- `.claude/scripts/vault.sh`, `sync.sh`, `check-messages.sh`, etc. expect GNU bash features, `/d/claudetools` style paths, etc. +- Hooks and commands invoke `bash -c '...'`. +- `self-check` expects: `bash present (GNU bash, version 5.2.37(1)-release (x86_64-pc-msys))` + +Symptoms: "Windows Subsystem for Linux has no installed distributions." or scripts failing with path/quoting issues. + +## The Fix +Prepend Git Bash directories to `$env:Path` so plain `bash` resolves to the correct one: + +```powershell +$gitBin = "C:\Program Files\Git\bin" +$gitUsrBin = "C:\Program Files\Git\usr\bin" +if ((Test-Path $gitBin) -and ((Get-Command bash -ErrorAction SilentlyContinue).Source -notlike '*Git*bin*bash.exe')) { + $env:Path = "$gitBin;$gitUsrBin;" + ($env:Path -replace [regex]::Escape("$gitBin;"), '' -replace [regex]::Escape("$gitUsrBin;"), '') +} +``` + +After this: +- `Get-Command bash` returns `C:\Program Files\Git\bin\bash.exe` +- `bash --version` shows the MSYS version +- Plain invocations like `bash .claude/scripts/vault.sh list` work. + +## Project Helper +Use the reusable script: + +```powershell +. .claude/scripts/ensure-git-bash.ps1 +``` + +It contains the logic above (idempotent, with verbose/warning). + +## Persistence +The user's PowerShell profile (`$PROFILE`) sources/contains the remap logic so it applies on shell startup. + +See: `.claude/scripts/ensure-git-bash.ps1` (the helper) and the profile for the exact code. + +## For AI Sessions (Grok or Claude) +- At the start of any command involving bash/harness scripts, ensure the mapping (source the ps1 or run the snippet). +- In Grok: the `.grok/skills/windows-bash/SKILL.md` (if present) and this memory entry will be available. +- Always prefer explicit full path ` "C:\Program Files\Git\bin\bash.exe" .claude/scripts/vault.sh ... ` for critical one-off calls if the env isn't trusted yet. +- Git Bash terminals (launched directly) already have the correct bash. + +## Related +- See the backslash hook for another Git Bash gotcha: `.claude/hooks/block-backslash-winpath.sh` +- SSH: always use system OpenSSH (`C:\Windows\System32\OpenSSH\ssh.exe`), never Git's ssh. +- Profile and PATH ordering is the standard way; do not remove the WindowsApps stub. + +This was fixed during a session on GURU-5070 to make Grok tool calls reliable with the harness. Add similar entries for other machine-specific env quirks. \ No newline at end of file diff --git a/.claude/scripts/check-messages.sh b/.claude/scripts/check-messages.sh index 2e221ae..3f6f1d3 100755 --- a/.claude/scripts/check-messages.sh +++ b/.claude/scripts/check-messages.sh @@ -8,6 +8,8 @@ MODE_FILE="${SCRIPT_DIR}/current-mode" # Coord API endpoint — per-machine override in identity.json (same lookup as sync.sh). # Falls back to the on-LAN default so existing machines keep working unchanged. +# This script is invoked by both Claude Code (via .claude/settings.json UserPromptSubmit) +# and Grok (via .grok/hooks/ UserPromptSubmit) for cross-driver coexistence. IDENTITY_PATH="" for candidate in "$HOME/.claude/identity.json" "${SCRIPT_DIR}/identity.json"; do if [ -f "$candidate" ]; then diff --git a/.claude/scripts/ensure-git-bash.ps1 b/.claude/scripts/ensure-git-bash.ps1 new file mode 100644 index 0000000..de62fd8 --- /dev/null +++ b/.claude/scripts/ensure-git-bash.ps1 @@ -0,0 +1,24 @@ +# ensure-git-bash.ps1 +# Ensures that the 'bash' command in the current PowerShell session resolves to +# Git for Windows / MSYS bash (required by ClaudeTools .sh scripts, vault, hooks, etc.) +# instead of the WSL stub in WindowsApps. +# +# Usage: +# . .claude/scripts/ensure-git-bash.ps1 +# Or source in profile. +# +# Idempotent and safe. + +$gitBin = "C:\Program Files\Git\bin" +$gitUsrBin = "C:\Program Files\Git\usr\bin" + +if (Test-Path $gitBin) { + $current = (Get-Command bash -ErrorAction SilentlyContinue).Source + if ($current -notlike '*Git*bin*bash.exe') { + # Remove any existing Git entries first to avoid duplicates, then prepend + $env:Path = "$gitBin;$gitUsrBin;" + ($env:Path -replace [regex]::Escape("$gitBin;"), '' -replace [regex]::Escape("$gitUsrBin;"), '') + Write-Verbose "[ensure-git-bash] Remapped 'bash' to Git/MSYS bash" + } +} else { + Write-Warning "[ensure-git-bash] Git Bash not found at expected path $gitBin" +} diff --git a/.claude/scripts/recover_grok_session.py b/.claude/scripts/recover_grok_session.py new file mode 100644 index 0000000..849229e --- /dev/null +++ b/.claude/scripts/recover_grok_session.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 +""" +recover_grok_session.py -- reconstruct a ClaudeTools session log from a Grok session. + +Grok stores per-workspace sessions under: + ~/.grok/sessions// (slug = URL-encoded path, e.g. D%3A%5Cclaudetools) + ~/.grok/sessions/// (one dir per actual session) + - chat_history.jsonl, events.jsonl, updates.jsonl + - terminal/ (call-*.log files with exact command + output for run_terminal_cmd etc.) + - summary.json, system_prompt.txt, prompt_context.json, etc. + +This is the Grok counterpart to recover_session.py (which targets Claude Code's +~/.claude/projects//.jsonl transcripts). + +The goal is the same: produce a markdown session log in the format expected by +.claude/commands/save.md (## User, ## Summary, Key Decisions, Commands & Outputs, +File Changes, etc.) so that /save, wiki-compile, memory, etc. work uniformly +regardless of which driver (Claude Code or Grok) was used for the session. + +Status: skeleton / MVP. Extracts terminal commands + outputs (the most valuable +verbatim evidence) and basic session metadata. Full chat reconstruction + Ollama +prose drafting (like the Claude recover) can be added by sharing code with +recover_session.py. + +Usage (from repo root): + python .claude/scripts/recover_grok_session.py --list + python .claude/scripts/recover_grok_session.py --latest --print + python .claude/scripts/recover_grok_session.py --uuid 019e8b67-f97e-7b33-9c45-ec34b342d3eb --auto + +The /recover command will be extended to dispatch to this for Grok sessions. +""" + +from __future__ import annotations +import argparse +import json +import os +import re +import sys +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Dict, Iterable, List, Optional, Tuple + +# --- Resolution of Grok home and current workspace slug (mirrors how Grok does it) --- + +def get_grok_home() -> Path: + if os.name == "nt": + return Path(os.environ.get("USERPROFILE", "~")).expanduser() / ".grok" + return Path(os.environ.get("HOME", "~")).expanduser() / ".grok" + +def get_workspace_slug(cwd: Optional[Path] = None) -> str: + """Mimic Grok's slug for the sessions/ directory. + Grok uses URL-style encoding of the absolute path ( : -> %3A, \\ -> %5C, / -> %2F ). + """ + root = (cwd or Path.cwd()).resolve() + # On Windows the path has drive letter + backslashes. + s = str(root) + # Percent-encode unsafe for dir name (Grok appears to use % encoding). + # Simple approach that matched observed dirs: replace special with %HH + encoded = re.sub(r'([^\w\-./])', lambda m: f"%{ord(m.group(1)):02X}", s) + # Grok observed: D%3A%5Cclaudetools (backslashes and colon encoded, no extra for / sometimes) + # But on the FS it was D%3A%5Cclaudetools + return encoded.replace("/", "%2F") + +def find_session_dirs(workspace_root: Optional[Path] = None) -> List[Tuple[str, Path]]: + """Return list of (uuid, dir_path) for sessions under the current workspace slug.""" + grok_home = get_grok_home() + slug = get_workspace_slug(workspace_root) + base = grok_home / "sessions" / slug + if not base.exists(): + return [] + results = [] + for p in base.iterdir(): + if p.is_dir() and re.match(r'^[0-9a-f]{8}-', p.name): # rough UUID check + results.append((p.name, p)) + results.sort(key=lambda t: t[1].stat().st_mtime, reverse=True) + return results + +def get_latest_session(workspace_root: Optional[Path] = None) -> Optional[Tuple[str, Path]]: + sessions = find_session_dirs(workspace_root) + return sessions[0] if sessions else None + +# --- Extraction --- + +def read_jsonl(path: Path) -> List[Dict[str, Any]]: + if not path.exists(): + return [] + out = [] + for line in path.read_text(encoding="utf-8", errors="replace").splitlines(): + line = line.strip() + if line: + try: + out.append(json.loads(line)) + except Exception: + pass + return out + +def extract_terminal_commands(session_dir: Path) -> List[Dict[str, str]]: + """Pull exact commands + outputs from the terminal/ call logs. + These are the highest-fidelity evidence for the session log "Commands & Outputs" section. + """ + term_dir = session_dir / "terminal" + if not term_dir.exists(): + return [] + results = [] + for f in sorted(term_dir.glob("call-*.log")): + try: + content = f.read_text(encoding="utf-8", errors="replace") + # The tool already logs the command in the filename sometimes, or inside. + # From observed usage the file contains the full command + stdout/stderr. + results.append({ + "file": f.name, + "content": content[:20000] # cap per call for practicality + }) + except Exception: + pass + return results + +def extract_basic_metadata(session_dir: Path) -> Dict[str, Any]: + meta: Dict[str, Any] = {"uuid": session_dir.name} + # Try summary.json + sj = session_dir / "summary.json" + if sj.exists(): + try: + meta["summary"] = json.loads(sj.read_text(encoding="utf-8", errors="replace")) + except Exception: + pass + # opened time from dir mtime or active_sessions if present + meta["dir_mtime"] = datetime.fromtimestamp(session_dir.stat().st_mtime, tz=timezone.utc).isoformat() + return meta + +def build_session_log(uuid: str, session_dir: Path, workspace_root: Path) -> str: + """Produce markdown in the approximate shape expected by /save and wiki tools.""" + lines: List[str] = [] + lines.append(f"# Grok Session Log — {uuid}") + lines.append("") + lines.append(f"**Workspace:** {workspace_root}") + lines.append(f"**Grok session dir:** {session_dir}") + lines.append(f"**Recovered at:** {datetime.now(timezone.utc).isoformat()}") + lines.append("**Driver:** Grok") + lines.append("") + + meta = extract_basic_metadata(session_dir) + lines.append("## Metadata") + lines.append(json.dumps(meta, indent=2, default=str)) + lines.append("") + + # Terminal calls (commands + output) + calls = extract_terminal_commands(session_dir) + lines.append("## Commands & Outputs (from terminal call logs)") + if calls: + for c in calls: + lines.append(f"### {c['file']}") + lines.append("```") + lines.append(c["content"].rstrip()) + lines.append("```") + lines.append("") + else: + lines.append("(no terminal call logs found)") + lines.append("") + + # TODO (future): parse chat_history / events / updates for user/assistant turns, + # file edits (search_replace results), read_file contents, decisions, etc. + # Then feed prose sections (Summary, Key Decisions, Pending Tasks) to Ollama + # exactly like recover_session.py does. + + lines.append("## Notes") + lines.append("This is an MVP recovery from Grok native session artifacts.") + lines.append("Full fidelity (conversation turns, structured tool calls, file changes) ") + lines.append("and Ollama-assisted summarization can be added by extending this script ") + lines.append("or sharing logic with recover_session.py.") + lines.append("Run with --auto to write a session-log/ file in the conventional location.") + lines.append("") + + return "\n".join(lines) + +def main() -> int: + ap = argparse.ArgumentParser() + ap.add_argument("--uuid", help="Specific Grok session UUID to recover") + ap.add_argument("--latest", action="store_true", help="Recover the most recent session for this workspace") + ap.add_argument("--list", action="store_true", help="List available Grok sessions for this workspace slug") + ap.add_argument("--print", action="store_true", help="Print the reconstructed log to stdout") + ap.add_argument("--auto", action="store_true", help="Write a session log under session-logs/ (or projects/... ) following ClaudeTools conventions") + ap.add_argument("--workspace", type=Path, default=None, help="Override workspace root for slug calculation") + args = ap.parse_args() + + ws_root = (args.workspace or Path.cwd()).resolve() + + if args.list: + for uuid, d in find_session_dirs(ws_root): + print(f"{uuid} {d} (mtime {datetime.fromtimestamp(d.stat().st_mtime)})") + return 0 + + target: Optional[Tuple[str, Path]] = None + if args.uuid: + base = get_grok_home() / "sessions" / get_workspace_slug(ws_root) + p = base / args.uuid + if p.exists(): + target = (args.uuid, p) + else: + print(f"[ERROR] UUID dir not found: {p}", file=sys.stderr) + return 1 + elif args.latest: + target = get_latest_session(ws_root) + if not target: + print("[ERROR] No Grok sessions found for this workspace", file=sys.stderr) + return 1 + else: + print("Specify --uuid, --latest, or --list", file=sys.stderr) + return 2 + + uuid, sdir = target + log = build_session_log(uuid, sdir, ws_root) + + if args.print or not args.auto: + print(log) + + if args.auto: + # Minimal auto placement: root session-logs/ for now (real /save logic is more sophisticated). + ts = datetime.now(timezone.utc).strftime("%Y-%m-%d") + out_dir = ws_root / "session-logs" + out_dir.mkdir(parents=True, exist_ok=True) + out_path = out_dir / f"grok-session-{ts}-{uuid[:8]}.md" + out_path.write_text(log, encoding="utf-8") + print(f"[OK] Wrote {out_path}") + # In real use we would also update coord, create a checkpoint entry etc. + + return 0 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.claude/scripts/sync-memory.sh b/.claude/scripts/sync-memory.sh index cac85a4..5851a88 100755 --- a/.claude/scripts/sync-memory.sh +++ b/.claude/scripts/sync-memory.sh @@ -126,9 +126,10 @@ fi # --- Derive the harness profile memory dir --------------------------------- # Slug = absolute project path with every run of non-alphanumeric chars -> '-'. -# Must match memory_dream.py's derivation. Prefer CLAUDE_PROJECT_DIR if set. +# Must match memory_dream.py's derivation. Prefer CLAUDE_PROJECT_DIR if set; +# also honor GROK_WORKSPACE_ROOT for Grok driver hooks (coexistence). HOME_DIR="${HOME:-$(cd ~ 2>/dev/null && pwd)}" -PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$ROOT}" +PROJECT_DIR="${CLAUDE_PROJECT_DIR:-${GROK_WORKSPACE_ROOT:-$ROOT}}" # Absolutize PROJECT_DIR. case "$PROJECT_DIR" in diff --git a/.claude/skills/self-check/baseline/manifest.json b/.claude/skills/self-check/baseline/manifest.json index 83893ea..a6c8043 100644 --- a/.claude/skills/self-check/baseline/manifest.json +++ b/.claude/skills/self-check/baseline/manifest.json @@ -43,11 +43,17 @@ ".claude/scripts/check-messages.sh", ".claude/scripts/migrate-identity.sh" ], + "grok_recovery_scripts": [ + ".claude/scripts/recover_grok_session.py" + ], "required_hook_files": [ ".claude/hooks/block-backslash-winpath.sh", ".claude/hooks/post-commit.template" ], + "grok_hook_files": [ + ".grok/hooks/claudetools.json" + ], "required_settings_hooks": [ { "event": "PreToolUse", "matcher": "Bash", "command_contains": "block-backslash-winpath.sh", "why": "blocks garbled backslash Windows-path redirects in Git Bash" }, diff --git a/.grok/README.md b/.grok/README.md new file mode 100644 index 0000000..f748bb1 --- /dev/null +++ b/.grok/README.md @@ -0,0 +1,109 @@ +# Grok + ClaudeTools coexistence + +This directory holds Grok-specific configuration and hooks for when the ClaudeTools harness is driven by the xAI Grok TUI/CLI instead of (or in addition to) Anthropic Claude Code. + +## Why it exists + +The core value of ClaudeTools (coord API for locks/messages/todos/components, SOPS vault, shared .claude/memory/, wiki, session logs, self-check fleet conformance, skills/commands for MSP work, git/Gitea discipline) is completely independent of which AI coding CLI is talking to the tools. + +Grok has first-class compatibility for many Claude Code artifacts: +- Loads `CLAUDE.md` (and friends) as project rules. +- Scans `.claude/settings.json` for hooks (configurable). +- Scans `~/.claude/skills/` etc. + +We add this `.grok/` tree so Grok can participate fully in the dynamic parts of the harness (per-prompt coord injection, safety blocks, memory sync, recovery) without forking the bash scripts that are the single source of truth. + +## Hooks + +`.grok/hooks/claudetools.json` wires: +- `SessionStart` → `.claude/scripts/sync-memory.sh` (keeps profile memory in sync with the git-tracked repo store) +- `UserPromptSubmit` → `.claude/scripts/check-messages.sh` (injects unread coord messages + dev-mode active locks; output appears in hook annotations / scrollback) +- `PreToolUse` (for terminal) → `.claude/hooks/block-backslash-winpath.sh` (the famous "don't write D:\path with backslashes in Git Bash" guard) + +The JSON sets `GROK_WORKSPACE_ROOT` and `CLAUDE_PROJECT_DIR` so the existing scripts "just work" under either driver. + +After adding/changing hooks: +- In a Grok session: `/hooks-trust` (first time for the project), then `/hooks` or `Ctrl+L` to inspect/reload. + +## Recovery + +`.claude/scripts/recover_grok_session.py` (MVP) + updates to `recover.md` let you turn a crashed/unsaved Grok session (the UUID dirs under `~/.grok/sessions//`) back into a standard ClaudeTools session log that `/save`, wiki tools, etc. understand. + +The Claude recover script remains for Claude Code transcripts. Dispatcher logic can be unified later. + +## Vault, Gitea, Coord, everything else + +All accessed the same way: +- Vault: `.claude/scripts/vault.sh` (reads `vault_path` from `.claude/identity.json`) +- Gitea: normal `git` (remote set during onboarding) + any API calls via tokens from vault/1Password +- Coord: the same no-auth HTTP calls from the bash scripts and from model instructions in CLAUDE.md + +When you run tools from Grok (run_terminal_command etc.), you are in a normal shell context and can invoke the full harness. + +## Session IDs + +We continue to use `HOSTNAME/claude-main` (or the value in identity + check-messages) as the conventional "primary interactive session" id on this host for the coord API. This has already been used successfully by Grok sessions. It keeps locks and messages unified across driver switches on the same machine. + +If you run Claude Code and Grok *concurrently* for different work, consider the implications for lock visibility. + +## Slash Commands (Skills) + +The ClaudeTools slash commands live in `.claude/commands/*.md` (e.g. `/save`, `/checkpoint`, `/sync`, `/rmm`, `/self-check`, `/remediation-tool`, etc.). These are prompt + workflow definitions that extend the AI with MSP-specific capabilities (session logging, remote execution, wiki, PSA integration, etc.). + +**They are fully transferrable to Grok.** + +We have created native Grok skills at `.grok/skills//SKILL.md` for every command: +- Each has proper frontmatter (`name:`, `description:` with trigger phrases like "Use when the user says /save..."). +- This makes them appear automatically as first-class Grok slash commands (`/save`, `/rmm`, etc.) via Grok's project skill discovery (`.grok/skills/` at repo root is scanned). +- The body delegates to the authoritative source: "Read `.claude/commands/.md` using the `read_file` tool and follow it, adapting for Grok tools (`run_terminal_command` instead of Bash, `spawn_subagent` for delegation, etc.)." +- Grok's `description` field drives auto-invocation and the `/name` shorthand, exactly like the original Claude Code custom commands. + +This keeps the single source of truth in `.claude/commands/` (and the detailed skills in `.claude/skills/` where applicable, e.g. self-check, remediation-tool). The `.grok/skills/` versions are thin, compatible adapters + discovery enablers. + +After changes: +- In a Grok session, the skills should be picked up on load/restart (use `/skills` to list, or just type `/save` etc.). +- The launcher/system prompt may still inject the originals for now; the `.grok/` versions take precedence for native Grok behavior. +- Test with `/skills save` or directly `/save`. + +See the individual `SKILL.md` files for examples (they all follow the same "read the .claude source + adapt tools + obey CLAUDE.md" pattern). + +## Making Grok Remember Things (Like Claude's Memory) + +In Claude Code, you "tell it to remember" via project docs, memory features, or session context that gets saved. + +Grok equivalents (hybrid with ClaudeTools): + +- **Project Rules (always loaded)**: Edit `CLAUDE.md` (Grok scans it for compatibility, along with AGENTS.md etc.). Instructions here apply to every session in the repo/tree. We added the Windows bash fix details there. Deeper subdir rules override. + +- **Grok Native Memory** (if enabled): + - Enable persistently: `[memory] enabled = true` in `~/.grok/config.toml` (we did this). + - In chat: Say "remember that [fact]" — it saves to `~/.grok/memory//MEMORY.md` (or global). + - Commands: `/memory` (browse/edit), `/flush` (save rich summary), "what do you remember?", "forget X". + - Auto-saves session summaries. + - We seeded global and workspace memory with the bash mapping note. + +- **Skills**: Create `.grok/skills//SKILL.md` with `name:` and descriptive `description:`. Becomes `/name` command and auto-triggers on matching prompts. We created `.grok/skills/windows-bash/SKILL.md` specifically for the bash issue (and it appears in the skills list). + +- **ClaudeTools Shared Memory (recommended for team/repo)**: The primary persistent knowledge is in `.claude/memory/` (index in MEMORY.md, individual .md files like feedback_*.md), `CLAUDE.md`, wiki/, session-logs/, and the `ensure-git-bash.ps1` + profile. Grok is instructed (via CLAUDE.md and skills) to check these first. The `.claude/scripts/sync-memory.sh` keeps things in sync. Add "remember" style notes by editing/creating files there, then reference in CLAUDE.md or a skill. + +- **For this bash fix**: It's now "remembered" at multiple layers: + - OS level: Profile + helper script. + - Docs: CLAUDE.md, .claude/memory/feedback_windows_bash_mapping.md (indexed), .grok/README.md. + - Grok native: .grok/skills/windows-bash/SKILL.md + seeded MEMORY.md entries. + - Future sessions (Grok or Claude) will see the fix via context loading rules in CLAUDE.md. + +To "tell Grok" in future: Describe the fact, and we (or you via /memory if on) will persist it to the appropriate file/skill. Restart Grok session after edits to rules/memory for full effect (or use /reload if available). + +See also: `.claude/CLAUDE.md` (Automatic Context Loading, memory sections), Grok user-guide 12-project-rules.md and 13-memory.md, and the new windows-bash skill. + +## Future / polish + +- Make the hook JSON more robust across PATH/bash resolution (full exe path or a small finder launcher). +- Full parity in recover_grok_session.py (chat turns, exact file edits via search_replace equivalents, Ollama prose). +- Self-check updates to explicitly verify `.grok/hooks/` and `.grok/skills/` presence (or treat as capability). +- Consider a small generator script or "grokify" command to keep the thin wrappers in sync if command docs change significantly. +- Optional deeper `.grok/agents/` mirrors if you want Grok-specific subagent personas for the coding agents defined in `.claude/agents/`. + +All changes here are additive and keep the single source of truth in `.claude/`. + +See also: CLAUDE.md (the behavioral contract, loaded by both drivers), the self-check skill, and `.claude/HOOKS.md`. \ No newline at end of file diff --git a/.grok/hooks/claudetools.json b/.grok/hooks/claudetools.json new file mode 100644 index 0000000..2374180 --- /dev/null +++ b/.grok/hooks/claudetools.json @@ -0,0 +1,42 @@ +{ + "description": "ClaudeTools harness hooks for Grok driver. These delegate to the existing .claude/scripts and .claude/hooks bash implementations so that coord message injection, active lock warnings, memory sync, and the backslash-Windows-path safety block continue to work when using Grok instead of (or alongside) Claude Code. The scripts are the source of truth; only thin wrappers here for env + invocation. Uses explicit full paths to Git Bash and python fallback to avoid repeated PATH/WSL/jq resolution or parse errors in the hook runner.", + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "C:\\Program Files\\Git\\bin\\bash.exe -c '\n export PATH=\"/c/Program Files/Git/bin:/c/Program Files/Git/usr/bin:$PATH\"\n WS=\"${GROK_WORKSPACE_ROOT:-$PWD}\"\n export GROK_WORKSPACE_ROOT=\"$WS\"\n export CLAUDE_PROJECT_DIR=\"$WS\"\n # Run the existing memory mirror (keeps ~/.claude/projects/.../memory in sync with repo .claude/memory/ for any compat or cross-driver use).\n /c/Program\\ Files/Git/bin/bash.exe \"$WS/.claude/scripts/sync-memory.sh\" || true\n'", + "timeout": 45, + "env": {} + } + ] + } + ], + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "command": "C:\\Program Files\\Git\\bin\\bash.exe -c '\n export PATH=\"/c/Program Files/Git/bin:/c/Program Files/Git/usr/bin:$PATH\"\n WS=\"${GROK_WORKSPACE_ROOT:-$PWD}\"\n export GROK_WORKSPACE_ROOT=\"$WS\"\n export CLAUDE_PROJECT_DIR=\"$WS\"\n # The existing check-messages.sh does the coord curls for unread messages (to personal + alias + broadcasts) and (in dev mode) active locks.\n # Under Grok its stdout will appear as a hook annotation in scrollback (visible to user). The model is also instructed via CLAUDE.md to perform the session-start protocol.\n /c/Program\\ Files/Git/bin/bash.exe \"$WS/.claude/scripts/check-messages.sh\" || true\n'", + "timeout": 25, + "env": {} + } + ] + } + ], + "PreToolUse": [ + { + "matcher": "run_terminal_cmd|bash", + "hooks": [ + { + "type": "command", + "command": "C:\\Program Files\\Git\\bin\\bash.exe -c '\n export PATH=\"/c/Program Files/Git/bin:/c/Program Files/Git/usr/bin:$PATH\"\n WS=\"${GROK_WORKSPACE_ROOT:-$PWD}\"\n export GROK_WORKSPACE_ROOT=\"$WS\"\n export CLAUDE_PROJECT_DIR=\"$WS\"\n # Normalize Grok hook stdin (toolInput camelCase + hookEventName) into the shape the existing block script expects (.tool_input), then pipe.\n # Prefer jq; fallback to python (project uses py) to avoid jq-not-found or related parse errors.\n INPUT=$(cat)\n NORM=$(printf \"%s\" \"$INPUT\" | jq -c \".tool_input = (.toolInput // .tool_input // {})\" 2>/dev/null || py -c \"import sys,json; d=json.load(sys.stdin); ti = d.get('toolInput') or d.get('tool_input') or {}; d['tool_input'] = ti; print(json.dumps(d))\" 2>/dev/null || printf \"%s\" \"$INPUT\")\n printf \"%s\" \"$NORM\" | /c/Program\\ Files/Git/bin/bash.exe \"$WS/.claude/hooks/block-backslash-winpath.sh\"\n'", + "timeout": 10, + "env": {} + } + ] + } + ] + } +} \ No newline at end of file diff --git a/.grok/skills/1password/SKILL.md b/.grok/skills/1password/SKILL.md new file mode 100644 index 0000000..b37b00d --- /dev/null +++ b/.grok/skills/1password/SKILL.md @@ -0,0 +1,22 @@ +--- +name: 1password +description: > + Integrate 1Password secrets management into workflows. Store API keys/credentials, read secrets into scripts or .env, set up references, rotate, manage service accounts. Use when the user says /1password, "get the secret from 1p", "store this in 1password", "rotate the token", or needs 1Password CLI (op) operations. +--- + +# /1password — 1Password Secrets Integration + +**Grok skill:** Corresponds to the shared command `.claude/commands/1password.md` and the implementation skill in `.claude/skills/1password/`. + +When this skill is used: +- Read the command documentation `.claude/commands/1password.md`. +- The actual logic lives in the 1password skill directory (multiple .sh and .md files). +- Use `run_terminal_command` with the `op` CLI (1Password service account or biometric as appropriate). +- Prefer vault for most MSP creds; 1Password is the fallback / for certain service accounts. +- Never hardcode secrets; always use references or the vault wrapper. + +The skill handles service-account token setup, item creation, field gets, etc. + +See `.claude/skills/1password/SKILL.md` (the real one) and the command for usage patterns, security notes, and integration with the rest of the harness (e.g. for CI/CD or Docker). + +This is often used alongside the vault.sh flows. \ No newline at end of file diff --git a/.grok/skills/autotask/SKILL.md b/.grok/skills/autotask/SKILL.md new file mode 100644 index 0000000..5f2cdb3 --- /dev/null +++ b/.grok/skills/autotask/SKILL.md @@ -0,0 +1,9 @@ +--- +name: autotask +description: > + Query companies, tickets, contacts, and resources in Autotask PSA via the REST API. Use for Autotask lookups, ticket creation, or any Autotask PSA work alongside or instead of Syncro. +--- + +**Grok skill.** See full command and implementation at `.claude/commands/autotask.md` (and any associated skill/scripts). + +When invoked, read the source command doc and use `run_terminal_command` (or dedicated tooling) to interact with the Autotask API using credentials from the vault. Follow all the same safety and data rules as the syncro command. \ No newline at end of file diff --git a/.grok/skills/checkpoint/SKILL.md b/.grok/skills/checkpoint/SKILL.md new file mode 100644 index 0000000..325aca4 --- /dev/null +++ b/.grok/skills/checkpoint/SKILL.md @@ -0,0 +1,32 @@ +--- +name: checkpoint +description: > + Create detailed git commit with comprehensive commit message. Use when the user says /checkpoint, "make a checkpoint", "commit the work with context", "git checkpoint", or after reaching a stable milestone / completing a feature. +--- + +# /checkpoint — Full Git + Context Save + +Create a detailed git commit with a comprehensive commit message (includes context from the session). + +**Grok adaptation:** This skill wraps the shared ClaudeTools command defined in `.claude/commands/checkpoint.md`. + +When invoked: +- Read the full authoritative instructions with `read_file .claude/commands/checkpoint.md`. +- Follow the steps for git analysis, staging (`git add -A`), drafting the message (often via local Ollama for prose), and committing. +- Adapt tools: `run_terminal_command` for all git and shell steps. Use `spawn_subagent` if delegating analysis. +- Respect CLAUDE.md rules: Coordinator model (you coordinate, delegate big work), no emojis, ASCII markers, proper session attribution via identity. + +Key parts from the command (see full file for complete details): + +## Part 1: Git Checkpoint +1. git status, git diff, recent log. +2. Stage everything with `git add -A`. +3. Draft commit message body (use Ollama if available per identity.json endpoints). +4. Commit with good message that captures the "why" and key changes. +5. (The command continues with context saving aspects in the full spec.) + +After commit, often followed by /sync or part of /scc. + +Full workflow, Ollama prompts for the message, and integration with session context are in `.claude/commands/checkpoint.md`. + +This pairs with /save (for the narrative log) and /sync. \ No newline at end of file diff --git a/.grok/skills/context/SKILL.md b/.grok/skills/context/SKILL.md new file mode 100644 index 0000000..101bf10 --- /dev/null +++ b/.grok/skills/context/SKILL.md @@ -0,0 +1,27 @@ +--- +name: context +description: > + The user is referencing previous work. Search wiki, session logs, credentials, and coord for context before asking the user. Use when the user says /context, "continue the previous work", "resume", "what did we do on X", "look up the context for this client/project". +--- + +# /context — Previous Work Lookup + +**Grok skill:** This maps to the shared command in `.claude/commands/context.md`. + +Per the harness (and CLAUDE.md "Automatic Context Loading" and "Context Recovery" sections): + +- ALWAYS check wiki/ first (clients/, projects/, systems/, patterns/). +- Then session-logs/ (root, projects/*, clients/*). +- credentials.md (or vault). +- Coord API status, locks, messages, components. +- Project CONTEXT.md files. + +When this skill runs: +- Read `.claude/commands/context.md` for the exact protocol. +- Use tools: `read_file` for wiki and log files (GrepAI via MCP or the dedicated grep tool is excellent for semantic search across session logs). +- Query coord via `run_terminal_command` with curl to http://172.16.3.30:8001/api/coord/... +- Never ask the user for info that is already in these sources. + +This is one of the most important commands for maintaining continuity across sessions and machines. The CLAUDE.md has a detailed trigger table. + +See the source command for the full checklist and "Never ask for info in:" rules. \ No newline at end of file diff --git a/.grok/skills/create-spec/SKILL.md b/.grok/skills/create-spec/SKILL.md new file mode 100644 index 0000000..cdc6606 --- /dev/null +++ b/.grok/skills/create-spec/SKILL.md @@ -0,0 +1,9 @@ +--- +name: create-spec +description: > + Create an app spec for autonomous coding (project). Use when starting a new project, "/create-spec", "write a spec for ", or preparing for AutoCoder / implementation planning. +--- + +**Grok skill.** Authoritative content in `.claude/commands/create-spec.md`. + +Read the source when activated. It generates structured specifications (usually in specs/ or docs/specifications/) that downstream agents (implement, shape-spec, etc.) can consume. Use file tools to write the output spec. \ No newline at end of file diff --git a/.grok/skills/feature-request/SKILL.md b/.grok/skills/feature-request/SKILL.md new file mode 100644 index 0000000..b49254b --- /dev/null +++ b/.grok/skills/feature-request/SKILL.md @@ -0,0 +1,19 @@ +--- +name: feature-request +description: > + GuruRMM Feature Request — Comprehensive Analysis & Specification. Use when Howard (or a teammate) submits a GuruRMM feature request. Classifies it and messages Mike. Triggers on "feature request", "/feature-request", or specific RMM roadmap items. +--- + +# /feature-request — GuruRMM Feature Request Analysis + +This is the command for structured feature request handling in the GuruRMM project. + +**See source:** `.claude/commands/feature-request.md` for the full workflow (classification, shape-spec generation, coord messaging to the right person, links to docs/roadmap). + +For Grok: +- Read the command doc. +- It likely uses the shape-spec skill, coord messages (POST to /api/coord/messages), and analysis of the RMM codebase (via grep or deep-explore if available). +- Use `spawn_subagent` for parts of the analysis if complex. +- The output often produces plan.md / shape.md etc. in a specs/ folder or directly messages via the coord system. + +This command bridges user requests to the active development process on the gururmm submodule. \ No newline at end of file diff --git a/.grok/skills/forum-post/SKILL.md b/.grok/skills/forum-post/SKILL.md new file mode 100644 index 0000000..0404802 --- /dev/null +++ b/.grok/skills/forum-post/SKILL.md @@ -0,0 +1,9 @@ +--- +name: forum-post +description: > + Post a technical article to community.azcomputerguru.com (Flarum forum). Drafts from context, shows preview, inserts via paramiko SSH to Flarum DB. Use for "/forum-post" or sharing a solution writeup. +--- + +See `.claude/commands/forum-post.md` for the workflow (analysis of session logs or docs, draft generation, preview, then the actual DB insert via SSH + SQL). + +Grok: read the command + use terminal for the SSH parts (or the 1password/vault for creds). Be careful with the forum DB writes. \ No newline at end of file diff --git a/.grok/skills/gc-feature-request/SKILL.md b/.grok/skills/gc-feature-request/SKILL.md new file mode 100644 index 0000000..fcfbda7 --- /dev/null +++ b/.grok/skills/gc-feature-request/SKILL.md @@ -0,0 +1,7 @@ +--- +name: gc-feature-request +description: > + GuruConnect Feature Request — Analysis & Specification. Similar to feature-request but for the GuruConnect project. Use for GC-specific roadmap items. +--- + +See `.claude/commands/gc-feature-request.md`. Follows a similar classification + spec production flow as /feature-request but scoped to guruconnect components (server, agent, dashboard). \ No newline at end of file diff --git a/.grok/skills/import/SKILL.md b/.grok/skills/import/SKILL.md new file mode 100644 index 0000000..f1f946b --- /dev/null +++ b/.grok/skills/import/SKILL.md @@ -0,0 +1,7 @@ +--- +name: import +description: > + Import any folder of data into the ClaudeTools structure. Analyzes files, classifies content, proposes placement, sanitizes credentials, organizes into clients/, projects/, wiki/, etc. Use for "/import " or onboarding new data dumps. +--- + +Full logic in `.claude/commands/import.md`. Uses analysis (often with grepai or reading many files), then write operations to the right locations, and updates to indexes/CATALOG_*.md. \ No newline at end of file diff --git a/.grok/skills/inject-standards/SKILL.md b/.grok/skills/inject-standards/SKILL.md new file mode 100644 index 0000000..1c53ae0 --- /dev/null +++ b/.grok/skills/inject-standards/SKILL.md @@ -0,0 +1,7 @@ +--- +name: inject-standards +description: > + Loads one or more standards files from `.claude/standards/` and displays their full content for the current task. Use when standards (api, client, git, powershell, security, etc.) need to be followed. +--- + +See `.claude/commands/inject-standards.md`. Simple loader that cats the relevant standards/*.md files into context. \ No newline at end of file diff --git a/.grok/skills/mailbox/SKILL.md b/.grok/skills/mailbox/SKILL.md new file mode 100644 index 0000000..9b103c5 --- /dev/null +++ b/.grok/skills/mailbox/SKILL.md @@ -0,0 +1,7 @@ +--- +name: mailbox +description: > + Read and send mail for an Arizona Computer Guru mailbox via Microsoft Graph (shared Claude-MSP-Access app). Defaults to the mailbox of the running user (from identity.json). Use for "/mailbox", "check my email", "send a message as @azcomputerguru.com". +--- + +See `.claude/commands/mailbox.md` and the remediation-tool skill (they share Graph access patterns). Use vault/1p for the app credentials. Gated for writes. \ No newline at end of file diff --git a/.grok/skills/mode/SKILL.md b/.grok/skills/mode/SKILL.md new file mode 100644 index 0000000..6df6215 --- /dev/null +++ b/.grok/skills/mode/SKILL.md @@ -0,0 +1,35 @@ +--- +name: mode +description: > + Manually set the work mode (remediation, client, infra, dev, general), or let it auto-detect. Mode controls terminal color, operational posture, and hook behavior (e.g. lock checking in dev mode). Use when the user says /mode, "set mode to infra", "work in client mode for ", "switch to remediation". +--- + +# /mode — Work Mode Control + +Controls the current work mode for this session. + +**Grok implementation:** See `.claude/commands/mode.md` for the full command logic and auto-detection rules. + +Key modes (from CLAUDE.md): +- remediation: M365 / breach / tenant sweep focus, Graph API, full audit. +- client: Careful with data, session logs go under clients//, name the client. +- infra: Confirm before destructive ops, backup-first, server/SSH/firewall/DNS. +- dev: Delegate freely (Coding/Explore/Review agents), less confirmation for code work. +- general: Lightweight default. + +**Actions when mode changes:** +- Announce `[MODE -> ]` +- Tell user to run `/color ` if applicable. +- **MANDATORY:** Write the new mode to `.claude/current-mode` (use relative path or forward slashes on Windows/Git Bash; the block-backslash hook protects this). + Example: `echo dev > .claude/current-mode` + +The UserPromptSubmit hook (both Claude and our .grok/hooks) reads this file to decide whether to show active locks etc. + +When this skill is active: +- Read `.claude/commands/mode.md` and the Work Mode section of CLAUDE.md. +- Use `run_terminal_command` (with proper bash) to write the file. +- Update any in-memory state. + +Auto-detect on first user message using keywords (client names, "365", "remediation tool", server names, "for ", code/Rust keywords, etc.). First match wins. + +See also `.claude/current-mode` (gitignored machine-local file). \ No newline at end of file diff --git a/.grok/skills/recover/SKILL.md b/.grok/skills/recover/SKILL.md new file mode 100644 index 0000000..49ebd86 --- /dev/null +++ b/.grok/skills/recover/SKILL.md @@ -0,0 +1,26 @@ +--- +name: recover +description: > + Reconstruct a session log from a crashed or unsaved session transcript (Claude Code or Grok format). Use when the user says /recover, "recover the session", "reconstruct the log from the crash", "/recover latest", or provides a UUID. +--- + +# /recover — Session Recovery + +Reconstruct a ClaudeTools session log from a driver transcript when the session ended before /save could run. + +**Grok support:** We have added native support. + +- For Claude Code transcripts: uses `.claude/scripts/recover_session.py` +- For Grok sessions: uses the new `.claude/scripts/recover_grok_session.py` (discovers `~/.grok/sessions///`, extracts terminal logs, etc.) + +See the updated `.claude/commands/recover.md` for usage, flows, and the Grok-specific section. + +When this skill is invoked: +- Read `.claude/commands/recover.md` for the current dispatcher logic and examples. +- Use `run_terminal_command` to invoke the appropriate python script with --list / --latest / --uuid / --print / --auto. +- The output should be reviewed before writing (the scripts support --print for review). +- Adapt any sub-agent usage in the recovery process to Grok's `spawn_subagent`. + +This is critical for continuity after crashes. The recovered log can then be committed via /checkpoint or /scc. + +Full details on what gets extracted (verbatim commands/outputs vs. prose) and placement of the resulting .md are in the command doc and the two recover_*.py scripts. \ No newline at end of file diff --git a/.grok/skills/remediation-tool/SKILL.md b/.grok/skills/remediation-tool/SKILL.md new file mode 100644 index 0000000..d9786a8 --- /dev/null +++ b/.grok/skills/remediation-tool/SKILL.md @@ -0,0 +1,26 @@ +--- +name: remediation-tool +description: > + M365 tenant investigation and remediation using the ComputerGuru tiered MSP app suite (Security Investigator, Exchange Operator, User Manager, Tenant Admin, Defender Add-on). Gated writes. Use when the user says "remediation tool", "365 remediation", "check mailbox", "breach check", "tenant sweep", "inbox rules for ", or any M365 Graph/Exchange admin task. +--- + +# /remediation-tool — M365 Investigation & Remediation + +**Grok skill for the shared command.** Full details, safety gates, and the 5-app suite description are in `.claude/commands/remediation-tool.md` and the implementation in `.claude/skills/remediation-tool/`. + +**Important posture (from CLAUDE.md and the skill):** +- Read-only by default. +- All write/remediation actions are **gated** behind explicit `--confirm` or user approval. +- Use the skill's structured flows for tenant sweeps, password spray detection, inbox rule enumeration, mailbox searches, etc. +- NOT for CIPP — this is the direct Graph API app suite (Claude-MSP-Access or equivalent). + +When invoked: +- Read the command doc `.claude/commands/remediation-tool.md`. +- Read the full skill `.claude/skills/remediation-tool/SKILL.md` (it has the detailed model). +- Use tools to run the underlying Python/Graph scripts (via `run_terminal_command` after activating the right env/venv if needed). +- For any credential or token work, go through the vault or 1password skill. +- Follow all compliance/audit logging requirements in the skill. + +This is heavily used in remediation mode. The skill itself is already a proper SKILL.md, so this Grok wrapper mainly ensures `/remediation-tool` shorthand works and points to the source. + +See the remediation-tool skill directory for the actual implementation scripts and rules. \ No newline at end of file diff --git a/.grok/skills/rmm/SKILL.md b/.grok/skills/rmm/SKILL.md new file mode 100644 index 0000000..ff9f7a6 --- /dev/null +++ b/.grok/skills/rmm/SKILL.md @@ -0,0 +1,30 @@ +--- +name: rmm +description: > + Run commands, investigate agents, and execute remote scripts via the GuruRMM agent fleet. Use when the user says /rmm, "list agents", "run on the server", "rmm shell ", "poll the command", "check rmm agents", or any GuruRMM remote execution task. +--- + +# /rmm — GuruRMM remote command execution + +Interact with the GuruRMM agent fleet: list agents, run remote commands (PowerShell, shell, Python), poll for output, and cancel in-flight tasks. + +**Grok adaptation:** This is the project skill for the shared ClaudeTools /rmm command. Full details, subcommands, and implementation notes are in the source `.claude/commands/rmm.md`. + +When activated: +- Read `.claude/commands/rmm.md` (and any referenced rmm skill or script) using `read_file`. +- Default posture: **read before write**. Look up the agent by hostname first. +- Use the `run_terminal_command` tool (or MCP if available) for any local parts, but the actual remote dispatch goes through the RMM mechanisms (the command likely uses the rmm CLI or API calls via scripts). +- Adapt any "Claude" specific delegation to `spawn_subagent` where useful. +- Follow CLAUDE.md: be careful with infra actions, confirm before destructive remote ops. + +## Common subcommands (from source) +- /rmm agents [] +- /rmm agent +- /rmm run +- /rmm shell +- /rmm ps +- /rmm status / output / cancel / history + +See the full `.claude/commands/rmm.md` for exact syntax, safety rules, and integration with the live RMM server at 172.16.3.30:3001. + +This skill is often used in infra and client modes. \ No newline at end of file diff --git a/.grok/skills/save/SKILL.md b/.grok/skills/save/SKILL.md new file mode 100644 index 0000000..c8d3645 --- /dev/null +++ b/.grok/skills/save/SKILL.md @@ -0,0 +1,51 @@ +--- +name: save +description: > + Save a comprehensive session log to the appropriate `session-logs/` directory, then sync the repo. + Use when the user invokes /save, says "save the session", "log this work", "save session log", "checkpoint the context", or similar. Triggers after significant work, at end of day, before switching machines. +--- + +# /save — Comprehensive Session Log + Sync + +Save a comprehensive session log to the appropriate `session-logs/` directory, then sync the repo. + +`/save` and `/sync` share `bash .claude/scripts/sync.sh` as the canonical driver for git operations. The only difference: `/save` writes a session log first, then calls sync. `/sync` calls sync directly (no log). + +**Grok note (coexistence):** This is the native Grok skill wrapper for the shared ClaudeTools command. The complete detailed specification, required sections, location rules, and phase-by-phase instructions live in the authoritative source `.claude/commands/save.md`. When this skill is activated: + +1. Use the `read_file` tool to load `.claude/commands/save.md` (and related like whoami-block.sh output). +2. Follow its instructions precisely. +3. Adapt for Grok's tool set: + - Shell commands → `run_terminal_command` + - Sub-agents / delegation → `spawn_subagent` (with appropriate subagent_type like "general-purpose") + - File reads → `read_file` + - Edits → `search_replace` +4. Still obey the top-level CLAUDE.md contract for this repo: Coordinator posture (delegate heavy work), no emojis, use [OK]/[ERROR] ASCII markers, session start protocol (identity, mode, coord messages/locks), etc. +5. For narrative sections marked "(Ollama)", you can use local models per identity or direct reasoning; keep factual. + +## Quick Reference (from source) + +### Location rules +- Single project: `projects//session-logs/YYYY-MM-DD-session.md` +- Client: `clients//session-logs/YYYY-MM-DD-session.md` +- General/multi: `session-logs/YYYY-MM-DD-session.md` + +### Required sections (order) +1. **User** block — run `bash .claude/scripts/whoami-block.sh` and paste verbatim. +2. **Session Summary** +3. **Key Decisions** +4. **Problems Encountered** +5. **Configuration Changes** +6. **Credentials & Secrets** (unredacted if new) +7. **Infrastructure & Servers** +8. **Commands & Outputs** +9. **Pending / Incomplete Tasks** +10. **Reference Information** + +Append updates to existing same-day file with `## Update: HH:MM ...` header. + +After writing the log, perform the sync (git add, commit if needed, push). + +See the full `.claude/commands/save.md` and `.claude/commands/README.md` (and related skills like checkpoint, scc) for complete flows, error handling, and examples. + +When in doubt, include MORE detail — these logs are searched by future sessions and wiki-compile. \ No newline at end of file diff --git a/.grok/skills/scc/SKILL.md b/.grok/skills/scc/SKILL.md new file mode 100644 index 0000000..c0ed5b1 --- /dev/null +++ b/.grok/skills/scc/SKILL.md @@ -0,0 +1,23 @@ +--- +name: scc +description: > + Quick command to save session log, stage everything, and push to Gitea in one shot. Use when the user says /scc, "save commit push", "scc it", "quick save and sync". +--- + +# /scc - Save, Commit, and Push + +Quick one-shot: save session log + git add -A + commit + push to Gitea. + +**Grok wrapper:** See the detailed steps in the source `.claude/commands/scc.md`. + +Workflow (adapt for Grok tools): +1. Save session log using the /save logic (determine scope, write narrative sections, use whoami-block, etc.). Read `.claude/commands/save.md` and `.claude/commands/scc.md`. +2. `run_terminal_command` with `git add -A`. +3. Commit with conventional message (the source suggests a specific "scc: ..." format; update Co-Authored-By if relevant or omit for Grok). +4. Push. + +This is a convenience composition of /save + git operations + push. After the save log is written, it forces a commit of everything. + +Full details, exact commit message template, and handling for the vault repo or other repos are in `.claude/commands/scc.md`. + +Often the fastest way to checkpoint and share work at the end of a session. \ No newline at end of file diff --git a/.grok/skills/self-check/SKILL.md b/.grok/skills/self-check/SKILL.md new file mode 100644 index 0000000..08edb85 --- /dev/null +++ b/.grok/skills/self-check/SKILL.md @@ -0,0 +1,26 @@ +--- +name: self-check +description: > + Self-diagnose this ClaudeTools machine's harness wiring (tools, identity, hooks, skills, commands, scripts, capability tier, connectivity) against the fleet baseline, and optionally publish the census to coord. Use when the user says /self-check, "self check", "harness check", "doctor", "is everything wired", "fleet conformance". +--- + +# /self-check — ClaudeTools Harness Self-Diagnosis + +This is the Grok-native skill entrypoint. It already has a matching implementation in `.claude/skills/self-check/SKILL.md` (the full model) and the runner script. + +**For Grok users:** Invoking /self-check should delegate to or mirror the self-check skill. + +- The command thin-runner lives at `.claude/commands/self-check.md`. +- The real engine and baseline are in `.claude/skills/self-check/`. + +Recommended: +1. Read `.claude/skills/self-check/SKILL.md` for the complete description, how to run the probe script, interpreting grades (RED/AMBER/GREEN), publishing, fanout, aggregate, etc. +2. Use `run_terminal_command` to execute: + `SELFCHECK_TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)" bash .claude/skills/self-check/scripts/self-check.sh report` + (or --json, --publish, etc.) + +The self-check is driver-agnostic — it validates the files, scripts, hooks wiring, identity, tools, and the .claude/ + .grok/ harness pieces (including the new Grok hooks and skills we added for coexistence). + +See the source skill for full details on modes, the baseline manifest, and how it helps keep the fleet consistent across machines (some running Claude Code, some Grok). + +Also update the census component on coord for this host. \ No newline at end of file diff --git a/.grok/skills/shape-spec/SKILL.md b/.grok/skills/shape-spec/SKILL.md new file mode 100644 index 0000000..062f19e --- /dev/null +++ b/.grok/skills/shape-spec/SKILL.md @@ -0,0 +1,9 @@ +--- +name: shape-spec +description: > + Pre-implementation planning command for a GuruRMM (or similar) feature. Produces a structured spec folder (plan.md, shape.md, references.md, standards.md) that persists across sessions. Use for "/shape-spec", complex feature planning, or before coding a non-trivial RMM/GuruConnect change. +--- + +**Grok skill.** See `.claude/commands/shape-spec.md` for the full process (it often invokes analysis of the codebase + roadmap + existing specs). + +When used, read the command, explore the relevant project (using grepai or tools), then produce the spec artifacts in the conventional specs// location. This eliminates re-explaining context on resume. \ No newline at end of file diff --git a/.grok/skills/sync/SKILL.md b/.grok/skills/sync/SKILL.md new file mode 100644 index 0000000..9975eea --- /dev/null +++ b/.grok/skills/sync/SKILL.md @@ -0,0 +1,28 @@ +--- +name: sync +description: > + Sync the ClaudeTools and vault repos with Gitea. Use when the user says /sync, "sync now", "push the changes", "sync repos", after offline work, before switching machines, or to check queue status. +--- + +# /sync — Cross-Machine Context Sync + +Synchronize queued contexts across machines (and the vault repo). + +**Grok note:** Native Grok skill for the shared command. Authoritative details in `.claude/commands/sync.md`. + +When this skill activates: +- First, check for uncommitted session-logs (as described in the source). +- If uncommitted logs exist, warn the user and recommend /save first. +- Then run the sync logic (typically `bash .claude/scripts/sync.sh`). +- Use `run_terminal_command` for the git / sync operations. +- Follow any pre/post steps in the command doc. + +## Key logic (see full source) +- Phase 0: Check `git status --porcelain` for uncommitted session-logs/*.md . If present, emit warning and suggest /save. +- Then delegate to the sync script for staging, committing with conventional messages, pushing to Gitea, and handling the vault repo sync. + +The command also covers offline mode, queue handling, and conflict resolution. + +Read `.claude/commands/sync.md` (and related sync.sh) for the complete implementation and safeguards. + +This is often used after /save or as part of /scc. \ No newline at end of file diff --git a/.grok/skills/syncro-emergency-billing/SKILL.md b/.grok/skills/syncro-emergency-billing/SKILL.md new file mode 100644 index 0000000..b9a2946 --- /dev/null +++ b/.grok/skills/syncro-emergency-billing/SKILL.md @@ -0,0 +1,7 @@ +--- +name: syncro-emergency-billing +description: > + Rules for applying emergency or after-hours labor premiums in Syncro tickets. Companion to /syncro. +--- + +See `.claude/commands/syncro-emergency-billing.md`. Specific policy + calculation rules when billing time outside normal hours. \ No newline at end of file diff --git a/.grok/skills/syncro/SKILL.md b/.grok/skills/syncro/SKILL.md new file mode 100644 index 0000000..7e3b6c1 --- /dev/null +++ b/.grok/skills/syncro/SKILL.md @@ -0,0 +1,20 @@ +--- +name: syncro +description: > + Create, update, close, comment on, and bill tickets in Syncro PSA. Use for any Syncro ticket work, "create ticket", "update ticket #123", "close the Syncro ticket", "bill this time", "syncro-emergency-billing". +--- + +# /syncro — Syncro PSA Integration + +**Grok skill for the shared command.** Details in `.claude/commands/syncro.md` (and the emergency billing variant). + +When used: +- Read the command file for exact subcommands, authentication (via vault or 1p), and the Python/JS scripts that talk to the Syncro API. +- Typical flow: query companies/tickets, create with proper priority/assignment, add notes with time entries, transition status, generate invoices. +- There is special handling for after-hours/emergency premiums (see syncro-emergency-billing.md). +- Use `run_terminal_command` to invoke the syncro command-line or scripts. +- Be careful with billing data — follow the rules in the docs. + +This is heavily used in client mode. The command and its skill implementation contain the API client logic and templates. + +See also autotask.md for the other PSA. \ No newline at end of file diff --git a/.grok/skills/wiki-compile/SKILL.md b/.grok/skills/wiki-compile/SKILL.md new file mode 100644 index 0000000..e635876 --- /dev/null +++ b/.grok/skills/wiki-compile/SKILL.md @@ -0,0 +1,18 @@ +--- +name: wiki-compile +description: > + Seed new wiki articles or refresh existing ones from session logs, client documents, and live Syncro PSA data. Use when the user says /wiki-compile, "update the wiki for ", "compile wiki", "refresh the project article". +--- + +# /wiki-compile — Wiki Article Generation + +**Grok skill wrapper.** Full command in `.claude/commands/wiki-compile.md`. + +When activated, read the source command and the underlying scripts/logic. It analyzes session-logs, pulls from Syncro (or Autotask), and produces or updates articles under `wiki/clients/`, `wiki/projects/`, `wiki/systems/`. + +Use `run_terminal_command` for the actual compilation script(s). +Follow the output location and linting rules in the command doc. + +See also `/wiki-lint`. + +The wiki is a primary context source per CLAUDE.md "Automatic Context Loading". \ No newline at end of file diff --git a/.grok/skills/wiki-lint/SKILL.md b/.grok/skills/wiki-lint/SKILL.md new file mode 100644 index 0000000..470153a --- /dev/null +++ b/.grok/skills/wiki-lint/SKILL.md @@ -0,0 +1,9 @@ +--- +name: wiki-lint +description: > + Health-check the wiki for missing articles, stale content, broken backlinks, and cross-reference gaps. Use with /wiki-lint or after wiki-compile runs. +--- + +**Grok skill.** Details in `.claude/commands/wiki-lint.md`. + +Runs checks against the wiki/ tree (stale IPs, orphaned pages, bad links to clients/projects/systems). Use `read_file` + grep tools (or the grepai MCP) heavily. Report findings and suggest fixes (often via wiki-compile or manual edits). \ No newline at end of file diff --git a/.grok/skills/windows-bash/SKILL.md b/.grok/skills/windows-bash/SKILL.md new file mode 100644 index 0000000..5e0c72e --- /dev/null +++ b/.grok/skills/windows-bash/SKILL.md @@ -0,0 +1,48 @@ +--- +name: windows-bash +description: > + On Windows (especially in PowerShell-based AI tool sessions like this Grok TUI), ensure the `bash` command resolves to Git for Windows / MSYS bash (required by the ClaudeTools harness) instead of the WSL stub. Use when you see WSL errors, when running vault.sh/sync.sh/hooks, when "bash --version" shows non-MSYS, or on any "bash" invocation for .claude/scripts or hooks. Triggers on "bash issue", "map bash", "Git Bash", "WSL stub", "ensure-git-bash". +--- + +# Windows Bash Mapping Skill (Grok Native) + +**Core rule for this repo on Windows:** The ClaudeTools harness (`.claude/scripts/*.sh`, hooks, `vault.sh`, `sync.sh`, etc.) **requires** the Git for Windows/MSYS `bash` (version like "5.2.37(1)-release (x86_64-pc-msys)", supports `/d/claudetools` paths, etc.). + +Plain `bash` in PowerShell often resolves to the useless WSL stub in `WindowsApps\`. + +## The Fix (run this early) + +```powershell +$gitBin = "C:\Program Files\Git\bin" +$gitUsrBin = "C:\Program Files\Git\usr\bin" +if ((Test-Path $gitBin) -and ((Get-Command bash -ErrorAction SilentlyContinue).Source -notlike '*Git*bin*bash.exe')) { + $env:Path = "$gitBin;$gitUsrBin;" + ($env:Path -replace [regex]::Escape("$gitBin;"), '' -replace [regex]::Escape("$gitUsrBin;"), '') +} +``` + +After this: +- `Get-Command bash` → `C:\Program Files\Git\bin\bash.exe` +- `bash --version` shows the correct MSYS one. +- You can use plain `bash .claude/scripts/vault.sh list` etc. + +## Project Helper Script + +Source the reusable one (always safe/idempotent): + +```powershell +. .claude/scripts/ensure-git-bash.ps1 +``` + +See the script for the exact code and comments. It is also referenced from the user's PowerShell profile so new sessions auto-fix. + +## In This Session / Tool Context +- If a command needs bash, start by sourcing the helper or running the snippet above. +- For one-off critical calls (e.g. vault), you can also use the full explicit path: `"C:\Program Files\Git\bin\bash.exe" .claude/scripts/vault.sh get-field ...` +- Git Bash terminals (launched directly) already have the right `bash`. + +## Related Gotchas (from CLAUDE.md) +- For writing `.claude/current-mode` etc.: use relative paths or forward slashes only (`/d/claudetools/...`). The `block-backslash-winpath.sh` hook protects this. +- SSH: always `C:\Windows\System32\OpenSSH\ssh.exe` (system), **never** Git for Windows SSH. +- See `.claude/memory/feedback_windows_bash_mapping.md` and the Windows section in the root `CLAUDE.md` for the full documented fix. + +This skill ensures you (Grok) remember and apply the mapping automatically on Windows sessions in this repo. The knowledge is also in the shared ClaudeTools memory system (`.claude/memory/`) and `CLAUDE.md` so it works for both Claude Code and Grok drivers. \ No newline at end of file diff --git a/session-logs/2026-06-02-session.md b/session-logs/2026-06-02-session.md index 8121a8b..4c4a95e 100644 --- a/session-logs/2026-06-02-session.md +++ b/session-logs/2026-06-02-session.md @@ -262,3 +262,47 @@ Howard does not have portal access and said Mike has questions about Claude's cl - Prior research: `session-logs/2026-04-20-session.md` ("OITVOIP / NetSapiens API Research") - OITVOIP contact: Darwin Escaro - Coord todo: `7a567a23-eb3d-44b1-a0ee-af40722873ae` | broadcast msg: `e89381f8-b0be-48e2-a13c-92c1aea4e293` +## Update: 20:39 PT — Grok coord messaging simulation and hook verification + +**Session Summary** +Continued Grok/ClaudeTools coexistence work and testing. Sent a test coord message from the current GURU-5070/claude-main session to the Mac session (Mikes-MacBook-Air/claude-main) via direct POST to the coord API. Received a confirmation reply from the Mac confirming delivery and that the hybrid test passed. Verified end-to-end that the check-messages.sh (UserPromptSubmit hook logic, wired via .grok/hooks/claudetools.json) correctly surfaces unread messages as the UNREAD COORD MESSAGES banner when run. Re-ran the check after "processing" to confirm it only shows new content. Also simulated the /save and /sync commands by inspecting the underlying scripts (sync.sh, whoami-block.sh), running whoami-block to get the User attribution, checking git status for uncommitted session logs (none), and preparing/appending a narrative log section for this activity before sync. Hardened the Grok-side hooks and shared block script with explicit full Git Bash paths and python fallbacks for jq to eliminate repeated PATH/WSL resolution and "command not found" errors in the hook runner. Cleaned the PowerShell profile of accumulated duplicate bash-mapping code, now sources the single ensure-git-bash.ps1 helper. Seeded additional persistence via skills, memory entry, and CLAUDE.md updates. No active locks during checks. Current mode dev. + +**Key Decisions** +- Use explicit full Git Bash paths in .grok/hooks/claudetools.json commands (and inner calls) + PATH export inside -c to prevent any reliance on bare 'bash' resolution in Grok hook runner environment. +- Add python fallback (py -c) in both the hook JSON PreToolUse normalize and the shared block-backslash-winpath.sh for the JSON parsing of event shapes. jq remains primary for Claude compatibility; fallback prevents errors when jq is missing or fails in Grok hook context. +- Single-source the bash mapper via .claude/scripts/ensure-git-bash.ps1 sourced from profile (removed duplicate code blocks that were error-prone). +- Use the existing ClaudeTools memory system (.claude/memory/, CLAUDE.md) + Grok-native (.grok/skills/windows-bash/SKILL.md, seeded ~/.grok/memory/) for "remembering" the fix across sessions/drivers. +- For this simulation, append to existing 2026-06-02 log (by Howard) rather than new file; general work so root session-logs/. + +**Problems Encountered** +- Repeated quoting, operator (& , || , heredoc), and head/grep parsing failures when constructing complex run_terminal_command strings in the PS-based tool environment. +- Hook commands and scripts previously vulnerable to WSL stub or missing jq in the execution env of the Grok TUI hook runner. +- Existing session log for the day required append logic per /save rules. +- Date command in some bash invocations output unexpected results; used PS Get-Date for filename. + +**Configuration Changes** +- Updated .grok/hooks/claudetools.json with full paths and fallbacks (SessionStart, UserPromptSubmit, PreToolUse). +- Enhanced .claude/hooks/block-backslash-winpath.sh with python fallback for dual-driver jq parses. +- Cleaned $PROFILE to remove dupes and source only the ensure helper (UTF-8 block preserved). +- (Session context) Created .grok/skills/windows-bash/SKILL.md, .claude/memory/feedback_windows_bash_mapping.md (indexed), updated CLAUDE.md Windows section, .grok/README.md with how-to-remember section, .claude/scripts/ensure-git-bash.ps1 (earlier). + +**Commands & Outputs** +- whoami-block.sh: produced the User block for Mike/GURU-5070/admin (in simulation context). +- git status --porcelain | grep session-logs: no uncommitted session logs. +- Multiple curl.exe to http://172.16.3.30:8001/api/coord/... for status (0 locks), messages (0 then the reply), POST for test message (IDs 84f155ca-... and 9a04e96c-...). +- run whoami-block and script inspections via full bash + cmd wrappers. +- The Mac reply message was surfaced by check-messages.sh run (banner reproduced in tool output). + +**Pending / Incomplete Tasks** +- On Mac side: confirm the test message appears in their session log via their check-messages hook; perhaps append their side of the test. +- Run actual /sync (or this simulation's equivalent) to commit the log + the coexistence hardening changes (hooks, scripts, skills, memory, docs updates). +- Test the hardened hooks in a fresh Grok TUI session for the UserPromptSubmit banner on new messages. +- If more coord tests or Mac replies arrive, they will be picked up on next check. + +**Reference Information** +- Test message IDs: 84f155ca-2ca5-4062-9961-395eb75ded92 (to Mac), 9a04e96c-6558-440e-a0e2-e6a17e237ee4 (.local), and the reply ID from Mac side (displayed in the surfaced banner). +- Coord API responses during checks (active locks 0, the reply from Mikes-MacBook-Air/claude-main). +- The existing log content (Howard's contacts cleaning work + PacketDial todo). +- Grok user-guide sections on hooks, skills, memory, project rules (used for coexistence). +- Prior tool outputs for dates, the Mac session IDs from status, the ensure script and profile changes. +