Skip to main content

Stdlib-only local CLI bridge for Gemini chat memory and world-state context

Project description

wayfarer-bridge

Wayfarer Bridge (wfb) is a local, Python standard library-only CLI for moving useful context between terminal agents and Gemini. It is intentionally small: local files, SQLite, OAuth, and raw Gemini REST calls with no external Python package dependencies.

The project currently has two working context channels:

  • World state: a local SQLite store for structured tasks, constraints, and style rules (wfb seed, wfb status).
  • Gemini chat memory: local Gemini session files that make repeated wfb gemini ask calls coherent across turns (wfb gemini session, wfb gemini ask).

Direct attachment to active browser Gemini side-panel sessions is not available through the validated official Gemini API surface today. For now, wfb uses local session memory as the bridgeable, agent-friendly fallback.

What Works Today

  • wfb init creates the local asset directory, initializes the SQLite DB, and runs OAuth login.
  • wfb seed ingests a structured world-state JSON envelope into SQLite.
  • wfb status prints a concise world-state summary in text or JSON.
  • wfb gemini ping verifies authenticated Gemini API access.
  • wfb gemini ask sends prompts to Gemini with local session continuity.
  • wfb gemini session ... creates, switches, lists, resets, and inspects local chat sessions.
  • wfb gemini ask --auto-summarize on can compact long local sessions with a Gemini-generated summary.
  • wfb chrome ... can launch a debuggable Chrome instance, list page targets, attach one target, and inspect bounded tab text context.

Still not supported:

  • Direct official Gemini API attachment to browser side-panel sessions.
  • A centralized OAuth client secret for the open-source/PyPI path.

Quick Start

Install locally (editable) from the repository root:

python3 -m pip install -e .

Then use:

wfb --help

You can also run the script directly:

python3 wfb.py --help

For isolated testing, install in a virtual environment first.

Set up OAuth:

  1. Create a Google Cloud project and enable the Generative Language API.
  2. Configure the OAuth consent screen and add yourself as a test user while developing.
  3. Create an OAuth Desktop app client.
  4. Download the JSON and place it at ~/.wfb/client_secret.json.
  5. Run wfb init, then wfb gemini ping.

Create a Gemini session and ask follow-up questions:

wfb gemini session new --name planning
wfb gemini ask --prompt "Remember that Wayfarer Bridge is stdlib-only."
wfb gemini ask --prompt "What constraint did I just mention?"
wfb gemini session inspect --format json

Asset Layout

~/.wfb/ is the canonical per-user asset directory.

Path Purpose
~/.wfb/wayfarer.db Default SQLite world-state database.
~/.wfb/client_secret.json User-provided OAuth Desktop client secret.
~/.wfb/token.json Local OAuth token cache.
~/.wfb/gemini_sessions/<session_id>.json Local Gemini chat session history and metadata.
~/.wfb/gemini_active_session.json Pointer to the current active Gemini session.
~/.wfb/chrome_debug_profile/ Isolated Chrome profile dir for wfb chrome launch --profile-mode isolated.
~/.wfb/chrome_attachment.json Persisted selected Chrome target for wfb chrome inspect.

The global --db PATH flag overrides only the SQLite database path. Other CLI assets still live under ~/.wfb/.

CLI Reference

Global option:

wfb [--db PATH] <command> ...

wfb init [--no-open-oauth-guide] [--no-browser] [--force-login]

  • Ensures ~/.wfb/ exists.
  • Initializes the SQLite schema at --db PATH or ~/.wfb/wayfarer.db.
  • Requires ~/.wfb/client_secret.json.
  • Runs OAuth login and stores token data at ~/.wfb/token.json.
  • --no-open-oauth-guide disables best-effort browser-open for setup instructions.
  • --no-browser prints the OAuth URL instead of attempting to open a browser.
  • --force-login ignores a valid cached token and reruns OAuth.

wfb seed (--json STRING | --file PATH) [--replace]

Ingests a structured world-state envelope into SQLite. Default behavior is upsert by id; --replace clears all entity tables before inserting the supplied envelope.

