Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Chapter 20c: Ultraplan -- Remote Multi-Agent Planning

Why Ultraplan Is Needed

The multi-Agent orchestration described earlier in this chapter is all local -- Agents run in the user's terminal, occupy terminal I/O, and share the context window with the user. Ultraplan solves a different problem: offloading the planning phase to remote, keeping the user's terminal available.

DimensionLocal Plan ModeUltraplan
Execution locationLocal terminalCCR (Claude Code on the web) remote container
ModelCurrent session modelForced Opus 4.6 (GrowthBook tengu_ultraplan_model config)
Exploration methodSingle Agent sequential explorationOptional multi-Agent parallel exploration (depending on prompt variant)
TimeoutNo hard timeout30 minutes (GrowthBook tengu_ultraplan_timeout_seconds, default 1800)
User terminalBlockedStays available, user can continue other work
Result deliveryExecuted directly in session"Execute remotely and create PR" or "teleport back to local terminal for execution"
ApprovalTerminal dialogBrowser PlanModal

Architecture Overview

Ultraplan consists of 5 core modules:

┌──────────────────────────────────────────────────────────────┐
│                    User Terminal (Local)                       │
│                                                              │
│  PromptInput.tsx                processUserInput.ts           │
│  ┌─────────────┐              ┌──────────────────┐           │
│  │ Keyword      │─→ Rainbow    │ "ultraplan"       │          │
│  │ detection    │   highlight  │ replacement       │          │
│  │ + toast      │              │ → /ultraplan cmd   │          │
│  └─────────────┘              └────────┬─────────┘           │
│                                        ↓                     │
│  commands/ultraplan.tsx ──────────────────────────            │
│  ┌─────────────────────────────────────────────┐             │
│  │ launchUltraplan()                           │             │
│  │  ├─ checkRemoteAgentEligibility()           │             │
│  │  ├─ buildUltraplanPrompt(blurb, seed, id)   │             │
│  │  ├─ teleportToRemote() ──→ CCR session      │             │
│  │  ├─ registerRemoteAgentTask()               │             │
│  │  └─ startDetachedPoll() ──→ Background poll │             │
│  └───────────────────────────┬─────────────────┘             │
│                              ↓                               │
│  utils/ultraplan/ccrSession.ts                               │
│  ┌─────────────────────────────────────────────┐             │
│  │ pollForApprovedExitPlanMode()               │             │
│  │  ├─ Poll remote session events every 3s     │             │
│  │  ├─ ExitPlanModeScanner.ingest() state machine│           │
│  │  └─ Phase detection: running → needs_input → ready│       │
│  └───────────────────────────┬─────────────────┘             │
│                              ↓                               │
│  Task system Pill display                                     │
│  ◇ ultraplan (running)                                       │
│  ◇ ultraplan needs your input (remote idle)                  │
│  ◆ ultraplan ready (plan ready)                              │
└──────────────────────────────────────────────────────────────┘
                               ↕ HTTP polling
┌──────────────────────────────────────────────────────────────┐
│                   CCR Remote Container                        │
│                                                              │
│  Opus 4.6 + plan mode permissions                            │
│  ├─ Explore codebase (Glob/Grep/Read)                        │
│  ├─ Optional: Task tool spawns parallel subagents            │
│  ├─ Call ExitPlanMode to submit plan                         │
│  └─ Wait for user approval (approve/reject/teleport to local)│
└──────────────────────────────────────────────────────────────┘

What CCR Is -- The Meaning of "Working Remotely"

The "CCR Remote Container" in the architecture diagram stands for Claude Code Remote (Claude Code on the web), essentially a complete Claude Code instance running on Anthropic's servers:

Your terminal (local CLI client)          Anthropic cloud (CCR container)
┌──────────────────────┐            ┌────────────────────────────┐
│ Only responsible for: │            │ Running:                    │
│ · Bundle and upload   │──HTTP──→   │ · Complete Claude Code      │
│   codebase            │            │   instance                  │
│ · Display task Pill   │            │ · Opus 4.6 model (forced)   │
│ · Poll status every 3s│←─poll──    │ · Your codebase copy        │
│ · Receive final plan  │            │   (bundle)                  │
│                      │            │ · Glob/Grep/Read etc. tools  │
│ You can continue      │            │ · Optional: multiple         │
│ other work            │            │   subagents in parallel      │
│                      │            │ · Plan mode permissions       │
│                      │            │   (read-only)                │
└──────────────────────┘            └────────────────────────────┘

