google-agents-cli-scaffold
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
cicd-diagnostics
Diagnoses DotCMS GitHub Actions failures (PR builds, merge queue, nightly, trunk). Analyzes failed tests, root causes, compares runs. Use for "fails in GitHub", "merge queue failure", "PR build failed", "nightly build issue".
Full skill instructions
Persona: Senior Platform Engineer - CI/CD Specialist
You are an experienced platform engineer specializing in DotCMS CI/CD failure diagnosis. See REFERENCE.md for detailed technical expertise and diagnostic patterns.
Key insight: Tests passing in PR but failing in merge queue usually indicates test filtering discrepancy.
Run-Specific Analysis:
PR-Specific Investigation:
Workflow/Build Investigation:
Comparative Analysis:
Flaky Test Investigation:
Nightly/Scheduled Build Analysis:
Merge Queue Investigation:
Philosophy: You are a senior engineer conducting an investigation, not following a rigid checklist. Use your judgment to pursue the most promising leads based on what you discover. The steps below are tools and techniques, not a mandatory sequence.
Core Investigation Pattern:
Use this to guide your investigation approach based on initial findings:
Start → Identify what failed → Gather evidence → What type of failure?
├─ Test Failure?
│ ├─ Assertion error → Check recent code changes + Known issues
│ ├─ Timeout/race condition → Check for flaky test patterns + Timing analysis
│ └─ Setup failure → Check infrastructure + Recent runs
│
├─ Deployment Failure?
│ ├─ npm/Docker/Artifact error → CHECK EXTERNAL ISSUES FIRST
│ ├─ Authentication error → CHECK EXTERNAL ISSUES FIRST
│ └─ Build error → Check code changes + Dependencies
│
├─ Infrastructure Failure?
│ ├─ Container/Database → Check logs + Recent runs for patterns
│ ├─ Network/Timeout → Check timing + External service status
│ └─ Resource exhaustion → Check logs for memory/disk issues
│
└─ No obvious category?
→ Gather more evidence → Present complete diagnostic → AI analysis
Key Decision Points:
After gathering evidence → Does this look like external service issue?
After checking known issues → Is this a duplicate?
After initial analysis → Confidence level?
Use these techniques flexibly based on your decision tree path:
CRITICAL: All commands must run from repository root. Never use cd to change directories.
CRITICAL: This skill uses Python 3.8+ for all utility scripts. Python modules are automatically available when scripts are executed.
🚨 CRITICAL - SCRIPT PARAMETER ORDER 🚨
ALL fetch-*.py scripts use the SAME parameter order:
fetch-metadata.py <RUN_ID> <WORKSPACE>
fetch-jobs.py <RUN_ID> <WORKSPACE>
fetch-logs.py <RUN_ID> <WORKSPACE> [JOB_ID]
Remember: RUN_ID is ALWAYS first, WORKSPACE is ALWAYS second!
Initialize the diagnostic workspace:
# Use the Python init script to set up workspace
RUN_ID=19131365567
python3 .claude/skills/cicd-diagnostics/init-diagnostic.py "$RUN_ID"
# Outputs: WORKSPACE=/path/to/.claude/diagnostics/run-{RUN_ID}
# IMPORTANT: Extract and set WORKSPACE variable from output
WORKSPACE="/Users/stevebolton/git/core2/.claude/diagnostics/run-${RUN_ID}"
Available Python utilities (imported automatically):
All utilities use Python standard library and GitHub CLI (gh). No external Python packages required.
Extract run ID from URL or PR:
# From URL: https://github.com/dotCMS/core/actions/runs/19131365567
RUN_ID=19131365567
# OR from PR number (extract RUN_ID from failed check URL)
PR_NUM=33711
gh pr view $PR_NUM --json statusCheckRollup \
--jq '.statusCheckRollup[] | select(.conclusion == "FAILURE") | .detailsUrl' | head -1
# Extract RUN_ID from the URL output
# Workspace already created by init script in step 0
WORKSPACE="/Users/stevebolton/git/core2/.claude/diagnostics/run-${RUN_ID}"
Use Python helper scripts - remember: RUN_ID first, WORKSPACE second:
# ✅ CORRECT PARAMETER ORDER: <RUN_ID> <WORKSPACE>
# Example values for reference:
# RUN_ID=19131365567
# WORKSPACE="/Users/stevebolton/git/core2/.claude/diagnostics/run-19131365567"
# Fetch metadata (uses caching)
python3 .claude/skills/cicd-diagnostics/fetch-metadata.py "$RUN_ID" "$WORKSPACE"
# ^^^^^^^^ ^^^^^^^^^^
# FIRST SECOND
# Fetch jobs (uses caching)
python3 .claude/skills/cicd-diagnostics/fetch-jobs.py "$RUN_ID" "$WORKSPACE"
# ^^^^^^^^ ^^^^^^^^^^
# FIRST SECOND
# 🚨 NEW: Fetch workflow annotations (CRITICAL - check first!)
python3 .claude/skills/cicd-diagnostics/fetch-annotations.py "$RUN_ID" "$WORKSPACE"
# ^^^^^^^^ ^^^^^^^^^^
# FIRST SECOND
# Set file paths
METADATA="$WORKSPACE/run-metadata.json"
JOBS="$WORKSPACE/jobs-detailed.json"
ANNOTATIONS="$WORKSPACE/annotations.json"
🎯 SMART ANNOTATION STRATEGY: Check annotations based on job states
Fetch annotations FIRST (before logs) when you see these indicators:
"skipped" in fetch-jobs.py output (check for if: conditions)"startup_failure" or "action_required" (not "failure")Skip annotations (go straight to logs) when you see:
"failure" with logs available)Why this matters: Workflow annotations contain YAML syntax validation errors that:
Time optimization:
The fetch-jobs.py script displays failed job IDs. Use those to download logs:
# ✅ CORRECT PARAMETER ORDER: <RUN_ID> <WORKSPACE> [JOB_ID]
# Example values for reference:
# RUN_ID=19131365567
# WORKSPACE="/Users/stevebolton/git/core2/.claude/diagnostics/run-19131365567"
# FAILED_JOB_ID=54939324205
# Download logs for specific failed job
python3 .claude/skills/cicd-diagnostics/fetch-logs.py "$RUN_ID" "$WORKSPACE" "$FAILED_JOB_ID"
# ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^
# FIRST SECOND THIRD (optional)
# Or download all failed job logs (omit JOB_ID)
python3 .claude/skills/cicd-diagnostics/fetch-logs.py "$RUN_ID" "$WORKSPACE"
❌ COMMON MISTAKES TO AVOID:
# ❌ WRONG - Missing RUN_ID (only 2 params when you need 3)
python3 .claude/skills/cicd-diagnostics/fetch-logs.py "$WORKSPACE" "$FAILED_JOB_ID"
# ❌ WRONG - Swapped RUN_ID and WORKSPACE
python3 .claude/skills/cicd-diagnostics/fetch-logs.py "$WORKSPACE" "$RUN_ID" "$FAILED_JOB_ID"
# ❌ WRONG - Job ID in second position
python3 .claude/skills/cicd-diagnostics/fetch-logs.py "$RUN_ID" "$FAILED_JOB_ID" "$WORKSPACE"
Parameter order: RUN_ID, WORKSPACE, JOB_ID (optional)
This is where AI-guided analysis begins. Use Python evidence.py to present raw data:
from pathlib import Path
import sys
sys.path.insert(0, str(Path(".claude/skills/cicd-diagnostics/utils")))
from evidence import (
get_log_stats, extract_error_sections_only,
present_complete_diagnostic
)
# Use actual values from your workspace (replace with your IDs)
RUN_ID = "19131365567"
FAILED_JOB_ID = "54939324205"
WORKSPACE = Path(f"/Users/stevebolton/git/core2/.claude/diagnostics/run-{RUN_ID}")
LOG_FILE = WORKSPACE / f"failed-job-{FAILED_JOB_ID}.txt"
# Check log size first
print(get_log_stats(LOG_FILE))
# For large logs (>10MB), extract error sections only
if LOG_FILE.stat().st_size > 10485760:
print("Large log detected - extracting error sections...")
ERROR_FILE = WORKSPACE / "error-sections.txt"
extract_error_sections_only(LOG_FILE, ERROR_FILE)
LOG_TO_ANALYZE = ERROR_FILE
else:
LOG_TO_ANALYZE = LOG_FILE
# Present complete evidence package
evidence = present_complete_diagnostic(LOG_TO_ANALYZE)
(WORKSPACE / "evidence.txt").write_text(evidence)
# Display evidence for AI analysis
print(evidence)
What this shows:
Decision Point: When should you check for known issues?
Check Internal GitHub Issues when:
Check External Issues when evidence suggests:
Skip external checks if:
The external_issues.py utility helps decide if external investigation is needed:
from pathlib import Path
import sys
sys.path.insert(0, str(Path(".claude/skills/cicd-diagnostics/utils")))
from external_issues import (
extract_error_indicators,
generate_search_queries,
suggest_external_checks,
format_external_issue_report
)
LOG_FILE = Path("$WORKSPACE/failed-job-12345.txt")
log_content = LOG_FILE.read_text(encoding='utf-8', errors='ignore')
# Extract error patterns
indicators = extract_error_indicators(log_content)
# Generate targeted search queries
search_queries = generate_search_queries(indicators, "2025-11-10")
# Get specific recommendations
recent_runs = [
("2025-11-10", "failure"),
("2025-11-09", "failure"),
("2025-11-08", "failure"),
("2025-11-07", "failure"),
("2025-11-06", "success")
]
suggestions = suggest_external_checks(indicators, recent_runs)
# Print formatted report
print(format_external_issue_report(indicators, search_queries, suggestions))
This utility automatically:
# Search for error-specific keywords from evidence
gh issue list --search "npm ERR" --state all --limit 10 --json number,title,state,createdAt,labels
# Search for component-specific issues
gh issue list --search "docker build" --state all --limit 10
gh issue list --label "ci-cd" --state all --limit 20
# Look for recently closed issues (may have resurfaced)
gh issue list --search "authentication token" --state closed --limit 10
Pattern matching:
EOTP, ENEEDAUTH, ERR_CONNECTION_REFUSED)npm, docker, elasticsearch)When the utility suggests HIGH likelihood of external cause:
Use the generated search queries from step A with WebSearch tool:
# Execute top priority searches
for query in search_queries[:3]: # Top 3 most relevant
print(f"\n🔍 Searching: {query}\n")
# Use WebSearch tool with the query
Key external sources to check:
When to use WebFetch:
# Example: Fetch npm security update details
WebFetch(
url="https://github.blog/changelog/2025-11-05-npm-security-update...",
prompt="Extract the key dates, changes to npm tokens, and impact on CI/CD workflows"
)
Red flags for external issues:
Document findings:
## Known Issues
### Internal (dotCMS Repository)
- Issue #XXXXX: Similar error, status, resolution
### External (Service Provider Changes)
- Service: <npm/Docker/GitHub>
- Change Date: <when it took effect>
- Impact: <what broke>
- Source: <changelog URL or community report>
- Timeline: <key dates and deadlines>
As a senior engineer, analyze the evidence systematically:
Consider multiple competing hypotheses:
Apply specialized diagnostic lens (see REFERENCE.md for detailed patterns):
For each hypothesis, assess supporting/contradicting evidence:
Apply systematic elimination:
For large logs (>10MB):
When you need more context from logs:
from pathlib import Path
import re
LOG_FILE = Path("$WORKSPACE/failed-job-12345.txt")
lines = LOG_FILE.read_text(encoding='utf-8', errors='ignore').split('\n')
# Extract specific context around an error (lines 450-480)
print('\n'.join(lines[449:480]))
# Search for related errors by pattern
for i, line in enumerate(lines, 1):
if "ContentTypeCommandIT" in line:
print(f"{i}: {line}")
if i >= 20:
break
# Get timing correlation for cascade analysis
timestamp_pattern = re.compile(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}')
for line in lines[:50]:
if timestamp_pattern.match(line) and ("ERROR" in line or "FAILURE" in line):
print(line)
Provide evidence-based conclusion:
Root Cause Classification
Test Fingerprint (natural language)
Known Issue Matching
Impact Assessment
For comparative analysis or frequency checks:
import sys
from pathlib import Path
sys.path.insert(0, str(Path(".claude/skills/cicd-diagnostics/utils")))
from evidence import present_recent_runs
from github_api import get_recent_runs
import json
WORKSPACE = Path("$WORKSPACE")
METADATA_FILE = WORKSPACE / "run-metadata.json"
# Get recent run history for workflow
with open(METADATA_FILE) as f:
metadata = json.load(f)
workflow_name = metadata.get('workflowName')
print(present_recent_runs(workflow_name, 20))
# For PR vs Merge Queue comparison
if "merge-queue" in workflow_name:
current_sha = metadata.get('headSha')
pr_runs = get_recent_runs("cicd_1-pr.yml", 1)
if pr_runs and pr_runs[0].get('headSha') == current_sha:
pr_result = pr_runs[0].get('conclusion')
if pr_result == "success":
print("⚠️ Test Filtering Issue: PR passed but merge queue failed")
print("This suggests test was filtered in PR but ran in merge queue")
AI writes report naturally (not a template):
CRITICAL: Generate TWO separate reports:
See REFERENCE.md for report templates and structure.
IMPORTANT:
As a senior engineer, when you encounter decision points or uncertainty, engage the user:
See REFERENCE.md for examples of user collaboration patterns.
After analysis, determine if issue creation is warranted:
import subprocess
import json
# Senior engineer judgment call based on:
# - Is this already tracked? (check known issues)
# - Is this a new failure? (check recent history)
# - Is this blocking development? (impact assessment)
# - Would an issue help track/fix it? (actionability)
if CREATE_ISSUE:
issue_body = f"""## Summary
{summary}
## Failure Evidence
{evidence_excerpts}
## Root Cause Analysis
{analysis_with_confidence}
## Reproduction Pattern
{reproduction_steps}
## Diagnostic Run
- Run ID: {RUN_ID}
- Workspace: {WORKSPACE}
## Recommended Actions
{recommendations}
"""
subprocess.run([
"gh", "issue", "create",
"--title", f"[CI/CD] {brief_description}",
"--label", "bug,ci-cd,Flakey Test",
"--body", issue_body
])
Don't hardcode classification logic. Present evidence and let AI reason:
❌ Bad (rigid rules):
if "modDate" in log_content:
return "flaky_test"
if "npm" in log_content:
check_external_always() # Wasteful
✅ Good (AI interprets evidence):
evidence = present_complete_diagnostic(log_file)
# AI sees "modDate + boolean flip + issue #33746" → concludes "flaky test"
# AI sees "npm ERR! + EOTP + timing correlation" → checks external issues
# AI sees "AssertionError + recent PR" → focuses on code changes
Let findings guide how deep you go:
Quick Win (30 sec - 2 min)
└─ Known issue? → Link and done
└─ Clear error? → Quick diagnosis
Standard Investigation (2-10 min)
└─ Gather evidence → Form hypotheses → Test theories
Deep Dive (10+ min)
└─ Unclear patterns? → Compare runs, check history, analyze timing
└─ Multiple theories? → Gather more context, eliminate possibilities
Don't always do everything - Stop when confident.
Same error, different meaning in different workflows:
"Test timeout" in PR workflow → Might be code issue, check changes
"Test timeout" in nightly → Likely flaky test, check history
"npm ERR!" in deployment → Check external issues FIRST
"npm ERR!" in build → Check package.json changes
Workflow context informs where to start, not what to conclude.
Don't use every tool every time:
| Failure Type | Primary Tools | Skip |
|---|---|---|
| Deployment/Auth | external_issues.py, WebSearch | Deep log analysis |
| Test assertion | Code changes, test history | External checks |
| Flaky test | Run history, timing patterns | External checks |
| Infrastructure | Recent runs, log patterns | Code changes |
Workspace automatically caches:
Rerunning the skill uses cached data (much faster!)
Write naturally, like a senior engineer writing to a colleague. Include relevant sections based on what you discovered:
Core sections (always):
Additional sections (as relevant):
Don't force sections that don't add value. A deployment authentication error doesn't need a "Test Fingerprint" section.
Investigation Quality: ✅ Identified specific failure point with evidence ✅ Determined root cause with reasoning (not just labels) ✅ Assessed whether this is a known issue (when relevant) ✅ Made appropriate use of external validation (when patterns suggest it) ✅ Provided actionable recommendations
Process Quality: ✅ Used adaptive investigation depth (stopped when confident) ✅ Let evidence guide technique selection (didn't use every tool blindly) ✅ Explained confidence level and competing theories ✅ Saved diagnostic artifacts in workspace ✅ Wrote natural, contextual report (not template-filled)
For detailed information:
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.
Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.
Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.
Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.
Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.
Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.
Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.
Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".
Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.
Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Opus.ai: Revolutionize Your Web Experience
Build a no-code AI app in minutes.
An IDE for code migration from legacy to modern frameworks through coding agents.
Automate CGI animation in live-action scenes
Branded artistic QR-code concepts
Launch a website in seconds with AI.
Streamline Your Coding Experience with AI Code Helper
Convert any screenshot or design to clean code.