wfb status [--format text|json] [--limit N]

Prints the SQLite world-state summary. --format json emits deterministic machine-readable state; --limit N caps preview lists in text output.

wfb gemini ping [--limit N]

Lists available Gemini model names using cached OAuth credentials.

wfb gemini ask --prompt STRING [options]

Sends a prompt to Gemini using local session memory.

Options:

  • --model ID: Gemini model id. Default: gemini-2.5-flash.
  • --session ID: route this ask to a specific local session. Defaults to the active session.
  • --max-history-turns N: include at most this many recent non-summary turns. Default: 30.
  • --system TEXT: system instruction override for this call.
  • --auto-summarize on|off: opt into model-generated session compaction. Default: off.
  • --summarize-model ID: optional model override used only for summary generation.
  • --sync-world-state on|off: per-ask override for world-state sync.
  • --world-state-db PATH: per-ask override for sync target DB.

If no active session exists, ask auto-creates one.

wfb gemini session current

Prints the active local Gemini session id, if any.

wfb gemini session list

Lists local sessions. The active session is marked with *.

wfb gemini session new [--name NAME] [--model ID] [--system TEXT] [sync options]

Creates a new local session and makes it active.

Sync options:

  • --sync-world-state on|off: default sync mode for this session.
  • --world-state-db PATH: default target DB for this session's sync.
  • --world-state-scope TEXT: optional scope tag injected into synced record metadata.

wfb gemini session use --id SESSION_ID [sync options]

Makes an existing session active.

wfb gemini session reset [--id SESSION_ID]

Clears message history for the target session. Defaults to the active session.

wfb gemini session inspect [--id SESSION_ID] [--format text|json]

Inspects a local session. Defaults to the active session.

wfb chrome launch [--port N] [--profile-mode isolated|user] [--chrome-path PATH]

Launches a Chrome instance with remote debugging enabled and verifies /json/version. If a debug endpoint is already available on the port, wfb reuses it and skips spawning a new process. If the requested port is unavailable, wfb auto-falls back to a detected healthy debug port.

  • --profile-mode isolated (default): uses ~/.wfb/chrome_debug_profile/.
  • --profile-mode user: uses your normal Chrome profile (higher fidelity, higher risk).

wfb chrome targets [--port N] [--include-types page,webview] [--gemini-only] [--format text|json]

Lists attachable CDP targets from /json/list.

  • Default target types: page (backward-compatible behavior).
  • --include-types page,webview includes Gemini side-panel webviews.
  • --gemini-only narrows output to Gemini-related targets.

wfb chrome attach --target-id ID [--port N] [--include-types page,webview] [--format text|json]

Stores the selected target in ~/.wfb/chrome_attachment.json for later inspection.

  • Default target types searched: page.
  • Use --include-types page,webview when attaching Gemini side-panel IDs.

wfb chrome inspect [--target-id ID] [--port N] [--include-types page,webview] [--max-chars N] [--format text|json]

Reads bounded tab context from CDP Runtime.evaluate and prints JSON by default:

  • url, title
  • selected_text
  • text_snapshot (bounded/truncated exactly by --max-chars)
  • capture metadata (captured_at_unix, length fields, target metadata)

Inspect defaults are attachment-aware: when using a persisted attachment and no explicit --include-types is provided, wfb auto-includes the attachment target type (for example webview) so inspect can resolve saved side-panel targets without extra flags.

Debug-port probing: inspect tries your --port (default 9222) first, then other locally detected debugging ports in stable order until /json/list succeeds — same ordering as chrome capture/bridge. When JSON output is enabled, a top-level debug object documents requested_port, resolved_port, and whether a fallback port was used (fallback_used).

wfb chrome detach

Clears the persisted attachment file.

wfb chrome current [--format json|text]

Shows the current persisted attachment and endpoint health. Default output is JSON.

wfb chrome capture [--target-id ID] [--port N] [--include-types page,webview] [--gemini-only] [--max-chars N] [--format json|text]