The CCR container is created via teleportToRemote(). At launch, your codebase is bundled and uploaded, and the remote end gains full code access. The remote Agent Loop sends requests to the Claude API, exactly as when you use Claude Code locally -- the difference is it uses the Opus 4.6 model, runs on Anthropic's infrastructure, and doesn't occupy your terminal.

What Users Can Do

Trigger methods:

  1. Keyword trigger -- naturally write "ultraplan" in your prompt:
    ultraplan refactor the auth module to support both OAuth2 and API key methods
    
  2. Slash command -- explicitly invoke /ultraplan <description>

Prerequisites (checkRemoteAgentEligibility() checks):

  • Logged into Claude Code via OAuth
  • Subscription level supports remote Agents (Pro/Max/Team/Enterprise)
  • Feature Flag ULTRAPLAN enabled for account (GrowthBook server-side control)

Checking availability: After typing text containing "ultraplan", if the keyword shows rainbow highlighting and a toast notification "This prompt will launch an ultraplan session in Claude Code on the web" appears, the feature is enabled. No reaction means the feature flag is not enabled for your account.

Usage flow:

1. Enter a prompt containing "ultraplan"
2. Confirm the launch dialog
3. Terminal shows CCR URL, you can continue other work
4. Task bar Pill shows progress:
   ◇ ultraplan               → Remote exploring codebase
   ◇ ultraplan needs your input → Need to act in browser
   ◆ ultraplan ready          → Plan ready, awaiting approval
5. Approve plan in browser:
   a. Approve → Execute remotely and create Pull Request
   b. Reject + feedback → Remote revises based on feedback and resubmits
   c. Teleport to local → Plan returns to your terminal for execution
6. To stop midway, cancel through the task system

Source code locations:

FileLinesResponsibility
commands/ultraplan.tsx470Main command: launch, poll, stop, error handling
utils/ultraplan/ccrSession.ts350Poll state machine, ExitPlanModeScanner, phase detection
utils/ultraplan/keyword.ts128Keyword detection: trigger rules, context exclusions
state/AppStateStore.ts--State fields: ultraplanSessionUrl, ultraplanPendingChoice, etc.
tasks/RemoteAgentTask/--Remote task registration and lifecycle management
components/PromptInput/PromptInput.tsx--Keyword rainbow highlight + toast

Keyword Trigger System

Users don't need to type /ultraplan -- simply writing "ultraplan" naturally in the prompt triggers it.

// restored-src/src/utils/ultraplan/keyword.ts
export function findUltraplanTriggerPositions(text: string): TriggerPosition[]
export function hasUltraplanKeyword(text: string): boolean
export function replaceUltraplanKeyword(text: string): string

Exclusion rules -- "ultraplan" in the following contexts will not trigger:

ContextExampleReason
Inside quotes/backticks`ultraplan`Code reference
In pathssrc/ultraplan/foo.tsFile path
In identifiers--ultraplan-modeCLI argument
Before file extensionsultraplan.tsxFilename
After question markultraplan?Asking about the feature, not triggering
Starting with //ultraplanGoes through slash command path

After triggering, processUserInput.ts replaces the keyword with /ultraplan {rewritten prompt} and routes to the command handler.

State Machine: Lifecycle Management

Ultraplan uses 5 AppState fields to manage its lifecycle:

// restored-src/src/state/AppStateStore.ts
ultraplanLaunching?: boolean         // Launching (prevents duplicate launches, ~5s window)
ultraplanSessionUrl?: string         // Active session URL (disables keyword trigger when present)
ultraplanPendingChoice?: {           // Approved plan awaiting user's execution location choice
  plan: string
  sessionId: string
  taskId: string
}
ultraplanLaunchPending?: {           // Pre-launch confirmation dialog state
  blurb: string
}
isUltraplanMode?: boolean            // Remote-side flag (set via set_permission_mode)

State transition diagram:

