ktg-plugin-marketplace/plugins/ultraplan-local/commands/ultracontinue-local.md
Kjell Tore Guttormsen 43cdc0b968 feat(ultraplan-local): add /ultracontinue command for multi-session resumption [skip-docs]
Reads .claude/projects/<project>/.session-state.local.json (Handover 7),
narrates a 3-line summary, and immediately begins executing the next
session — no interactive confirmation, headless-safe.

Phases:
- 0: --help (self-documenting per brief NFR)
- 1: resolve project dir (auto-discover via node -e enumeration)
- 2: validate via session-state-validator
- 3: narrate (project / next_session_label / brief path)
- 4: read brief and begin
- 5: stats

[skip-docs] rationale: README + CLAUDE.md updates land in Step 11 (Session
2b) per plan structure. Step 8 (docs:) updates HANDOVER-CONTRACTS.md and
the doc-consistency test pin in the same session.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 20:49:01 +02:00

161 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: ultracontinue-local
description: Resume the next session in a multi-session ultraplan project. Reads .session-state.local.json and immediately begins the next session.
argument-hint: "[<project-dir> | --help]"
model: opus
---
# Ultracontinue Local v1.0
Zero-friction multi-session resumption. In a fresh Claude Code session, type
`/ultracontinue` — the command reads the per-project state file
(`.claude/projects/<project>/.session-state.local.json`), shows a 3-line summary,
and immediately begins executing the next session.
The state file is the contract. Any session-end mechanism may write it
(`/ultraexecute-local` Phase 8 / Phase 2.55 / Phase 4, the
`/ultraplan-end-session-local` helper, or — in the future — `graceful-handoff`).
This command only reads.
Pipeline position:
```
/ultraplan-local → plan.md
/ultraexecute-local → progress.json + .session-state.local.json
... session boundary, fresh chat ...
/ultracontinue → reads .session-state.local.json, starts next session
```
See **Handover 7** in `docs/HANDOVER-CONTRACTS.md` for the full schema.
## Phase 0 — `--help` handling
If `$ARGUMENTS` contains `--help` or `-h`, print the usage block below and exit
cleanly. Do NOT proceed to any further phase.
```
/ultracontinue — Resume the next session in a multi-session ultraplan project.
Usage:
/ultracontinue # auto-discover state file under cwd
/ultracontinue <project-dir> # explicit project directory
/ultracontinue --help # this message
Reads .claude/projects/<project>/.session-state.local.json (per-project,
gitignored). On a valid resumable state, prints a 3-line summary and begins
executing the next session immediately. No interactive confirmation prompt.
State-file schema (v1):
schema_version 1
project string
next_session_brief_path string (validator soft-checks file existence)
next_session_label string
status in_progress | partial | failed | stopped | completed
(completed → no further sessions to resume)
updated_at ISO-8601 timestamp
(unknown top-level keys are tolerated — forward-compat for graceful-handoff v2.2)
Typical flow:
/ultrabrief-local # produces brief.md
/ultraplan-local --project ... # produces plan.md
/ultraexecute-local --project .. # writes session-state on session-end
... (fresh Claude chat) ...
/ultracontinue # reads session-state, runs next session
```
## Phase 1 — Resolve project directory
If `$ARGUMENTS` is non-empty and not `--help`/`-h`, treat the first positional
argument as the explicit `<project-dir>`. Otherwise auto-discover via Bash by
enumerating `.claude/projects/*/.session-state.local.json` paths with `node -e`
(NOT shell glob — harness-mode safety):
```bash
!`node -e "const fs=require('fs'),path=require('path');const root='.claude/projects';if(!fs.existsSync(root))process.exit(0);const dirs=fs.readdirSync(root).map(d=>path.join(root,d,'.session-state.local.json')).filter(p=>fs.existsSync(p));dirs.forEach(p=>process.stdout.write(p+'\\n'));"`
```
Decision tree:
- **0 candidates and no explicit arg:** print SC-2 cold-start message and exit:
```
No active multi-session project here.
Start with /ultrabrief-local or /ultraplan-local.
```
- **1 candidate (or explicit arg):** continue to Phase 2 with that path.
- **>1 candidates and no explicit arg:** print all paths sorted by `updated_at`
descending, instruct the user to disambiguate via explicit `<project-dir>`,
then exit:
```
Multiple active multi-session projects found:
.claude/projects/<a>/.session-state.local.json updated <ts>
.claude/projects/<b>/.session-state.local.json updated <ts>
Re-run as: /ultracontinue <project-dir>
```
## Phase 2 — Validate the state file
Run the validator from a Bash invocation:
```bash
!`node lib/validators/session-state-validator.mjs --json {state-file-path}`
```
Interpret the result:
- **Validator exit code != 0 OR `valid: false` in JSON output:** print the
structured `errors[]` (each `[code] message` on its own line) and exit. Do not
proceed to narration. Suggest running the validator directly for follow-up:
`node lib/validators/session-state-validator.mjs <path>`.
- **`valid: true` AND any warning has `code: SESSION_STATE_NOT_RESUMABLE`** (i.e.
`status: completed`): print "no further sessions to resume; project complete"
and exit cleanly.
- **`valid: true` AND status is one of `in_progress | partial | failed | stopped`:**
proceed to Phase 3.
## Phase 3 — Narrate 3-line summary
Print this exact template (using values from the validated `parsed` object):
```
Project: {project}
Next session: {next_session_label}
Brief: {next_session_brief_path}
```
No interactive confirmation prompt — per the brief NFR ("ingen prompts, men la
informasjon synes"). The 3-line block is informational only.
## Phase 4 — Begin execution
Read the file at `next_session_brief_path` (it is the brief that the next
session is supposed to execute — typically the same `brief.md` for
single-brief multi-session plans, or a session-specific spec for parallel
session decomposition). Understand the task and begin executing per the
standard ultraplan-local pipeline. The user did not type a separate "start"
command — `/ultracontinue` is the start.
If the brief file does not exist (validator emits a warning but does not
fail), print: `Warning: next_session_brief_path "{path}" does not exist on
disk. Cannot continue automatically.` and exit. Do not guess.
## Phase 5 — Stats tracking
Append a one-line JSON record to `${CLAUDE_PLUGIN_DATA}/ultracontinue-stats.jsonl`
if the env var is set; silently skip otherwise.
```json
{"ts":"<iso-8601>","project":"<project>","next_session_label":"<label>","status":"<status>"}
```
## Hard rules
- **Idempotent.** Running `/ultracontinue` twice in the same Claude session
does not advance state — the writer (Phase 8 / hook / helper) advances state
only when a session completes.
- **Zero secrets in the state file.** Status, paths, labels — never API keys,
never user content beyond filenames.
- **NEVER auto-load via SessionStart.** The command is operator-invoked only.
Auto-loading would re-introduce the stale-file risk noted in
`feedback_next_session_prompt_manual.md`.
- **No interactive prompts.** Phases 04 must run without `AskUserQuestion`.
This keeps the command headless-safe.