github getagentseal/codeburn v0.9.23

4 hours ago

Added

  • codeburn sync push sends additive CB-3 usage-span fields from the Teams boundary spec section 7. Every new attribute is optional and emitted only when its value is proven, so a receiver ignoring unknown attributes loses nothing. Sessions with provider-recorded lineage (the #1140 field) now carry ai.work_unit_id (deriveTraceId of the root session, the same derivation trace ids already use, resolved by the #1145 work-unit resolver), ai.session_role (root|child), and ai.lineage_evidence (provider-recorded) - all three or none, never inferred, and a child whose parent is out of range, ambiguous, or cyclic fails closed with none of the three. Cache tokens ride as ai.cache_read_tokens / ai.cache_write_tokens, billable-consistent with ai.input_tokens via the display layer's max-of-both-vocabularies convention, each sent only when non-zero. ai.call_count and ai.session_duration_ms describe the span's session (span count, and last-minus-first provider-recorded event time, omitted when either timestamp is missing or unordered). ai.subscription_covered reports the plan/proxy-path machinery's decision and is omitted when it cannot decide (no plan match and no cwd to proxy-check). Each export batch also carries a codeburn.coverage_through resource attribute with the ISO date the local corpus is complete through, stamped only when a complete parse finalized the daily-cache watermark. Span ids, trace ids, and ledger keys are unchanged, so nothing re-sends; new string values pass the same #1128 serialization sanitizers, with the lineage trio falling together if any value fails. sync push --dry-run stays zero-push and now reports how many spans carry lineage, cache tokens, and each subscription_covered verdict plus the coverage watermark, and the field disclosure in docs/sync/README.md (which also back-fills the previously undocumented ai.speed and ai.cost_estimated) and docs/sync/DEVELOPER.md lists every new attribute. Implements slice CB-3 of the CodeBurn main/Teams boundary spec (CODEBURN-MAIN-TEAMS-BOUNDARY-v0.1). (#1135, #1140)
  • codeburn sync auto adds opt-in, consent-once automatic sync that never sends until you accept. sync auto enable --cadence daily|hourly [--attribution] [--accept] first prints the full plain-language disclosure - every outbound field carries a written meaning, pinned by a test asserting the meanings map covers CORE_SYNC_ATTRIBUTE_KEYS exactly - and without --accept stores nothing at all. Acceptance is recorded as a sha256 fingerprint over the org, destination, wire contract version, the sorted outbound field set, your work-matching choice, a 7-day scan scope, and the cadence; enable, run, and status build that input through one shared function so they can never disagree. The scheduler-invoked sync auto run sends only on an exact fingerprint match through the same push path as manual sync push (attribution included when and only when it was accepted); if the config is killed or was never accepted it writes a receipt and makes zero network calls, and if the accepted terms have since drifted it writes an acceptance-required receipt and again sends nothing until you re-accept. sync auto disable is a hard kill switch: it removes the scheduled job and stops all automatic outbound immediately, leaving manual sync push untouched. Every automatic attempt - sent, skipped, killed, or drift-blocked - is recorded as an append-only JSONL receipt beside the sync config. macOS installs a LaunchAgent; other platforms print a crontab line to add. Implements slice CB-4 of the CodeBurn main/Teams boundary spec (CODEBURN-MAIN-TEAMS-BOUNDARY-v0.1). (#1153)

Added (macOS)

  • The macOS menubar gains a native Capacity Dock - an optional floating usage widget that rests against any screen edge. It sits collapsed on a single provider and expands on hover or click into per-provider quota rings, opening its usage details inward from whichever screen edge it is docked to, and drags across edges with surface-tension shoulders, usable-screen recovery, and shape-aware click-through. Each ring reads a provider's quota - the weekly window when there is one, otherwise the monthly - as a headline gauge whose colour shifts by severity as it fills (green below 50%, then yellow, orange, and red), with plan labels and inline hide/connect actions. Connected subscriptions surface themselves automatically, up to five, until you curate the set yourself, after which your choice is kept. It ships Graphite and Liquid Glass appearances and circle or squircle gauges, with Apple-system typography, warm off-white text, reduced-motion behaviour, and VoiceOver labels. Provider credentials stay provider-scoped in CodeBurn-owned Keychain accounts, and catalog entries without a live quota adapter stay informational and can never claim a connection. (#1167)

Fixed

  • OMP-provider rows now respect the period filter, attribute cost correctly, and price Grok 4.6 at its high tier. codeburn models -p <period> had returned an identical OMP aggregate at every scope because the session-header branch dropped its timestamp, so an absent entry.timestamp handed the range filter an invalid date and the today row reflected a cumulative rather than a daily total; timestamps are now retained for date slicing. A valid alias plus price override had still produced a zero-cost OMP row because any finite msg.usage.cost.total was treated as authoritative and OMP writes cost.total = 0 for xai-oauth ids; a zero reported cost is now treated as absent and repriced through the alias table and overrides, while a nonzero reported cost keeps its existing behaviour. And Grok 4.6, which xAI prices in two tiers, gains its 200k prompt-token tier ($4.00 / $1.00 cached / $12.00 output, applied to every token in a request once prompt tokens - input plus cached input - reach 200,000 inclusively), where the bundled card had carried only the low tier and under-reported large-context traffic; an exact configured priceOverrides entry still wins over the built-in tier. CACHE_SCHEMA_VERSION moves to 3 so cached rendered costs recompute. (#1150)

Fixed (desktop)

  • The desktop app paints the last exact totals immediately while the selected period refreshes. On a large corpus, switching Today / 7D / 30D / Month / 6M / Life could make the app feel frozen while it rehydrated every detailed panel, and it could briefly show the previous period's total. It now paints the last exact cached headline at once with honest progress copy and drill-down skeletons behind it, pre-warms the standard horizons without a provider-by-period parse storm, and keys data, errors, and late responses to the selected period/provider so a total can never leak across filters. Partial resident hydration is rejected as an exact snapshot, boundary-sensitive Today/Month keys stay current, the session memo is capped at 96 LRU entries so date-boundary keys cannot grow forever, and progressive data is invalidated safely after configuration changes. Long activity timelines read better too: fixed weekday labels, month labels aligned to the scrolling heatmap, newest dates first, and readable long daily-spend labels. (#1157)
  • Every desktop destination stays useful across restarts instead of greeting you with a blank skeleton. Sessions, Spend, Optimize, Models, Compare, and Plans now persist versioned, compressed report snapshots per destination and paint the last exact same-key (period/provider/range) result immediately on a renderer restart, labelled as cached, then revalidate once. The in-memory LRU is bounded by both count (96) and serialized weight (12M characters) and durable storage to 72 snapshots, restart persistence is pre-capped at 300k raw JSON characters so multi-megabyte reports are never synchronously compressed on the renderer thread, and recompression and writes are skipped when a poll returns an unchanged report. Stale and partially hydrated results are rejected from restart persistence while still retained as last-good data in the live renderer, Today and Month snapshots are keyed to local calendar boundaries so yesterday's answer cannot appear under today's label, and horizons warm serially at background priority (Today to 7D to 30D to Month to 6M to Life) while normal Chromium background throttling is preserved. Quota endpoint discovery stays user-driven (opening Plans), report generations are invalidated after settings changes, and the footer now describes the selected destination and ages old snapshots in hours/days. Renderer storage contains report output only. (#1163)
  • The packaged desktop CLI recovers safely when its resident stdio child dies and no longer misroutes ordinary commands. When resident stdin closes the app now detaches the dead child and falls back to one-shot execution rather than turning a closed pipe into an EPIPE failure, and the generated Electron-as-Node launcher preserves serve --stdio dispatch without swallowing ordinary CLI arguments. The packaging gate now proves both an ordinary CLI command and a held-open resident ready handshake, running the packaged resident smoke under a disposable HOME/data/cache tree so packaging can never arm watchers against a developer's real corpus. (#1155)
  • Quitting CodeBurn reaps the resident CLI's whole process tree instead of leaking it. Release testing found live codeburn serve --stdio processes reparented to PID 1 after earlier runs, because a direct child-only signal cannot reach a provider parser or other grandchild - which could also strand owned cache locks. The resident CLI is now launched in its own POSIX process group and the complete owned group is terminated on normal quit (SIGTERM, then a bounded SIGKILL fallback) within Electron's existing before-quit window, with process-group ownership recorded in the serve PID file so a stale owned resident can be reaped safely. The grace period is short and bounded (750 ms cooperative plus 250 ms post-kill, inside the existing 1.5 s quit deadline); Windows retains direct-child termination since POSIX process groups are unavailable there. (#1166)

Fixed (TUI)

  • The interactive TUI is useful before a large corpus has finished re-indexing. It now paints an exact cached period first, clearly labelled as cached while source refresh continues, making Today, 7D, 30D, Month, 6M, and Lifetime immediately selectable from one normalized cached index, then stages cold-cache readiness in that order while parsing source contents once. Today falls back to 7D only when Today is exactly empty across calls, cost, savings, and tokens - unpriced or token-only activity keeps Today - and provider and period truth are preserved across rapid navigation, custom ranges, day mode, and in-flight reloads. Cached snapshots are kept out of the parse memo and the index is replaced atomically after reconciliation, and real q and Ctrl-C termination are preserved. On one heavy corpus first-visible dropped from a median of about 26s to about 3s. (#1159)
  • Rapidly resizing the terminal no longer leaves ghost panels below the frame. Resizing between wide and narrow layouts could leave pixels from the old dashboard under the newly rendered one, looking like duplicated panels even though the live layout was correct. Resize bursts are now coalesced and the stale viewport is cleared before the settled redraw, with one redraw forced even when Ink considers the next frame textually unchanged. The clear/redraw path stays disabled in screen-reader mode so accessible text is never erased. (#1156)
  • The TUI releases its cache locks on a confirmed exit. Both cache-lock families are now released before the TUI's direct process exit, so a hydrating.lock (and its sibling) can no longer be left behind after quit, while the existing first-q confirmation and second-q fast exit during indexing are preserved and the terminal is fully restored (raw mode, mouse tracking, and the alternate screen all off). Exit status is conventional: 130 for Ctrl-C, 0 for q. (#1165)

Fixed (menubar)

  • The macOS menubar recovers its status item when Tahoe parks it. The existing status item is given a stable AppKit autosave identity, and only the confirmed Tahoe parked geometry is detected; when the menu bar is revealed the app recovers with at most three supported visibility pulses and never removes or recreates the status item. (#1161)

Don't miss a new codeburn release

NewReleases is sending notifications on new releases.