toolpath-copilot
Derive Toolpath provenance documents from
GitHub Copilot CLI session logs — the standalone agentic CLI distributed
as the npm package @github/copilot
(command copilot).
⚠️ Preview — schema partly verified. Copilot CLI's
events.jsonlformat is undocumented. This crate was first built from docs + community reverse-engineering, then verified against a first-hand session capture atcopilotVersion1.0.67: the line envelope,session.startcontext,tool.execution_*(incl.result.content),assistant.message(reasoningText/outputTokens), andsystem.messageare confirmed. Event types that didn't occur in that session (subagent.*,skill.invoked,hook.*,abort,session.shutdown, compaction) and thecheckpoints/format remain unverified — the parser stays deliberately tolerant (payload inline or nested, multiple key spellings, unknown events preserved). See the format reference + verification checklist atdocs/agents/formats/copilot-cli/.
What it reads
Sessions live under ~/.copilot/session-state/<session-id>/ (override the root
with COPILOT_HOME):
events.jsonl— the append-only event stream this crate parses into a conversation.workspace.yaml— git context (root / repository / branch / revision), read intoPath.base(tolerant key-scan parser; the schema is reverse-engineered).checkpoints/— file snapshots (not yet consumed; see file-fidelity.md).
It also tolerates the legacy history-session-state/ location.
Usage
use ;
let convo = new;
// List sessions (newest first).
for meta in convo.list_sessions?
// Read one and derive a Toolpath `Path`.
let session = convo.read_session?;
let path = derive_path;
# Ok::
The forward pipeline is EventReader::read_session_dir → provider::to_view
(producing a toolpath_convo::ConversationView) → the shared
toolpath_convo::derive_path. The derived Path carries the
agent-coding-session kind, per-turn tool invocations classified into
toolpath's ToolCategory ontology, and — for file writes whose args carry full
content — a raw unified-diff perspective.
Status & limitations
- Both directions. Forward (
path p import/list/show copilot,path share) and reverse viaCopilotProjector(path p export copilot,path resume). Resume writes~/.copilot/session-state/<id>/+ asession-store.dbsessionsrow (only ever a fresh id). ✅ Verified against copilotVersion 1.0.67: a projected session loads and resumes in the realcopilot --resume. The loader's writer requirements (UUID ids, offset ISO timestamps,turnId,messageId, …) are documented in writing-compatible.md. - File fidelity is best-effort. Copilot records file edits as tool-call args
plus separate
checkpoints//rewind-snapshots/rather than inline diffs (unlike Codex). This crate synthesizes arawdiff when the tool args contain full file content; edit-shaped calls without the full file yield a structural change only. Snapshot-based diff reconstruction is deferred. - Token accounting sums per-message
outputTokensfor the session output total (falling back tosession.shutdownwhen present); no per-turn attribution, and no input-token total observed in an open session.
See the known-gaps doc for the full list and the checklist to run once a real session is captured.
License
MIT