From htmlgraph
> **DEPRECATED:** This skill is replaced by the `gemini-operator` agent.
npx claudepluginhub shakestzd/htmlgraphThis skill uses the workspace's default tool permissions.
> **DEPRECATED:** This skill is replaced by the `gemini-operator` agent.
Provides Ktor server patterns for routing DSL, plugins (auth, CORS, serialization), Koin DI, WebSockets, services, and testApplication testing.
Conducts multi-source web research with firecrawl and exa MCPs: searches, scrapes pages, synthesizes cited reports. For deep dives, competitive analysis, tech evaluations, or due diligence.
Provides demand forecasting, safety stock optimization, replenishment planning, and promotional lift estimation for multi-location retailers managing 300-800 SKUs.
DEPRECATED: This skill is replaced by the
gemini-operatoragent. UseAgent(subagent_type="htmlgraph:gemini-operator", prompt="...")instead. The gemini-operator agent tries Gemini CLI first with 2M context and JSON output. Free tier.
name: gemini description: GeminiSpawner with full event tracking for exploration and large-context research when_to_use:
โ ๏ธ IMPORTANT: This skill teaches TWO EXECUTION PATTERNS
Choose based on your needs. See "EXECUTION PATTERNS" below.
| Pattern | Use Case | When to Use |
|---|---|---|
| Task(Explore) | General exploration via Claude Explore agent | When you want simplicity and Claude handles everything |
| GeminiSpawner | Direct Gemini CLI invocation with full subprocess tracking | When you need precise Gemini control + full parent event context |
CRITICAL: GeminiSpawner is invoked DIRECTLY via Python SDK, NOT via Task().
GeminiSpawner is the HtmlGraph-integrated way to invoke Google Gemini CLI directly with full parent event context and subprocess tracking.
Key distinction: GeminiSpawner is invoked directly via Python SDK - NOT wrapped in Task(). Task() is only for Claude subagents (Haiku, Sonnet, Opus).
GeminiSpawner:
Use Task(Explore):
# Simple Claude exploration via subagent
Task(subagent_type="Explore",
prompt="Analyze this codebase for patterns")
# Task() delegates to Claude Explore agent - no external CLI needed
Use GeminiSpawner (direct Python invocation):
# Direct Gemini CLI invocation with full tracking
spawner = GeminiSpawner()
result = spawner.spawn(
prompt="Analyze codebase",
track_in_htmlgraph=True,
tracker=tracker,
parent_event_id=parent_event_id
)
# NOT Task(GeminiSpawner) - invoke directly!
import os
import sys
from pathlib import Path
from datetime import datetime, timezone
import uuid
# Add plugin agents directory to path
PLUGIN_AGENTS_DIR = Path("/path/to/htmlgraph/packages/claude-plugin/.claude-plugin/agents")
sys.path.insert(0, str(PLUGIN_AGENTS_DIR))
from htmlgraph import SDK
from htmlgraph.orchestration.spawners import GeminiSpawner
from htmlgraph.db.schema import HtmlGraphDB
from htmlgraph.config import get_database_path
from spawner_event_tracker import SpawnerEventTracker
# Initialize
sdk = SDK(agent='claude')
db = HtmlGraphDB(str(get_database_path()))
session_id = f"sess-{uuid.uuid4().hex[:8]}"
db._ensure_session_exists(session_id, "claude")
# Create parent event context (like PreToolUse hook does)
user_query_event_id = f"event-query-{uuid.uuid4().hex[:8]}"
parent_event_id = f"event-{uuid.uuid4().hex[:8]}"
start_time = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
# Insert UserQuery event
db.connection.cursor().execute(
"""INSERT INTO agent_events
(event_id, agent_id, event_type, session_id, tool_name, input_summary, status, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
(user_query_event_id, "claude-code", "tool_call", session_id, "UserPromptSubmit",
"Analyze codebase quality", "completed", start_time)
)
# Insert Task delegation event
db.connection.cursor().execute(
"""INSERT INTO agent_events
(event_id, agent_id, event_type, session_id, tool_name, input_summary,
context, parent_event_id, subagent_type, status, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(parent_event_id, "claude-code", "task_delegation", session_id, "Task",
"Analyze spawner architecture quality", '{"subagent_type":"general-purpose"}',
user_query_event_id, "general-purpose", "started", start_time)
)
db.connection.commit()
# Export parent context (like PreToolUse hook does)
os.environ["HTMLGRAPH_PARENT_EVENT"] = parent_event_id
os.environ["HTMLGRAPH_PARENT_SESSION"] = session_id
os.environ["HTMLGRAPH_SESSION_ID"] = session_id
# Create tracker with parent context
tracker = SpawnerEventTracker(
delegation_event_id=parent_event_id,
parent_agent="claude",
spawner_type="gemini",
session_id=session_id
)
tracker.db = db
# Invoke GeminiSpawner with FULL tracking
spawner = GeminiSpawner()
result = spawner.spawn(
prompt="Analyze the refactored spawner architecture for quality",
# model=None is RECOMMENDED - uses latest Gemini models (including Gemini 3 preview)
output_format="stream-json",
track_in_htmlgraph=True, # Enable SDK activity tracking
tracker=tracker, # Enable subprocess event tracking
parent_event_id=parent_event_id, # Link to parent event
timeout=120
)
# Check results
print(f"Success: {result.success}")
print(f"Response: {result.response}")
if result.tracked_events:
print(f"Tracked {len(result.tracked_events)} events in HtmlGraph")
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | str | โ | Research/analysis task for Gemini |
model | str | None | โ | Model selection (default: None = RECOMMENDED, uses latest models including Gemini 3 preview) |
output_format | str | โ | "json" or "stream-json" (default: "stream-json") |
track_in_htmlgraph | bool | โ | Enable SDK activity tracking (default: True) |
tracker | SpawnerEventTracker | โ | Tracker instance for subprocess events |
parent_event_id | str | โ | Parent event ID for event hierarchy |
timeout | int | โ | Max seconds to wait (default: 120) |
Model Selection Note:
model=None (default): RECOMMENDED - CLI chooses best available model (gemini-2.5-flash-lite, gemini-3-flash-preview)gemini-2.0-flash, gemini-1.5-flash (may cause "thinking mode" errors)# See above code example + this prompt:
result = spawner.spawn(
prompt="""Analyze the quality of this refactored spawner architecture:
src/python/htmlgraph/orchestration/spawners/
โโโ base.py (BaseSpawner - 195 lines)
โโโ gemini.py (GeminiSpawner - 430 lines)
โโโ codex.py (CodexSpawner - 443 lines)
โโโ copilot.py (CopilotSpawner - 300 lines)
โโโ claude.py (ClaudeSpawner - 171 lines)
Please evaluate:
1. Separation of concerns
2. Code reusability
3. Error handling patterns
4. Event tracking integration
""",
# model=None uses latest Gemini models (Gemini 3 preview)
output_format="stream-json",
track_in_htmlgraph=True,
tracker=tracker,
parent_event_id=parent_event_id,
timeout=120
)
# Result: Full tracking with Gemini's quality analysis
# All subprocess invocations recorded in HtmlGraph
CRITICAL: If external spawner fails, delegate to Claude sub-agent (NOT direct execution).
# Try external spawner first
try:
spawner = GeminiSpawner()
result = spawner.spawn(
prompt="Your analysis task",
# model=None (default) - uses latest Gemini models
track_in_htmlgraph=True,
tracker=tracker,
parent_event_id=parent_event_id,
timeout=120
)
if result.success:
return result # Success, use spawner result
else:
# Spawner returned error result
raise Exception(f"Spawner failed: {result.error}")
except Exception as e:
# External spawner failed (CLI not installed, API issues, timeout, etc.)
# FALLBACK to Claude sub-agent - do NOT attempt direct execution
print(f"โ ๏ธ GeminiSpawner failed: {e}")
print("๐ Falling back to Claude Explore agent...")
return Task(
subagent_type="Explore",
prompt="Your analysis task here"
)
# Task(Explore) guarantees execution via Claude Explore agent
Why fallback to Task()?
Pattern Summary:
task_prompt = skill_args if 'skill_args' in dir() else ""
if not task_prompt: print("โ ERROR: No task prompt provided") print("Usage: Skill(skill='.claude-plugin:gemini', args='Your exploration task')") sys.exit(1)
cli_check = subprocess.run( ["which", "gemini"], capture_output=True, text=True )
if cli_check.returncode != 0: print("โ ๏ธ Gemini CLI not found on system") print("Install from: https://github.com/google/gemini-cli") print("\nFallback: Use Task(subagent_type='Explore', prompt='...')") print("The Claude Explore agent integrates with Gemini automatically.") sys.exit(1)
print("โ Gemini CLI found, executing spawner...") print(f"\nTask: {task_prompt[:100]}...")
try: spawner = HeadlessSpawner() result = spawner.spawn_gemini( prompt=task_prompt, output_format="stream-json", track_in_htmlgraph=True, timeout=120 )
if result.success:
print("\nโ
Gemini execution successful")
if result.tokens_used:
print(f"๐ Tokens used: {result.tokens_used}")
print("\n" + "="*60)
print("RESPONSE:")
print("="*60)
print(result.response)
if result.tracked_events:
print(f"\n๐ Tracked {len(result.tracked_events)} events in HtmlGraph")
else:
print(f"\nโ Gemini execution failed: {result.error}")
sys.exit(1)
except Exception as e: print(f"โ Error executing spawner: {type(e).name}: {e}") sys.exit(1)
Use Google Gemini (latest models including Gemini 3 preview) for exploration and research tasks via the GeminiSpawner SDK.
CRITICAL DISTINCTION:
| What | Description |
|---|---|
| This Skill | Documentation + embedded coordination logic |
| Embedded Python | Internal check for gemini CLI โ spawns if available |
| Task() Tool | PRIMARY execution path for exploration work |
| Bash Tool | ALTERNATIVE for direct CLI invocation (if you have gemini CLI) |
Workflow:
โ ๏ธ To actually perform exploration, use these approaches:
# Use Claude's Explore agent (automatically uses appropriate model)
Task(
subagent_type="Explore",
prompt="Analyze all authentication patterns in the codebase and document findings"
)
# For large-context research
Task(
subagent_type="Explore",
prompt="Review entire API documentation and extract deprecated endpoints"
)
# If you have gemini CLI installed on your system
Bash("gemini analyze 'Find all authentication patterns'")
# Or use the SDK spawner
uv run python -c "
from htmlgraph.orchestration.headless_spawner import HeadlessSpawner
spawner = HeadlessSpawner()
result = spawner.spawn_gemini(
prompt='Analyze auth patterns',
track_in_htmlgraph=True
)
print(result.response)
"
PRIMARY: Use Skill() to invoke (tries external CLI first):
# Recommended approach - uses external gemini CLI via agent spawner
Skill(skill=".claude-plugin:gemini", args="Analyze authentication patterns in the codebase")
What happens internally:
gemini CLI is installed on your systemgemini analyze "auth patterns"Task(subagent_type="Explore", prompt="Analyze auth patterns")FALLBACK: Direct Task() invocation (when Skill unavailable):
# Manual fallback - uses Claude's built-in Explore agent
Task(
subagent_type="Explore",
prompt="Analyze authentication patterns in the codebase",
model="haiku" # Optional: specify model
)
The Explore agent automatically uses Gemini for large-context work.
Task(
subagent_type="Explore",
prompt="""
Search codebase for all authentication patterns:
1. Where auth is implemented
2. What auth methods are used
3. Where auth is validated
4. Recommendations for adding OAuth 2.0
"""
)
# Analyze multiple files for security issues
Task(
subagent_type="Explore",
prompt="Review all API endpoints in src/ for security vulnerabilities"
)
# Extract information from diagrams or images
Task(
subagent_type="Explore",
prompt="Extract all text and tables from architecture diagrams in docs/"
)
# Process extensive documentation
Task(
subagent_type="Explore",
prompt="Summarize all API documentation and find deprecated endpoints"
)
Use Gemini for:
Use Claude for:
The skill implements a multi-level fallback strategy:
Skill(skill=".claude-plugin:gemini", args="Your exploration task")
# Attempts to use external gemini CLI via agent spawner SDK
# If gemini CLI not found, automatically falls back to:
Task(subagent_type="Explore", prompt="Your exploration task")
# Uses Claude's built-in Explore agent
# If alternative unavailable, uses Claude models for exploration
# Maintains full functionality with different inference model
Error Handling:
Track exploration work in spikes:
from htmlgraph import SDK
sdk = SDK(agent="claude")
# Create spike for research findings
spike = sdk.spikes.create(
title="Auth Pattern Analysis via Gemini",
findings="""
## Research Question
Where and how is authentication implemented?
## Findings
[Results from Gemini exploration]
## Recommendations
[Next steps based on research]
"""
).save()
Avoid Gemini for:
/codex - For code implementation after exploration/copilot - For GitHub integration and git operations/debugging-workflow - Research-first debugging methodology