Runs discover -> attach -> inspect in one deterministic command.

  • Defaults to --include-types page,webview for side-panel compatibility.
  • Selection priority: explicit --target-id, then focused/active target, then heuristic ranking, then first-candidate fallback.
  • JSON output includes selection, target, attachment, inspect, and debug ports (requested_port, resolved_port).

wfb bridge doctor [--port N] [--include-types page,webview] [--gemini-only] [--format json|text]

Read-only diagnostics for agents: endpoint reachability (/json/version), target summaries (/json/list), persisted attachment state, Gemini session id, and ordered recommendations (recover / happy-path next commands). Default format is JSON; --format text prints a compact checklist.

Example:

wfb bridge doctor
wfb bridge doctor --include-types page,webview --gemini-only --format text

wfb bridge ask --prompt "..." [--session ID] [--model MODEL] [--system TEXT] [--port N] [--target-id ID] [--include-types page,webview] [--gemini-only] [--max-chars N] [--format json|text]

Runs the full browser-to-Gemini pipeline in one command: capture -> prompt envelope -> Gemini ask.

  • Captures browser context via the same logic as chrome capture (including unified debug-port probing: requested_port vs resolved_port in the capture section when fallback occurs).
  • Builds a versioned prompt envelope embedding the page snapshot and user prompt.
  • Sends the composed prompt to Gemini within the target session (creates one if none active).
  • Appends both the composed prompt and model response to session history.

JSON output includes three provenance sections:

  • capture: target selection details, snapshot metadata, debug ports.
  • prompt_envelope: template version, original user prompt, composed prompt character count.
  • gemini_response: model, session id, full answer text.

Example:

wfb bridge ask --prompt "summarize the feedback on this page" --format json
wfb bridge ask --prompt "extract the test failures" --gemini-only --format text

wfb bridge loop --prompt "..." [--max-iterations N] [--stability-check on|off] [--session ID] [--model MODEL] [--system TEXT] [--port N] [--target-id ID] [--include-types page,webview] [--gemini-only] [--max-chars N] [--format json|text]

Runs a bounded iterative automation loop: each iteration captures browser context and asks Gemini about it.

  • Uses the same capture path as wfb bridge ask / chrome capture for port probing and provenance (requested_port/resolved_port per iteration).

  • --max-iterations N (default 3): hard upper bound on iterations.

  • --stability-check on: stops early if the page snapshot is unchanged between iterations.

  • Each iteration produces full provenance in the output transcript.

Stop reasons:

  • max_iterations: budget exhausted normally.
  • no_change: stability check detected identical snapshots.
  • error: a capture or ask stage failed (error details in the iteration record).

JSON output includes:

  • run: start/end timestamps, iteration budget, stop reason.
  • iterations[]: per-step capture, prompt_envelope, gemini_response, and status.
  • summary: last answer, session id, model, and stop reason.

Example:

wfb bridge loop --prompt "check for new test results" --max-iterations 5 --stability-check on
wfb bridge loop --prompt "summarize changes" --gemini-only --format text

Gemini Sessions For Agents

The Gemini REST calls used by wfb do not return a reusable API-managed conversation handle. See docs/gemini_session_discovery.md for the discovery notes.

wfb therefore maintains local session history:

flowchart TD
    askCmd[geminiAsk] --> loadSession[loadLocalSession]
    loadSession --> buildPrompt[buildPromptHistory]
    buildPrompt --> geminiApi[GeminiGenerateContent]
    geminiApi --> appendTurns[appendUserAndModelTurns]
    appendTurns --> saveSession[saveLocalSession]

Session behavior:

  • wfb gemini ask targets the active session by default.
  • --session ID overrides routing for one call and makes that session active.
  • Each successful ask appends both the user prompt and Gemini response.
  • session inspect --format json exposes the stored history for orchestration.
  • session reset clears a session without deleting the session file.

Chat To World-State Sync

wfb can distill chat context into the SQLite world-state store after successful asks.

Mode and source of truth:

  • Chat is primary context.
  • World state is extracted, structured output.
  • Sync is session-default configurable and per-ask overridable.

Enable sync by default for a session:

wfb gemini session new --name triage --sync-world-state on

