5.4 KiB

name, description
name description
chat-to-plan Enrich a plan markdown with precise file locations, API signatures, and event firing conditions. Use when a plan has been discussed in chat and needs to be made implementation-ready, or when asked to "enrich a plan", "refine a plan", or "chat-to-plan".

Chat-to-Plan Enrichment

Take a plan written in chat or a markdown file and enrich it with precise, verifiable details so a coding agent can execute it without guessing.

When to Use

  • A plan has been discussed in chat and needs to be written to markdown
  • A markdown plan exists but lacks file locations, API signatures, or event details
  • The user says "enrich this plan", "refine the plan", or "chat-to-plan "

Enrichment Checklist

For each phase/step in the plan, add the following where applicable:

1. File Locations

  • What to do: Grep the source code to find the exact files that need modification.
  • How: Use grep/find/rg to locate relevant code, imports, and type definitions.
  • Output: A table or list of files with a brief note on what changes in each.
  • Example:
    | File | Change |
    |------|--------|
    | `src/turn-limit.ts` | Add command registration, widget updates, confirmation logic |
    

2. API Signatures

  • What to do: Grep the pi-coding-agent type definitions for exact handler signatures.
  • How: Search ~/.local/share/mise/installs/node/*/lib/node_modules/@mariozechner/pi-coding-agent/dist/core/extensions/types.d.ts for relevant interfaces.
  • Key things to check:
    • registerCommand handler signature: (args: string, ctx: ExtensionCommandContext) => Promise<void>
    • registerShortcut handler signature: (ctx: ExtensionContext) => Promise<void> | void
    • registerFlag options shape
    • ui.confirm, ui.notify, ui.setWidget signatures
    • Event handler signatures: (event: E, ctx: ExtensionContext) => Promise<R | void>
  • Output: Include the exact signature in the plan, not just a description.
  • Example:
    Handler signature: `async (args: string, ctx: ExtensionCommandContext) => Promise<void>`
    - `args` is a single string (not array), use `args.trim().split(/\s+/)` for parsing
    

3. Event Firing Conditions

  • What to do: Check when each event fires (fresh start, reload, compact, etc.).
  • How: Search agent-session.js for this._extensionRunner.emit({ type: "..." to find event emission points.
  • Key mappings:
    • session_start with reason: "startup" — fresh session start
    • session_start with reason: "reload" — session reload
    • agent_start — agent begins a new turn (NOT on reload)
    • turn_start — each agent turn begins
    • agent_end — agent finishes a turn
  • Output: Note when each event fires in the plan.
  • Example:
    Note: `session_start` fires on both startup (reason: "startup") and reload (reason: "reload").
    `agent_start` only fires when the agent begins a turn, NOT on reload.
    

4. Required Imports

  • What to do: Check what imports are needed for new APIs.
  • How: Look at existing imports in the file and grep for new types/functions.
  • Output: List any new imports needed.
  • Example:
    No new imports needed — `pi.registerCommand` is available on the `pi` object.
    

5. Type Definitions to Reference

  • What to do: Note which type interfaces are relevant.
  • How: List the exact interface names from the type definitions.
  • Output: Link to the relevant types.
  • Example:
    Relevant types: `RegisteredCommand`, `ExtensionCommandContext`, `ExtensionContext`, `ExtensionAPI`
    Location: `@mariozechner/pi-coding-agent/dist/core/extensions/types.d.ts`
    

Process

  1. Read the plan — understand what needs to be implemented.
  2. Grep source files — find the exact files, functions, and types involved.
  3. Grep pi-coding-agent types — find exact API signatures.
  4. Grep event emission points — find when events fire.
  5. Enrich the plan — add the findings to the markdown.
  6. Save the enriched plan — overwrite the original file or create a new one.

Example Enrichment

Given a plan phase like:

- [ ] Add `/turn-limit` command
  - Register via `pi.registerCommand()`
  - Handler parses args, validates positive integer
  - Updates `maxTurns` in-memory variable

Enrich it to:

- [ ] Add `/turn-limit` command
  - **File:** `packages/pi-turn-limit/src/turn-limit.ts`
  - **API:** `pi.registerCommand("turn-limit", { description, handler })`
  - **Handler signature:** `async (args: string, ctx: ExtensionCommandContext) => Promise<void>`
    - `args` is a single string — use `args.trim().split(/\s+/)` for parsing
    - `ctx` is `ExtensionCommandContext` (extends `ExtensionContext`) — has `ctx.ui`, `ctx.abort()`
  - **Handler:**
    - Parse `args.trim()` as integer
    - If invalid: `ctx.ui.notify("Invalid turn limit. Must be a positive integer.", "error")`
    - Update `maxTurns` in-memory variable (change `const` to `let`)
    - `ctx.ui.setWidget("turn-limit", ["Turns: ${turnCount}/${maxTurns}"])`
    - `ctx.ui.notify("Turn limit set to {N}.", "info")`

Tips

  • Be specific, not descriptive. Prefer exact signatures over "parses args as integer".
  • Verify before including. Don't guess — grep the actual files.
  • Keep it concise. The enrichment should make the plan actionable, not bloated.
  • Preserve the original structure. Add enrichment inline, don't rewrite the plan.