Files
Gabriel Vidal e2842e27e0 refactor(complete): replace the CTA system with a complete skill
Completing a conversation is now a skill the session runs on itself before it
ends, instead of a button that resumes it afterwards. A resume is a new process,
so it re-creates the whole transcript as fresh input tokens — the same tidy-up
costs several times more once the process has exited. The spawn guidelines point
the session at `.claude/skills/complete/SKILL.md` after its final notification;
that pass waits 30s (a window to redirect after reading the result), publishes
the summary via conv-scaffold + one subagent, tidies up, and signs off with
COMPLETED.

With the prompts living in a skill, the whole CTA layer goes:

- backend: ctas.py, /api/ctas* (+ /run, /prompt, /reorder), the seeded prompt
  writer, the Cta* schemas, meta.ctas and its merge path. /api/claude-hooks
  stays — it just no longer lives in a CTA-shaped section.
- frontend: Settings -> CTAs page, the CTA buttons under a finished thread,
  the CTA badge, ctaIcons, the cta:<id> composer tags, and the ctas SSE event.
- the native Claude Code hooks list moves onto the main Settings page
  (/settings#hooks), where it is the only hooks surface left.

The COMPLETED seal now reads `meta.completedAt`, derived from the transcript's
COMPLETED marker the parser already flags, rather than the meta.ctas["complete"]
ledger — nothing has to stamp it. What survives of the old pass is unchanged:
conv-scaffold, the published summary on meta.summary, and the Summary card
(ConversationCtas -> ConversationSummary).

Existing meta.ctas data is left alone in the store; it is simply no longer read.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 00:15:34 +02:00

98 lines
4.2 KiB
Markdown

---
name: complete
description: Close out a finished conversation — wait 30 s for a change of mind, then publish its summary (conv-scaffold + one subagent) and tidy up (memories, docs, artefacts, worktrees, changelog). Use when the task is done, the final notification has been sent, and the conversation guidelines say to complete it. Not for starting new work.
---
# complete — the end-of-task pass
The last thing a conversation does. Everything about the task is already
finished and notified; this pass turns the conversation into a **record** and
leaves the machine tidy.
It runs **inside the still-running session**, not as a resume. That is the whole
point: a `--resume` is a new process, so it re-creates the entire transcript as
fresh input tokens (see the ai-agent repo's `CLAUDE.md`). Running the pass
before the session ends reuses the prompt cache it already built.
## When to run it
After the task is done **and** the final `notify-done` has gone out — the
conversation guidelines say so explicitly. Never as a way to start new work.
## 0. Wait 30 seconds first
Gabriel reads the finished conversation on his phone as the notification lands.
The pause is his window to **interrupt and redirect** before the pass starts —
without it, the tidy-up races his reply and he ends up correcting a conversation
that has already summarised itself.
Arm a Monitor and end the turn. Do **not** run a foreground `sleep` (it is
blocked), and do not skip the wait:
```
Monitor: command = "sleep 30; echo 'window over — completing'"
description = "30 s grace period before the completion pass"
timeout_ms = 120000
persistent = false
```
The monitor emits one line and exits. If Gabriel sends something in the
meantime, **that wins**: drop the completion pass, do what he asked, and only
come back here once that is finished too.
## 1. Scaffold + summary
Run `conv-scaffold` — it writes a markdown scaffold of *this* conversation
(metadata and tags, the squashed diff of everything that changed, merged
bash/tool/task summaries) and prints its path:
```bash
conv-scaffold # → /tmp/conv-scaffold-<sessionId>.md
```
Then spawn **one subagent** whose whole job is that file: it reads the scaffold,
fills in the `## Summary` and `## Analysis` sections (what was built, the key
decisions, what is worth remembering, what is still open), and publishes it:
```bash
conv-scaffold publish <path>
```
Everything the subagent needs is in the scaffold — it does **not** need this
conversation's history, which is why the analysis costs a fraction of what
re-reading the transcript would. An untouched scaffold is refused (HTTP 422).
The published summary lands on the conversation's `meta.summary` and renders as
the folded **Summary** card under the thread in the ai-agent viewer.
## 2. Tidy up
While the subagent works, do the housekeeping this task earned — only what
genuinely applies, and keep it short:
- **Memory.** Anything non-obvious here — a gotcha, a wrong turn, a constraint
invisible in the code? One fact per file in your memory directory, plus its
line in `MEMORY.md`. Skip what the repo already records.
- **Docs.** If the change altered how something is used, built or deployed,
update the affected `README.md` / `CLAUDE.md` / `GOAL.md`. Describe the
current state — no changelog prose.
- **Artefacts.** Copy anything worth keeping (screenshots, diagrams, reports)
into the canonical project's `.ai/artefacts/<sessionId>/`. Leave scratch
behind.
- **Cleanup.** Remove worktrees you created once their branch is merged
(`scripts/new-worktree.sh -r <path>`), and kill background processes, dev
servers or standby containers you no longer need.
- **Changelog.** If the project keeps one, add the user-facing entry.
Do **not** re-notify (no `notify-done`) and do not start new feature work.
## 3. Sign off with `COMPLETED`
End your reply with `COMPLETED` on its own line — **not** `DONE`.
That marker is load-bearing, not decoration. The ai-agent backend parses the
transcript's last message for it (`completedMarker``meta.completedAt`) and
uses it to tell "the task finished" apart from "the task finished **and** was
tidied up after": the spinning COMPLETED seal on the conversation card is that
timestamp, and nothing else writes it.