nils-plan-issue-cli 0.6.5

CLI crate for nils-plan-issue-cli in the nils-cli workspace.
Documentation
# plan-issue-cli

## Overview

`plan-issue-cli` provides the Rust command contract for plan/issue delivery orchestration. It is the typed replacement lane for
`plan-issue-delivery-loop.sh` behavior and is built around deterministic task-spec generation, issue-body rendering, and gate-enforced
sprint transitions. `Task Decomposition` is the runtime-truth execution table; sprint task-spec/prompt artifacts are derived from those
issue rows. `plan-tooling split-prs` provides grouping primitives only in the current model; `plan-issue-cli` materializes runtime
`Owner/Branch/Worktree/Notes` metadata from plan content plus grouping results.

The crate ships two binaries with the same command surface:

- `plan-issue`: live GitHub-backed mode
- `plan-issue-local`: local-first rehearsal mode (offline/dry-run friendly)

Shell wrapper scripts are deprecated for this crate path. Use `plan-issue` / `plan-issue-local` directly.

## Command surface

### Build and preparation

- `build-task-spec`: build sprint-scoped task-spec TSV from a plan.
- `build-plan-task-spec`: build plan-scoped task-spec TSV (all sprints).

### Plan-level flow

- `start-plan`: open one plan issue and emit plan artifacts.
- `status-plan`: summarize Task Decomposition status from issue body/body file.
- `link-pr`: link a concrete PR to task rows and update row status (default `in-progress`).
- `ready-plan`: apply review-ready markers and optional review summary comment.
- `close-plan`: enforce final close gate and close the plan issue.
- `cleanup-worktrees`: enforce cleanup of all issue-assigned task worktrees.

### Sprint-level flow

- `start-sprint`: open sprint execution loop after previous sprint gate passes, validate runtime-truth rows against plan lanes, and render
  artifacts without rewriting issue rows.
- `ready-sprint`: post sprint-ready signal for main-agent review.
- `accept-sprint`: enforce merged-PR gate and mark sprint accepted.
- `multi-sprint-guide`: print repeated command flow for a whole plan.

### Shell completion

- `completion <bash|zsh>`: export completion script for each binary.

## Global flags

- `--repo <owner/repo>`: pass-through repo target for GitHub operations.
- `--dry-run`: print write actions without mutating GitHub state.
- `-f, --force`: bypass markdown payload guard for body/comment writes.
- `--json` or `--format json`: machine-readable contract output.
- `--format text`: human-readable output.

## Local-mode constraints

- `plan-issue-local` does not support live `--issue` paths that require GitHub reads/writes.
- Use `plan-issue <command>` for live operations.
- Use `--body-file` + `--dry-run` flows for local rehearsal where supported.
- `start-plan` in local mode emits deterministic placeholder issue number `999`.

## Task Decomposition schema

- Canonical table columns are fixed to:
  - `Task | Summary | Owner | Branch | Worktree | Execution Mode | PR | Status | Notes`
- Writer and parser share the same schema contract.
- Writer sanitizes cell values (including `|`) via `nils-common::markdown::canonicalize_table_cell` so parser column count remains
  deterministic and drift checks stay stable.
- Shared runtime lanes (`per-sprint`, `pr-shared`) must keep a consistent `PR` value across rows.

## Grouping and strategy rules

- `--strategy deterministic` requires `--pr-grouping` for split-dependent commands:
  - `build-task-spec`, `build-plan-task-spec`, `start-plan`, `start-sprint`, `ready-sprint`, `accept-sprint`.
- `--pr-grouping per-sprint`: one shared group per sprint.
- `--pr-grouping group --strategy deterministic`: requires explicit `--pr-group <task>=<group>` mappings.
- `--strategy auto` rejects `--pr-grouping`.
- `--strategy auto` resolves each sprint from plan metadata `PR grouping intent` first, then `--default-pr-grouping` for metadata gaps.
- `--strategy auto` allows optional pins only for sprints resolved to `group`; pins targeting `per-sprint` lanes fail fast.
- Use `plan-tooling validate` before orchestration when sprint metadata is present; invalid/partial metadata is blocked there.
- When a sprint resolves to a single shared PR group, `Execution Mode` is normalized to `per-sprint` (instead of `pr-shared`) to reflect
  single-lane execution semantics.
- Runtime lane metadata is materialized locally in `plan-issue-cli` (not read from split-prs runtime placeholders).

## Quick examples

```bash
# 1) Build plan-scoped task spec locally
plan-issue-local build-plan-task-spec \
  --plan docs/plans/example-plan.md \
  --pr-grouping per-sprint

# 2) Start plan issue in live mode
plan-issue start-plan \
  --repo owner/repo \
  --plan docs/plans/example-plan.md \
  --pr-grouping per-sprint

# 3) Local rehearsal start-plan (deterministic placeholder issue_number=999)
plan-issue-local --format json --dry-run start-plan \
  --plan docs/plans/example-plan.md \
  --pr-grouping per-sprint

# 4) Export completion
plan-issue completion zsh > completions/zsh/_plan-issue
plan-issue-local completion bash > completions/bash/plan-issue-local

# 5) Auto grouping with metadata fallback
plan-issue-local build-plan-task-spec \
  --plan docs/plans/example-plan.md \
  --strategy auto \
  --default-pr-grouping group
```

## Exit codes

- `0`: success
- `1`: runtime/validation failure
- `2`: usage failure

## Specifications

- [CLI contract v2]docs/specs/plan-issue-cli-contract-v2.md
- [State machine and gate invariants v1]docs/specs/plan-issue-state-machine-v1.md
- [Gate matrix v1]docs/specs/plan-issue-gate-matrix-v1.md

## Fixtures

- Shell parity fixtures live under `tests/fixtures/shell_parity/`.
- Use `tests/fixtures/shell_parity/regenerate.sh` to refresh fixture snapshots when shell behavior intentionally changes.