Skip to content

fix(pi): backport #813 (lazy MCP bridge bootstrap) to main — fixes hang on pi list/update/install#828

Open
unship wants to merge 9 commits into
mksglu:nextfrom
unship:fix/defer-mcp-bridge-to-session-lifecycle
Open

fix(pi): backport #813 (lazy MCP bridge bootstrap) to main — fixes hang on pi list/update/install#828
unship wants to merge 9 commits into
mksglu:nextfrom
unship:fix/defer-mcp-bridge-to-session-lifecycle

Conversation

@unship

@unship unship commented Jun 14, 2026

Copy link
Copy Markdown

Problem

pi list, pi update, and pi install print their output and then hang forever when context-mode is installed (Ctrl-C required). Reported upstream as earendil-works/pi#5687.

Root cause

Pi runs every extension's factory (piExtension(pi)) during module discovery — for every invocation, including the package subcommands and --help/--version, none of which start a session. The factory spawned server.bundle.mjs as a long-lived stdio child whose open handles keep the Node event loop alive, so a one-shot command never exits. The #534 argv denylist only covered help/version, so the package subcommands slipped through.

Fix

This is a clean backport of #813 ("lazy bootstrap MCP bridge for agent turns") to main. #813 is already on next, but main — what npm currently ships — still has the bug, so users hit the hang today.

#813 starts the bridge lazily from before_agent_start (the first lifecycle signal that Pi is about to dispatch a model call), removes the brittle argv denylist, and keeps the session_shutdown cleanup. CLI-only paths never fire before_agent_start, so they never spawn a child; subagents (pi --mode json -p --no-session) do, and the handler awaits readiness so the ctx_* tools are registered before Pi snapshots the tool registry.

Cherry-picked with provenance (git cherry-pick -x); credit to @Gandem / #813.

Verification (local, on this branch against main)

  • tsc --noEmit clean — no next-only dependencies.
  • Full pi suite green: pi-extension.test.ts + pi-help-skip-bootstrap + pi-no-orphan-on-help + pi-mcp-bridge + pi-extension-workspace-resolve126 passed.

Note on base branch

Targets main deliberately, to fix the released line. If you'd rather let #813 reach main via the normal nextmain merge, feel free to close — opening this so the published version is fixed sooner.

Fixes the extension side of earendil-works/pi#5687.

mksglu and others added 6 commits June 12, 2026 16:42
Two regressions snuck back in when the /context-saving rename agent
copied from the next branch (which never had the hero pattern fix).
Re-applying on main:

- .cm-master + .cm-wordmark: inline-flex → flex (so the hero-tag
  pill never shares a baseline-aligned row with the wordmark)
- .hero-tag: margin-bottom → margin-top + align-self:flex-start
  (sits below the wordmark on its own line)
- Insight wordmark italic: 1.18em → 1em, margin-left .12em → .14em
- HTML order: <h1> wordmark first, <p class="hero-tag"> after
  (matches master/insight/context-saving)

Plus making the Insight landing's "287,000+ developers" references
dynamic (.js-user-count + the GitHub stats.json fetch shim), so the
number matches the OSS plugin's source-of-truth count instead of
drifting like the screenshots showed (290k+ on /, 287k+ here).
OG PNGs are static, so the 287,000+ number drifted away from the
landing page (which already reads stats.json live). Solution:

- Mark every user-count occurrence in master-og.html and
  context-saving-og.html with class js-user-count
- render-og.mjs now fetches the same stats.json before opening the
  browser, then runs a one-shot DOM swap on every .js-user-count
  element before the screenshot

Result: each render bakes the freshest count in, no manual update
needed. Today's render shows 290,000+ across all three banners.
The hero green cursor was driving compositor work harder than it
needed to: steps(2) + a 24px box-shadow meant the GPU repainted
the full glow on every tick, which user reported as a low-FPS feel.

- animation timing: 1.06s steps(2) → 1.4s ease-in-out (smooth pulse
  between opacity 1 and 0.28, terminal-feeling without hard flicker)
- box-shadow blur: 24px → 18px and alpha .45 → .40 (lighter recompose)
- add will-change:opacity + translateZ(0) so the cursor lives on its
  own composited layer (no repaint of surrounding text)
- topnav cursor: same easing pass, renamed keyframe to nav-blink so
  the hero and nav don't share a single declaration name
- prefers-reduced-motion now resolves to a static 0.85 opacity cursor
  instead of a stuck-on solid block
@mksglu

mksglu commented Jun 14, 2026

Copy link
Copy Markdown
Owner

@unship We have conflicts

@unship unship changed the base branch from next to main June 14, 2026 10:03
@unship unship force-pushed the fix/defer-mcp-bridge-to-session-lifecycle branch from 95d5dae to 9299dae Compare June 14, 2026 10:03
@unship unship changed the title fix(pi): defer MCP bridge spawn to the session lifecycle fix(pi): lazily bootstrap MCP bridge from before_agent_start (fixes hang on pi list/update/install) Jun 14, 2026
@unship unship force-pushed the fix/defer-mcp-bridge-to-session-lifecycle branch from 9299dae to 53b15f9 Compare June 14, 2026 10:13
@unship unship changed the title fix(pi): lazily bootstrap MCP bridge from before_agent_start (fixes hang on pi list/update/install) fix(pi): backport #813 (lazy MCP bridge bootstrap) to main — fixes hang on pi list/update/install Jun 14, 2026
@mksglu mksglu changed the base branch from main to next June 14, 2026 10:26
@mksglu

mksglu commented Jun 14, 2026

Copy link
Copy Markdown
Owner

The target branch SHOULD BE next NOT main

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.

3 participants