Providers
trkr never couples to a vendor API. A provider is just a shell command template that runs an agent CLI against a prompt file.
Built-ins
| Name | Command | Co-author trailer | Streams |
|---|---|---|---|
claude (default) | claude -p {promptFile} --permission-mode bypassPermissions | Co-Authored-By: Claude <noreply@anthropic.com> | yes |
copilot | copilot -p {promptFile} | GitHub Copilot | no |
kiro | kiro chat --no-interactive {promptFile} | Kiro | no |
Custom providers
Add or override providers in .trkr.json; entries merge over the built-ins by name:
{
"providers": {
"claude-opus": {
"run": "claude -p {promptFile} --model {model} --permission-mode bypassPermissions",
"model": "claude-opus-5",
"trailer": "Co-Authored-By: Claude <noreply@anthropic.com>"
}
},
"provider": "claude-opus"
}run— command template;{promptFile}and{model}are substituted shell-quoted.{model}renders as''when unset.stream— set to"claude-json"for providers built on theclaudeCLI to get live session logs (see below). Omit for providers that only print at exit.- Resolution precedence: ticket's Agent field → stage's
provider→ repoprovider→"claude". - The command runs via
/bin/sh -cwith stdout/stderr appended to the session's log file under.trkr/.
Assigning an agent per ticket
trkr init creates a single-select Agent field on the board whose options are the provider names (built-ins plus your config's). trkr new asks who works the ticket during intake and stamps the field; the daemon then runs that provider for every stage of the ticket. You can also change the field on the board mid-flight — the stage runner reads it fresh at dispatch.
- An Agent value that matches no known provider is ignored (logged, falls back down the chain).
- The isolated
validatestage keepsvalidate.providerregardless of the ticket's agent, so the black-box check stays independent of the implementer. - Existing boards: rerun
trkr initto add the field.
Streaming session logs
claude -p buffers: without streaming, a session's log is empty until the stage exits. Providers with stream: "claude-json" (the built-in claude has it) get --output-format stream-json --verbose appended to daemon-run sessions, and the daemon renders each event into the log as it arrives:
∴ session started (claude-opus-5)
Reading the spec first.
▸ Read src/lib/store.ts
▸ Bash pnpm vitest run
✗ Command failed: 2 tests failing
— session success · 312s · $1.84Assistant text renders as prose, tool calls as ▸ Tool detail lines, tool errors as ✗ …, and the closing footer carries duration and cost. This is what trkr watch's Worker panel tails live. Interactive sessions (intake, grill) parse stdout directly and are unaffected by streaming.
Session environment
Stage sessions receive trace context in their environment so an agent's own telemetry can join trkr's trace:
TRKR_TRACEPARENT— W3C traceparent (00-<traceId>-<spanId>-01)TRKR_TICKET— issue numberTRKR_TURN— current turn number
Intake sessions (which predate any ticket) get no extra environment.