Feature request for product/service
Cursor CLI
Describe the request
Feature request: richer agent transcripts + lifecycle data for observability
Context. We’re replaying Cursor agent sessions into Langfuse via the stop hook + on-disk
transcript (~/.cursor/projects/.../agent-transcripts/). That pattern works (zero SDK in the
request path), but Cursor’s transcript is much thinner than Claude Code’s JSONL, so traces are
incomplete.
What already works well
stopfires in local CLI + IDE and includesconversation_id,transcript_path,model/
model_id/model_params- Transcript has user/assistant text and
tool_use(name + input) - Nested layouts for transcripts are discoverable
What we can’t get today (and why it matters)
| Gap | Impact on Langfuse / evals |
|—|—|
| No per-row timestamps | Waterfall timings are synthetic; can’t measure real tool latency or turn
duration |
| No token / cache usage | No cost dashboards, no model cost comparison |
| Notool_result/ tool outputs | Tool spans are input-only; can’t debug failures or build eval
datasets from real tool I/O |
| No message / tool-call IDs | Hard to join tool_use ↔ tool_result, hard to dedupe |
| Model only onstop, not on transcript rows | If several turns flush in onestop, older turns
get the current model |
|afterAgentResponse/afterAgentThoughtnot in CLI | Can’t stream mid-turn text/thinking into
observability without stdout hacks |
| Cloud agents: lifecycle hooks historically incomplete | Same setup doesn’t cover Cloud the same
way as local |
| No project env injection into hooks | Secrets/config need sidecar files; Claude Code’s
settings.local.jsonenv is cleaner |
Ask 1 — Enrich the conversation transcript (highest value)
Emit one JSONL object per event with a stable schema, e.g.:
{
"type": "user" | "assistant" | "tool_result" | "turn_ended",
"id": "msg_…",
"timestamp": "2026-07-24T22:00:00.123Z",
"role": "user" | "assistant" | "tool",
"model": "claude-opus-4-8-thinking-high",
"model_id": "claude-opus-4-8",
"message": {
"id": "msg_…",
"content": [
{ "type": "text", "text": "…" },
{ "type": "tool_use", "id": "toolu_…", "name": "Shell", "input": { } },
{ "type": "tool_result", "tool_use_id": "toolu_…", "content": "…", "is_error": false }
],
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0
}
}
}
Minimum viable fields (in priority order):
- ISO timestamps on every row
usageon assistant rows (input/output + cache if available)tool_resultrows (or blocks) withtool_use_id+ truncated output + error flag- Stable
idon messages andtool_use model/model_idon each assistant row (not only onstop)
Optional but useful: thinking blocks (or a redacted length/hash), request/generation id matching
the hook payload’sgeneration_id.
Ask 2 — Flush transcript before stop (or document a ready signal)
Today stop can fire before the last turn’s lines are on disk, so hooks must poll. Prefer:
- Flush + fsync transcript before invoking
stop, or - Add
"transcript_ready": true/transcript_byte_sizeon thestoppayload so hooks don’t
guess
Ask 3 — CLI / Cloud hook parity
- Fire
afterAgentResponseandafterAgentThoughtin headless CLI (agent --print) the same as
IDE - Fire lifecycle hooks (
sessionStart,stop,afterAgentResponse) on Cloud agents with the
same payload shape as local - Keep
stopas the reliable “turn complete” signal; don’t make observability depend only on tool
hooks
Ask 4 — Hook config / secrets ergonomics
- Allow project-scoped env for hooks (similar to Claude Code
settings.local.json→env), or
document a supported secrets path - Keep
transcript_pathalways absolute and non-null when transcripts are enabled; document
nested vs flat transcript layouts as a stable contract
Ask 5 — Privacy controls (so richer data is shippable)
If richer transcripts raise privacy concerns, ship toggles rather than omitting fields entirely:
transcript.include_tool_results: off | truncated | fulltranscript.include_usage: on/offtranscript.max_tool_result_chars: N
Default can stay conservative; power users / teams can opt into observability fidelity.
Why this matters
With the fields above, third-party hooks can produce Langfuse-quality traces without
instrumenting the agent or proxying model calls: real waterfalls, real cost, joinable tool I/O,
and accurate per-turn model tags — the same bar Claude Code already enables via its Stop-hook +
JSONL transcript design.
Happy to share a sample of current vs desired JSONL from local agent-transcripts/ if useful.