Run your build, test, and validate commands on a remote CircleCI-provisioned Linux environment instead of locally. The 90% job is the sync → validate dev loop. This skill also handles first-time setup, debugging, test-suite scaffolding, and snapshot management.
Step 0 — Probe State, Then Ask
Run these probes before anything else. They are read-only and always safe:
chunk --version 2>&1 || echo "CHUNK_NOT_INSTALLED"
chunk auth status 2>&1
cat .chunk/config.json 2>&1 || echo "{}"
chunk sidecar current 2>&1
If chunk is not installed: Stop. Tell the user to install chunk before using this skill.
If auth shows CircleCI "Not set": Run the OAuth login for them — see Logging in — then re-run chunk auth status. Only continue once CircleCI shows "Configured".
Otherwise, call AskUserQuestion based on detected state (choose the block that matches):
No active sidecar + no validation.sidecarImage in config (first time)
AskUserQuestion:
header: "Sidecar intent"
question: "No sidecar is configured yet. What would you like to do?"
options:
- "Walk me through first-time setup"
→ invoke the chunk-sidecar-setup skill via the Skill tool
- "I have a snapshot ID — create from it"
→ ask user for the snapshot ID, then:
chunk sidecar create --image <id>
chunk sidecar sync
→ continue to Dev Loop section
- "Diagnose what's missing"
→ go to Prerequisites section, report findings
- "Scaffold test-suites.yml for Smarter Testing"
→ go to Scaffolding section
No active sidecar + validation.sidecarImage IS set
AskUserQuestion:
header: "Sidecar action"
question: "You have a configured snapshot but no running sidecar. What would you like to do?"
options:
- "Launch from snapshot and start dev loop" ← Recommended
→ chunk sidecar create --image <sidecarImage>
chunk sidecar sync
→ continue to Dev Loop section
- "Debug or fix something"
→ go to Troubleshooting section
- "Scaffold test-suites.yml"
→ go to Scaffolding section
- "Manage snapshots"
→ go to Snapshot Management section
Active sidecar exists
AskUserQuestion:
header: "Sidecar action"
question: "Your sidecar is active. What would you like to do?"
options:
- "Sync and validate (dev loop)" ← Recommended
→ go to Dev Loop section
- "Debug or fix something"
→ go to Troubleshooting section
- "Scaffold test-suites.yml"
→ go to Scaffolding section
- "Manage snapshots"
→ go to Snapshot Management section
Prerequisites
Before any chunk sidecar command, confirm:
chunk --version— CLI is installed and on PATH.chunk auth status— exit code 0, CircleCI shows "Configured". If not, see Logging in.- OrgID — read
cat .chunk/config.jsonand checkorgID. If missing, runtest -n "${CIRCLECI_ORG_ID:-}". If both are unset, runchunk org list --json: one org, use it automatically; several, show the list and ask exactly once; error or empty, stop and see Logging in. Persist withchunk config set orgID <id>.
Never run echo $CIRCLE_TOKEN, env, printenv, or any command that exposes credential env vars.
Logging in
OAuth is the default. It opens a browser, exchanges the code over PKCE, and stores the token in the system keychain — no token pasting, nothing on disk in plaintext.
chunk auth login
Run it with a Bash timeout of 300000ms — the command blocks until the browser callback lands (5 minute limit). No browser opens when the agent runs it: stdin is not a terminal, so chunk auth login prints the authorize URL and waits. Relay that URL to the user and ask them to open it. Never open a browser on their behalf.
The callback listens on 127.0.0.1 on this machine, so the URL only works from a browser on the same host. --no-browser forces the same print-and-wait behaviour when a terminal is present.
Fall back to chunk auth set circleci (paste a personal API token) only when OAuth is unavailable, or when the user explicitly asks for token auth. Both paths land in the keychain; --insecure-storage writes to ~/.config/chunk/config.json instead.
If chunk auth status reports the CircleCI source as Environment, do not log in — CIRCLE_TOKEN is already set and takes precedence over the keychain, so a login would store a token that never gets used. Treat it as configured and move on.
Dev Loop
Once per project, after the sidecar is working, mark the commands that should run
on it. A sidecar being up routes nothing on its own: chunk sidecar setup marks
only install and gate-role commands, and a sidecar set up by hand has none
marked. chunk validate --list tags each command [local|remote, role], so read
it first, then:
chunk validate --mark-remote # mark all but autofix commands
chunk validate --mark-remote test # or one at a time
The bare form deliberately skips autofix commands (formatters, codegen) and
prints which ones it left alone — those rewrite files, and on the sidecar the edits
never reach the local working tree. Mark one by name only if the user wants that.
Already-marked commands report no change, so re-running is safe, and the flag
persists in .chunk/config.json across sessions.
Caveat: this routing only applies while validation.sidecarImage is unset.
Once a snapshot ID is recorded there, chunk validate sends every command to the
sidecar regardless of marking or role — the same as --remote. On such a project,
run formatters directly instead of through chunk validate.
Then, for each round of edits:
chunk sidecar sync— pushes the local working tree (staged + unstaged) to the active sidecar. Skip if nothing changed.chunk validate— runs configured commands. Commands markedremote: truein.chunk/config.jsonrun on the sidecar; others run locally.- One command by name:
chunk validate <name> - Ad-hoc remote command:
chunk validate --remote --cmd "<cmd>" - Everything on the sidecar regardless of marking:
chunk validate --remote
- One command by name:
- Zero exit = pass. Non-zero = go to Troubleshooting.
Snapshot Management
Snapshots save a configured sidecar state so future sessions boot fast.
- Create:
chunk sidecar snapshot create --name <name>— captures current sidecar. The source sidecar is deleted after a successful snapshot. - List:
chunk sidecar snapshot list - Record in config:
chunk config set validation.sidecarImage <snapshot-id> - Launch from:
chunk sidecar create --image <snapshot-id>thenchunk sidecar sync
Always snapshot after chunk validate passes.
Scaffolding .circleci/test-suites.yml
CircleCI Smarter Testing splits your test suite into atoms and runs only the affected subset. Driven by .circleci/test-suites.yml.
File shape
---
name: <suite-name>
discover: <command that prints one test atom per line>
run: <command that runs `<< test.atoms >>` and writes junit XML to `<< outputs.junit >>`>
outputs:
junit: <path/to/junit.xml>
Stack templates
Go:
discover: go list -f '{{ if or (len .TestGoFiles) (len .XTestGoFiles) }} {{ .ImportPath }} {{end}}' ./...
run: go tool gotestsum --junitfile="<< outputs.junit >>" -- -race << test.atoms >>
Python (pytest):
discover: python -m pytest --collect-only -q
run: python -m pytest --junit-xml=<< outputs.junit >> << test.atoms >>
Node (Jest):
discover: npx jest --listTests
run: JEST_JUNIT_OUTPUT_FILE=<< outputs.junit >> npx jest --reporters=default --reporters=jest-junit << test.atoms >>
Validate after writing
chunk sidecar sync- Run doctor on the sidecar:
chunk validate --remote --cmd 'script -q /dev/null circleci run testsuite "<suite-name>" --doctor' - Fix reported issues locally, sync, re-run doctor. Repeat until all checks pass.
If circleci-testsuite is not installed, fall back to manual validation (see v1 skill for manual steps).
Troubleshooting
Could not select an organization/no interactive terminal— orgID missing. Runchunk org list --json, auto-select if there is one org, otherwise ask once, thenchunk config set orgID <id>.- Auth errors (401/403, "token invalid") — run
chunk auth status. If the CircleCI token is stale or missing, re-runchunk auth login(Logging in); otherwise follow the printed remediation. - Sidecar 404 on
current/sync/validate— sidecar was deleted externally. Runchunk sidecar forget, return to Step 0. permission denied (publickey)— runchunk sidecar add-ssh-key --public-key-file ~/.ssh/chunk_ai.pub. If it persists, tell user to remove~/.ssh/chunk_ai*to regenerate the keypair.context deadline exceededon SSH or API calls — sidecar is unhealthy. IfsidecarImageis set, create a fresh one from snapshot. Otherwisechunk sidecar forgetand redo setup viachunk-sidecar-setup.- Missing binary on sidecar —
chunk validate --remote --cmd "<install-command>". Re-snapshot afterchunk validatepasses. chunk validateran everything locally — no command is markedremote: true. Runchunk validate --mark-remote(see Dev Loop). Do not paper over it with--remoteon every call.syncerrors about merge base — ask user to push the branch (git push -u origin <branch>).- Snapshot
--imagewon't boot — snapshot IDs are org-scoped. Confirm both the snapshot and new sidecar are in the same org.
Parallel Sessions
chunk scopes the active-sidecar file to your session and branch (under XDG_DATA_HOME, keyed on CLAUDE_CODE_SESSION_ID or the Stop hook payload), so two sessions in the same repo target different sidecars and never sync into the same remote workspace. A session with no sidecar yet takes over one the project already has, unless another session owns it. Nothing to configure, and do not hand-edit those files.
Out of Scope
- Running
chunk initor bulk-editing.chunk/config.json. The skill may runchunk config setfororgIDandvalidation.sidecarImageonly. - Editing files on the sidecar over SSH — they will be overwritten on the next
sync.