forked from bchanot/claude
chore(seo-data): install/make/doctor wiring + gitleaks allowlist for token store
This commit is contained in:
@@ -4,3 +4,12 @@
|
|||||||
# Used by: lib/toggle-external.sh enable|disable magic
|
# Used by: lib/toggle-external.sh enable|disable magic
|
||||||
# Get a key at: https://21st.dev/magic (dashboard → API keys)
|
# Get a key at: https://21st.dev/magic (dashboard → API keys)
|
||||||
MAGIC_API_KEY=your_21st_dev_magic_api_key_here
|
MAGIC_API_KEY=your_21st_dev_magic_api_key_here
|
||||||
|
|
||||||
|
# ── Google SEO data layer (lib/seo-data) — used by /seo FULL ──
|
||||||
|
# OAuth Desktop client: GCP console → APIs & Services → Credentials → OAuth client (Desktop).
|
||||||
|
# Scope requested at consent: webmasters.readonly. One-time setup: make seo-connect
|
||||||
|
GOOGLE_OAUTH_CLIENT_ID=<your-client-id.apps.googleusercontent.com>
|
||||||
|
GOOGLE_OAUTH_CLIENT_SECRET=<your-client-secret>
|
||||||
|
# CrUX + PageSpeed API key (GCP console → Credentials → API key, restricted to those APIs).
|
||||||
|
# Get it: https://developer.chrome.com/docs/crux/api
|
||||||
|
CRUX_API_KEY=<your-crux-api-key>
|
||||||
|
|||||||
@@ -113,6 +113,11 @@ install-*.log
|
|||||||
.env.*
|
.env.*
|
||||||
!.env.example
|
!.env.example
|
||||||
|
|
||||||
|
# seo-data engine local artifacts (live under ~/.claude, never committed)
|
||||||
|
.venv-seo-data/
|
||||||
|
seo-data/tokens.json
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|||||||
@@ -34,4 +34,7 @@ paths = [
|
|||||||
# for stray COPIES of secrets outside this file; flagging the vault
|
# for stray COPIES of secrets outside this file; flagging the vault
|
||||||
# itself on every run is pure noise, not signal.
|
# itself on every run is pure noise, not signal.
|
||||||
'''(^|/)\.env$''',
|
'''(^|/)\.env$''',
|
||||||
|
# seo-data OAuth token store — legitimate local secret (like ~/.claude/.env),
|
||||||
|
# 0600, outside git. Allowlisted so `make scan-secrets` doesn't flag the vault.
|
||||||
|
'''(^|/)\.claude/seo-data/tokens\.json$''',
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: help install plugin link doctor update new-skill profile profile-list profile-current profile-reset onboard test scan-secrets
|
.PHONY: help install plugin link doctor update new-skill profile profile-list profile-current profile-reset onboard test scan-secrets seo-connect
|
||||||
|
|
||||||
help: ## Show available commands
|
help: ## Show available commands
|
||||||
@grep -E '^[a-zA-Z_-]+:.*##' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " make %-14s %s\n", $$1, $$2}'
|
@grep -E '^[a-zA-Z_-]+:.*##' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " make %-14s %s\n", $$1, $$2}'
|
||||||
@@ -22,8 +22,14 @@ onboard: link ## Onboard an existing project (run from the project directory)
|
|||||||
@echo "Open Claude Code in your project directory and run: /onboard"
|
@echo "Open Claude Code in your project directory and run: /onboard"
|
||||||
@echo "Or with hints: /onboard Python FastAPI monorepo"
|
@echo "Or with hints: /onboard Python FastAPI monorepo"
|
||||||
|
|
||||||
|
seo-connect: ## Connect a Google account for /seo FULL (creates venv, OAuth consent)
|
||||||
|
@python3 -m venv "$$HOME/.claude/.venv-seo-data"
|
||||||
|
@"$$HOME/.claude/.venv-seo-data/bin/pip" install -q -r lib/seo-data/requirements.txt
|
||||||
|
@bash -c 'read -r -p "Label for this account (e.g. client-a): " label; \
|
||||||
|
"$$HOME/.claude/.venv-seo-data/bin/python3" lib/seo-data/connect.py --label "$$label"'
|
||||||
|
|
||||||
test: ## Run deterministic tests (lib/tests/*.test.sh + lib/gitflow-test.sh + lib/tests/run-*.sh)
|
test: ## Run deterministic tests (lib/tests/*.test.sh + lib/gitflow-test.sh + lib/tests/run-*.sh)
|
||||||
@fail=0; for t in lib/tests/*.test.sh lib/gitflow-test.sh lib/tests/run-*.sh; do \
|
@fail=0; for t in lib/tests/*.test.sh lib/seo-data/*.test.sh lib/gitflow-test.sh lib/tests/run-*.sh; do \
|
||||||
echo "== $$t"; \
|
echo "== $$t"; \
|
||||||
case "$$(basename "$$t")" in \
|
case "$$(basename "$$t")" in \
|
||||||
run-release-candidate.sh) RC_WORK=$$(mktemp -d) RC_TAG=1 bash "$$t" || fail=1 ;; \
|
run-release-candidate.sh) RC_WORK=$$(mktemp -d) RC_TAG=1 bash "$$t" || fail=1 ;; \
|
||||||
|
|||||||
@@ -400,6 +400,21 @@ fi
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# ── seo-data (GSC/CrUX data layer) — non-fatal ──
|
||||||
|
ENVF="$HOME/.claude/.env"
|
||||||
|
if grep -qE '^[[:space:]]*(export[[:space:]]+)?CRUX_API_KEY=.' "$ENVF" 2>/dev/null; then
|
||||||
|
pass "seo-data: CRUX_API_KEY present"
|
||||||
|
else
|
||||||
|
warn "seo-data: CRUX_API_KEY absent in ~/.claude/.env — /seo FULL falls back to lab PageSpeed"
|
||||||
|
fi
|
||||||
|
STORE="$HOME/.claude/seo-data/tokens.json"
|
||||||
|
if [ -f "$STORE" ]; then
|
||||||
|
N=$(python3 "$REPO/lib/seo-data/tokenstore.py" list --file "$STORE" 2>/dev/null | grep -o '"label"' | wc -l)
|
||||||
|
pass "seo-data: $N Google account(s) connected"
|
||||||
|
else
|
||||||
|
warn "seo-data: no Google account connected (run: make seo-connect) — GSC data disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
# ────────────────────────────────────────────────────────────
|
# ────────────────────────────────────────────────────────────
|
||||||
# Summary
|
# Summary
|
||||||
# ────────────────────────────────────────────────────────────
|
# ────────────────────────────────────────────────────────────
|
||||||
|
|||||||
+10
@@ -106,6 +106,16 @@ echo ""
|
|||||||
echo "── Setting up symlinks..."
|
echo "── Setting up symlinks..."
|
||||||
bash "$REPO/link.sh"
|
bash "$REPO/link.sh"
|
||||||
|
|
||||||
|
# ── 5b. Optional: connect a Google account for /seo FULL ──
|
||||||
|
echo ""
|
||||||
|
if [ -f "$HOME/.claude/seo-data/tokens.json" ]; then
|
||||||
|
ok "seo-data: a Google account is already connected"
|
||||||
|
else
|
||||||
|
info "SEO data layer (GSC + CrUX) is optional. To enable real Search Console"
|
||||||
|
info "data in /seo FULL: add GOOGLE_OAUTH_* + CRUX_API_KEY to ~/.claude/.env,"
|
||||||
|
info "then run: make seo-connect"
|
||||||
|
fi
|
||||||
|
|
||||||
# ── 6. Install plugins ──
|
# ── 6. Install plugins ──
|
||||||
echo ""
|
echo ""
|
||||||
echo "── Installing plugins..."
|
echo "── Installing plugins..."
|
||||||
|
|||||||
@@ -106,6 +106,17 @@ has "connect.persist wrote prop" "$L3" 'sc-domain:x.com'
|
|||||||
hasnt "connect.persist redacts" "$L3" 'RT_X'
|
hasnt "connect.persist redacts" "$L3" 'RT_X'
|
||||||
rm -rf "$TMP3"
|
rm -rf "$TMP3"
|
||||||
|
|
||||||
|
echo "── wiring locks ──"
|
||||||
|
tf() { if grep -qF -- "$3" "$2" 2>/dev/null; then ok "$1"; else no "$1" "missing: $3"; fi; }
|
||||||
|
tf "env.example client id" "$REPO/.env.example" "GOOGLE_OAUTH_CLIENT_ID="
|
||||||
|
tf "env.example crux key" "$REPO/.env.example" "CRUX_API_KEY="
|
||||||
|
tf "makefile seo-connect" "$REPO/Makefile" "seo-connect:"
|
||||||
|
tf "makefile discovers test" "$REPO/Makefile" "lib/seo-data/*.test.sh"
|
||||||
|
tf "install prompts connect" "$REPO/install.sh" "make seo-connect"
|
||||||
|
tf "doctor checks seo-data" "$REPO/doctor.sh" "seo-data"
|
||||||
|
tf "gitleaks allowlist store" "$REPO/.gitleaks.toml" "seo-data/tokens"
|
||||||
|
tf "gitignore venv" "$REPO/.gitignore" ".venv-seo-data"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "seo-data engine: $PASS pass, $FAIL fail"
|
echo "seo-data engine: $PASS pass, $FAIL fail"
|
||||||
[ "$FAIL" -eq 0 ]
|
[ "$FAIL" -eq 0 ]
|
||||||
|
|||||||
Reference in New Issue
Block a user