AI Draft Sessions

This document captures the draft-review pattern now used across multiple plugins.

Current examples:

The pattern is for AI commands that do not immediately mutate real data.

Instead, they:

When to use this pattern

Use an AI draft session when a command:

Good fits:

Less necessary when:

Core model

Each draft row should carry an internal session_id.

The user should never need to see or type that value.

The session model is:

Minimal draft requirements:

User interaction contract

Inside the interactive session, use the same action set across plugins:

Recommended behavior:

Important rule: revise in place

revise should update the existing draft row in place.

Do not create a replacement draft unless there is a very strong domain reason.

Why:

That means revise should normally:

Manual fallback commands remain important

Interactive review does not replace manual draft commands.

Keep these commands working:

Why:

The interactive session is the preferred path. The manual commands are the recovery and fallback path.

Session rendering rules

The session view should focus on the current draft only.

Recommended structure:

Avoid showing manual reply-command blocks inside the interactive session.

So inside a session, do not show things like:

Those belong in manual/non-interactive draft previews only.

Inside the session, show only the direct interaction hint line.

Session completion behavior

When there are no drafts left in the session:

When the review cursor passes the last remaining draft but skipped drafts still exist:

When the user quits:

Mixed-operation sessions

Some plugins may have AI flows that can generate multiple kinds of operations.

Examples:

Recommended approach:

This is better than forcing a half-broken generic session UI too early.

Suggested implementation structure

Inside a plugin, the session logic usually belongs under the AI command:

plugins/<alias>/commands/ai/
  handler.ts
  prompts.ts
  parse-*.ts
  schemas.ts
  session.ts

Typical functions in session.ts:

This session module is usually command-local, not shared globally.

Reason:

DB/storage helpers you will usually need

For draft-backed sessions, shared draft storage should normally provide:

If two or more subcommands need these helpers, keep them in shared plugin draft storage.

Adapter/context requirements

A plugin using interactive AI review needs access to:

Sometimes also:

If a plugin command context already has sendReply, that does not automatically mean it should be used for prompt sessions.

For prompt loops, prefer promptFn(...).

UX guidelines

Practical checklist

When adding AI draft sessions to a plugin:

  1. add session_id to draft rows
  2. add storage helpers for per-session listing/indexing
  3. keep manual draft commands working
  4. add commands/ai/session.ts
  5. make ai group all created drafts under one session_id
  6. start the interactive session immediately after draft creation
  7. make revise update the same draft in place
  8. hide manual reply-command blocks inside the interactive session
  9. keep skipped drafts available through manual draft commands

Default recommendation

If a plugin has an ai subcommand that creates drafts, prefer this session-based review flow by default.

It is now the established plugin pattern in this repo.