Skip to content

Project Structure

Ghost is a monorepo — all the code for the Go backend, React frontend, Tauri desktop shell, and Chrome extension lives in a single Git repository. This page maps out every directory and key file, explaining what each piece does and how it connects to the rest of the system.


ghost/
├── cmd/ghost/main.go # Go entry point — wires everything together
├── internal/ # Go backend packages (16 packages)
├── frontend/ # React app + Tauri desktop shell
├── extension/ # Chrome/Firefox extension (Manifest V3)
├── docs/ # Plans, specs, sprint plans, design docs
├── docs-site/ # Starlight documentation website (this site)
├── landing/ # ghost.proxy landing page (cert serving)
├── Makefile # Build targets for all platforms
├── go.mod / go.sum # Go module dependencies
├── CLAUDE.md # AI assistant instructions
├── PLAN.md # Full product & architecture plan
└── .gitlab-ci.yml # CI/CD pipeline configuration

cmd/ghost/main.go is the single entry point for the entire Go backend. It creates and wires together all subsystems — the proxy, API server, WebSocket hub, database, config manager, agent, addon engine, device manager, security interceptor, and all background goroutines. When Ghost runs as a Tauri sidecar, it receives the --sidecar flag and picks ephemeral ports instead of using configured defaults.


The backend is organized into 16 packages, each responsible for a distinct subsystem. Go’s internal/ directory convention means these packages can only be imported by code within the Ghost module — they’re not a public API.

internal/
├── addon/ # JavaScript addon engine
├── agent/ # AI agent system
├── api/ # REST API + WebSocket hub
├── cert/ # CA certificate generation
├── certinstall/ # OS trust store installation
├── config/ # Configuration management
├── device/ # Mobile device management
├── extension/ # Browser extension hub
├── frida/ # Dynamic instrumentation
├── hub/ # Central WebSocket hub
├── inspector/ # Mobile UI inspection
├── proxy/ # MITM proxy core
├── sectools/ # External security tools
├── store/ # SQLite database layer
├── sysproxy/ # System proxy configuration
└── testrail/ # TestRail integration

Sandboxed JavaScript execution using the goja pure-Go JS engine. Each addon runs in its own isolated VM with a ghost.* API for inspecting and modifying traffic.

FilePurpose
engine.goVM lifecycle management — creating, loading, unloading, and hot-reloading addon VMs. Handler execution with timeout (5 seconds) and call stack depth limit (512).
addon.goAddon data model — ID, name, code, enabled status, priority.
interceptor.goIntegrates addons into the proxy pipeline. Implements the Interceptor interface with OnRequest/OnResponse methods. Sorts addons by priority and short-circuits on the first non-Continue action.

The largest backend package (~48 files). Contains the plan-execute-reflect loop, provider integrations, tool implementations, context management, and engagement state tracking.

