# Changelog

All notable user-facing changes to `pi-xai-oauth` are recorded here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and version numbers follow [Semantic Versioning](https://semver.org/).

Dates below are npm publication dates. The earliest rapid-release series is grouped where the repository did not preserve reliable per-version release notes.

## Unreleased

## 1.4.0 - 2026-07-23

### Added

- Added disabled-by-default, session-scoped vision routing for exact authenticated text-only entitlements, with deterministic exact-catalog target selection, a bounded image-only description request, final image-free enforcement, lifecycle invalidation, and `/xai-tools` cost/privacy controls.
- Added the listener-owned, versioned `pi-clickable-menu:xai-tools` bridge contract, covering its canonical channel, request shape, action timing, and honest result semantics.
- Added disabled-by-default `xai_image_to_video` with pinned create/status polling, DNS-pinned unauthenticated MP4 download, bounded streamed private storage, and honest remote-job cancellation semantics.
- Added ModelRuntime re-registration coverage, a store-backed models-store precedence regression (discard stale overlays when the local catalog is newer), and request-auth tests that prefer `ModelRuntime.getAuth` over the legacy `getApiKeyAndHeaders` projection.
- Added opt-in network-tool and OAuth-only usage support for Pi's built-in `xai` provider, with active-provider credential preference, subscription/API-key provenance routing, and explicit isolation from package-owned catalog, stream, vision, and local-adapter behavior.

### Changed

- Recorded the package-scope decision to keep provider-neutral goal/plan workflows, autonomous continuation, runtime plan management, and write-restriction policy out of `pi-xai-oauth`; see [ADR 0001](docs/decisions/0001-goal-plan-package-scope.md).
- Reviewed Pi 0.80.8 through 0.81.0 and adopted 0.81.0 as the latest exact tested boundary after clean packed candidate validation, while preserving the 0.80.1 minimum.
- Reviewed Pi 0.81.1 and adopted it as the latest exact tested boundary after clean packed candidate validation, while preserving the 0.80.1 minimum and `>=0.80.1 <0.82.0` peer range.
- Widened aligned Pi peers to `>=0.80.1 <0.82.0` and pinned development metadata exactly to 0.81.1.
- Migrated extension request-auth resolution to prefer `ModelRuntime.getAuth` when the host exposes it, then the ModelRegistry `getApiKeyAndHeaders` / `getProviderAuth` projections for older supported boundaries.
- Deferred adopting Pi's `refreshModels(context)` provider hook: account-bound `/models-v2` discovery still needs login-generation tracking, force-refresh after credential switch, and package-owned token-free cache TTL/stale policy that the generic hook does not replace.

### Fixed

- Fixed the `pi-clickable-menu:xai-tools` bridge so malformed action, tool, and command-context fields are rejected before dispatch and every request with a callable `done` receives exactly one result.
- Fixed the `pi-clickable-menu:xai-tools` bridge so `status`, `enable`, and `disable` return the shared command handler's actual success or failure instead of acknowledging toast-only failures as successful.
- Fixed the `pi-clickable-menu:xai-tools` bridge so `action: "open"` acknowledges `done` when the interactive picker is accepted for launch, instead of waiting until the picker closes (avoids the menu host's ~4s false timeout).
- Consolidated duplicate `xai_web_search` and Grok-native `web_search` registrations into one collision-safe, opt-in `web_search` picker entry. The old `xai_web_search` command spelling remains an input-only compatibility alias, and the public name is still never registered globally.
- Contained the direct Grok-native `read_file`, `search_replace`, and `list_dir` adapters to resolved workspace paths, safely limited missing-leaf creation to contained physical parents, and capped package-owned full text reads at 5,000,000 bytes. `run_terminal_command` remains an unrestricted delegation to pi `bash`, so this is direct-adapter defense-in-depth rather than a filesystem sandbox.
- Restricted legacy local PNG/JPEG inputs across custom tools, Responses payload normalization, and vision routing to byte-bounded, byte-validated regular files inside the active workspace, with sanitized failures for traversal, outward symlinks, special files, MIME spoofing, oversized sources, and pixel bombs.
- Fixed opt-in vision routing so enabled sessions advertise image input only to Pi's delegated Responses converter, retain truthful text-only metadata elsewhere, recursively strip nested historical image and screenshot shapes, reapply consumed-history pruning after caller payload hooks, route only current unconsumed user/tool images, and bind each request to its original reset-sensitive authorization grant.
- Kept vision-routed images available across mid tool-loop turns so multi-step image work does not drop the original user/tool image after the first model hop.
- Pinned managed credential lookup for network tools and `/xai-usage` to the active xAI-compatible provider (`xai` or `xai-auth`) instead of falling through to a sibling provider's stored credentials, and derived `catalogScope: "host"` from the credential's provider id.
- Pinned public IPv4 resolution for dual-stack xAI video downloads so IPv6-only download hosts fail closed.
- Handled empty web-search responses without treating a successful empty result set as a transport failure.

## 1.3.6 - 2026-07-18

### Added

- Added encrypted reasoning replay on the pinned OAuth Responses route, including final `store:false` defaults, deduplicated encrypted-content requests, complete inline typed-item persistence/replay, exact provider/API/model isolation, and fixed redacted mismatch guidance.
- Added a revision-pinned Grok Build wire-protocol matrix, ID-ownership policy, repeatable upstream review procedure, and an explicit encrypted-reasoning handoff to issue #79.
- Added deterministic streaming/direct Responses, catalog, OAuth form, client-mode, media-boundary, reserved-header, bounded-error, and proxy version-gate request-shape coverage.
- Added bounded authenticated `acceptsImages` / `inputModalities` normalization with explicit input-capability provenance and redacted schema fixtures.
- Added focused typed Vitest regressions across provider/catalog routing, browser/device OAuth and OIDC, Responses payloads/streams/errors, images, network-tool lifecycle, custom tools, Cursor shims, and setup/settings.
- Added the disabled-by-default `xai_edit_image` tool with exact singular/plural Imagine edit payloads, a distinct pinned `/images/edits` route, timeout/cancellation, and redacted errors.
- Added reusable bounded media primitives for byte-validated PNG/JPEG data URLs and workspace files, source-backed compression, explicit request/response/output budgets, and atomic 0700/0600 Pi-session storage.
- Added the explicit `/xai-usage` command with pinned authenticated `/user` identity resolution followed by the unofficial revision-pinned `/billing?format=credits` lookup.
- Added an optional session-only compact usage status that is off by default, refreshes no more than once per minute after completed xAI turns, and clears on model, provider, account, and session changes.
- Added fixture-based usage parser, transport, cancellation, redaction, command, bounds, and status-lifecycle coverage.
- Added a small real Pi extension-loader smoke plus V8 text/JSON/LCOV coverage with measured regression floors.
- Added a browser-first native login-method selector with device authorization for SSH, WSL, containers, remote workspaces/VMs, and human-operated headless sessions.
- Added pinned, bounded, cancellable RFC 8628 polling with initial wait, server interval plus cumulative `slow_down`, denial/expiry handling, strict secret-safe schema validation, and deterministic timing tests.
- Added authenticated OAuth-visible model discovery from the official CLI proxy `/models-v2` endpoint.
- Added defensive model normalization plus an atomic, token-free last-known-good cache with a 15-minute fresh TTL, a 5-second bounded refresh, and a 7-day stale-if-transient window.
- Added fixture-based coverage for catalog additions, removals, empty entitlements, malformed entries, API-key-only filtering, cache freshness, auth/network failures, and curated fallback selection.
- Added packed-package compatibility validation at exact Pi 0.80.1 and 0.80.10 boundaries, with requested/resolved version reporting, range and registry-drift checks, packed-manifest inspection, and unsupported-peer install diagnostics.
- Added PR/main CI that derives its exact compatibility matrix from the checked-in Pi version policy instead of reusing the development lockfile version.

### Changed

- Centralized xAI wire headers around pinned routes, truthful `pi-xai-oauth/<version>` attribution, package-controlled proxy versioning, and shared OAuth form metadata.
- Migrated the normalized model cache to schema 2 while safely retaining schema-1 membership and rederiving legacy input as known/default rather than authenticated evidence.
- Bounded the unofficial usage transport to pinned endpoints, rejected redirects, 15-second request timeouts, 64 KiB bodies, bounded JSON complexity/history, and conservative numeric/timestamp ranges.
- Replaced the shared-state monolithic behavior verifiers with isolated per-domain suites and closure-local fixtures; production runtime behavior is unchanged.
- Made the repository CI job run the full unit suite once under coverage and the loader smoke separately; packed compatibility jobs rerun unit, loader, and TypeScript checks at each exact Pi boundary.
- Centralized xAI endpoint selection around explicit OAuth-session versus API-key credential provenance instead of model IDs.
- Kept Grok Build and Composer payload, header, and tool compatibility separate from transport routing.
- Updated fresh OAuth logins to request xAI's current eight-scope Grok client grant, including conversation read/write access, while leaving existing refresh grants compatible.
- Derived the proxy client identifier and version from this package's own metadata instead of impersonating a stale Grok CLI release.
- Made the authenticated account catalog authoritative for OAuth model additions and removals; known static metadata now enriches returned IDs without advertising unreturned models.
- Made successful login force-refresh and immediately replace the model catalog, while `/reload` follows the documented cache TTL.
- Kept browser authorization-code + PKCE as the desktop default while recommending device login in remote/headless selector copy without automatically changing the selected method.
- Replaced wildcard Pi peers with the aligned, bounded `>=0.80.1 <0.81.0` range and pinned development metadata exactly to the latest tested boundary, 0.80.10.
- Reviewed Pi 0.80.8 through 0.80.10 and adopted 0.80.10 after clean packed candidate validation, while preserving the 0.80.1 minimum and existing peer range.
- Documented the deliberate candidate-test and review process required before widening support to another pre-1.0 Pi line.

### Fixed

- Kept startup credential discovery compatible with Pi 0.80.1 and Pi 0.80.10 by using the new read-only `readStoredCredential()` API when available and a synchronous JSON-only fallback on older supported hosts, without creating credential storage.
- Migrated the real Pi credential-persistence integration test to exercise `ModelRuntime` and `InMemoryCredentialStore` on current Pi while retaining the legacy boundary path.
- Explicitly negotiated `text/event-stream` for streaming Responses while keeping direct Responses and media requests on JSON Accept semantics.
- Scrubbed caller/model authorization, content negotiation, User-Agent, proxy metadata, generic delegate affinity IDs, unsupported IDs, and unknown `x-grok-*` headers before applying the approved route contract.
- Rejected redirects for streaming/direct Responses and media POSTs before fetch can replay request bodies or metadata to another origin.
- Replaced raw direct-response error reflection with bounded status/route classification and actionable, non-impersonating proxy version-gate guidance.
- Prevented authenticated text-only entitlements from sending image-bearing Responses payloads, including payload-hook mutations and image-input custom tools, without changing image generation.
- Canonicalized final Responses payloads before model and modality enforcement, detected computer screenshots, disabled unsafe delegated retries, and hardened wide-payload traversal so custom serializers cannot bypass authenticated text-only policy.
- Made usage credential and identity resolution fail closed before billing, rejected stored/runtime API-key provenance, and prevented account identity, authenticated headers, raw response bodies, and transport details from being cached, persisted, logged, or reflected in errors.
- Removed the unbound raw authorization-code fallback; pasted browser completions require matching OAuth state, and raw-code users are directed to device login or a complete state-bound redirect URL.
- Pinned xAI OIDC discovery and JWKS policy and validated fresh-login ID-token ES256 signatures, signing keys, issuer, audience, expiry, and nonce before retaining credentials.
- Stopped reflecting xAI token endpoint response bodies in authentication errors.
- Routed normal streaming and separate Responses helpers for every `xai-auth` model through the official Grok CLI session-token proxy, matching the intended OAuth/session-token transport contract for Responses traffic.
- Preserved the official direct `api.x.ai` Images endpoint for OAuth-backed image generation while keeping a future explicit API-key Responses route on the public API.
- Added the complete CLI-proxy authentication, client-mode, request, conversation, session, and model metadata to every OAuth Responses request, with required values protected from caller overrides.
- Filtered hidden, malformed, unsupported-backend, secret-bearing, and known API-key-only entries such as `grok-build-0.1` from the OAuth provider catalog.
- Invalidated stale entitlement data after authentication/permanent failures and prevented a forced post-login refresh from reusing another account's stale cache.
- Prevented device authorization failures, denial, expiry, cancellation, malformed data, and missing access/refresh tokens from returning or replacing credentials; device ID tokens are not retained without browser nonce validation.

## 1.3.5 - 2026-07-15

### Changed

- Replaced the repeated `/xai-tools` TUI selector with one persistent picker.
- Added arrow and page navigation, Enter or Space toggling, and Escape-to-close controls without rebuilding the list.
- Updated TypeScript and Node.js development type dependencies.

### Fixed

- Preserved the highlighted tool and scroll position after enabling or disabling a tool.
- Kept the existing selector behavior for RPC clients.
- Tightened npm package exclusions for local development artifacts.

## 1.3.4 - 2026-07-15

### Added

- Added the package-owned `/xai-tools` command with an interactive picker plus `status`, `enable`, and `disable` arguments.
- Added category and cost-risk context for all network-backed xAI tools:
  - `xai_generate_text`
  - `xai_web_search`
  - `xai_x_search`
  - `xai_multi_agent`
  - `xai_deep_research`
  - `xai_code_execution`
  - `xai_generate_image`
  - `xai_analyze_image`
  - `xai_critique`
  - `WebSearch` for Grok Build and Composer models

### Changed

- Made every helper that sends an additional xAI request inactive by default and explicitly opt-in for the current session.
- Kept local filesystem and shell compatibility shims automatic for eligible Grok Build and Composer models because they do not make additional xAI requests.
- Reset outbound-tool activation at session start and when switching away from eligible xAI models.

### Fixed

- Isolated the xAI Responses transport from unsupported root-module assumptions.
- Blocked disabled tools before OAuth credential resolution or network access.
- Made tool-registry failures fail closed and prevented stale activation from bypassing explicit authorization.
- Fixed paid web, X, multi-agent, deep-research, and `WebSearch` gating.
- Fixed repeated screenshot and image replay in long Responses conversations.
- Added consumed-image cleanup, safe image compaction, and a 3 MiB aggregate inline-image transport budget with clear local failures.
- Normalized multimodal Responses payloads, image-bearing tool results, and active-model routing.

## 1.3.3 - 2026-07-11

### Fixed

- Routed xAI Responses streaming through pi-ai's compatibility dispatcher so pi 0.80's extension loader no longer rewrites a subpath into an invalid module path.

## 1.3.2 - 2026-07-11

### Fixed

- Added initial compatibility with the pi-ai 0.80 Responses API.
- Scoped Cursor/Grok CLI compatibility shims to eligible models so they no longer leaked into normal Grok requests.

## 1.3.1 - 2026-07-09

### Fixed

- Improved setup cleanup so duplicate local and npm installations are detected and pruned instead of causing tool-name conflicts.

## 1.3.0 - 2026-07-08

### Added

- Added Grok 4.5 with text and image input, a 500K context window, and `low`, `medium`, and `high` reasoning levels.
- Added Grok 4.5 fast mode through `low` reasoning effort on the same model ID.

### Changed

- Made Grok 4.5 the default model across provider registration, setup, and documentation.
- Added stable Responses cache and conversation identifiers for more reliable multi-turn cache reuse.
- Hardened Grep argument normalization and missing-pattern errors for Grok CLI compatibility.

## 1.2.6 - 2026-07-07

### Fixed

- Corrected xAI image-generation request parameters and rejected the unsupported `size` option locally.
- Preserved support for generating one to four images with the active xAI image model.

## 1.2.5 - 2026-06-20

### Fixed

- Refreshed the npm compatibility guidance and Node.js development type dependency.

## 1.2.4 - 2026-06-20

### Fixed

- Added the xAI API guard delegate required by pi 0.79.8+ for OpenAI Responses streaming.
- Added direct verification against pi 0.79's guarded provider path.
- Hardened OAuth wrong-state verification timeout behavior.
- Resolved repository CodeQL findings.
- Excluded agent worktrees from npm packages.

## 1.2.3 - 2026-06-04

### Fixed

- Corrected manual OAuth callback-code parsing.

## 1.2.2 - 2026-06-04

### Added

- Added Grok Build and Composer 2.5 Fast through the Grok CLI OAuth endpoint.
- Added Grok 4.20 reasoning, non-reasoning, and multi-agent model variants.
- Added Cursor/Grok CLI compatibility shims for filesystem, search, shell, todo, and native `WebSearch` tool calls.

### Changed

- Split the original monolithic extension into focused OAuth, authentication, model, payload, Responses, and tool modules.

### Fixed

- Repaired xAI OAuth provider registration, token reuse and refresh, Responses streaming, payload normalization, and custom-tool integration.
- Added automated extension verification for provider, model, tool, authentication, and streaming behavior.

## 1.2.1 - 2026-05-17

- Republished the same Git revision as 1.2.0. The repository records no source difference between these two npm versions.

## 1.2.0 - 2026-05-17

- Short-lived publishing transition superseded by 1.2.1. The npm package metadata points to the same Git revision for both versions.

## Initial series - 2026-05-16 to 2026-05-17

### 1.0.25-1.0.26

- Added OAuth-first image generation, image analysis, critique, and deep-research tools.
- Added advanced X-search filters and moved remaining custom tools to shared OAuth token resolution.
- Added provider payload sanitization, repository security policy, contribution templates, and agent scaffolding support.
- Removed an erroneous package self-dependency and cleaned npm package contents.

### 1.0.19-1.0.22

- Added the one-command installer and automatic settings configuration.
- Fixed browser-based OAuth launch and duplicate authorization URLs.
- Improved native web and X search prompting and added multimodal image input support.
- Fixed xAI image Responses payload serialization.

### 1.0.12-1.0.17

- Reworked the extension structure, completed the OAuth flow, improved tool registration, and added automatic browser opening.
- Added clean npm packaging and the first setup experience.

### 1.0.1-1.0.9

- Added Responses API transport, reuse of `~/.grok/auth.json`, device-code authentication, and refresh-token support.
- Added text generation, multi-agent research, web search, X search, and code-execution tools.
- Added initial agentic model-change behavior and expanded usage documentation.

### 0.1.0

- Initial npm release with the `xai-auth` OAuth provider, Grok 4.3, and configurable thinking levels.
