ktg-plugin-marketplace/plugins/graceful-handoff/commands/graceful-handoff.md
Kjell Tore Guttormsen b9269f853d feat(graceful-handoff): initial plugin with /graceful-handoff command
New plugin that produces a complete session handoff in under 60s:
NEXT-SESSION artifact, commit+push, and copy-paste prompt for next
session. Built for context-constrained models like Opus 4.7 where
sessions fill fast.

- Single declarative command, no hooks/agents/skills
- Detects handoff type: multi-session / plugin-work / single-task
- Default filename NEXT-SESSION-PROMPT.local.md; slug-override
- Flags: --no-commit, --dry-run
- Auto-generated Conventional Commits message from git diff --stat
- Respects pre-commit hooks (secrets, pathguard) — never bypasses

Also: add *.local.md to root .gitignore (existing NEXT-SESSION files
were untracked but not ignored) and list plugin in marketplace
README + CLAUDE.md per docs-convention.
2026-04-19 22:54:10 +02:00

13 KiB

name description argument-hint allowed-tools
graceful-handoff Produser handoff-artefakt, commit+push, og copy-paste-prompt for neste sesjon. Bruk når du nærmer deg 60-70% kontekst og må fortsette arbeidet i en ny sesjon uten tap. [topic-slug] [--no-commit] [--dry-run] Read, Write, Edit, Bash, Glob

Graceful Handoff — sesjonsoverlevering

Produser en komplett handoff-pakke i ett steg: analyser state, skriv NEXT-SESSION-artefakt, oppdater REMEMBER/TODO, commit+push hvis mulig, og print en copy-paste-prompt for neste sesjon.

Tidsbudsjett: Hele kjøringen (fase 1-6) skal ligge under 60 sekunder reell tid. Bruker er typisk på 60-70% kontekst når de trigger dette — ikke bruk Agent-delegering eller WebSearch.

Argumenter

Argument Effekt
[topic-slug] Kebab-case slug som styrer filnavnet. Default: NEXT-SESSION-PROMPT.local.md. Med slug: NEXT-SESSION-<slug>.local.md
--no-commit Hopp over fase 5 (commit+push). Bruker håndterer commit manuelt
--dry-run Ikke skriv filer eller gjør git-operasjoner. Print kun hva som ville skjedd

Parse argumenter fra $ARGUMENTS (kombinert streng). Støtt flag i vilkårlig rekkefølge. Første ikke-flag-token er slug.


Fase 1 — Detekter arbeidsmappe og aktivt prosjekt

Kjør i parallell (én Bash-melding med flere tool calls):

pwd
git rev-parse --show-toplevel 2>/dev/null
git status --porcelain
git log --oneline -10
git branch --show-current

Let oppover i tre etter plugin-markør (maks 5 nivåer):

# Fra cwd og oppover, stopp på første treff
cur="$(pwd)"
for i in 1 2 3 4 5; do
  if [ -f "$cur/.claude-plugin/plugin.json" ]; then
    echo "PLUGIN_ROOT=$cur"
    break
  fi
  cur="$(dirname "$cur")"
  [ "$cur" = "/" ] && break
done

Finn ultraplan-prosjekt (nyeste først):

find . -maxdepth 4 -path '*/.claude/projects/*/brief.md' 2>/dev/null | sort -r | head -3
find . -maxdepth 4 -path '*/.claude/projects/*/progress.json' 2>/dev/null | sort -r | head -3

For hver progress.json-treff: kjør jq -r '.status' <file> for å se om prosjektet er aktivt.

Fase 2 — Identifiser handoff-type

Prioritet: multi-sesjon > plugin-arbeid > enkelt-oppgave

Type Betingelse
multi-sesjon Finnes .claude/projects/<NN>/progress.json med status != "completed" OG status != null. Eller: finnes .claude/projects/<NN>/plan.md uten progress.json
plugin-arbeid Fase 1 fant PLUGIN_ROOT OG ingen aktiv multi-sesjon
enkelt-oppgave Ingen av over