FilePurpose
agent.goCore agent loop — up to 25 iterations of planning, tool execution, and reflection. Steer channel (capacity 5) for mid-run user guidance.
manager.goAgent lifecycle — provider factory (CreateProvider), Reconfigure for hot-swapping providers, SimpleChat for one-shot prompts.
provider.goProvider interface — Chat, StreamChat, Name, ModelName.
provider_anthropic.goAnthropic Claude integration — prompt caching on system prompt and last tool, retry with rate limit parsing.
provider_openai.goOpenAI GPT integration — shared message/tool converters (also used by Ollama).
provider_ollama.goOllama local model integration — OpenAI-compatible /v1 endpoint, extended retry for model loading and connection errors.
tool_router.goPhase-based tool selection — 4 layers (base, phase-specific, step-explicit, conditional). Alphabetical sort for prompt cache hits.
engagement_state.goTracks agent progress — phases (recon, analysis, active_test, exploit, report for security; similar for QA), tool call counts, endpoint coverage, finding IDs.
termination.go6 termination signals — plan+reflection stop, plan+no-tools stop, loop detection (3x in 10), diminishing returns (same tool 6x after iter 8), budget (iter >= 22), user stop.
reflection.goStep reflections (after complete_step tool calls) and final reflections (when all plan steps are done).
context_manager.goToken-aware context pruning — estimates tokens at ~4 chars/token, prunes from 10 exchanges down to 1, preserves system prompt and original user message.
message_pruning.goMechanical message summarization (no LLM call) — counts tool usage, extracts key findings, inserts spacer messages for Anthropic API alternation rules.
plan.goTaskPlan model — 1-15 steps, 5 categories, 5 statuses, XML serialization with truncated results.
prompt.goQA mode prompt builder — system prompt with session context, tool descriptions, engagement state.
prompt_security.goSecurity mode prompt builder — scan mode restrictions, PTES phases, attack surface context.
tools_core.goAlways-available tools — traffic queries, plan management, filesystem access.
tools_traffic.goTraffic analysis tools — flow search, body reading, header inspection.
tools_qa.goQA-specific tools — test scenario generation, framework-specific code generation.
tools_qa_advanced.goAdvanced QA tools — k6 load testing, hey benchmarking.
tools_qa_external.goExternal QA tools — TestRail integration helpers.
tools_security.goSecurity-specific tools — finding management, engagement tracking.
tools_attacker.goAttacker/fuzzer tools — request mutation, payload selection, result analysis.
tools_browser.goBrowser extension tools — page reading, element clicking, form filling, screenshot capture (6 registered, 2 defined but not registered).
tools_inspector.goMobile inspector tools — element tree, screenshot, selectors, touch simulation.
tools_proxy.goProxy manipulation tools — script injection, map rules.
tools_workspace.goWorkspace filesystem tools — read, write, list files in the session workspace.
tools_testrail.goTestRail integration tools — project/suite/case operations.
tools_external.goExternal scanner tools — Nuclei, Dalfox, ffuf, sqlmap, TruffleHog, Katana, Semgrep wrappers.
tools_external_new.goAdditional external tools — Nmap, SSLScan, Hydra (agent-only, no UI management).
tools_plan.goPlan management tools — create_plan, complete_step, revise_plan, think, present_options.
attacker.goRequest attacker engine — token bucket rate limiting, baseline comparison, payload wordlists.
parallel.goConcurrent tool execution — read-only tools run in parallel (semaphore of 4), mutating tools run sequentially.
tool_output.goTool output compression — 16,000 char max, tool-specific strategies (severity caps for Nuclei, URL prioritization for Katana).
types.goCore types — Message, ToolCall, StreamEvent, RunMetrics (16 fields).
payloads/10 attack payload files embedded via go:embed — SQL injection, XSS, path traversal, command injection, etc.
wordlists/2 wordlist files — API paths, common paths for directory brute-forcing.

35 handler files implementing ~168 endpoints under /api/v1/, plus the health endpoint and WebSocket connections.

FilePurpose
server.goRouter setup (chi/v5), middleware chain, route registration, server lifecycle. Server timeouts: 30s read, 60s write, 120s idle, 10s shutdown.
middleware.go5 middleware: requestID (ULID), RealIP, requestLogger (DEBUG level), recovery (Sentry), CORS (AllowedOrigins=*, MaxAge=3600). Auth via Bearer header or ?token= query param with constant-time comparison.
response.goJSON response helpers — respondJSON, respondError (captures 5xx to Sentry). Error format: {"error": "message"}.
hub.goWebSocket hub — register/unregister (buffer 16), broadcast (buffer 256), non-blocking send with slow client disconnection. Client constants: writeWait 10s, pongWait 60s, pingPeriod 54s, maxMessageSize 512, sendBufferSize 256.
flow_handlers.goFlow CRUD — list, get, delete (JSON body), batch replay, tags, body streaming, decode, WebSocket frames, stats.
session_handlers.goSession CRUD — list, create, get, delete (cascades to 11 tables), activate.
export_handlers.go5 export formats (HAR/JSON/CSV/Postman/HTML report) + 2 import formats (HAR/JSON).
compare_handlers.goSession comparison — path normalization, 4 change types, 30s timeout.
report_handlers.goAgent reports and PoC exports.
proxy_handlers.goProxy start/stop/status — async listener, VPN detection, watchdog.
sysproxy_handlers.goSystem proxy enable/disable/status.
throttle_handlers.goNetwork throttling — 5 presets, custom profiles, token bucket.
cert_handlers.goCertificate download, install, status.
setup_handlers.goFirst-run wizard — status and complete.
agent_handlers.goSSE chat streaming, conversation CRUD, file upload, steer.
workspace_handlers.goAgent workspace — list and read files with path traversal protection.
addon_handlers.goAddon CRUD with hot-reload.
maprule_handlers.goMap rule CRUD.
breakpoint_handlers.goBreakpoint CRUD + resume with modifications.
injection_rule_handlers.goInjection rule CRUD (64KB script cap).
device_handlers.goDevice inspector — connect, screenshot, hierarchy, selectors, correlation, interactions, tap, input, WebViews, bug reports.
mobile_handlers.goMobile setup — platform info, simulator/emulator listing, cert install, proxy config.
security_handlers.goSecurity findings CRUD, tool management.
frida_handlers.goFrida session management — attach, spawn, detach, script CRUD.
attacker_handlers.goRequest attacker — run, stop, status, wordlists.
settings_handlers.goSettings get/update, LLM validation, TestRail validation, token rotation, export/import.
monitor_handlers.goResource monitoring — DB size, memory, goroutines, uptime.
extension_handlers.goExtension status and actions.
journey_handlers.goJourney CRUD + steps listing.
artifact_handlers.goArtifact CRUD + download.
compose_handlers.goRequest composer — send with 2MB request / 1MB response caps.
analyze_handler.goScript analysis endpoint for injection bridge.
fetch_handler.goScript fetch endpoint for injection bridge.
telemetry_handlers.goExtension error relay — rate limited, forwards to Sentry.