Or update an existing session:

wfb gemini session use --id sess_abc --sync-world-state on --world-state-db ~/.wfb/wayfarer.db --world-state-scope triage

Override for a single ask:

wfb gemini ask --prompt "..." --sync-world-state on --world-state-db ~/.wfb/wayfarer.db

Pipeline:

  1. ask gets model response and persists chat turns.
  2. If sync is enabled, wfb asks Gemini to emit a strict v1 seed envelope JSON.
  3. Envelope is validated with the same seed validators.
  4. Valid rows are upserted into the target DB via seed_db(...).

Failure semantics:

  • Sync failures are non-fatal for chat continuity.
  • Ask still succeeds and prints response.
  • Sync failures are emitted as deterministic warnings to stderr.

Session Summarization

Summarization is opt-in:

wfb gemini ask --auto-summarize on --prompt "continue"

When enabled and a session exceeds model-aware drift thresholds, wfb asks Gemini to summarize older turns. It then stores a synthetic history_summary message plus recent raw turns.

Important safety details:

  • Summaries are Gemini-generated only; there is no deterministic fallback.
  • If summary generation fails, ask fails and reports the API error.
  • Compacted state is persisted only after the final ask succeeds, so transient final-call failures do not overwrite raw history.
  • Summary artifacts are always included in prompt history even when --max-history-turns trims older ordinary turns.
  • Thresholds are drift heuristics, not hard Gemini context-window limits.

OAuth Setup

The open-source wfb CLI does not ship a centralized OAuth client secret. Users provide their own Desktop OAuth client JSON at:

~/.wfb/client_secret.json

Reference:

Troubleshooting:

  • If browser-open fails, copy/paste the printed auth URL manually.
  • For headless/manual environments, run wfb init --no-browser.
  • If token refresh fails, rerun wfb init --force-login.
  • In testing-mode OAuth projects, refresh tokens may expire periodically and require re-login.

World-State Reference

The SQLite world-state store is the original relational context channel. It is useful for durable, structured facts that agents should be able to query or summarize without replaying chat history.

Seed Envelope

Top-level JSON object:

Field Required Notes
version Yes Integer; must equal 1.
generated_at No ISO-8601 UTC string recommended.
source No Short origin label, e.g. gemini or cursor.
active_tasks No Array; omit or [] for none.
environmental_constraints No Array; omit or [] for none.
style_specifications No Array; omit or [] for none.

Example:

{
  "version": 1,
  "generated_at": "2026-05-05T23:00:00Z",
  "source": "gemini",
  "active_tasks": [],
  "environmental_constraints": [],
  "style_specifications": []
}

Record Shapes

Validation runs before any DB writes. metadata, when present, must be a JSON object and is stored as compact JSON text in metadata_json.

active_tasks[]

Field Required Type Constraints
id Yes string Primary upsert key.
title Yes string
status Yes string One of pending, in_progress, blocked, done.
priority No int Default 0.
owner No string
due_at No string ISO-8601 recommended.
notes No string
source No string Overrides envelope source.
metadata No object

environmental_constraints[]

Field Required Type Constraints
id Yes string Primary upsert key.
kind Yes string One of tool_version_warning, policy, runtime_limit, dependency, other.
name Yes string
value Yes string
severity Yes string One of info, warn, error.
scope No string e.g. global, repo, task:<id>.
source No string Overrides envelope source.
metadata No object

style_specifications[]

Field Required Type Constraints
id Yes string Primary upsert key.
category Yes string One of tone, formatting, coding_style, workflow, other.
rule Yes string
priority No int Default 0.
applies_to No string e.g. all, python, docs.
source No string Overrides envelope source.
metadata No object

Upsert Semantics

  • Rows are inserted or updated by id.
  • updated_at is refreshed on every successful write.
  • Row source uses item source, then envelope source, then NULL.
  • Unknown top-level envelope keys are rejected.
  • Unknown keys inside entity records are rejected.

SQLite Schema

wfb init creates a v1 schema with one schema_version row and three entity tables:

  • active_tasks
  • environmental_constraints
  • style_specifications

Indexes:

  • idx_active_tasks_status
  • idx_constraints_severity
  • idx_style_priority

The implementation source of truth is wfb_db.py.

wfb status --format json

Top-level shape:

{
  "version": 1,
  "db_path": "/Users/you/.wfb/wayfarer.db",
  "summary": {
    "tasks": {
      "pending": 0,
      "in_progress": 0,
      "blocked": 0,
      "done": 0
    },
    "constraints": {
      "info": 0,
      "warn": 0,
      "error": 0
    },
    "style_specifications": 0
  },
  "highlights": {
    "tasks": [],
    "constraints": [],
    "style_specifications": []
  },
  "updated_at": {
    "active_tasks": null,
    "environmental_constraints": null,
    "style_specifications": null
  }
}

db_path is the resolved absolute database path. highlights.* rows use SQL column names; metadata_json remains a JSON string.

Exit Codes

Code Meaning
0 Success.
2 CLI usage / argument error.
3 Validation error.
4 Database error.
5 File I/O, OAuth, token refresh, network, or Gemini API error.

Implementation Notes

  • Python standard library only.
  • No external Python package requirements.
  • wfb.py is the CLI entrypoint.
  • Supporting modules:
    • wfb_paths.py: local asset paths.
    • wfb_db.py: SQLite schema and lifecycle.
    • wfb_oauth.py: OAuth installed-app flow and token storage.
    • wfb_gemini_api.py: Gemini REST client, model calls, summarization.
    • wfb_gemini_sessions.py: local session storage and compaction helpers.
    • wfb_chrome_bridge.py: stdlib CDP discovery, websocket, and page inspection helpers.
    • wfb_chrome_session.py: persisted Chrome target attachment record helpers.

The security posture is intentionally conservative: local-first, stdlib-only, no shared OSS OAuth client secret, and no vendored third-party libraries yet. A deeper security review is still future work.

Known Limits / Next Work

  • No direct browser Gemini session attach through official API endpoints validated so far.
  • Chrome bridge is currently macOS-focused for launch ergonomics.
  • wfb chrome inspect is read-only text extraction only (no click/type/navigation automation).
  • No retry/backoff policy for transient Gemini 429 / 503 errors yet.
  • No tool/function-calling support yet.
  • Summarization thresholds are heuristic and should be adjusted with real usage.
  • Planned next CLI ergonomics after webview support include wrapper capture flow and trust-profile work.

Packaging and Release (PyPI-style)

Build distribution artifacts:

python3 -m pip install --upgrade build
python3 -m build

This generates:

  • dist/wfb-0.1.0.tar.gz (sdist)
  • dist/wfb-0.1.0-py3-none-any.whl (wheel)

Check artifacts before upload:

python3 -m pip install --upgrade twine
python3 -m twine check dist/*

Upload to TestPyPI:

python3 -m twine upload --repository testpypi dist/*

Upload to PyPI:

python3 -m twine upload dist/*

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wfb-0.1.2.tar.gz (57.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wfb-0.1.2-py3-none-any.whl (42.7 kB view details)

Uploaded Python 3

File details

Details for the file wfb-0.1.2.tar.gz.

File metadata

  • Download URL: wfb-0.1.2.tar.gz
  • Upload date:
  • Size: 57.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for wfb-0.1.2.tar.gz
Algorithm Hash digest
SHA256 8d998c4cc7838bc2e10c0a2011bfd98d970c486de0b944ccc3614c093353cc9e
MD5 b0507de6b0694e76900bb1dd869756d6
BLAKE2b-256 e3a9c6b02a627d0c728b99a50be36a7df486328ba5af4996f3ff7495c034eaaf

See more details on using hashes here.

File details

Details for the file wfb-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: wfb-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 42.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for wfb-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 bdfee902d6c8debafa4a2933df8061c6f8a1774d6170dbeed7eb794781880fb0
MD5 32a49fcaa285ad38ebd4a01326a28c84
BLAKE2b-256 0645fa3ad3c9c9a7be0cfb7a955e5473b8a1f7736718181052396b7d47867394

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page