Lagre i intern state: HANDOFF_TYPE, PROJECT_DIR (hvis multi-sesjon), PLUGIN_ROOT (hvis plugin-arbeid), WRITE_DIR (hvor artefakten skal skrives).

Write-dir-logikk:

  • multi-sesjonWRITE_DIR = <PROJECT_DIR>
  • plugin-arbeidWRITE_DIR = <PLUGIN_ROOT>
  • enkelt-oppgaveWRITE_DIR = $(pwd)

Rapporter til bruker i en kort linje:

Handoff-type: plugin-arbeid (llm-security). Skriver til /Users/ktg/.../plugins/llm-security/

Hvis overlapp eksisterer (f.eks. plugin-arbeid innenfor et aktivt ultraplan-prosjekt): rapporter begge, men velg multi-sesjon som primær.

Fase 3 — Skriv/oppdater NEXT-SESSION-artefakt

Filnavn:

  • Hvis [topic-slug] gitt: NEXT-SESSION-<slug>.local.md
  • Ellers: NEXT-SESSION-PROMPT.local.md

Full sti: <WRITE_DIR>/<filename>.

Hvis filen finnes: les den først, bevar "Hvorfor dette eksisterer"-seksjonen hvis den er relevant, oppdater status-seksjoner med dagens dato og aktuell state.

Template (samme 7-seksjons-struktur som llm-security/config-audit bruker):

# NEXT-SESSION-PROMPT — <plugin-eller-prosjekt-navn> <kort-tittel>

## Hvorfor dette eksisterer

<1-3 setninger om hva bruker jobber med og hvorfor denne sesjonen stoppet. Hent fra: siste commits, brief.md hvis multi-sesjon, git diff, samtale-kontekst. Vær konkret — ingen fluff.>

## Status ved sesjonshåndoff

### ✅ Ferdig

<List commits fra denne sesjonen med SHA + hva hver gjorde. Eks:
- `a9fb328` fix(config-audit): complete conflict-project fixture
- `94ce701` test(config-audit): add Opus 4.7 pattern fixtures

Hvis ingen commits: skriv "Ingen nye commits i denne sesjonen".>

### ⏳ Ikke startet / delvis

<Konkrete neste steg. Nevn filnavn og linjenummer hvis du vet dem. Eks:
- Commit 2: Kontekst-bevisst entropy — scanners/entropy-scanner.mjs:40-47, 90-137
- Commit 3: Policy-integrasjon

Hvis det finnes en plan-fil: peker til den.>

### ⚠️ Brutt / kjent risiko

<Tester som feiler, uncommittede endringer, antakelser som ikke er verifisert. Eks:
- 25/80 tester feiler i tests/lib/severity.test.mjs (forventet — tester gammel formel)
- Commit 1 er lokal, ikke pushet

Hvis ingenting er brutt: skriv "Ingen kjente broken tester".>

## Slik fortsetter du

1. `cd <absolute-path-til-WRITE_DIR>`
2. `cat <filename>` — les denne filen igjen
3. `git log --oneline -5` og `git status`
<4. (hvis multi-sesjon) Les planen: `cat .claude/projects/<slug>/plan.md`>
<5. Start med: <konkret neste handling>>

## Push-policy

- Direkte push til `main` på Forgejo er pre-autorisert (ikke spør om tillatelse)
- Aldri GitHub — kun Forgejo (`git.fromaitochitta.com`)
<evt. prosjekt- eller plugin-spesifikke regler, f.eks. versjonsbump-timing>

## Verifiseringskommandoer