CA certificate and key pair generation using ECDSA P-256. Creates ~/.ghost/ca.crt and ~/.ghost/ca.key on first run.

certinstall/ — OS Trust Store Installation

Section titled “certinstall/ — OS Trust Store Installation”

Platform-specific certificate installation into the operating system’s trust store.

FilePlatformMethod
certinstall.goAllInterface definition
certinstall_darwin.gomacOSsecurity add-trusted-cert to login keychain
certinstall_windows.goWindowscertutil -user -addstore Root (no UAC needed)
certinstall_linux.goLinuxAuto-detects distro family from /etc/os-release (Debian, RHEL, Arch, SUSE)
certinstall_other.goOtherReturns ErrUnsupported

TOML-based configuration with thread-safe access and AES-256-GCM encryption for API keys.

FilePurpose
config.goConfig struct (9 sections), Manager (RWMutex), Load/Save (atomic write), applyDefaults, DefaultHostExclude (134 patterns).
encrypt.goAES-256-GCM encryption/decryption with machine-specific key derivation. enc: prefix for encrypted values, automatic plaintext migration.

Manages connections to iOS simulators, Android emulators, and physical devices.

FilePurpose
manager.goDevice discovery (Android 5s, iOS 15s polling), connection lifecycle, 11 mutexes for thread safety.
device.goDevice model, screenshot ring buffer (30 frames), coordinate transforms.
android.goADB commands, atx-agent management, port allocation from 17912.
ios.gosimctl + WDA (WebDriverAgent) commands, auto-launch, dual coordinate spaces.
touch.goBase interaction monitoring types and interfaces.
touch_apple.goiOS hierarchy-based interaction detection — polling, diff-based tap/text detection, 2s text coalescing.
touch_droid.goAndroid getevent kernel stream parsing — tap (<500ms, <20px), long press (>=800ms), scroll (>=50px).
analyze.goHierarchy analysis for bug reports — element identification, action classification.

Dedicated WebSocket hub for the Chrome/Firefox extension — single-client, bidirectional protocol.

FilePurpose
hub.goExtension WebSocket hub — single client, 1MB messages, 64 send buffer, dedup ring buffer, ghost.welcome on connect.
bridge.goBridges extension events to the main WebSocket hub — converts capture.* messages to extension.* events.
correlator.goCorrelates browser interactions with HTTP flows — 4-weighted scoring (host 0.4, timing 0.3, path 0.2, method 0.1).
types.goExtension protocol message types.

Frida integration for SSL pinning bypass, root detection bypass, and custom script injection on mobile apps.

FilePurpose
frida.goFrida detection (checks python3 -c "import frida"), pip installation with SSE progress, CA bundle for pip proxy trust. Version pinned at 16.5.9.
manager.goSession lifecycle — attach/spawn/detach, output ring buffer (1000 lines/session), saved scripts CRUD in SQLite, device/app enumeration with timeouts.

The core WebSocket broadcasting infrastructure used by the API server.

Parses element hierarchies, generates selectors, creates bug reports, and detects WebViews.

