Record your work as a trajectory for future agents and humans to follow.
If trail is installed globally, run commands directly:
trail start "Task description"If not globally installed, use npx to run from local installation:
npx trail start "Task description"Start a trajectory when beginning a task:
trail start "Implement user authentication"With external task reference:
trail start "Fix login bug" --task "ENG-123"Record key decisions as you work:
trail decision "Chose JWT over sessions" \
--reasoning "Stateless scaling requirements"For minor decisions, reasoning is optional:
trail decision "Used existing auth middleware"Record decisions when you:
- Choose between alternatives
- Make architectural trade-offs
- Decide on an approach after investigation
Periodically step back and synthesize progress:
trail reflect "Workers aligned on auth approach, API layer progressing well" \
--confidence 0.8With focal points and adjustments:
trail reflect "Frontend and backend duplicating validation logic" \
--focal-points "duplication,ownership" \
--adjustments "Reassigning validation to backend team" \
--confidence 0.7Record reflections when you:
- Have received several updates and need to synthesize the big picture
- Notice workers or tasks diverging from the plan
- Want to course-correct before continuing
- Are coordinating multiple agents and need to assess overall progress
Reflections differ from decisions: decisions record a specific choice, reflections record a higher-level synthesis of what's happening and whether the current approach is working.
When done, complete with a retrospective:
trail complete --summary "Added JWT auth with refresh tokens" --confidence 0.85After completing work, compact the finished trajectory or merged PR into a
durable summary. When the compacted summary is sufficient, discard the raw
source trajectories so .trajectories/index.json and list output stay focused:
trail compact --discard-sources
# or after a PR merge:
trail compact --pr 42 --discard-sources--discard-sources removes the source trajectory JSON/Markdown/trace files and
updates the index. Use it after confirming the compacted artifact is the record
you want to keep.
Confidence levels:
- 0.9+ : High confidence, well-tested
- 0.7-0.9 : Good confidence, standard implementation
- 0.5-0.7 : Some uncertainty, edge cases possible
- <0.5 : Significant uncertainty, needs review
If you need to stop without completing:
trail abandon --reason "Blocked by missing API credentials"View current trajectory:
trail statusList all trajectories:
trail listView a specific trajectory:
trail show <trajectory-id>Export a trajectory (markdown, json, timeline, html):
trail export <trajectory-id> --format markdownAfter a PR merge, compact related trajectories into a single summary and prune raw source trajectories when the summary should replace them:
trail compact --pr 42 --discard-sourcesCompact by branch (finds trajectories with commits not in the specified base branch):
trail compact --branch main --discard-sourcesCompact by specific commits:
trail compact --commits abc123,def456 --discard-sourcesCompaction consolidates decisions and creates a grouped summary. Adding
--discard-sources makes the compacted artifact the durable record by removing
the raw trajectories and their index entries.
Your trajectory helps others understand:
- What you built (commits show this)
- Why you built it this way (trajectory shows this)
- What alternatives you considered
- What challenges you faced
Future agents can query past trajectories to learn from your decisions.
Several downstream consumers of @agent-assistant/* deploy to Cloudflare Workers (cloud/specialist-worker, sage, relayfile, cataloging-agent, web). When adding or modifying any fetch() call site in this repo, follow .claude/rules/workers-fetch.md. The short version:
- Never store a bare
fetchreference at module load or in a constructor:this.fetchImpl = config.fetchImpl ?? fetch;is wrong. - Always fall back to a lambda that reads
globalThis.fetchat call time:this.fetchImpl = config.fetchImpl ?? ((input, init) => globalThis.fetch(input, init));
The bare-fetch pattern has caused Illegal invocation runtime failures in Worker consumers downstream (cloud#328, sage#110, and most recently an entire specialist incident on 2026-04-24 where every OpenRouter call through createOpenRouterModelAdapter threw on first invocation). Tests use vi.stubGlobal("fetch", fetchMock) — the lambda variant stays stubbable while the bare fetch variant does not.