digest

package
v0.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TagMilestone = "MILESTONE"
	TagFinding   = "FINDING"
	TagActivity  = "ACTIVITY"
)

Variables

This section is empty.

Functions

func Classify added in v0.6.0

func Classify(event map[string]any) string

Classify returns a tag (MILESTONE, FINDING, or ACTIVITY) for a parsed event. The event map is what DigestLine has already unmarshaled.

Rules (in priority order):

  1. MILESTONE: session.end, permission.request, and tool.call / tool.call_update where kind=="commit" or kind=="task" with status=="completed", or where the title/command contains "git commit".

  2. FINDING: agent.message_chunk, agent.thought_chunk, user.message_chunk where the content text contains a deliberate finding signal (confidence ≥60, explicit [finding] prefix, or multi-word phrase: "reviewer flagged", "correction needed", "failed test").

  3. ACTIVITY: everything else.

func DigestLine

func DigestLine(raw []byte) (line string, event map[string]any, err error)

DigestLine parses a single raw JSON line and returns the formatted plain-text line, the parsed event map, and any error.

When the JSON has no "event" field the line should be skipped: the returned string is empty and event is nil (no error). Callers that only need the string can ignore the map; callers that also need classification (e.g. streamLine) can pass the returned map directly to Classify without re-parsing the bytes.

func ExtractLoopMarker added in v0.9.0

func ExtractLoopMarker(text string) (directive, label string, ok bool)

func ExtractStatusMarker added in v0.7.2

func ExtractStatusMarker(text string) (phase, label string, ok bool)

ExtractStatusMarker scans text for the first [status: <phase>] or [status: <phase> | <label>] marker. Returns the normalised phase, trimmed label, and ok=true when a known phase is found. Unknown phase words are ignored (ok=false) to avoid spurious events from unrelated bracket text.

Known phases: thinking, working, waiting, done.

func Stream

func Stream(in io.Reader, out io.Writer, opts Options) error

Types

type Options

type Options struct {
	Follow       bool
	PollInterval time.Duration
	Format       string
	// Classify, when true, prefixes each plain-format line with a tag:
	// MILESTONE, FINDING, or ACTIVITY. For JSON format, a top-level
	// "classify" field is injected into each emitted object.
	Classify bool

	// CursorPath, when non-empty, causes Stream to atomically rewrite the
	// cursor file after processing. The caller is responsible for seeking the
	// underlying reader to the offset recorded in the cursor file before
	// calling Stream; CursorStartOffset must be set to that same offset so
	// Stream can compute the absolute file position when writing the cursor.
	//
	// Design note: we keep Stream's signature as io.Reader (rather than
	// *os.File) so tests can pass bytes.Buffer or strings.Reader without
	// touching the filesystem. The caller in watch.go handles the actual
	// os.File seek; we track bytes consumed here via a counting wrapper.
	CursorPath        string
	CursorStartOffset int64
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL