How AxiOwl Finds Existing Provider Chats

AxiOwl does not treat every chat tool as a blank slate. A major part of the Windows desktop implementation is discovery: finding provider chats that already exist, proving whether they are useful delivery targets, and saving them into AxiOwl's local agent registry so operators can address them by name.

That distinction matters. A file, database row, or provider state entry may prove that a chat once existed. It does not always prove that AxiOwl can safely send to it today. The current implementation keeps those two ideas separate: discovery can find evidence, but enrollment into the registry depends on identity fields, sendability, status, and provider-specific proof.

The Discovery Command

The user-facing command is:

axiowl discover <codex|codex-cli|vscode-native|vscode-copilot|copilot-cli|antigravity|antigravity-cli|cursor|cursor-cli|claude-code-cli|opencode-cli|all> [--target <agent>] [--json]

When the command runs, AxiOwl creates its state directories, runs the selected provider discovery routine, merges discovered rows into the registry, and prints either a text report or JSON lines. The registry itself lives under the AxiOwl state root. On Windows, that root is %LOCALAPPDATA%\AxiOwl, and the agent registry path is:

%LOCALAPPDATA%\AxiOwl\registry\agents.tsv

The registry row shape is intentionally explicit. It stores the AxiOwl agent ID, display name, aliases, provider, provider session ID, node ID, enabled flag, sendable flag, source, first seen time, last seen time, last verified time, and last error. That gives operators a durable list of addressable targets without hiding where the target came from.

What A Discovery Row Contains

Provider discovery returns DiscoveredAgent rows. Each row has a display name, provider, provider session ID, node ID, status, sendable flag, enrollment proof flag, source, evidence strings, last seen time, and last error.

That model is the reason AxiOwl can be conservative. A row can say "I saw a Codex thread in SQLite" while still refusing to enroll it as a sendable target. A different row can say "I saw a VS Code native chat session file with a usable title and ownership evidence" and enroll it immediately. Both are discoveries, but they have different trust levels.

The merge step skips rows with missing identity fields. It also refuses to enroll rows that do not prove sendability. If a row is valid, AxiOwl builds a stable agent ID from provider, node, and provider session ID, then adds helpful aliases such as the display name, a "<name> agent" variant, the provider session ID, and provider-specific session aliases.

Provider-Specific Sources

AxiOwl does not use one generic scraper for every tool. Each provider has its own source of truth and its own proof rules.

For local Codex, discovery checks known Codex state database candidates under .codex, the session_index.jsonl file, and .codex-global-state.json. It reads the threads table from Codex SQLite state and looks for active user threads, desktop state references, active workspace references, titles, current working directories, and update timestamps. On Windows, stronger local Codex enrollment proof can come from desktop thread state or targeted desktop IPC ownership, while weaker SQLite-only evidence is treated as evidence-only unless it meets the provider policy.

For Codex CLI, AxiOwl also reads Codex state, but it narrows results to execution-sourced sessions or sessions already registered as codex_cli. On non-Windows builds, an exec thread can be treated as a CLI resume target when the title is usable and the row is sendable.

For VS Code native chat, AxiOwl reads chat session JSONL files from VS Code workspaceStorage and from the empty-window chat session storage. It extracts a session ID and visible title, resolves ownership evidence for the VS Code bridge, and creates provider session IDs in the vscode_native:session:<id> shape.

For VS Code Copilot-backed sessions, AxiOwl reads YAML state under .copilot/session-state, uses the YAML name as the visible title, and creates session IDs in the copilot_cli:session:<id> shape. It also checks the VS Code Copilot patch status; if the patch state blocks delivery, the row is marked unhealthy instead of sendable.

For standalone Copilot CLI, AxiOwl reads .copilot/session-state workspace YAML files, verifies that the session is a standalone CLI session, checks that the recorded working directory still exists, finds the Copilot executable, and looks for explicit headless authentication through environment variables such as COPILOT_GITHUB_TOKEN, GH_TOKEN, GITHUB_TOKEN, or COPILOT_PROVIDER_BASE_URL. Without that proof, the row can be discovered but not promoted to a proven sendable target.

For Antigravity, discovery reads annotation files under .gemini\antigravity\annotations, extracts titles from protobuf-text-like or JSON-like fields, and creates provider session IDs in the antigravity:cascade:<id> shape.

For Cursor, discovery reads Cursor's global state SQLite database under the user application data directory, queries ItemTable for composer headers, extracts composer IDs and names, and creates provider session IDs in the cursor:composer:<id> shape. Archived composers are not sendable. Composer IDs must be stable UUIDs, and Cursor patch status can also block sendability.

Remote discovery follows a different path. A remote target is discovered by SSHing to an enrolled node and asking that node to run its own axiowl discover codex --json --target .... The local machine then records the returned target as a remote provider row tied to that node. That means remote discovery is based on the remote node's own local evidence, not on a public manager port.

Targeted Discovery After a Miss

Discovery is not only an installer-time action. AxiOwl also has targeted miss resolution. If a requested target is not already present as a usable registry entry, AxiOwl can search provider discovery functions in order and stop when it finds a sendable target.

The current local sequence checks local Codex, Codex CLI, VS Code native, VS Code Copilot-backed, Copilot CLI, Antigravity, Antigravity CLI, Cursor, Cursor CLI, Claude Code CLI, and OpenCode CLI. The targeted path logs how many rows were found, how many were evidence-only, how many were enrolled or updated, and why the search stopped.

This is useful in day-to-day operation because the operator does not have to manually register every existing chat before trying to send to it. If the provider state contains enough proof, AxiOwl can repair the missing registry entry and continue with a real target.

Evidence Is Not Permission

One of the most important implementation details is that AxiOwl separates discovery evidence from permission to treat a chat as sendable.

Local Codex is the clearest example. A thread found in SQLite may be real, but the Codex policy marks some sources as evidence-only, including active workspace references and SQLite rows without desktop state. Stronger sources, such as desktop thread state, targeted desktop IPC ownership, manual registration, MCP host metadata, or supported CLI execution evidence, rank higher. This prevents AxiOwl from silently treating every historical state row as a live destination.

The merge logic also protects manual rows. If an operator manually added a registry entry, later discovery can enrich it with aliases or last-seen timestamps, but discovery does not downgrade that manual row just because a provider scan returned weaker evidence.

Why This Matters

Provider chats are messy operational objects. They can move between desktop state, local databases, workspace storage, CLI state files, YAML records, and remote nodes. Titles can be missing. Some sessions are archived. Some IDs are not stable. Some provider integrations require a patch to be healthy before delivery is safe.

AxiOwl's discovery layer turns that messy provider state into a structured registry. It records where a chat was found, what ID should be used to address it, whether the target is sendable, and what evidence supports that decision.

The practical result is simple: operators can run discovery, inspect list agents, and send to known names without memorizing provider-specific storage paths. Developers still get the evidence trail they need when a target is skipped, marked stale, blocked by patch status, or left as evidence-only.

That is the point of AxiOwl's provider chat discovery. It is not just a convenience scan. It is a controlled promotion path from provider state to an addressable AxiOwl agent.