Skill: bluebirdback/exec-clawhub-publish-doctor (version 1.0.1)

--- name: exec-clawhub-publish-doctor description: "Diagnose and mitigate exec-related tooling failures around ClawHub publishing and GitHub CLI queries (auth, browser-login, missing dependencies, pending security-scan visibility errors, wrong profile/skill URLs, and gh JSON-field mismatch errors like Unknown JSON field). Use when publishing skills to ClawHub fails, inspect reports temporary errors, or GitHub CLI search commands fail due to field schema differences." --- # Exec ClawHub Publish Doctor Stabilize ClawHub publishing with preflight checks, safer publish commands, and post-publish verification that tolerates temporary registry states. ## Quick workflow 1. Run preflight checks: - `scripts/clawhub_preflight.sh` 2. If login/browser issues appear, follow `references/error-map.md`. 3. Publish with retry-aware verification: - `scripts/clawhub_publish_safe.sh <skill_path> <slug> <name> <version> [changelog]` 4. For GitHub search failures like `Unknown JSON field`, use: - `scripts/gh_search_repos_safe.sh "<query>" [limit]` 5. If errors persist, classify with `references/error-map.md` before escalating. ## Standard commands ### Preflight ```bash bash scripts/clawhub_preflight.sh ``` ### Login (token-based, headless-safe) ```bash clawhub login --token <clh_token> clawhub whoami ``` ### Safe publish ```bash bash scripts/clawhub_publish_safe.sh ./my-skill my-skill "My Skill" 1.0.0 "Initial release" ``` ### Manual inspect ```bash clawhub inspect my-skill --json ``` ### Safe GitHub repo search (schema-aware) ```bash bash scripts/gh_search_repos_safe.sh "safe-exec skill" 15 ``` ## Rules - Prefer token login in server/headless environments. - Treat `inspect` errors right after publish as potentially transient for a few minutes. - Verify with both CLI (`clawhub inspect`) and web URL (`/skills/<slug>`). - For `gh search repos --json` failures, prefer `fullName` over unsupported aliases like `nameWithOwner`, or run `scripts/gh_search_repos_safe.sh`. - Use canonical URLs: - Skill: `https://clawhub.ai/skills/<slug>` - Owner/slug: `https://clawhub.ai/<handle>/<slug>` - User profile (if available): `https://clawhub.ai/users/<handle>` ## Resources - `references/error-map.md`: quick diagnosis for common failure signatures. - `scripts/clawhub_preflight.sh`: dependency + environment checks. - `scripts/clawhub_publish_safe.sh`: publish + retry verification wrapper. - `scripts/gh_search_repos_safe.sh`: resilient `gh search repos` wrapper with JSON-field mismatch fallback.

path: references/error-map.md
content: # ClawHub Publish Error Map

Use this to quickly classify failures before taking action.

## 1) Browser login fails with `spawn xdg-open ENOENT`

**Cause:** GUI opener not available on headless/server environment.

**Fix options:**
- Preferred: `clawhub login --token <clh_token>`
- Optional: install `xdg-utils`

## 2) `Error: Not logged in. Run: clawhub login`

**Cause:** No stored auth token (or logged out).

**Fix:**
- `clawhub login --token <clh_token>`
- Verify: `clawhub whoami`

## 3) `inspect` says hidden/pending scan or not found right after publish

**Cause:** Newly published skills may be temporarily hidden while security scan indexes.

**Fix:**
- Retry inspect with backoff for a few minutes.
- Confirm web route: `https://clawhub.ai/skills/<slug>`

## 4) Profile URL says not found

**Cause:** Route mismatch/quirk.

**Fix:**
- Use canonical skill links: `/skills/<slug>`
- Use owner+slug link: `/<handle>/<slug>`
- Try `/users/<handle>` for profile pages.

## 5) `rg: command not found`

**Cause:** ripgrep missing.

**Fix:**
- Install ripgrep or use `grep` fallback.

## 6) Mixed `clawhub` vs `clawdhub`

**Cause:** Legacy CLI binary conflict/old install.

**Fix:**
- Standardize on `clawhub`.
- If needed, reinstall: `npm i -g clawhub --force`

## 7) `gh search repos ... --json ...` fails with `Unknown JSON field: nameWithOwner`

**Cause:** GitHub CLI JSON schema mismatch; `nameWithOwner` is not a valid field for this command/version.

**Fix:**
- Replace `nameWithOwner` with `fullName`
- Or run schema-aware wrapper:
  - `bash scripts/gh_search_repos_safe.sh "<query>" <limit>`

## 8) Non-transient publish failures (permission/moderation/validation)

**Symptoms:**
- Consistent error after retries
- Explicit auth/permission/validation message

**Fix:**
- Verify account owner with `clawhub whoami`
- Check slug ownership and version bump
- Re-run publish with corrected slug/version


path: scripts/clawhub_preflight.sh
content: #!/usr/bin/env bash
set -euo pipefail

ok() { printf '✔ %s\n' "$*"; }
warn() { printf '⚠ %s\n' "$*"; }

if command -v clawhub >/dev/null 2>&1; then
  ok "clawhub found: $(clawhub --cli-version 2>/dev/null || echo 'unknown version')"
else
  warn "clawhub not found. Install: npm i -g clawhub"
fi

if command -v clawdhub >/dev/null 2>&1; then
  warn "legacy clawdhub binary also present (possible confusion). Prefer clawhub."
fi

if command -v xdg-open >/dev/null 2>&1; then
  ok "xdg-open available (browser login should work)"
else
  warn "xdg-open missing. Browser login may fail on this host; use token login: clawhub login --token <clh_token>"
fi

if command -v rg >/dev/null 2>&1; then
  ok "ripgrep available"
else
  warn "ripgrep missing (optional). Install for faster diagnostics."