FilePurpose
android_parser.goParses Android UI hierarchy XML — extracts bounds ([left,top][right,bottom]), 25+ element fields.
ios_parser.goParses iOS hierarchy XML — streaming parser with depth limit (30), class name as element type.
element.goElement data model — 25+ fields including clickable, focused, scrollable, selected, checked, traits, package_name.
selector.goGenerates selectors — Android 5 strategies (accessibility_id, resource_id, content_desc, ui_selector, xpath), iOS 4 strategies (accessibility_id, predicate_string, class_chain, xpath).
correlation.goTraffic-UI correlation — matches user interactions to HTTP flows using timestamp proximity, noise filtering, body preview (2048 bytes).
bugreport.goBug report generator — flow attribution (200ms lookback, 3s window), step inference, GIF encoding (0.25x scale, Plan9 palette, Floyd-Steinberg dithering, 5MB cap).
bugreport_ai.goAI-enhanced bug reports — XML-tagged prompt (~2K tokens), 60s timeout.
gif.goGIF encoding from screenshot frames.
webview.goWebView detection — 4 Android classes + /proc/net/unix sockets, iOS XCUIElementTypeWebView.
noise_domains.go~50 SDK domains filtered from inspector traffic (analytics, crash reporting, ad networks).

The heart of Ghost — a full-featured HTTP/HTTPS intercepting proxy (~27 files).

FilePurpose
proxy.goMain proxy server (~2000 lines) — handleHTTP (16-step flow), handleConnect (HTTPS tunnel + MITM), adaptive transport (per-host HTTP/1.1 vs HTTP/2), connection pooling, response streaming with TeeReader.
flow.goFlow data model — request, response, timing, metadata, device info.
interceptor.goPipeline interface — OnRequest/OnResponse methods, Name(), 3 action types (Continue, Drop, Respond).
ca.goCA generation — ECDSA P-256, 10-year validity, 1-hour backdate, 128-bit serial.
mitm.goLeaf certificate issuer — 24-hour validity, SAN wildcards, OCSP stapling, LRU cache (10K default) with single-flight dedup.
websocket.goWebSocket traffic capture — RFC 6455 frame parsing, 1MB payload cap, opcode handling.
maprule.goMap rule model and manager — URL/header/body rewrite rules.
map_interceptor.goMap rule interceptor — file serving, regex rewrite with caching, Content-Length auto-update.
breakpoint.goBreakpoint manager — channel-based goroutine blocking, 60s default timeout.
breakpoint_interceptor.goBreakpoint interceptor — pauses flows for inspection/modification.
script_injector.goJavaScript injection — CSP stripping (4 header variants), </script> escaping, decompression check (5MB cap).
security_interceptor.goPassive security scanner — 8 detection methods, 16 CWE/OWASP mappings, async channel (2048 buffer), dedup by host|type|title.
throttle.goToken bucket rate limiter — bandwidth throttling with 32KB burst, per-connection latency injection.
noise.goNoise detection — sliding window, fingerprint (METHOD:host:path), threshold/hysteresis, sample rate.
device_resolver.goDevice identification — 3-layer resolution (UA → simulator registry → PID walk), 15s poll, 60s PID cache.
normalize.goPath normalization for session comparison — replaces numeric IDs, UUIDs, ULIDs, hex hashes with {id}.
protobuf.goProtobuf/gRPC body decoding for flow inspection.
useragent.goUser-Agent string parsing for device type detection.
FilePurpose
sectools.go8 known tools (Frida, Nuclei, Dalfox, ffuf, sqlmap, TruffleHog, Katana, Semgrep) with descriptions, package managers (brew/pip/go), installation and toggle management.
FilePurpose
store.go15 sub-interfaces totaling ~80 methods. Defines all data models — flows, sessions, conversations, messages, addons, findings, interactions, journeys, breakpoints, map rules, injection rules, artifacts, Frida scripts.
sqlite.goSQLite implementation — pure Go (modernc.org/sqlite), MaxOpenConns(1) for single-writer, WAL mode, 5 PRAGMAs (WAL, busy_timeout=10000, synchronous=NORMAL, foreign_keys=ON, cache_size=-64000). FTS5 full-text search with porter+unicode61 tokenizer. GQL→SQL translation.
migrations.go18 schema migrations — evolves the database from v1 to v18, adding tables for WebSocket frames, security findings, Frida scripts, extension events, injection rules, etc. ~37 indexes.
purger.goAuto-purge background worker — 5-minute interval, by-age and by-count strategies.

Platform-specific system proxy management.

FilePlatformMethod
sysproxy_darwin.gomacOSnetworksetup (Setup layer) + SCDynamicStore override (State layer) for VPN coexistence. PAC URL format. 16 tunnel keywords for VPN filtering.
sysproxy_windows.goWindowsRegistry (HKCU\Software\Microsoft\Windows\Internet Settings) + WinINet notification.
sysproxy_linux.goLinuxGNOME gsettings + KDE kwriteconfig6 + DBus.

