claudio.cool
CCDV-FLessons

CCDV-F · Claude Code

Headless in CI, sessions, commands and skills

⏱ 3 min readDraft

A CI job asks Claude Code to review every pull request and hangs waiting for someone to approve a permission. Someone proposes skipping all the checks so it never asks again. On the same team, every Friday a person types the same long prompt from memory to put together the release notes. Both are solved with pieces Claude Code already has.

With nobody watching: headless mode

Headless mode runs Claude Code without an interface, with claude -p "..." (or --print). For CI, what matters:

  • --output-format json returns an object with the result, session ID, usage and cost; stream-json emits JSON events line by line while it works.
  • --json-schema together with --output-format json returns the structured output in the structured_output field. If it didn’t arrive (for example, because Claude declined), the field is missing: the script has to check for it.
  • --allowedTools approves only what’s needed, using permission rule syntax: "Read,Grep,Bash(git diff *)".
  • --bare skips loading the machine’s hooks, skills, plugins, MCP servers and CLAUDE.md, so the result is the same on any runner; whatever is needed gets passed with flags.
  • The exit code is 0 on success and non-zero on failure, so the pipeline can branch.

Permission modes

Permission modes set what runs without asking:

Mode What runs without asking
default (manual) Reads only
acceptEdits Reads, file edits and common filesystem commands in the working directory
plan Analyzes and proposes a plan without editing
auto Almost everything, with a classifier that reviews each action and blocks what goes beyond the request
dontAsk Pre-approved actions; anything that would prompt is denied (useful for locked-down CI)
bypassPermissions Everything; only in isolated containers or machines

For fewer prompts with a safety net there’s auto; “full permissions so it doesn’t ask” is almost never the answer.

Sessions

  • claude --continue opens the most recent session in the directory; claude --resume <name> picks up a specific session. Sessions are named with -n at startup or with /rename.
  • To fork a session and try another path without touching the original: /branch from inside, or --fork-session together with --resume or --continue.
  • /clear starts with an empty context (the previous session stays saved) and /compact replaces the history with a summary.

Watch out: if you opened another session after an investigation, --continue no longer takes you to the investigation. To resume a session that’s a specific one, use --resume with its name.

Commands, skills, agents and memory

  • Built-in slash commands: /init, /clear, /compact, /resume, /memory, among others.
  • Skills: a procedure that repeats goes in the project’s .claude/skills/<name>/SKILL.md, gets committed and everyone invokes it with /name. Custom commands in .claude/commands/ still work and behave the same way. At startup only the description is loaded; the body loads when it’s used. With disable-model-invocation: true, Claude doesn’t trigger it on its own, which matters if it has side effects (creating a release draft, deploying).
  • Agents: subagents in .claude/agents/, with their own tools and their own context, for tasks worth isolating.
  • Auto memory: notes Claude writes on its own from your corrections, per repository. You review it and turn it off with /memory. It’s context, just like CLAUDE.md.

The typical traps

  • bypassPermissions or full permissions in CI “so it doesn’t hang”.
  • Parsing plain-text output instead of using --output-format json.
  • Using --continue to return to a session that’s no longer the most recent.
  • Retyping every week a prompt that could be a project skill.
  • Letting Claude invoke a skill with side effects on its own.

On the exam

If something has to run with nobody watching, look for claude -p with JSON output and a narrow --allowedTools. If you need to return to a specific session and try alternatives, look for --resume with the name and /branch. And if someone repeats a procedure by hand, look for a versioned skill in the project, with model invocation disabled if it has side effects.

Quick question

A practice exam question on this domain. It counts towards your progress.

Every Friday, developers on a mobile team ask Claude Code to prepare the weekly release notes. Each person types a long prompt from memory: collect merged PRs since the last tag, group them by feature area, flag anything touching payments, and write the summary in the team's template. Results vary a lot because people forget steps or phrase them differently.

The tech lead wants everyone to run the same procedure with one short command, keep it versioned with the code, and make sure Claude never starts it on its own, since it creates a draft release.

What should the team set up?

Practise this domain in a practice exam →