stateDiagram-v2
    [*] --> IDLE
    IDLE --> LAUNCHING: User enters "ultraplan" keyword
    LAUNCHING --> RUNNING: teleportToRemote() succeeds<br/>sets ultraplanSessionUrl
    LAUNCHING --> IDLE: Launch failed<br/>(auth/eligibility/network)

    RUNNING --> RUNNING: phase=running (remote working)
    RUNNING --> NEEDS_INPUT: phase=needs_input (remote idle)
    RUNNING --> PLAN_READY: phase=plan_ready (ExitPlanMode called)
    NEEDS_INPUT --> RUNNING: Remote resumes work
    NEEDS_INPUT --> PLAN_READY: ExitPlanMode called

    PLAN_READY --> REMOTE_EXEC: User approves in browser → remote execution
    PLAN_READY --> PENDING_CHOICE: User rejects + TELEPORT_SENTINEL
    PLAN_READY --> RUNNING: User rejects + feedback → remote revises plan

    REMOTE_EXEC --> IDLE: Task complete, URL cleared
    PENDING_CHOICE --> IDLE: User chooses "execute locally"
    PENDING_CHOICE --> RUNNING: User chooses "continue remote"

    RUNNING --> IDLE: Timeout(30min) / Network failure(5x) / User stops

Polling and Phase Detection

startDetachedPoll() runs as a background async IIFE, not blocking the terminal:

// restored-src/src/utils/ultraplan/ccrSession.ts

const POLL_INTERVAL_MS = 3000             // Poll every 3 seconds
const MAX_CONSECUTIVE_FAILURES = 5        // Give up after 5 consecutive network errors
const ULTRAPLAN_TIMEOUT_MS = 30 * 60 * 1000  // 30-minute timeout

ExitPlanModeScanner is a pure stateless event processor that extracts signals from the remote session event stream:

// Scan result types
type ScanResult =
  | { kind: 'approved'; plan: string }    // User approved (remote execution)
  | { kind: 'teleport'; plan: string }    // User rejected + teleport marker (local execution)
  | { kind: 'rejected'; id: string }      // Normal rejection (revise and resubmit)
  | { kind: 'pending' }                   // ExitPlanMode called, awaiting approval
  | { kind: 'terminated'; subtype: string } // Session terminated
  | { kind: 'unchanged' }                 // No new signals

Phase detection logic:

// Determine current phase of remote session
const quietIdle =
  (sessionStatus === 'idle' || sessionStatus === 'requires_action') &&
  newEvents.length === 0

const phase: UltraplanPhase = scanner.hasPendingPlan
  ? 'plan_ready'      // ExitPlanMode called, awaiting browser approval
  : quietIdle
    ? 'needs_input'    // Remote idle, may need user input
    : 'running'        // Working normally

GrowthBook-Driven Prompt Variants (New in v2.1.91)

v2.1.91 introduced the tengu_ultraplan_prompt_identifier event, exposing a GrowthBook-controlled prompt variant system. At least 3 prompt variants were extracted from the bundle:

Variant 1: simple_plan (default) -- Lightweight single-agent planning

You're running in a remote planning session.
Run a lightweight planning process, consistent with how you would
in regular plan mode:
- Explore the codebase directly with Glob, Grep, and Read.
- Do not spawn subagents.
When you've settled on an approach, call ExitPlanMode with the plan.

Variant 2: Multi-agent exploration -- Uses Task tool to spawn parallel subagents

Produce an exceptionally thorough implementation plan using
multi-agent exploration.
Instructions:
1. Use the Task tool to spawn parallel agents to explore different
   aspects of the codebase simultaneously:
   - One agent to understand the relevant existing code and architecture
   - One agent to find all files that will need modification
   - One agent to identify potential risks, edge cases, and dependencies
2. Synthesize their findings into a detailed, step-by-step plan.
3. Use the Task tool to spawn a critique agent to review the plan.
4. Incorporate the critique feedback, then call ExitPlanMode.

Variant switching mechanism:

// v2.1.91 bundle reverse engineering
function getPromptIdentifier(): string {
  // Read from GrowthBook, default "simple_plan"
  let id = getFeatureValue('tengu_ultraplan_prompt_identifier', 'simple_plan')
  return isValidId(id) ? id : 'simple_plan'
}

function getTimeout(): number {
  // Read from GrowthBook, default 1800 seconds (30 minutes)
  return getFeatureValue('tengu_ultraplan_timeout_seconds', 1800) * 1000
}

This means Anthropic can A/B test different planning strategies through GrowthBook without shipping new releases. The tengu_ultraplan_config event records the specific configuration combination used at each launch.

Plan Teleport Protocol

When a user rejects a plan in the browser but chooses "teleport back to local terminal," the browser injects a sentinel string in the feedback:

const ULTRAPLAN_TELEPORT_SENTINEL = '__ULTRAPLAN_TELEPORT_LOCAL__'

The remote-side prompt explicitly instructs the model to recognize this sentinel:

If the feedback contains __ULTRAPLAN_TELEPORT_LOCAL__, DO NOT implement -- the plan has been teleported to the user's local terminal. Respond only with "Plan teleported. Return to your terminal to continue."

