Documentation
¶
Overview ¶
Package parse is the Go port of the embedded Python engine from the v1 bash script (legacy/agentdash.sh): it locates and folds agent session JSONL into per-session entries, incrementally by byte offset.
Parser contract (see CONTRIBUTING.md): an update function folds one parsed line into the entry; every field is optional; never fail on a weird line, just skip it.
Index ¶
- Constants
- Variables
- func Ago(sec int64) string
- func Apply(kind string, ent *Entry, line []byte)
- func Clean(s string, width int) string
- func FirstTS(path string) int64
- func Hum(n int64) string
- func Known(kind string) bool
- func LearnWindow(confPath, model string, win int64, overrides *[]Override)
- func ScanMany(jobs map[string]string, c *Cache, now float64)
- func ShortModel(m string) string
- func SparkOf(hist []int64) string
- func StatusOf(ent *Entry, respawnN int, now float64, th Thresholds) string
- func TaskOf(ent *Entry, path string, labels map[string]string) string
- func TitleOf(ent *Entry, path string, labels map[string]string) string
- func WindowFor(model string, overrides []Override) (int64, string)
- type Cache
- type Entry
- type Override
- type PidInfo
- type Thresholds
Constants ¶
const ParserV = 6
ParserV is bumped when parsers extract new fields: forces a one-time rescan. It tracks the v1 PARSER_V so a v1 cache survives the upgrade.
const TaskW = 60
Variables ¶
var DefaultThresholds = Thresholds{WorkingSecs: 60, StuckSecs: 90, IdleSecs: 600}
Functions ¶
func Apply ¶
Apply folds one raw JSONL line into ent, failing soft: malformed lines, surprising shapes and panics never propagate.
func Clean ¶
Clean collapses whitespace, strips slash-command style <tags>, and truncates to width with an ellipsis; "" means nothing usable.
func FirstTS ¶
FirstTS returns the epoch of the session's first timestamped entry (approximately the session start), looking at most 25 lines in; 0 when none is found. Callers should memoize per draw.
func LearnWindow ¶
LearnWindow persists a self-correction (observed context exceeded the assumed window) so CTX% is right from the first refresh next time. The appended override is also added to the in-memory list.
func ScanMany ¶
ScanMany scans several session files concurrently (a cold cache means parsing every paired session in full, and the wall time of a serial pass is the sum instead of the max). Entries are written back to the cache serially after the join.
func ShortModel ¶
ShortModel strips the vendor prefix, [1m] tag and date suffix.
func SparkOf ¶
SparkOf renders the 8-slot bytes-consumed history on a log-ish scale: ~256B lights the first level, ~1MB the last.
func StatusOf ¶
func StatusOf(ent *Entry, respawnN int, now float64, th Thresholds) string
StatusOf derives the row status from write age and the last entry type: fresh writes are working, long-quiet is idle, and in between the agent is waiting on you (last turn assistant) or possibly stuck (user/tool). Three or more fresh pids on one file within 10 minutes is a respawn loop.
func TaskOf ¶
TaskOf picks the board row text. A pinned label is still explicit user intent; otherwise prefer the stable work name over the newest tool call so the board says what the session is about.
Types ¶
type Cache ¶
type Cache struct {
Entries map[string]*Entry
Labels map[string]string
PidMap map[string]PidInfo
PidsByPath map[string]map[string]float64
RecapTS float64
// contains filtered or unexported fields
}
Cache mirrors ~/.cache/agentdash/usage.json: session entries keyed by path plus the v1 special keys (_labels, _pidmap, _recap_ts, _pids_by_path). Unknown underscore keys are preserved verbatim so a newer writer never destroys an older reader's state.
type Entry ¶
type Entry struct {
Kind string `json:"kind"`
Offset int64 `json:"offset"`
V int `json:"v"`
Hist []int64 `json:"hist,omitempty"`
Mtime float64 `json:"mtime,omitempty"`
Seen float64 `json:"seen,omitempty"`
Cwd string `json:"cwd,omitempty"`
Model string `json:"model,omitempty"`
In int64 `json:"in,omitempty"`
Out int64 `json:"out,omitempty"`
Ctx int64 `json:"ctx,omitempty"`
Win int64 `json:"win,omitempty"`
LastType string `json:"last_type,omitempty"`
LastUserTS int64 `json:"last_user_ts,omitempty"`
TitleUser string `json:"title_user,omitempty"`
Summary string `json:"summary,omitempty"`
LastText string `json:"last_text,omitempty"`
LastTool string `json:"last_tool,omitempty"`
Activity string `json:"activity,omitempty"`
LastMid string `json:"last_mid,omitempty"`
CompactionN int `json:"compaction_n,omitempty"` // number of context-compaction summary entries
}
Entry is one session file's accumulated state. The JSON tags match the v1 Python cache exactly so ~/.cache/agentdash/usage.json round-trips between versions without a rescan.
func ScanSession ¶
ScanSession folds the bytes appended to path since the last look into its cache entry and returns it; nil when the file is unreadable. Only complete lines are consumed (the agent may be mid-write); a partial tail waits for the next call. The entry resets when the kind changed, the file shrank, or the parser version was bumped.
type Override ¶
Override is one line of ~/.config/agentdash/context-windows.conf: "<model-id-substring> <window-tokens>", first match wins.
func LoadOverrides ¶
type PidInfo ¶
type PidInfo struct {
Path string `json:"path"`
Start float64 `json:"start"`
Sure bool `json:"sure"`
Cwd string `json:"cwd"`
How string `json:"how"`
Kind string `json:"kind,omitempty"`
Profile string `json:"profile,omitempty"`
}
PidInfo records a pid-to-session pairing and the evidence tier that made it ("how"), for the why/show/resume/label subcommands.
type Thresholds ¶
Thresholds carries the working/idle cutoffs (AGENTDASH_WORKING_SECS, AGENTDASH_IDLE_SECS).