Documentation
¶
Overview ¶
Package capture is the episodic tier: sampling, coalescing, storage and retention.
The event record itself lives in internal/event so that this package and the sources it drives can share it without an import cycle. These aliases keep capture.Event working as the natural spelling at call sites.
Index ¶
- Constants
- Variables
- func Count(db *sql.DB) (int, error)
- func Cursor(db *sql.DB, source string) int64
- func Dur(secs int64) string
- func Footprint(db *sql.DB) (events int, bytes int64, days float64, err error)
- func HHMM(ts int64) string
- func InitStore(db *sql.DB) error
- func Insert(db *sql.DB, e Event) error
- func InsertMany(db *sql.DB, events []Event) (int, error)
- func PollOnce(db *sql.DB, scratch string, repos []string, policy *Policy, backfill int64) (int, error)
- func Prune(db *sql.DB, olderThanTS int64) (int, error)
- func Render(events []Event, verbose bool) string
- func ReplaceCalendarWindow(db *sql.DB, from int64, events []Event) (int, error)
- func SetCursor(db *sql.DB, source string, cursor int64) error
- func TodayBounds() (int64, int64)
- type AppTotal
- type Coalescer
- type Event
- type Kind
- type Policy
Constants ¶
const ( Focus = event.Focus URL = event.URL File = event.File Commit = event.Commit Calendar = event.Calendar Clipboard = event.Clipboard Screen = event.Screen )
const IncidentalSecs = event.IncidentalSecs
const Schema = `` /* 570-byte string literal not displayed */
Schema lives in the same SQLite file as the vault index but is conceptually separate: the index is a cache derived from markdown, this is primary data that exists nowhere else. That is why retention is a deliberate setting rather than a cleanup detail.
Variables ¶
var DefaultBlocklist = []string{
"1Password", "Bitwarden", "KeePassXC", "Keychain Access",
"Messages", "Signal", "WhatsApp", "Telegram",
"Mail", "FaceTime", "System Settings",
}
DefaultBlocklist is seeded with the categories never worth recording. The user's own additions are appended from config.
var Now = event.Now
Functions ¶
func Footprint ¶
Footprint is what raw capture currently costs, measured rather than guessed.
A user deciding whether to leave the daemon running deserves a number, and the only honest number is one taken from their own data: how much text their own apps and URLs actually produce. Bytes is the stored text plus a fixed allowance for the integer columns and row overhead — close enough to size a disk budget, and never presented as exact.
Days is how long the existing events span. It is the reason this returns a span at all: with less than a day of data there is nothing to extrapolate from, and saying so is better than projecting a week from ten minutes.
func PollOnce ¶
func PollOnce(db *sql.DB, scratch string, repos []string, policy *Policy, backfill int64) (int, error)
PollOnce runs one pass over the pull-based sources. The frontmost sampler is push-based and lives in the daemon loop instead.
backfill caps how far back a first run reaches. A second brain with no history is amnesiac on day one, but silently ingesting a year of browsing should be a choice rather than a default.
func Prune ¶
Prune drops raw events past the retention window. Rollups must already have extracted anything worth keeping — that is the whole contract of the two-tier design.
func Render ¶
Render produces a human-readable day. verbose keeps the incidental sub-8s focus flickers that are otherwise noise.
func ReplaceCalendarWindow ¶
ReplaceCalendarWindow swaps out the captured calendar window wholesale.
Calendar is the one source that captures the future, and the future changes: meetings move, get cancelled, get added. Cursoring an append-only table would accumulate stale ghosts of rescheduled meetings. Deleting everything from `from` onward and re-inserting the fresh window keeps the stored view honest and idempotent — re-polling never duplicates a meeting.
func TodayBounds ¶
TodayBounds returns [start, end) of the current local day.
Types ¶
type Coalescer ¶
type Coalescer struct {
// contains filtered or unexported fields
}
Coalescer collapses a stream of identical samples into durable sessions.
Polling frontmost-app every 5s produces ~17k rows per day per source, almost all repeats. Coalescing happens on write, not on read: storing the raw stream and aggregating at query time costs disk and query latency forever in exchange for nothing.
func NewCoalescer ¶
type Event ¶
type Policy ¶
Policy fails closed everywhere: an app we cannot identify is treated as blocked, because wrongly recording a password manager costs far more than a gap in the timeline.
func DefaultPolicy ¶
func DefaultPolicy() *Policy
func (*Policy) ShouldDrop ¶
ShouldDrop reports whether a sample must never be written. Dropped means never persisted — not written-then-filtered, which would leave the content on disk.