diff --git a/internal/agent/claude/parse_jsonl.go b/internal/agent/claude/parse_jsonl.go index 1901ecb..d1d911d 100644 --- a/internal/agent/claude/parse_jsonl.go +++ b/internal/agent/claude/parse_jsonl.go @@ -5,11 +5,23 @@ import ( "encoding/json" "fmt" "os" + "regexp" + "strings" "time" "github.com/partio-io/cli/internal/agent" ) +var systemReminderRe = regexp.MustCompile(`(?s).*?`) + +// stripSystemReminders removes all ... blocks from text. +// Returns the stripped text and whether any reminders were found. +func stripSystemReminders(text string) (string, bool) { + stripped := systemReminderRe.ReplaceAllString(text, "") + had := stripped != text + return strings.TrimSpace(stripped), had +} + // ParseJSONL reads a Claude Code JSONL transcript and extracts session data. func ParseJSONL(path string) (*agent.SessionData, error) { f, err := os.Open(path) @@ -24,6 +36,7 @@ func ParseJSONL(path string) (*agent.SessionData, error) { sessionID string slug string totalTokens int + promptCount int firstTS time.Time lastTS time.Time ) @@ -71,6 +84,17 @@ func ParseJSONL(path string) (*agent.SessionData, error) { role = entry.Type } + // Filter system-reminder injections from user/human messages + if role == "human" || role == "user" { + filtered, _ := stripSystemReminders(text) + if filtered == "" { + // Message was entirely system-reminder content; skip it + continue + } + text = filtered + promptCount++ + } + msg := agent.Message{ Role: role, Content: text, @@ -99,6 +123,7 @@ func ParseJSONL(path string) (*agent.SessionData, error) { TotalTokens: totalTokens, Duration: duration, PlanSlug: slug, + PromptCount: promptCount, }, nil } diff --git a/internal/agent/types.go b/internal/agent/types.go index 5695d75..b7c577b 100644 --- a/internal/agent/types.go +++ b/internal/agent/types.go @@ -12,6 +12,7 @@ type SessionData struct { TotalTokens int `json:"total_tokens"` Duration time.Duration `json:"duration"` PlanSlug string `json:"plan_slug,omitempty"` + PromptCount int `json:"prompt_count,omitempty"` } // Message represents a single message in an agent transcript. diff --git a/internal/checkpoint/metadata.go b/internal/checkpoint/metadata.go index 344d30e..6b441ee 100644 --- a/internal/checkpoint/metadata.go +++ b/internal/checkpoint/metadata.go @@ -5,4 +5,5 @@ type SessionMetadata struct { Agent string `json:"agent"` TotalTokens int `json:"total_tokens"` Duration string `json:"duration"` + PromptCount int `json:"prompt_count,omitempty"` }