```bash
<Copy-paste-klare sjekker som beviser state. Eks:
git log --oneline -5           # forventet: <siste commit SHA>
git status                      # forventet: clean (eller <N> uncommittede)
node --test tests/              # forventet: alle grønne
>

Husk

  • <Gotchas og antakelser som ikke er åpenbare fra koden. Eks:
    • Hooks (pre-edit-secrets, pre-write-pathguard) blokkerer writes til .claude-plugin/
    • Versjonsbump krever sync i 7+ filer — bruk grep-mønster
    • Opus 4.7 fyller kontekst raskt — kjør /graceful-handoff ved 60-70%>

**Innholdsregler:**
- Ikke fyll inn plassholdere med placeholder-tekst. Les faktisk git-state, samtalekontekst, og evt. brief.md/plan.md for å fylle inn ekte info.
- Hvis en seksjon er irrelevant (f.eks. ingen push-policy avvik): skriv én setning som sier det, ikke utelat seksjonen (strukturen må være konsistent).
- Tone: nøktern, norsk, teknisk. Ingen "gøy å jobbe med deg" eller "vi har kommet langt". Hvis brukeren var sint eller frustrert: nevn det kort i "Husk" slik at neste sesjon ikke trår i samme fellen.

Hvis `--dry-run`: print artefakten til stdout i stedet for å skrive.

## Fase 4 — Oppdater REMEMBER.md og TODO.md

**Lokasjon:**
- `plugin-arbeid` → `<PLUGIN_ROOT>/REMEMBER.md` og `<PLUGIN_ROOT>/TODO.md`
- `multi-sesjon` → `<PROJECT_DIR>/REMEMBER.md` og `<PROJECT_DIR>/TODO.md` (hvis de finnes; ellers skip — ultraplan-prosjekter har ikke alltid disse)
- `enkelt-oppgave` → `$(pwd)/REMEMBER.md` og `$(pwd)/TODO.md` (kun hvis de allerede finnes; ikke opprett nye i random mapper)

**REMEMBER.md-oppdatering:**

Hvis filen finnes — les, oppdater:
- Øverst: `## Sist oppdatert\n<YYYY-MM-DD>` (absolutt dato, ikke "i dag")
- "PÅGÅENDE"-seksjon (eller lag den): plan-sti hvis relevant, 3-5 status-bullets (✅ ferdig, ⏳ pågående, ⚠️ blokkert)
- Flytt tidligere "PÅGÅENDE" til "TIDLIGERE" med datostempel hvis den peker på annet arbeid

Hvis filen ikke finnes og type er `plugin-arbeid`: opprett minimal REMEMBER.md med dagens dato og én PÅGÅENDE-bullet. Ellers skip.

**TODO.md-oppdatering:**

Hvis filen finnes — les, oppdater:
- Flytt items som ble gjort denne sesjonen til en "✅ Ferdig denne sesjonen (YYYY-MM-DD)"-seksjon øverst
- Legg til items for neste sesjon under "⏳ Neste"
- Ikke slett — kommenter ut eller flytt

Hvis filen ikke finnes: skip (ikke push onboarding i en handoff).

**Gitignore-verifisering:** Etter skriving, kjør `git check-ignore -v <path>` for hver fil. Hvis filen IKKE er ignorert: rapporter til bruker som advarsel (ikke blokker, men bruker må vite).

Hvis `--dry-run`: print diff i stedet for å skrive.

## Fase 5 — Commit + push hvis ucommittet arbeid finnes

Skip hele fasen hvis `--no-commit` eller `--dry-run`.

Skip hvis `git status --porcelain` er tom (ingenting å commite).

**Steg 5a — Klassifiser endringer:**

