From google-ecosystem
Parses Gemini CLI JSON and stream-JSON outputs for responses, token stats, tool calls, errors. Use in automation pipelines processing headless CLI results.
npx claudepluginhub melodic-software/claude-code-plugins --plugin google-ecosystemThis skill is limited to using the following tools:
> **STOP - Before providing ANY response about Gemini JSON output:**
Guides non-interactive Google Gemini CLI execution: positional syntax, stdin piping, JSON output parsing, sandboxing, and automation scripting patterns.
Delegates tasks to Gemini CLI for large-context analysis like broad codebase reviews or long-document processing. Activates on explicit requests such as 'use gemini' or 'delegate to gemini'.
Invokes Google Gemini CLI for complex reasoning, research, and AI tasks in headless mode. Supports preview models, fallbacks, and session continuation.
Share bugs, ideas, or general feedback.
STOP - Before providing ANY response about Gemini JSON output:
- INVOKE
gemini-cli-docsskill- QUERY for the specific output format topic
- BASE all responses EXCLUSIVELY on official documentation loaded
Skill for parsing Gemini CLI's structured output formats. Essential for integration workflows where Claude needs to process Gemini's responses programmatically.
Keywords: parse gemini output, json output, stream json, gemini stats, token usage, jq parsing, gemini response
Use this skill when:
--output-format json)Single JSON object returned after completion:
{
"response": "The main AI-generated content",
"stats": {
"models": {
"gemini-2.5-pro": {
"api": {
"totalRequests": 2,
"totalErrors": 0,
"totalLatencyMs": 5053
},
"tokens": {
"prompt": 24939,
"candidates": 20,
"total": 25113,
"cached": 21263,
"thoughts": 154,
"tool": 0
}
}
},
"tools": {
"totalCalls": 1,
"totalSuccess": 1,
"totalFail": 0,
"totalDurationMs": 1881,
"totalDecisions": {
"accept": 0,
"reject": 0,
"modify": 0,
"auto_accept": 1
},
"byName": {
"google_web_search": {
"count": 1,
"success": 1,
"fail": 0,
"durationMs": 1881
}
}
},
"files": {
"totalLinesAdded": 0,
"totalLinesRemoved": 0
}
},
"error": {
"type": "ApiError",
"message": "Error description",
"code": 500
}
}
--output-format stream-json)Newline-delimited JSON (JSONL) with real-time events:
| Event Type | Description | Fields |
|---|---|---|
init | Session start | session_id, model, timestamp |
message | User/assistant messages | role, content, timestamp |
tool_use | Tool call requests | tool_name, tool_id, parameters |
tool_result | Tool execution results | tool_id, status, output |
error | Non-fatal errors | type, message |
result | Final outcome | status, stats |
Example stream:
{"type":"init","timestamp":"2025-10-10T12:00:00.000Z","session_id":"abc123","model":"gemini-2.5-flash"}
{"type":"message","role":"user","content":"List files","timestamp":"2025-10-10T12:00:01.000Z"}
{"type":"tool_use","tool_name":"Bash","tool_id":"bash-123","parameters":{"command":"ls -la"}}
{"type":"tool_result","tool_id":"bash-123","status":"success","output":"file1.txt\nfile2.txt"}
{"type":"message","role":"assistant","content":"Here are the files...","delta":true}
{"type":"result","status":"success","stats":{"total_tokens":250}}
# Get main response
gemini "query" --output-format json | jq -r '.response'
# With error handling
result=$(gemini "query" --output-format json)
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
echo "Error: $(echo "$result" | jq -r '.error.message')"
else
echo "$result" | jq -r '.response'
fi
# Total tokens used
echo "$result" | jq '.stats.models | to_entries | map(.value.tokens.total) | add'
# Cached tokens (cost savings)
echo "$result" | jq '.stats.models | to_entries | map(.value.tokens.cached) | add'
# Billable tokens
total=$(echo "$result" | jq '.stats.models | to_entries | map(.value.tokens.total) | add')
cached=$(echo "$result" | jq '.stats.models | to_entries | map(.value.tokens.cached) | add')
echo "Billable: $((total - cached))"
# Tokens by model
echo "$result" | jq '.stats.models | to_entries[] | "\(.key): \(.value.tokens.total) tokens"'
# Total tool calls
echo "$result" | jq '.stats.tools.totalCalls'
# List tools used
echo "$result" | jq -r '.stats.tools.byName | keys | join(", ")'
# Tool success rate
total=$(echo "$result" | jq '.stats.tools.totalCalls')
success=$(echo "$result" | jq '.stats.tools.totalSuccess')
echo "Success rate: $((success * 100 / total))%"
# Detailed tool stats
echo "$result" | jq '.stats.tools.byName | to_entries[] | "\(.key): \(.value.count) calls, \(.value.durationMs)ms"'
# List models used
echo "$result" | jq -r '.stats.models | keys | join(", ")'
# Model latency
echo "$result" | jq '.stats.models | to_entries[] | "\(.key): \(.value.api.totalLatencyMs)ms"'
# Request counts
echo "$result" | jq '.stats.models | to_entries[] | "\(.key): \(.value.api.totalRequests) requests"'
# Check for errors
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
error_type=$(echo "$result" | jq -r '.error.type // "Unknown"')
error_msg=$(echo "$result" | jq -r '.error.message // "No message"')
error_code=$(echo "$result" | jq -r '.error.code // "N/A"')
echo "Error [$error_type]: $error_msg (code: $error_code)"
exit 1
fi
# Lines changed
echo "$result" | jq '"Added: \(.stats.files.totalLinesAdded), Removed: \(.stats.files.totalLinesRemoved)"'
# Get only tool results
gemini --output-format stream-json -p "query" | jq -r 'select(.type == "tool_result")'
# Get only errors
gemini --output-format stream-json -p "query" | jq -r 'select(.type == "error")'
# Get assistant messages
gemini --output-format stream-json -p "query" | jq -r 'select(.type == "message" and .role == "assistant") | .content'
# Watch tool calls as they happen
gemini --output-format stream-json -p "analyze code" | while read line; do
type=$(echo "$line" | jq -r '.type')
case "$type" in
tool_use)
tool=$(echo "$line" | jq -r '.tool_name')
echo "[TOOL] Calling: $tool"
;;
tool_result)
status=$(echo "$line" | jq -r '.status')
echo "[RESULT] Status: $status"
;;
error)
msg=$(echo "$line" | jq -r '.message')
echo "[ERROR] $msg"
;;
esac
done
| What | jq Command |
|---|---|
| Response text | .response |
| Total tokens | .stats.models | to_entries | map(.value.tokens.total) | add |
| Cached tokens | .stats.models | to_entries | map(.value.tokens.cached) | add |
| Tool calls | .stats.tools.totalCalls |
| Tools used | .stats.tools.byName | keys | join(", ") |
| Models used | .stats.models | keys | join(", ") |
| Error message | .error.message // "none" |
| Error type | .error.type // "none" |
| Lines added | .stats.files.totalLinesAdded |
| Lines removed | .stats.files.totalLinesRemoved |
| Total latency | .stats.models | to_entries | map(.value.api.totalLatencyMs) | add |
#!/bin/bash
# Analyze code and report stats
result=$(cat src/main.ts | gemini "Review this code for security issues" --output-format json)
# Check for errors
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
echo "Error: $(echo "$result" | jq -r '.error.message')"
exit 1
fi
# Extract response
echo "=== Security Review ==="
echo "$result" | jq -r '.response'
# Report stats
echo ""
echo "=== Stats ==="
total=$(echo "$result" | jq '.stats.models | to_entries | map(.value.tokens.total) | add // 0')
cached=$(echo "$result" | jq '.stats.models | to_entries | map(.value.tokens.cached) | add // 0')
models=$(echo "$result" | jq -r '.stats.models | keys | join(", ") | if . == "" then "none" else . end')
tools=$(echo "$result" | jq '.stats.tools.totalCalls // 0')
echo "Tokens: $total (cached: $cached)"
echo "Models: $models"
echo "Tool calls: $tools"
Query: "How do I extract the response from Gemini JSON output?" Expected Behavior:
.response extraction commandQuery: "How do I track token usage from Gemini CLI?" Expected Behavior:
Query: "How do I process Gemini CLI stream-json output?" Expected Behavior:
Query gemini-cli-docs for official documentation on: