diff --git a/.claude/DATABASE_FIRST_PROTOCOL.md b/.claude/DATABASE_FIRST_PROTOCOL.md index 80ba80e..49423e3 100644 --- a/.claude/DATABASE_FIRST_PROTOCOL.md +++ b/.claude/DATABASE_FIRST_PROTOCOL.md @@ -232,7 +232,7 @@ curl http://172.16.3.30:8001/health # Check total contexts curl -H "Authorization: Bearer $JWT" \ http://172.16.3.30:8001/api/conversation-contexts | \ - python -c "import sys,json; print(f'Total: {json.load(sys.stdin)[\"total\"]}')" + jq -r '.total' # Try different search term # Instead of: search_term=dataforth%20DOS diff --git a/.claude/OLLAMA.md b/.claude/OLLAMA.md index 9e3ee6a..5df74d8 100644 --- a/.claude/OLLAMA.md +++ b/.claude/OLLAMA.md @@ -17,7 +17,7 @@ Ollama runs on Mike's workstation (DESKTOP-0O8A1RL) with GPU acceleration. Avail Check reachability: ```bash -curl -s http://100.92.127.64:11434/api/tags | python -c "import sys,json; [print(m['name']) for m in json.load(sys.stdin).get('models',[])]" +curl -s http://100.92.127.64:11434/api/tags | jq -r '.models[].name' ``` If it fails: verify Tailscale is connected (`tailscale status`) and Mike's workstation is online. @@ -38,7 +38,7 @@ OLLAMA=$([ "$(jq -r .machine .claude/identity.json 2>/dev/null)" = "DESKTOP-0O8A Preferred one-liner (avoids shell escaping): ```bash -python3 -c " +py -c " import urllib.request, json, sys url = 'http://localhost:11434/api/generate' body = json.dumps({'model':'qwen3:14b','prompt': sys.argv[1],'stream':False}).encode() diff --git a/.claude/commands/syncro.md b/.claude/commands/syncro.md index 9eaf290..5418fab 100644 --- a/.claude/commands/syncro.md +++ b/.claude/commands/syncro.md @@ -36,7 +36,7 @@ BASE="https://computerguru.syncromsp.com/api/v1" If `vault.sh get-field` fails (yq not installed), fall back to: ```bash -API_KEY=$(sops -d D:/vault/msp-tools/syncro.sops.yaml | python -c "import sys,yaml; print(yaml.safe_load(sys.stdin)['credentials']['credential'])") +API_KEY=$(sops -d D:/vault/msp-tools/syncro.sops.yaml | py -c "import sys,yaml; print(yaml.safe_load(sys.stdin)['credentials']['credential'])") ``` ### Endpoints reference diff --git a/.claude/scripts/sync.sh b/.claude/scripts/sync.sh index a9d620f..4a3957b 100755 --- a/.claude/scripts/sync.sh +++ b/.claude/scripts/sync.sh @@ -39,7 +39,7 @@ echo -e "${GREEN}[OK]${NC} Working directory: $(pwd)" # Detect Python interpreter — verify it actually runs (Windows Store stub passes command -v but fails to execute) PYTHON="" -for candidate in python3 python; do +for candidate in py python3 python; do if command -v "$candidate" >/dev/null 2>&1; then if "$candidate" -c "import sys; sys.exit(0)" >/dev/null 2>&1; then PYTHON="$candidate" @@ -48,7 +48,7 @@ for candidate in python3 python; do fi done if [ -z "$PYTHON" ]; then - echo -e "${RED}[ERROR]${NC} No Python interpreter found (need python or python3)" + echo -e "${RED}[ERROR]${NC} No Python interpreter found (tried: py, python3, python)" exit 1 fi diff --git a/.claude/skills/1password/references/op_commands.md b/.claude/skills/1password/references/op_commands.md index 3122731..61178fa 100644 --- a/.claude/skills/1password/references/op_commands.md +++ b/.claude/skills/1password/references/op_commands.md @@ -154,18 +154,12 @@ op vault list --format=json # Vaults as JSON ## Useful Patterns ```bash -# Find item by field value (search) -op item list --format=json | \ - python3 -c "import sys,json; [print(i['title']) for i in json.load(sys.stdin)]" - -# Export all items in a vault to JSON (backup) -op item list --vault Dev --format=json | \ - python3 -c "import sys,json; ids=[i['id'] for i in json.load(sys.stdin)]" -# (then loop to get each) +# List item titles +op item list --format=json | jq -r '.[].title' # Check if a specific item exists op item get "My Item" &>/dev/null && echo "exists" || echo "not found" # Get item ID (for scripting) -op item get "My Item" --format=json | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])" +op item get "My Item" --format=json | jq -r '.id' ``` diff --git a/.claude/skills/1password/references/secret_references.md b/.claude/skills/1password/references/secret_references.md index 72db38d..5900932 100644 --- a/.claude/skills/1password/references/secret_references.md +++ b/.claude/skills/1password/references/secret_references.md @@ -102,8 +102,7 @@ op run --env-file=n8n.env.tpl -- docker compose up n8n ```bash # List all fields in an item -op item get "Item Name" --format=json | \ - python3 -c "import sys,json; [print(f['label']) for f in json.load(sys.stdin)['fields'] if f.get('value')]" +op item get "Item Name" --format=json | jq -r '.fields[] | select(.value) | .label' # Or view interactively op item get "Item Name" diff --git a/.claude/skills/1password/scripts/check_setup.sh b/.claude/skills/1password/scripts/check_setup.sh index 3b0a37f..d793bee 100755 --- a/.claude/skills/1password/scripts/check_setup.sh +++ b/.claude/skills/1password/scripts/check_setup.sh @@ -50,7 +50,7 @@ if op account list &>/dev/null 2>&1; then echo "" echo " Vaults:" op vault list --format=json 2>/dev/null | \ - python3 -c "import sys,json; [print(f' • {v[\"name\"]} ({v[\"id\"]})') for v in json.load(sys.stdin)]" 2>/dev/null || true + jq -r '.[] | " \u2022 \(.name) (\(.id))"' 2>/dev/null || true fi echo "" diff --git a/.claude/skills/1password/scripts/env_from_op.sh b/.claude/skills/1password/scripts/env_from_op.sh index 17e1d4e..b74a905 100755 --- a/.claude/skills/1password/scripts/env_from_op.sh +++ b/.claude/skills/1password/scripts/env_from_op.sh @@ -42,11 +42,9 @@ fi if [[ -z "$ITEM" ]]; then echo "Available items in vault '${VAULT:-all vaults}':" if [[ -n "$VAULT" ]]; then - op item list --vault "$VAULT" --format=json | \ - python3 -c "import sys,json; [print(f' {i[\"title\"]}') for i in json.load(sys.stdin)]" + op item list --vault "$VAULT" --format=json | jq -r '.[] | " \(.title)"' else - op item list --format=json | \ - python3 -c "import sys,json; [print(f' [{i[\"vault\"][\"name\"]}] {i[\"title\"]}') for i in json.load(sys.stdin)]" + op item list --format=json | jq -r '.[] | " [\(.vault.name)] \(.title)"' fi echo "" read -rp "Enter item title: " ITEM @@ -61,11 +59,11 @@ else ITEM_JSON=$(op item get "$ITEM" --format=json) fi -VAULT_NAME=$(echo "$ITEM_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['vault']['name'])") -ITEM_TITLE=$(echo "$ITEM_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['title'])") +VAULT_NAME=$(echo "$ITEM_JSON" | jq -r '.vault.name') +ITEM_TITLE=$(echo "$ITEM_JSON" | jq -r '.title') # Build .env content -ENV_CONTENT=$(echo "$ITEM_JSON" | python3 - <<'PYEOF' +ENV_CONTENT=$(echo "$ITEM_JSON" | py - <<'PYEOF' import sys, json, re data = json.load(sys.stdin) diff --git a/.claude/skills/1password/scripts/store_secret.sh b/.claude/skills/1password/scripts/store_secret.sh index 50b0f0c..d96eeb6 100755 --- a/.claude/skills/1password/scripts/store_secret.sh +++ b/.claude/skills/1password/scripts/store_secret.sh @@ -78,8 +78,8 @@ else "${FIELD}[password]=${VALUE}" \ --format=json) - ITEM_ID=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") - VAULT_NAME=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['vault']['name'])") + ITEM_ID=$(echo "$RESULT" | jq -r '.id') + VAULT_NAME=$(echo "$RESULT" | jq -r '.vault.name') echo "✅ Created '${TITLE}' (ID: ${ITEM_ID})" echo "" diff --git a/.claude/skills/remediation-tool/scripts/get-token.sh b/.claude/skills/remediation-tool/scripts/get-token.sh index 71d00e5..55aea61 100644 --- a/.claude/skills/remediation-tool/scripts/get-token.sh +++ b/.claude/skills/remediation-tool/scripts/get-token.sh @@ -96,7 +96,7 @@ fi if [[ -z "$CLIENT_SECRET" ]]; then PYTHON_BIN="" - for p in python3 python py; do command -v "$p" >/dev/null 2>&1 && PYTHON_BIN="$p" && break; done + for p in py python python3; do command -v "$p" >/dev/null 2>&1 && PYTHON_BIN="$p" && break; done [[ -z "$PYTHON_BIN" ]] && { echo "ERROR: vault.sh failed and python unavailable for SOPS fallback" >&2; exit 3; } command -v sops >/dev/null 2>&1 || { echo "ERROR: sops not on PATH (needed for fallback decrypt)" >&2; exit 3; }