--- name: trekendsession description: Mark the current session as complete and write session-state pointing at the next session. Helper for informal multi-session flows. argument-hint: " | --help" disable-model-invocation: true --- # Voyage End-Session Local v1.0 Tiny helper for **informal** multi-session flows (no formal plan with Execution Strategy). Writes a `.session-state.local.json` pointing at the next session so `/trekcontinue` can resume in a fresh Claude chat. For formal flows (a plan produced by `/trekplan --project`), `/trekexecute` Phase 8 already writes the state file — this helper is unnecessary there. Use this command for ad-hoc release runs, manual multi-session handovers, or any flow that does not run through `/trekexecute`. Pipeline position: ``` ... session N work ... /trekendsession "" → writes state ... session boundary, fresh chat ... /trekcontinue → reads state, starts session N+1 ``` See **Handover 7** in `docs/HANDOVER-CONTRACTS.md` for the schema. ## Phase 0 — `--help` handling Parse `$ARGUMENTS` with the arg parser. Run this via the Bash tool at runtime (NOT eager-exec), exactly as written: the arguments reach the parser as the one line inside the quoted heredoc, on stdin, never as shell words: ```bash setopt nonomatch 2>/dev/null || true node ${CLAUDE_PLUGIN_ROOT}/lib/parsers/arg-parser.mjs --command trekendsession --stdin <<'VOYAGE_ARGS_EOF_7F3C9E' $ARGUMENTS VOYAGE_ARGS_EOF_7F3C9E ``` The `setopt nonomatch` line is no longer needed for the arguments (the quoted heredoc expands no glob); it stays harmless. It prints the parse result as JSON. On exit 1, print its `errors` and stop. When it prints no JSON, say that the parser did not run and stop. Print the usage block below and exit cleanly ONLY when one of these two conditions equals exactly true (no substring search, no "contains" check): - `flags['--help'] === true`, OR - `positional[0] === '-h'` (single-dash short form — the parser keeps it as positional because the schema declares no alias). Then do NOT proceed to any further phase. In every other case — a slug or a label that holds `-h` or `help` too — go on to Phase 1. ``` /trekendsession — Mark current session done; point at next session. Usage: /trekendsession /trekendsession --help Both arguments are REQUIRED. No interactive prompt — headless-safe. Writes /.session-state.local.json with: schema_version 1 project next_session_brief_path next_session_label status in_progress updated_at Then validates via lib/validators/session-state-validator.mjs and prints the same 3-line narration that /trekcontinue will show in the next session. Example: /trekendsession .claude/projects/2026-05-01-feature/brief.md "Session 2 of 3" ``` ## Phase 1 — Resolve project directory Resolve the nearest `.claude/projects/*/brief.md` from cwd (the current working directory). Use `node -e` enumeration (NOT shell glob — harness-mode safety): ```bash !`node --input-type=module -e "import {existsSync, readdirSync} from 'node:fs'; import {join} from 'node:path'; const root='.claude/projects'; if(!existsSync(root)) process.exit(0); readdirSync(root).filter(d=>existsSync(join(root,d,'brief.md'))).forEach(d=>process.stdout.write(join(root,d)+'\\n'));"` ``` Decision tree: - **0 candidates:** print error to stderr — "no `.claude/projects//brief.md` found under cwd; cannot determine project directory" — and exit 1. Do NOT fall back to a synthesized path. - **1 candidate:** use it as ``. Continue. - **>1 candidates:** print all paths and ask the operator to `cd` into the intended project directory before retrying. Exit 1. ## Phase 2 — Required args check (headless-safe) Read the parse result from Phase 0: `` is `positional[0]` and `` is the parser's `tail` (the rest of the text as typed after the brief path, one outer quote pair removed, so a label with spaces stays whole). Both are required. If either is missing or empty: ``` Error: missing required args. Usage: /trekendsession '' ``` Print to stderr and exit 1. **No interactive prompt** — this keeps the helper headless-safe (per brief NFR; addresses adversarial-review major #11). If you want an interactive flow, use `/trekcontinue --help` to see the full pipeline. ## Phase 3 — Atomically write `.session-state.local.json` + sibling NEXT-SESSION-PROMPT.local.md Write `{project_dir}/.session-state.local.json` with the schema-v1 object: ```json { "schema_version": 1, "project": "{project_dir}", "next_session_brief_path": "{arg 1}", "next_session_label": "{arg 2}", "status": "in_progress", "updated_at": "{now, ISO-8601}" } ``` Use the atomic-write util — write to `.tmp`, then `rename` into place — to avoid partial-state on crash. The util is ESM, so invoke via `node --input-type=module -e` with an `import` statement (a CommonJS shim would throw `ERR_REQUIRE_ESM` on Node 18+ since `atomic-write.mjs` is ESM). Under `node --input-type=module -e "