Skip to content

Httsig changes#11

Merged
rohanharikr merged 6 commits into
mainfrom
httsig-changes
May 22, 2026
Merged

Httsig changes#11
rohanharikr merged 6 commits into
mainfrom
httsig-changes

Conversation

@rohanharikr
Copy link
Copy Markdown
Contributor

No description provided.

rohanharikr and others added 6 commits May 15, 2026 14:50
--log is now a pure event log: HTTP exchanges, decoded JWTs, request/response
headers. Protocol explanation moves out of the CLI and into the prompt's
spec-draft reference, where an AI agent can fetch it on demand.

Removed from bootstrap --ps --log:
  - "What is AAuth?" opener prose
  - "Protocol parties:" block (AGENT / RESOURCE / PS / AS descriptions)
  - ASCII flow diagram (one-time + per-call)
  - "Key properties:" footer line
  - "You're about to run the one-time setup." closer line

Removed from fetch --log:
  - Same TL;DR block when marker stale
  - Condensed 4-line flow diagram + bootstrap pointer when marker fresh

Marker file (~/.aauth/.tldr-shown) logic dropped entirely — there's no
TL;DR left to suppress, so the read/write/freshness-check codepath becomes
dead. Removes node:os, node:path, node:fs imports from fetch/src/log.ts
and node:fs/node:path imports from bootstrap/src/log.ts.

Kept (these are log data, not pedagogy):
  - Step cards with numbered actor-prefixed titles and per-step prose
  - HTTP request/response data (headers, status, body)
  - Decoded JWT payloads with inline annotations
  - bootstrap Step 0 with bullet prose + identity data
  - fetch Already-set-up block (agent identity that will sign requests)
  - fetch This-call block (per-invocation params)
  - Closing summary line

Net: bootstrap/src/log.ts −69 lines, fetch/src/log.ts −78 lines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The ← preceding `HTTP/1.1 200 OK` (and similar) on every response line
was wrapped in c.dim(), making it visibly fainter than the rest of the
status line. Strip the dim wrapper so the arrow renders in the terminal's
default colour, matching the surrounding text.

Two call sites:
  - fetch/src/log.ts statusLine() — used by every step card's response
  - bootstrap/src/log.ts renderStep0() — PS metadata response

Other arrows unchanged: step-header → between actors stays plain, the
consent-prompt → Open stays bold, inline annotation arrows (← same key
as Step 1) stay dim because the whole annotation reads as a footnote.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Events emitted by mcp-agent now carry the real on-the-wire signed
request (Signature, Signature-Input, Signature-Key with full JWT,
Content-Type, Content-Digest, Prefer, Aauth-Capabilities, etc.) plus
request body for POSTs and response body for the 401 challenge / 202
deferred / PS metadata steps. Previously consumers had to fabricate
these values or rely on hardcoded placeholders.

How it works:
  - signed-fetch.ts: createSignedFetch gains an optional
    `onSigned: (sent: CapturedSent) => void` callback. When provided,
    it calls @hellocoop/httpsig with returnSent: true, fires the
    callback synchronously with the captured request, returns just the
    Response (so existing return-type expectations are unchanged).
  - aauth-fetch.ts/token-exchange.ts/deferred.ts: a shared
    `sentTracker: { latest: CapturedSent | undefined }` is threaded
    through. onSigned updates `sentTracker.latest`. Each emitting site
    reads `sentTracker.latest?.headers` immediately after the awaited
    signedFetch() returns (onSigned fires synchronously inside it, so
    no race) and attaches to the next emitted :done event.
  - log-helpers.ts: captureSentFromHttpsig() converts httpsig's
    Headers-object SentRequest to a JSON-serialisable CapturedSent
    with plain Record<string, string> headers. peekResponseBody()
    clones the Response so the body can be read for logging without
    consuming it for downstream code.
  - types.ts: AAuthEvent gains optional request_headers, request_body
    fields. New CapturedSent type.

Response bodies are peeked (via Response.clone().text()) for the 401
challenge in aauth-fetch.ts, the 202 deferred response and PS metadata
in token-exchange.ts. Bodies for 200 responses aren't peeked because
downstream code consumes them via .json() and we'd rather not double-buffer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two related changes to the fetch + bootstrap --log UX.

1. Explicit format flags replace TTY auto-detect
   - --log: always pretty narrative on stderr
   - --jsonl (alias --ndjson): always one JSON object per line on stderr
   - both: error ("--log and --jsonl are mutually exclusive (same
     events, different formats). Pick one.")
   - neither: silent
   buildLogEmitter now takes an explicit `LogMode` enum instead of a
   boolean + TTY check. AAUTH_FORCE_PRETTY env-var override is no
   longer needed (kept for now in case existing tests use it).

2. Render real signed headers, with shared prose
   fetch/src/log.ts renderRequestHeaders() now takes a real
   Record<string, string> of captured headers (from the mcp-agent
   event's request_headers field) instead of synthesising
   `created=<Date.now()>`, `sig=:<base64 signature>:`, etc. Headers
   render in canonical order (Content-Type, Content-Digest, Prefer,
   Signature-Input, Signature, Signature-Key) with display truncation
   for the long base64 values: signature → `=:<first 16 chars>…:`,
   signature-key → `jwt="<first 24 chars>…"`. POST body (e.g. the
   token-endpoint request body) is JSON-pretty-printed inline with
   long JWT-shaped string values truncated.

   The hardcoded per-step prose paragraphs in renderColdFlow used to
   live as duplicated `out.push(...)` lines. They are now a single
   `descriptions` map keyed by step+phase+status (e.g.,
   ps_token_request:done branches on 200 for warm-path vs 202 for
   cold-path narration). formatNdjson attaches the same prose under a
   `description` field on each JSON event, so --jsonl consumers (AI
   agents, log shippers) get the same paragraph --log shows. The
   pretty renderer uses a `describe()` lookup + `wrap()` helper to
   word-wrap to terminal width. Same descriptions-map pattern is
   applied symmetrically to bootstrap.

   Additional UX cleanup:
   - Step 4 (POST to PS) now shows the agent_token decoded block again
     (was previously implicit "see Step 1"). Step 6/8 (retry) shows
     the auth_token decoded block again. Cross-reference annotations
     (`← same key as Step 1`, `← the auth_token from the previous step`)
     are gone — repetition is fine when the reader can compare values
     side-by-side themselves.

bootstrap mirrors the same pattern: pickLogMode helper, descriptions
map for the three prose'd events (key_info, key_generation,
ps_metadata_request, bootstrap_complete), formatNdjson attaches
description, renderStep0 reads via describe() with bulletWrap().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e-lock.json. Add new @napi-rs/keyring platform entries for various operating systems in the lockfile, ensuring compatibility across environments.
@rohanharikr rohanharikr merged commit fdf1640 into main May 22, 2026
1 check passed
@rohanharikr rohanharikr deleted the httsig-changes branch May 22, 2026 09:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant