Skip to content

Release 1.37.1 — MCP token-refresh fix + nested-substep rendering fix (DEV→main) - #2706

Merged
jung-thomas merged 20 commits into
mainfrom
worktree-release-1.37.1
Oct 9, 2026
Merged

jung-thomas merged 20 commits into
mainfrom
worktree-release-1.37.1

Conversation

@jung-thomas

Copy link
Copy Markdown
Contributor

Promotes the 4 PRs merged to DEV since 1.37.0 to main for a full production deploy.

Patch bump (1.36.0 → 1.37.1 in .deploy/mta.yaml): fixes/docs/tooling only, no new user-facing features.

What's in this train

PR Category Change
#2701 Fix MCP sessions stay connected across token refresh — AI clients no longer drop on reconnect after initial sign-in
#2704 Fix OS-option panels nested in numbered sub-steps render correctly (numbering, code, images, notes preserved; Note vs Important callouts styled distinctly) — fixes #2703
#2700 Docs MCP quickstart shows the correct production client_id
#2705 Maintenance Internal Discovery Center → platform tutorial converter skill

Release mechanics

Deploy

After merge, deploy from a fresh origin/main (never a feature branch). Main tutorials-ims MTA only — the tutorials-mcp MTA is deployed separately.

🤖 Generated with Claude Code

…ed XSUAA id)

