Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions internal/agent/claude/parse_jsonl.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,23 @@ import (
"encoding/json"
"fmt"
"os"
"regexp"
"strings"
"time"

"github.com/partio-io/cli/internal/agent"
)

var systemReminderRe = regexp.MustCompile(`(?s)<system-reminder>.*?</system-reminder>`)

// stripSystemReminders removes all <system-reminder>...</system-reminder> 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)
Expand All @@ -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
)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -99,6 +123,7 @@ func ParseJSONL(path string) (*agent.SessionData, error) {
TotalTokens: totalTokens,
Duration: duration,
PlanSlug: slug,
PromptCount: promptCount,
}, nil
}

Expand Down
1 change: 1 addition & 0 deletions internal/agent/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions internal/checkpoint/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}