The connector hooks into GitHub Copilot CLI’s event system and captures structured data from each session. This page documents what events are captured and how they map to Infinium traces.

Hook Events

The connector listens for these Copilot CLI hook events (camelCase naming, following Copilot’s convention):

EventWhen It FiresWhat’s Captured
sessionStartA Copilot session beginsSource (new / resume / startup), optional initialPrompt
userPromptSubmittedUser sends a promptPrompt text
preToolUseBefore a tool executestoolName, toolArgs (parsed from JSON string)
postToolUseAfter a tool completestoolName, toolArgs, toolResult.resultType, toolResult.textResultForLlm
errorOccurredAn error occurs in CopilotError message, name, stack
sessionEndSession endsreason (complete / error / abort / timeout / user_exit) — triggers trace send

Timestamp Conversion

Copilot CLI sends timestamps as Unix milliseconds. The connector converts them to ISO 8601 (2026-04-18T10:00:00Z) on ingest so everything downstream speaks one format.

Session ID Synthesis

If Copilot CLI doesn’t include a sessionId on an event, the connector synthesizes one from the parent process’s PID (copilot-{ppid}). This keeps all hooks from one Copilot session grouped under a single ID, even when Copilot’s event payload doesn’t carry the field.

Event Name Normalization

Both camelCase (sessionStart) and PascalCase (SessionStart) forms are accepted. The connector canonicalizes to camelCase internally. Codex-style aliases (StopsessionEnd) are also mapped so shared tooling can target both connectors.

How Events Become Traces

A typical session lifecycle looks like this:

Session:
  sessionStart         → source="new"
  userPromptSubmitted  → "Fix the failing npm test"
  preToolUse           → bash, toolArgs='{"command":"npm test"}'
  postToolUse          → resultType="success", textResultForLlm="All 42 tests passed"
  sessionEnd           → reason="complete"

                        Trace sent to Infinium

The trace is sent on sessionEnd. One trace per session (per-turn flushing is available as an opt-in).

Synthesized Assistant Response

Copilot CLI has no “final assistant message” event (unlike Codex’s Stop.last_assistant_message or Claude Code’s Stop). To give Maestro a recognizable outcome, the connector synthesizes a response summary on sessionEnd:

{tool_name} -> {textResultForLlm or resultType} (session ended: {reason})

Example: bash -> All 42 tests passed (session ended: complete)

This appears as both output_summary at the top of the trace and output_preview on the user prompt step.

Trace Structure

Each trace sent to Infinium contains:

Top-Level Fields

FieldSourceExample
nameFirst user prompt (truncated to 30 chars)"Fix the failing npm test"
descriptionFirst user prompt (full)"Fix the failing npm test"
durationSession timing (sessionStart → sessionEnd)6.0 (seconds)
input_summaryFirst prompt"Fix the failing npm test"
output_summarySynthesized from last tool result + session end reason"bash -> All 42 tests passed (session ended: complete)"

Execution Steps

Each trace includes an ordered list of steps:

Step TypeActionFields
User promptuser_promptdescription, input_preview, output_preview (synthesized)
Tool calltool_usedescription (e.g. "Tool: bash"), input_preview (command from parsed toolArgs), output_preview (textResultForLlm), duration_ms
Tool errortool_use with errorerror.error_type = "ToolError", error.message, error.recoverable = true

Environment Context

Every trace includes environment metadata:

TagValue
session_idCopilot-provided or synthesized (copilot-{ppid})
session_sourcenew / resume / startup
session_end_reasoncomplete / error / abort / timeout / user_exit
working_directorySession cwd
framework"copilot-cli"

Tool Input Summarization

For preToolUse, the connector parses the toolArgs JSON string and extracts a human-readable summary:

  • bash → the command field
  • view / edit → the path or filePath field
  • Other tools → compact JSON of the full args

Error Tracking

errorOccurred events are surfaced as structured errors:

FieldDescription
error_typeFrom Copilot’s error.name (or "Error")
messageFrom Copilot’s error.message (truncated)
recoverabletrue

Tool calls whose toolResult.resultType is "error" / "failure" / "failed" are also captured as tool errors.

Data Truncation

To keep payloads manageable, the connector truncates:

  • Prompt text: First 200 characters (configurable via CONNECTOR_MAX_INPUT_PREVIEW)
  • Tool output preview: First 300 characters (configurable via CONNECTOR_MAX_OUTPUT_PREVIEW)
  • Payload size: Progressive truncation if the total payload exceeds ~950KB

Full data is never sent — only summaries that give Maestro enough context to evaluate quality.

Transcripts

At the time of writing, Copilot CLI does not expose a session transcript file for token usage extraction. LLM usage (llm_usage) is therefore not populated in the trace. When / if GitHub ships a transcript format, the connector will be updated to attach token counts just like the Codex and Cline connectors do.