The quickstart told PROD users to connect with the XSUAA client_id
sb-tutorials-prod!t676072, but since MCP_ISSUER_KIND:ias landed in both mtaexts
(#2593, 2026-10-04) PROD discovery advertises IAS — and IAS rejects an XSUAA
sb-... id at the authorize endpoint ("client_id must match the configuration")
before PKCE is even evaluated. Live PROD failure confirmed 2026-10-08.

DEV and PROD share ONE IAS tenant (atxgsg7zi) and ONE tutorials-identity app,
with both approuter hosts registered as redirect URIs, so there is a SINGLE
client UUID for both: 0b1e8b56-5f5d-4ebf-a9e9-28aae2964236.

Updates: the two mcp-remote JSON snippets, the env table (both rows → the IAS
UUID), and the explanatory prose (IAS public client, XSUAA ids retired, how to
re-read the UUID from the IAS console). No code change.
…oint

Live PROD failure (2026-10-08) after a SUCCESSFUL initial auth: on reconnect
mcp-remote POSTs grant_type=refresh_token to our /token, but handleToken only
accepted authorization_code → 400 "unsupported_grant_type" on every refresh.

The discovery doc advertises refresh_token in grant_types_supported, and we pass
IAS's refresh_token through to the client verbatim at the code exchange — so the
client correctly tries to refresh against us (its advertised AS). We just never
implemented the branch.

Fix: add an idpRefresh() boundary (mirrors idpExchange) that relays the client's
refresh_token to IAS /oauth2/token with grant_type=refresh_token + the client's
own client_id (public client, no secret, no PKCE on refresh). handleToken now
branches: refresh_token → idpRefresh; authorization_code → unchanged; anything
else → unsupported_grant_type. Passes rotated refresh_token through, falls back
to the old one when IAS doesn't rotate.

Tests: +6 (refresh proxy happy path, rotation + no-rotation fallback, missing
refresh_token 400, IAS-failure 400, real idpRefresh body with fetch mocked).
31 unit tests green.
…esh-grant

fix(mcp): handle refresh_token grant in the consent proxy /token endpoint
…lientid-doc

docs(mcp): correct PROD client_id to the shared IAS client (not retired XSUAA id)
#2703)

Author feedback on the new blockquote alerts + OS option-settings surfaced
six rendering bugs on /tutorials-qa/ (hana-clients-*). Root causes:

1. OPTION blocks nested inside numbered substeps emitted their Hugo
   shortcode flush-left with the panel body still indented. Goldmark then
   closed the surrounding list AND treated the indented ```fence``` inside
   the panel as literal indented-code, so substeps after [OPTION END]
   detached, code blocks showed raw backticks, and images/notes dropped.
2. {{< os-panel >}} is an angle-bracket shortcode, so its .Inner was never
   markdown-rendered — latent since OS options shipped (#173), exposed by
   the newly-nested QA tutorials.
3. [!NOTE] and [!IMPORTANT] shared one CSS rule, both rendering blue.
4. The OS picker always showed all four platforms (incl. BAS) regardless
   of which the tutorial actually provided; the only label was the generic
   "Steps" section heading.

Fixes:
- options.ts: emit the shortcode flush-left and dedent each panel/tab body
  to column 0 (new dedentBlock). The list reopens as <ol start="N">, so
  substep numbering is preserved, and the dedented body parses as markdown.
- os-panel.html: render .Inner via markdownify so fences/images/alerts
  inside OS panels parse correctly.
- sap-fundamental(.src).css: split .alert-note / .alert-important; NOTE
  stays Information blue, IMPORTANT uses the Horizon emphasis purple.
- New osList frontmatter (compose -> render-frontmatter -> fetch-tutorials
  + srv-qa preview path) drives the picker to render only the OSes the
  tutorial supports, in canonical order; added a "Platform:" picker label
  (the "Steps" section heading is unchanged).
- os-toggle.ts: activate() returns the effective OS so the picker reflects
  the panel actually shown when the detected OS has no panel.

Verified by building the four cited tutorials through the real Hugo
pipeline: substeps after [OPTION END] keep numbering, code blocks/images/
notes render inside panels, picker shows only supported OSes. Two remaining
literal-fence cases (fence-inside-blockquote, intentional example fences)
are pre-existing and out of scope.

Tests: options-hugo, compose (osList), blockquote-alert-css, os-toggle.
fix(tutorials): OS-option & alert rendering in nested substeps (#2703)
Extend the convert-body.mjs CLI so that:

  node convert-body.mjs --precheck <full.md> <slug> <imagesDir>

reads <full.md>, scans <imagesDir> with readdirSync, and prints the
JSON array returned by precheck() — empty array means clean.  The
existing (non-precheck) CLI branch is unchanged.

Also add the smoke test:
  'CLI --precheck is reachable' — asserts typeof precheck === 'function'

SKILL.md (user-global) documents the exact one-liner for the two-stage
validation procedure (Task 6B, not committed here).
- Add discovery-sync:convert npm script (node scripts/discovery-sync/convert-body.mjs)
- Add .sync-draft/ to .gitignore (local working drafts, never committed)
- E2E verified: build-cap-app converts with 8 balanced OPTION blocks (4x Node.js/Java pairs),
  8 images fetched, precheck [], composeTutorial returns 5 steps on Node v26/Windows
…tained)

Move convert-body.mjs + tests + fixtures from scripts/discovery-sync/ into
.claude/skills/sap-discovery-tutorial-sync/scripts/ so the skill is fully
self-contained. Update vitest.config.ts include glob, package.json
discovery-sync:convert script, and SKILL.md path references accordingly.
…al-sync-spec

feat: sap-discovery-tutorial-sync skill (Discovery Center → platform converter)
Bump deploy version 1.36.0 -> 1.37.1 (.deploy/mta.yaml) for the DEV->main
promotion and refresh the user-facing What's New digest
(hugo/data/whats_new.json) with the 4 PRs merged since 1.37.0.

Patch bump: fixes/docs/tooling only, no new user-facing features.

Headline items in this train:
- MCP reliability: sessions now stay connected across token refresh so AI
  clients no longer drop on reconnect after the initial sign-in (#2701).
- Tutorial rendering: OS-specific option panels nested inside numbered
  sub-steps now render correctly — step numbering, code blocks, images, and
  notes inside those panels all display, with distinct Note vs Important
  callout styling (#2704).
- Docs: MCP quickstart now shows the correct production client_id (#2700).
- Tooling: internal Discovery Center -> platform tutorial converter skill
  for authors bringing existing content onto the portal (#2705).

whats_new.json rebased onto main's published digest (752 entries through
#2698) then extended to 757 (through #2705). srv/version.json is a gitignored
build artifact written at deploy time (scripts/deploy-mta.cjs), not committed.
Resolves the 1.37.0 vs 1.37.1 overlap on the two release-managed files:
- .deploy/mta.yaml: keep 1.37.1 (supersedes main's 1.37.0 bump).
- hugo/data/whats_new.json: keep the 757-entry digest, which already
  incorporates main's 752-entry 1.37.0 digest (rebased onto it) plus the
  4 new 1.37.1 PRs (#2700/#2701/#2704/#2705). Verified superset: all
  1.37.0 entries retained, 4 new entries added, no duplicates.
@jung-thomas
jung-thomas merged commit 2f741e4 into main Oct 9, 2026
8 checks passed
@jung-thomas
jung-thomas deleted the worktree-release-1.37.1 branch October 9, 2026 23:10
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.

Tutorial Rendering on Optional Notes and OS Platform

1 participant