HTTP client for TestRail’s API — project listing, test suite/case creation, result posting. Used by the agent’s TestRail tools.


frontend/src/
├── App.tsx # Root — WebSocket setup, init sequence, WS event routing
├── index.css # Design tokens, Tailwind v4 base, animations
├── components/
│ ├── app-shell.tsx # Main layout — CommandBar + content + StatusBar
│ ├── command-bar.tsx # Top toolbar — session selector, proxy controls, mode switch
│ ├── command-palette.tsx # Cmd+K fuzzy search — 11 commands
│ ├── status-bar.tsx # Bottom bar — proxy status, resource monitor, network indicator
│ ├── flow-list.tsx # Virtual-scrolled traffic list — @tanstack/react-virtual
│ ├── flow-inspector.tsx # Split-pane request/response detail — resizable panels
│ ├── flow-comparison.tsx # Side-by-side flow diff — JSON deep comparison
│ ├── flow-context-menu.tsx # Right-click menu — copy as, compare, delete, tag
│ ├── filter-strip.tsx # Smart filters — 5 presets, content type pills, visual query
│ ├── waterfall-timeline.tsx # Session-wide timing waterfall — virtualized, zoomable
│ ├── timing-waterfall.tsx # Single-flow timing breakdown — DNS, TCP, TLS, TTFB, transfer
│ ├── request-composer.tsx # Request builder — headers, body, cURL import, comparison
│ ├── breakpoint-editor.tsx # Full-screen overlay — request/response modification
│ ├── breakpoint-rules.tsx # Breakpoint rule management panel
│ ├── rules-view.tsx # Map rules panel — pattern, action, preview
│ ├── injection-rules-view.tsx # JavaScript injection rules panel
│ ├── scope-panel.tsx # Domain/app/device sidebar navigator
│ ├── domain-navigator.tsx # Collapsible domain tree with flow counts
│ ├── device-navigator.tsx # Connected device list
│ ├── settings-modal.tsx # Full settings overlay — 7 settings pages
│ ├── drop-zone.tsx # Drag-and-drop import — HAR/JSON, 256MB max
│ ├── slide-over.tsx # Right-side panel system — 420px default, 11 panel types
│ ├── body-viewer.tsx # Response body renderer — JSON, HTML, images, hex
│ ├── code-viewer.tsx # Syntax-highlighted code display
│ ├── json-tree.tsx # Collapsible JSON tree viewer
│ ├── ws-frame-viewer.tsx # WebSocket frame list — direction, opcode, payload
│ ├── error-boundary.tsx # React error boundary with Sentry capture
│ ├── empty-state.tsx # Empty state illustrations
│ ├── icon-button.tsx # Design system icon button wrapper
│ ├── skeleton.tsx # Loading skeleton components
│ ├── ui/ # 21 restyled shadcn/ui components (Button, Input, Select, etc.)
│ ├── inspector/ # Flow inspector sub-tabs and overlays
│ ├── addons/ # Addon editor (Monaco) + console + templates
│ ├── chat/ # AI agent conversation — SSE streaming, tool results, file upload
│ ├── security/ # Security panel — findings, JWT viewer, attacker, tools management
│ ├── frida/ # Frida panel — sessions, scripts (Monaco), console, device/app selection
│ ├── mobile-inspector/ # Device inspector — screenshot, element tree, selectors, bug reports
│ ├── extension/ # Browser extension panel — status, interactions, actions
│ ├── session-comparison/ # Session comparison view — endpoint diff, timing, filters
│ └── settings/ # Settings sub-pages — proxy, AI, security, storage, SSL, TestRail, about
├── stores/ # 19 Zustand stores
│ ├── flow-store.ts # Flows — 5000 fetch limit, 100ms batching, range select
│ ├── ui-store.ts # UI state — 39 actions, 30+ fields, 11 localStorage keys
│ ├── agent-store.ts # Agent — SSE streaming, AbortController, race protection
│ ├── session-store.ts # Sessions — CRUD, active session tracking
│ ├── proxy-store.ts # Proxy status — running, capturing, network
│ ├── device-store.ts # Devices — discovery, connection (120s timeout)
│ ├── frida-store.ts # Frida — 500 lines/session, 100ms console batching
│ ├── attacker-store.ts # Attacker — 50 max results display
│ ├── extension-store.ts # Extension — 50 interactions, camelCase→snake_case
│ ├── rules-store.ts # Map rules
│ ├── injection-rules-store.ts # Injection rules
│ ├── breakpoint-store.ts # Breakpoints
│ ├── security-store.ts # Security findings and tools
│ ├── comparison-store.ts # Session comparison
│ ├── inspector-store.ts # Flow inspector state
│ ├── addon-store.ts # Addons
│ ├── artifact-store.ts # Artifacts
│ ├── settings-store.ts # Settings
│ ├── setup-store.ts # First-run wizard
│ └── updater-store.ts # Auto-updater
├── hooks/ # Custom React hooks
│ ├── use-websocket.ts # WebSocket connection with reconnect (1s→30s backoff)
│ ├── use-keyboard-shortcuts.ts # 12 keyboard shortcuts
│ └── use-native-menu.ts # Tauri native menu event bridge
├── lib/ # Utilities
│ ├── api.ts # API client — typed methods for all ~168 endpoints
│ ├── sentry.ts # Sentry init + captureError utility
│ ├── telemetry.ts # Anonymous usage heartbeat
│ ├── toast-bridge.ts # Store error → toast notification bridge
│ ├── formatters.ts # Size, duration, date formatting
│ └── export-utils.ts # Copy-as (cURL, fetch, Markdown, Python, HTTPie)
└── types/ # TypeScript type definitions
└── api.ts # All DTO interfaces matching Go structs

