Skip to content

0.26.1

Choose a tag to compare

@zackbart zackbart released this 27 Sep 01:54
· 1 commit to main since this release
484b6d5

This patch fixes slow OAuth restarts, unbounded downstream authorization waits,
and operator pages that signed people out after a temporary load failure.
Connect now opens consent in one click, and browser-facing pages share the
configured theme. Agent guidance preserves one-time write results and keeps
an authorized batch in one resumable program. Approval defaults and the eight
MCP tools are unchanged. No configuration or storage migration is required;
deployments without the operator UI can ignore the page changes. OAuth starts
abort downstream work after 30 seconds, but uncancellable storage resets and
cleanup must finish before the response. Restart reuses a matching client
registration; a revoked client may still fail at consent or callback and need
another restart. The Node template now pins 0.26.1.

Added

  • Continue or restart an operator OAuth start. POST /ui/oauth/<id>
    takes ?mode=continue or ?mode=restart. restart, still the default
    when mode is absent, creates a new epoch and clears the grant and
    discovery while retaining a matching issuer-bound client registration. continue hands back the pending
    authorization URL when it was written in the last ten minutes. Otherwise it
    starts a flow in the current epoch, reusing a stored registration when one
    exists. A first connection still registers dynamically. A disconnected
    connector resets first. A response with a URL now carries reused. A continue that reused a
    URL or found the connection healthy leaves the cached catalog alone. Any
    other mode is a 400. After a publicUrl change, continue keeps a client
    registered for the old callback, which the authorization server refuses;
    restart recovers. ConnectorStatus gains the optional
    authorizationReused, set by remoteMcp()'s startAuth.

Changed

  • Pending authorization URLs expire for reuse. A non-forced startAuth,
    including authorize_connector without force, reissues a pending URL only
    when it is under ten minutes old. The pending URL's envelope now records its
    write time, which older readers ignore. A URL written before this release,
    or under a pre-epoch generation, starts a fresh flow instead.

  • OAuth cleanup deletes run concurrently. A restart's epoch cleanup,
    clearPending, and invalidateCredentials("all") keep up to six deletes
    in flight, the Workers limit on simultaneous connections. Every delete is
    still attempted, and a falsy rejection now counts as a failure. A retired
    epoch's manifest is still removed only after all of its values. Catalog
    invalidation deletes the root and its chunks together under the registry's
    chunk I/O bound, so a failed root delete no longer skips the chunks.

  • Every page connecta renders for a person now shares one token layer and one
    layout: the operator shell, the OAuth callback, a browser's 404, and the
    artifact frame follow branding.theme and light or dark. The OAuth callback
    names the outcome in its heading with a status mark, names the connector by
    title only after the state check, uses branding.productName in its copy,
    and folds the agent fix prompt under "Details for the operator". Refusals
    stay byte-identical across connectors and paths.

  • A request whose Accept names text/html gets a themed 404 page; every
    other client keeps the plain Not Found body.

  • Markdown artifacts take the deployment's resolved scheme and tokens instead
    of the OS palette, and drop an opening # Heading that only repeats the
    title the viewer already shows. The frame waits on the viewer's surface with
    a loading line, and says so if the page never arrives.

  • Without the operator UI, callback and 404 pages no longer link the default
    /favicon.svg, which only the UI serves.

  • The operator UI starts OAuth in one click. Connect opens the provider's
    page in a new tab straight away and asks the server to continue a pending
    authorization rather than restart it; only Reconnect on a healthy
    connection restarts, behind an in-page confirm. A tab returning to the page
    quietly re-reads the status of connectors waiting on authorization.

  • Operator UI notices appear in the card that caused them, in fixed
    sentences rather than the route's error text; problems fixed by authorizing
    or adding a credential are warnings rather than errors, with one primary
    action per row. Activity and artifact states, the confirm dialogs, the
    mobile masthead, and the vocabulary shown to people (outcomes, actors,
    timestamps) now read the same across pages and use branding.productName.

Fixed

  • Operator OAuth starts now abort downstream discovery and registration after
    30 seconds or browser cancellation, with a fixed timeout response. Every
    reset already started by the request, including issuer-mismatch recovery,
    drains before catalog invalidation and response so a delayed generation
    write cannot replace a later flow. These uncancellable storage waits can
    exceed the deadline. Disconnect still finishes after browser cancellation.
  • Forced OAuth restarts reuse registrations bound to the issuer, redirect URI,
    client metadata, connector settings, and owner partition. Credentials are
    re-sealed for the replacement epoch, and fresh discovery detects issuer
    changes. Disconnect and issuer-mismatch recovery discard the registration.
    The SDK cannot detect a revoked client while constructing a consent URL;
    a callback refusal clears it so the next restart can register again.
  • Agent sampling advice now applies to reads. For a one-time write, agents
    reduce the full result in the program or page a direct-call result through
    get_result, without repeating the write to recover discarded output.
  • Authorized batches stay in one resumable program. Guidance explains how
    tool-scoped approval covers repeated calls to one address while other
    approval-required writes retain their own approvals. The call-scoped
    default and host enforcement are unchanged.
  • A restart's cleanup no longer grows with every earlier restart. Each
    OAuth restart re-deleted every epoch the connector had ever retired, one key
    at a time, and restart 1,001 failed forever with a full cleanup backlog. A
    restart now deletes the epoch it retires, retries any of the eight most
    recent epochs whose cleanup failed (their manifest outlives their values),
    and sweeps at most 16 epochs retired more than 24 hours ago, dropping each
    from the lineage only when all of its keys are gone. A Disconnect that
    reported a failed cleanup still deletes the old grant when retried. The
    cleanup work stays bounded independently of earlier resets. Residue a late
    writer leaves in a younger epoch stays unreadable behind the fence until the
    sweep reaches it. A late writer whose cleanup fails in an epoch already
    listed now restarts that epoch's grace. The accepted assumption is that no
    request holds a retired epoch for a day. The lineage records retirement
    times in a sibling record older releases ignore, and its cap rises to 5,000
    epochs. A connector stuck at the old 1,000 wall restarts the day it
    upgrades. Rolling back is clean unless a lineage has grown past 1,000. See
    auth.
  • A failed or unreachable /ui/data no longer signs the operator out. Only a
    401 or 403 on that read returns to the token gate; anything else keeps the
    page and offers Retry. A connector whose details fail to load says whether
    the session, the browser's connection, or the downstream service is at
    fault, and only the last offers the fix prompt.