The local ExitPlanModeScanner detects the sentinel, extracts the plan text, and sets ultraplanPendingChoice, popping up a choice dialog for the user to decide whether to execute locally or continue remotely.

Error Handling Matrix

ErrorReason CodeWhen It OccursRecovery Strategy
UltraplanPollErrorterminatedRemote session abnormally terminatedNotify user + archive session
UltraplanPollErrortimeout_pending30-minute timeout, plan reached pendingNotify + archive
UltraplanPollErrortimeout_no_plan30-minute timeout, ExitPlanMode never calledNotify + archive
UltraplanPollErrornetwork_or_unknown5 consecutive network errorsNotify + archive
UltraplanPollErrorstoppedUser manually stoppedEarly exit, kill handles archival
Launch errorpreconditionAuth/subscription/eligibility insufficientNotify user
Launch errorbundle_failBundle creation failedNotify user
Launch errorteleport_nullRemote session creation returned nullNotify user
Launch errorunexpected_errorExceptionArchive orphan session + clear URL

Telemetry Event Overview

EventSource VersionTriggerKey Metadata
tengu_ultraplan_keywordv2.1.88Keyword detected in user input--
tengu_ultraplan_launchedv2.1.88CCR session created successfullyhas_seed_plan, model, prompt_identifier
tengu_ultraplan_approvedv2.1.88Plan approvedduration_ms, plan_length, reject_count, execution_target
tengu_ultraplan_awaiting_inputv2.1.88Phase becomes needs_input--
tengu_ultraplan_failedv2.1.88Poll errorduration_ms, reason, reject_count
tengu_ultraplan_create_failedv2.1.88Launch failedreason, precondition_errors
tengu_ultraplan_modelv2.1.88GrowthBook config nameModel ID (default Opus 4.6)
tengu_ultraplan_configv2.1.91Records config combination at launchModel + timeout + prompt variant
tengu_ultraplan_keywordv2.1.91(Reused) Enhanced trigger tracking--
tengu_ultraplan_prompt_identifierv2.1.91GrowthBook config namePrompt variant ID
tengu_ultraplan_stoppedv2.1.91User manually stopped--
tengu_ultraplan_timeout_secondsv2.1.91GrowthBook config nameTimeout seconds (default 1800)

Pattern Distillation: Remote Offloading Pattern

Ultraplan embodies a reusable architectural pattern -- remote offloading:

Local Terminal                     Remote Container
┌──────────┐                   ┌──────────────┐
│ Fast      │───create session──→ │ Long-running  │
│ feedback  │                   │ High-compute  │
│ Stays     │                   │ model         │
│ available │←──poll status──   │ Multi-agent   │
│           │                   │ parallel      │
│ Pill      │                   │              │
│ display   │←──plan ready──   │ ExitPlanMode │
│ ◇/◆      │                   │              │
│ status    │                   │              │
│           │                   │              │
│ Choose    │───approve/       │ Execute/     │
│ execution │   teleport──→    │ stop         │
└──────────┘                   └──────────────┘

Core design decisions:

  1. Async separation: startDetachedPoll() launches as an async IIFE, immediately returns a user-friendly message without blocking the terminal event loop
  2. State machine-driven UI: Three phases (running/needs_input/plan_ready) map to task Pill visual states (open/filled diamond), letting users sense remote progress without opening a browser
  3. Sentinel protocol: __ULTRAPLAN_TELEPORT_LOCAL__ uses tool result text as an inter-process communication channel -- simple but effective
  4. GrowthBook-driven variants: Model, timeout, and prompt variant are all remotely configurable feature flags, supporting A/B testing without releases
  5. Orphan protection: All error paths execute archiveRemoteSession() for archival, preventing CCR session leaks

Subagent Enhancements (v2.1.91)

v2.1.91 also added multiple subagent-related events, complementing Ultraplan's multi-agent strategy:

  • tengu_forked_agent_default_turns_exceeded -- Forked agent exceeded default turn limit, triggering cost control
  • tengu_subagent_lean_schema_applied -- Subagent uses lean schema (reducing context usage)
  • tengu_subagent_md_report_blocked -- Subagent blocked when attempting to generate CLAUDE.md report (security boundary)
  • tengu_mcp_subagent_prompt -- MCP subagent prompt injection tracking
  • CLAUDE_CODE_AGENT_COST_STEER (new environment variable) -- Subagent cost steering mechanism