```bash
git diff --stat
git diff --cached --stat
git status --porcelain

Kategoriser endrede filer for å utlede commit-type:

Filmønster Type
tests/**, **/*.test.* test
*.md, README, CHANGELOG, CLAUDE.md (kun docs-endring) docs
plugins/<name>/hooks/**, plugins/<name>/scanners/** (ny funksjon) feat
Samme mønster, men fikser eksisterende atferd fix
package.json, config, lockfile kun chore
Blandet Bruk dominerende kategori; hvis uklart, chore

Scope: plugin-navn hvis plugin-arbeid eller hvis alle endringer er i én plugin. Ellers ingen scope.

Steg 5b — Generer commit-melding:

Format: <type>(<scope>): <kort beskrivelse> (Conventional Commits).

Krav:

  • Første linje ≤ 72 tegn
  • Beskrivelse på norsk eller engelsk (match eksisterende commits i repoet — sjekk git log --oneline -10)
  • Beskriv hva som endres, ikke hvorfor (hvorfor hører hjemme i body hvis nødvendig)
  • Hvis flere uavhengige endringer: vurder om de skal splittes i to commits. Hvis bruker er i hastverk (kontekst-trøskel): ett commit med samlet beskrivelse er akseptabelt, men noter at det er samlet i body.

Eksempler (match stil fra eksisterende repo):

  • test(config-audit): add Opus 4.7 pattern fixtures
  • fix(llm-security): complete conflict-project fixture for CNF cross-scope tests
  • feat(graceful-handoff): initial plugin with /graceful-handoff command

Body (valgfri, bruk hvis commit dekker flere endringer):

- Endring 1
- Endring 2

Samlet som ett commit pga. graceful-handoff-flyt.

Steg 5c — Vis meldingen og commit:

Print den genererte meldingen ordrett til bruker FØR commit:

Commit-melding:
---
feat(graceful-handoff): initial plugin with /graceful-handoff command
---

Deretter:

git add -A  # eller eksplisitt filvalg hvis endringene spenner flere uavhengige områder
git commit -m "$(cat <<'EOF'
<meldingen>
EOF
)"

Hvis commit feiler pga. pre-commit hook (secrets, pathguard, osv.): STOPP, rapporter feilmeldingen, ikke bypass med --no-verify. Be bruker håndtere manuelt.

Steg 5d — Push:

BRANCH="$(git branch --show-current)"
if [ -n "$BRANCH" ]; then
  git push origin "$BRANCH"
else
  git push origin HEAD
fi

Bekreft push med git rev-parse @{u} (at upstream er satt) eller hent siste output fra push-kommandoen.

Hvis push feiler: rapporter, men ikke force-push. Bruker kan håndtere manuelt.

Fase 6 — Print copy-paste-prompt for neste sesjon

Print en kompakt prompt til terminal som bruker kan kopiere direkte inn i ny Claude Code-sesjon:

════════════════════════════════════════════════════════════
NESTE SESJON — copy-paste til ny Claude:
════════════════════════════════════════════════════════════

cd <absolute-WRITE_DIR>
cat <NEXT-SESSION-filnavn>
git log --oneline -5
git status

Fortsett fra <konkret neste handling - én setning>.

════════════════════════════════════════════════════════════
Artefakt: <full sti til NEXT-SESSION-filen>
Commit:   <siste SHA eller "ingen endringer">
Push:     <"pushet til Forgejo" eller "skippet (flag / ingenting)">
════════════════════════════════════════════════════════════

Dette er den KRITISKE output-en — hvis alt annet feiler, må minst denne blokken nå bruker slik at de kan fortsette. Bruk én final assistant-tekst-melding til å printe dette.


Tidsbudsjett og escalation

  • Hele kommandoen: < 60 sekunder
  • Hvis du oppdager at du trenger å lese >5 filer eller kjøre >3 Agent-delegeringer: stopp, skriv en minimal handoff med det du har, og noter i "Brutt/risiko" at handoff var ufullstendig.
  • Aldri Agent-delegering i denne kommandoen — main-sesjonen er raskere enn å spinne opp en subagent for noe mekanisk som dette.
  • Aldri WebSearch — ingen ekstern info trengs.

Fallback hvis state er helt uklart

Hvis fase 1-2 ikke kan identifisere noen av de tre handoff-typene (f.eks. cwd er utenfor git, ingen plugin-markør, ingen ultraplan-prosjekt):

  1. Sett HANDOFF_TYPE = enkelt-oppgave
  2. WRITE_DIR = $(pwd)
  3. Varsle bruker: "Kunne ikke detektere handoff-type. Skriver til cwd."
  4. Fortsett som vanlig — prompten er fremdeles nyttig