fi

if command -v gh >/dev/null 2>&1; then
  ok "gh CLI available"
else
  warn "gh CLI missing. Install if you need GitHub search/repo diagnostics."
fi

if command -v clawhub >/dev/null 2>&1; then
  if clawhub whoami >/tmp/clawhub_whoami.txt 2>/tmp/clawhub_whoami.err; then
    ok "authenticated with clawhub"
  else
    warn "not authenticated. Run: clawhub login --token <clh_token>"
  fi
fi


path: scripts/clawhub_publish_safe.sh
content: #!/usr/bin/env bash
set -euo pipefail

usage() {
  cat <<'EOF'
Usage:
  clawhub_publish_safe.sh <skill_path> <slug> <name> <version> [changelog]

Example:
  clawhub_publish_safe.sh ./skills/my-skill my-skill "My Skill" 1.0.0 "Initial release"
EOF
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
  usage
  exit 0
fi

if [[ $# -lt 4 ]]; then
  usage
  exit 2
fi

SKILL_PATH="$1"
SLUG="$2"
NAME="$3"
VERSION="$4"
CHANGELOG="${5:-Auto publish via exec-clawhub-publish-doctor}"
MAX_RETRIES="${MAX_RETRIES:-12}"
SLEEP_SECONDS="${SLEEP_SECONDS:-10}"

if ! command -v clawhub >/dev/null 2>&1; then
  echo "ERROR: clawhub not found. Install: npm i -g clawhub" >&2
  exit 3
fi

if ! clawhub whoami >/tmp/clawhub_publish_whoami.out 2>/tmp/clawhub_publish_whoami.err; then
  echo "ERROR: Not logged in. Run: clawhub login --token <clh_token>" >&2
  exit 4
fi

echo "Publishing ${SLUG}@${VERSION}..."
clawhub publish "$SKILL_PATH" \
  --slug "$SLUG" \
  --name "$NAME" \
  --version "$VERSION" \
  --changelog "$CHANGELOG" \
  --tags latest

echo "Verifying with retry (inspect may be temporarily hidden during security scan)..."
for ((i=1; i<=MAX_RETRIES; i++)); do
  if OUT=$(clawhub inspect "$SLUG" --json 2>&1); then
    echo "$OUT"
    echo "OK: ${SLUG} is inspectable."
    exit 0
  fi

  if echo "$OUT" | grep -qiE 'hidden while security scan is pending|Skill not found'; then
    echo "Attempt ${i}/${MAX_RETRIES}: still pending visibility. Waiting ${SLEEP_SECONDS}s..."
    sleep "$SLEEP_SECONDS"
    continue
  fi

  echo "ERROR: Non-transient inspect failure:" >&2
  echo "$OUT" >&2
  exit 5
done

echo "WARN: Published, but inspect is still pending after retries." >&2
echo "Check: https://clawhub.ai/skills/${SLUG}" >&2
exit 0


path: scripts/gh_search_repos_safe.sh
content: #!/usr/bin/env bash
set -euo pipefail

usage() {
  cat <<'EOF'
Usage:
  gh_search_repos_safe.sh <query> [limit]

Env overrides:
  GH_FIELDS   comma-separated JSON fields for gh search repos

Examples:
  gh_search_repos_safe.sh "safe-exec skill" 15
  GH_FIELDS="nameWithOwner,url,description" gh_search_repos_safe.sh "clawhub doctor" 10
EOF
}

if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
  usage
  exit 0
fi

if [[ $# -lt 1 ]]; then
  usage
  exit 2
fi

QUERY="$1"
LIMIT="${2:-15}"
FIELDS="${GH_FIELDS:-fullName,url,description,stargazersCount,updatedAt}"

if ! command -v gh >/dev/null 2>&1; then
  echo "ERROR: gh CLI not found. Install GitHub CLI first." >&2
  exit 3
fi

# common alias fix for older snippets
FIELDS="${FIELDS//nameWithOwner/fullName}"

run_search() {
  local fields="$1"
  gh search repos "$QUERY" --limit "$LIMIT" --json "$fields"
}

set +e
OUT=$(run_search "$FIELDS" 2>&1)
EC=$?
set -e

if [[ $EC -eq 0 ]]; then
  echo "$OUT"
  exit 0
fi

if ! grep -qi "Unknown JSON field" <<<"$OUT"; then
  echo "$OUT" >&2
  exit $EC
fi

echo "WARN: JSON field mismatch detected. Attempting fallback field set..." >&2

AVAILABLE=$(awk '
  /Available fields:/ {capture=1; next}
  capture && NF==0 {capture=0}
  capture {gsub(/^ +/, "", $0); if ($1 ~ /^[a-zA-Z]/) print $1}
' <<<"$OUT" | tr '\n' ',' | sed 's/,$//')

if [[ -z "$AVAILABLE" ]]; then
  FALLBACK="fullName,url,description,stargazersCount,updatedAt"
else
  declare -a WANT=(fullName url description stargazersCount updatedAt)
  FALLBACK=""
  for f in "${WANT[@]}"; do
    if grep -qE "(^|,)$f(,|$)" <<<"$AVAILABLE"; then
      FALLBACK+="$f,"
    fi
  done
  FALLBACK="${FALLBACK%,}"
  if [[ -z "$FALLBACK" ]]; then
    FALLBACK="$(cut -d',' -f1-5 <<<"$AVAILABLE")"
  fi
fi

set +e
OUT2=$(run_search "$FALLBACK" 2>&1)
EC2=$?
set -e

if [[ $EC2 -eq 0 ]]; then
  echo "INFO: Fallback fields used: $FALLBACK" >&2
  echo "$OUT2"
  exit 0
fi

echo "$OUT2" >&2
exit $EC2


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)