feat: add /wiki-compile skill + Syncro live-check in /wiki-lint
/wiki-compile: new skill that seeds or refreshes wiki client articles from session logs and live Syncro PSA data. - Three modes: seed (new article), refresh (surgical update), full (--full flag) - Syncro enrichment for client targets: customer profile, contacts, open tickets, recent invoices, asset count - Ambiguous customer search: pause and ask user to pick - Customer not found: graceful warn + continue with session logs only - Syncro is authoritative for all billing fields (hours, rate, contract type) - Refresh mode: surgical edits only (hours, active tickets, frontmatter) - Seed/full: Ollama qwen3:14b synthesis; Claude-direct fallback - Asset count in Profile only — no asset detail tables in wiki - Commits and pushes after write /wiki-lint: add Step 6 — Syncro Live-Check - Pulls live prepay_hours for every client article with a Syncro customer ID - Auto-fixes stale hours in place; commits fixes in one batch - Flags articles with open tickets and stale compiled date for review - Adds Syncro section to lint report output Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,86 @@ Read the `## Compilation Queue` section in `wiki/index.md`. For each entry:
|
||||
|
||||
---
|
||||
|
||||
## Step 6 — Syncro Live-Check (Client Articles, Auto-Fix)
|
||||
|
||||
For every client wiki article that contains a `Syncro customer ID` line, pull live billing data from Syncro and auto-fix stale values in place. This step runs silently — no user confirmation needed. Fixes are committed at the end.
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
BASE="https://computerguru.syncromsp.com/api/v1"
|
||||
USER_ID=$(jq -r '.user // empty' "$CLAUDETOOLS_ROOT/.claude/identity.json")
|
||||
case "$USER_ID" in
|
||||
mike) API_KEY="T259810e5c9917386b-52c2aeea7cdb5ff41c6685a73cebbeb3" ;;
|
||||
howard) API_KEY="Tde5174a6e9e312d14-02fd5bfe0f0ee40c87d027507c680e18" ;;
|
||||
*) echo "[SYNCRO] No API key for user '$USER_ID' — skipping Step 6" ; exit 0 ;;
|
||||
esac
|
||||
```
|
||||
|
||||
### For Each Client Article
|
||||
|
||||
```bash
|
||||
for ARTICLE in wiki/clients/*.md; do
|
||||
SLUG=$(basename "$ARTICLE" .md)
|
||||
|
||||
# Extract Syncro customer ID — skip if not documented
|
||||
CUST_ID=$(grep -oP '(?<=\*\*Syncro customer ID:\*\* )\d+' "$ARTICLE" 2>/dev/null)
|
||||
[ -z "$CUST_ID" ] && continue
|
||||
|
||||
# Pull live customer data
|
||||
CUST=$(curl -s "$BASE/customers/${CUST_ID}?api_key=$API_KEY" | jq '.customer')
|
||||
[ -z "$CUST" ] && echo "[SYNCRO][WARNING] $SLUG — API returned empty for customer $CUST_ID" && continue
|
||||
|
||||
LIVE_HOURS=$(echo "$CUST" | jq -r '.prepay_hours // "0"')
|
||||
TODAY=$(date +%Y-%m-%d)
|
||||
|
||||
# --- Fix 1: Hours remaining ---
|
||||
# Extract current wiki value (match pattern: "X.X hrs as of")
|
||||
WIKI_HOURS=$(grep -oP '[\d.]+ hrs as of' "$ARTICLE" | grep -oP '[\d.]+' | head -1)
|
||||
|
||||
if [ -n "$WIKI_HOURS" ] && [ "$WIKI_HOURS" != "$LIVE_HOURS" ]; then
|
||||
# Replace the Hours remaining line with live value
|
||||
sed -i "s/\*\*Hours remaining[^:]*:\*\*[^\n]*/\*\*Hours remaining (if prepaid):\*\* ${LIVE_HOURS} hrs as of ${TODAY} (Syncro live)/" "$ARTICLE"
|
||||
echo "[SYNCRO][FIXED] $SLUG — hours: wiki=${WIKI_HOURS} → Syncro=${LIVE_HOURS}"
|
||||
SYNCRO_FIXES+=("$SLUG: hours ${WIKI_HOURS} → ${LIVE_HOURS}")
|
||||
fi
|
||||
|
||||
# --- Check 2: Open ticket count (flag only, no auto-fix) ---
|
||||
OPEN_COUNT=$(curl -s "$BASE/tickets?customer_id=${CUST_ID}&status=New,In+Progress,Scheduled,Waiting+on+Customer&per_page=1&api_key=$API_KEY" | jq '.meta.total_count // (.tickets | length)')
|
||||
# Flag if article was compiled > 7 days ago and open ticket count changed
|
||||
COMPILED=$(grep -oP '(?<=last_compiled: )[\d-]+' "$ARTICLE")
|
||||
COMPILED_AGE=$(( ( $(date +%s) - $(date -d "$COMPILED" +%s 2>/dev/null || echo 0) ) / 86400 ))
|
||||
if [ "$COMPILED_AGE" -gt 7 ] && [ "$OPEN_COUNT" -gt 0 ]; then
|
||||
SYNCRO_TICKET_FLAGS+=("[TICKETS_CHECK] $SLUG — $OPEN_COUNT open ticket(s) in Syncro; article compiled ${COMPILED_AGE}d ago")
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### Commit Fixes (if any)
|
||||
|
||||
```bash
|
||||
if [ ${#SYNCRO_FIXES[@]} -gt 0 ]; then
|
||||
cd "$CLAUDETOOLS_ROOT"
|
||||
git add wiki/clients/*.md
|
||||
git commit -m "wiki-lint: Syncro live-check auto-fix (${#SYNCRO_FIXES[@]} article(s))"
|
||||
git push origin main
|
||||
fi
|
||||
```
|
||||
|
||||
### Add to Lint Report
|
||||
|
||||
Append to the report output:
|
||||
|
||||
```
|
||||
### Syncro Live-Check (N auto-fixed, M flagged)
|
||||
[SYNCRO][FIXED] cascades-tucson — hours: 37.5 → 31.0 (Syncro live as of YYYY-MM-DD)
|
||||
[TICKETS_CHECK] valleywide — 2 open ticket(s) in Syncro; article compiled 14d ago
|
||||
```
|
||||
|
||||
If API key is missing or Syncro is unreachable, emit `[SYNCRO] Skipped (API unavailable)` and continue.
|
||||
|
||||
---
|
||||
|
||||
## Output Format
|
||||
|
||||
Emit a clean lint report:
|
||||
@@ -116,11 +196,17 @@ Emit a clean lint report:
|
||||
[QUEUE_STALE] client:birthbiologic — wiki/clients/birth-biologic.md exists; remove from queue
|
||||
...
|
||||
|
||||
### Syncro Live-Check (N auto-fixed, M flagged)
|
||||
[SYNCRO][FIXED] cascades-tucson — hours: 37.5 → 31.0 (Syncro live)
|
||||
[TICKETS_CHECK] valleywide — 2 open ticket(s); article compiled 14d ago
|
||||
...
|
||||
|
||||
### Summary
|
||||
- N missing articles → run /wiki-compile for each
|
||||
- N stale articles → run /wiki-compile to refresh
|
||||
- N broken links → fix manually or after recompile
|
||||
- N index gaps → update wiki/index.md
|
||||
- N Syncro hours auto-fixed, M ticket flags for review
|
||||
```
|
||||
|
||||
After the report, ask: "Run /wiki-compile for any of the missing articles now?"
|
||||
|
||||
Reference in New Issue
Block a user