The Tauri shell is a thin Rust layer that provides native OS integration. It contains no business logic — everything happens in the Go sidecar.

frontend/src-tauri/
├── src/
│ ├── lib.rs # Main Rust code (~940 lines):
│ │ # - Sidecar spawn + JSON handshake (15s timeout)
│ │ # - 9 native menus with 30+ items
│ │ # - System tray (4 items, 3s poll)
│ │ # - Safety net (3 consecutive failures → disable proxy)
│ │ # - 3 Tauri commands (force_disable_system_proxy,
│ │ # open_path, airdrop_cert)
│ └── main.rs # Entry point — suppresses console window on Windows
├── tauri.conf.json # App config:
│ # - Window: 1280×800, min 900×600, overlay title bar
│ # - CSP: self + localhost only, no unsafe-eval
│ # - Bundle: DMG + NSIS (currentUser, no admin)
│ # - Updater: EdDSA signing, passive Windows install
├── Cargo.toml # Rust dependencies:
│ # - tauri v2 (tray-icon, image-png)
│ # - 5 plugins (shell, dialog, fs, process, updater)
│ # - reqwest (HTTP), serde (JSON), tokio (async)
│ # - winreg (Windows-only, registry access)
├── capabilities/
│ ├── default.json # Default permissions — sidecar spawn, dialog, updater
│ └── localhost.json # Remote origin permissions — IPC for WebView at localhost
├── icons/ # App icons for all platforms and sizes
└── binaries/ # Go sidecar binary (placed here by Makefile during build)

Manifest V3 extension for Chrome and Firefox that captures browser interactions, executes actions on behalf of the AI agent, and injects JavaScript into web pages.

extension/
├── manifest.json # Manifest V3:
│ # - Permissions: activeTab, storage, tabs, scripting, alarms
│ # - Host permissions: <all_urls>
│ # - Keyboard shortcuts: Alt+G (popup), Alt+Shift+C (capture),
│ # Alt+Shift+S (screenshot)
├── src/
│ ├── service-worker.ts # Background service worker — WebSocket connection to Ghost,
│ │ # message routing, action execution, error reporting
│ ├── content/
│ │ ├── index.ts # Content script entry — DOM event listeners, interaction capture
│ │ ├── capture.ts # 7 capture subsystems: clicks, form inputs, submissions,
│ │ │ # navigation, hover/focus (50ms rate limit), console errors,
│ │ │ # storage changes
│ │ ├── actions.ts # Action execution — page read, click, fill, screenshot
│ │ └── inject.ts # Page-world script injection
│ ├── popup/
│ │ ├── popup.ts # Extension popup logic — connection status, toggle capture
│ │ ├── popup.html # Popup HTML
│ │ └── popup.css # Popup styles
│ └── shared/
│ ├── protocol.ts # Extension ↔ Ghost message protocol types
│ ├── types.ts # Shared TypeScript types
│ ├── selectors.ts # CSS selector generation for captured elements
│ └── error-reporter.ts # Error relay to Ghost backend (POST /telemetry/error)
├── vite.config.ts # Main build — service worker + popup as ES modules
├── vite.content.config.ts # Content script build — IIFE format (no ES modules in content scripts)
├── package.json # Dependencies: @types/chrome, typescript, vite
└── tsconfig.json # TypeScript config