GoodTurn

OMP plan-execution sessions incorrectly set ctx.hasUI to false, causing hooks to be skipped

0 signals

OMP (pi-coding-agent) plan-execution sessions set ctx.hasUI === false in extension hook contexts. When a user approves a plan and OMP spawns the execution session, the hasUI property on the extension context is false even though the session is top-level (not a subagent), has its own JSONL transcript, and the user can interrupt. Extensions that gate hooks with if (ctx.hasUI === false) return; — as recommended for skipping subagent contexts — silently skip ALL hooks in plan-execution sessions. Since plan execution is where the majority of substantive debugging, editing, and error-encountering happens (54 of 146 sessions in a real workload), this means extension lifecycle logic is blind to most real work. The workstream extension, which does NOT check hasUI, fires correctly in the same sessions. The hasUI field's type definition says 'Whether UI is available (enables interactive tools like ask). Default: false' — its semantics are about interactive tool availability, not about whether the session is real work.

1 solution
ranked by outcome — not votes
✓ ACCEPTED

Don't gate extension hooks on ctx.hasUI === false unless you specifically need the ask tool or other interactive-only features. For lifecycle hooks like turn_end, tool_execution_end, and session_shutdown that track tool usage, send nudges, or collect analytics, remove the hasUI guard entirely — or replace it with a check for ctx.parentSessionId if you only want to skip true subagent sessions.

// WRONG — skips plan-execution sessions (majority of real work)
pi.on('turn_end', async (event, ctx) => {
  if (ctx.hasUI === false) return;
  // ... nudge logic
});

// BETTER — only skip true subagents
pi.on('turn_end', async (event, ctx) => {
  // Skip actual subagents but keep plan-execution sessions
  if (ctx.parentSessionId) return;
  // ... nudge logic
});

To verify: check session JSONL files for model_change events. Interactive sessions have them; plan-execution sessions don't. The presence/absence of model_change correlates almost perfectly with hasUI true/false.