Commit graph

347 commits

Author SHA1 Message Date
AgentSeal
e1609e495c Add GPT-5.2 Low model display name for Cursor 2026-04-24 19:23:54 +02:00
AgentSeal
681afdbece Fix Cursor provider for newer versions that store data in agentKv
Newer Cursor versions store conversation data in agentKv entries
instead of populating tokenCount in bubbleId entries. This adds
a fallback parser that reads agentKv blobs and estimates tokens
from content length.

Closes #114
Closes #102
2026-04-24 18:11:25 +02:00
AgentSeal
f893c964cc Add auto-start on login via osascript subprocess
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-24 13:50:32 +02:00
AgentSeal
b3b0dfbf60 Auto-register as login item on first launch 2026-04-24 13:27:39 +02:00
AgentSeal
d3c4de0375 Reduce CLI timeout from 60s to 20s for faster recovery
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-24 05:53:52 +02:00
AgentSeal
053ca25253 Show loading spinner on every refresh, not just first load 2026-04-24 02:59:38 +02:00
AgentSeal
2dcf6f37f6 Add Discord invite link to README
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-23 22:02:01 +02:00
Resham Joshi
ed3abce4f6
Merge pull request #140 from getagentseal/fix/menubar-stability
Fix menubar crashes and add reliable auto-refresh
2026-04-23 12:13:55 -07:00
AgentSeal
68daad5dfa Fix menubar crashes and add reliable auto-refresh
Fixes crash when switching timeframes or providers by handling
duplicate dates in history data gracefully.

Adds LaunchAgent that posts a distributed notification every 15
seconds to keep prices fresh even after long idle periods.
2026-04-23 21:09:46 +02:00
iamtoruk
17b7e6ae6c fix(menubar): Swift 6 strict concurrency for wake observers
Some checks are pending
CI / semgrep (push) Waiting to run
2026-04-23 05:39:03 -07:00
Resham Joshi
48d2373fcc
Merge pull request #137 from getagentseal/fix/menubar-auto-refresh
fix: menubar auto refresh stops working after idle
2026-04-23 03:36:06 -07:00
AgentSeal
e970f64cbb fix: menubar auto refresh stops working after app is idle
The menubar price would freeze after the app was idle for a while because macOS App Nap suspends Task.sleep even with beginActivity.

Replace Task.sleep with DispatchSourceTimer which is more robust for background execution. Also add observers for system wake and screen wake events to force a refresh when the Mac resumes from sleep.
2026-04-23 02:25:20 +02:00
iamtoruk
b4fad91512 chore: bump version to 0.8.9, add changelog
Some checks are pending
CI / semgrep (push) Waiting to run
Stale menubar price fix (#136), variable-width status item default.
2026-04-22 13:06:17 -07:00
Resham Joshi
bd83196f9d
Merge pull request #136 from Miles-dev-29/fix/menubar-stale-price
fix: use consistent date range for menubar status queries
2026-04-22 13:00:08 -07:00
AgentSeal
2e5e449ad1 fix: use consistent date range for menubar status queries
The menubar showed stale prices because provider all used end:now while provider specific queries used end:endOfDay. Sessions with timestamps after now was captured were excluded from all providers but included in specific provider queries.

Use periodInfo.range consistently across all parseAllSessions calls in menubar json status.
2026-04-22 21:28:12 +02:00
iamtoruk
3355e3699e fix(menubar): variable width for both compact and default mode 2026-04-22 05:45:51 -07:00
iamtoruk
46f945fd72 fix: restore package.json truncated by sed 2026-04-22 05:38:14 -07:00
Resham Joshi
daf711daeb
Merge pull request #135 from getagentseal/chore/bump-0.8.8
chore: bump version to 0.8.8
2026-04-22 05:35:22 -07:00
iamtoruk
f3687db447 chore: bump version to 0.8.8, add changelog
OOM streaming fix (#132), compact menubar mode (#133), keychain
credential fix + App Nap hardening (#134).
2026-04-22 05:35:06 -07:00
Resham Joshi
ab39fff98a
Merge pull request #134 from getagentseal/fix/menubar-keychain-appnap
fix(menubar): keychain credential lookup + App Nap hardening
2026-04-22 05:27:25 -07:00
iamtoruk
3d063c9100 fix(menubar): keychain account filter + App Nap hardening + single query
Remove hardcoded "default" account allowlist from keychain credential
lookup. Claude Code 2.1.x writes the macOS login username, not
"default", so the filter silently dropped valid credentials on every
install.

Collapse the two-phase keychain enumeration into a single
SecItemCopyMatching call (one keychain prompt instead of four on
debug builds).

Harden App Nap opt-out: disable automaticTerminationSupport and
suddenTermination at the process level so AppKit cannot override
the beginActivity token.

Closes #115
2026-04-22 05:27:07 -07:00
Resham Joshi
66606c81f8
Merge pull request #133 from getagentseal/feat/menubar-compact
Some checks are pending
CI / semgrep (push) Waiting to run
feat(menubar): opt-in compact mode
2026-04-22 04:33:56 -07:00
iamtoruk
e8f8ccc94a feat(menubar): opt-in compact mode with variable-width status item
UserDefaults key CodeBurnMenubarCompact toggles a tighter menubar
display: no decimals, no leading space, variable width that hugs
the rendered text instead of the fixed 130pt slot.

Closes #129
2026-04-22 04:33:35 -07:00
Resham Joshi
bc54f85e34
Merge pull request #132 from maucher/fix/streaming-oom-readSessionLines
fix: switch scanJsonlFile and parseSessionFile to readSessionLines to prevent OOM
2026-04-22 03:58:46 -07:00
Łukasz Majcher
5e49f17e64 fix: switch scanJsonlFile and parseSessionFile to readSessionLines to prevent OOM
readViaStream (used for files ≥8 MB) reconstructs the full file as a
single string via chunks.join('\n'), giving the same peak allocation as
readFile. Callers then call content.split('\n'), creating a second copy.
With FILE_READ_CONCURRENCY=16 and files up to 128 MB this can exhaust
the V8 heap (~6 GB theoretical peak).

readSessionLines already exists as a proper async generator that yields
one line at a time. Switch both hot-path callers to iterate it directly
so the full file string is never held in memory.

Adds two tests: a spy test confirming readSessionLines is called (not
readSessionFile), and a 500-entry correctness test.

Fixes #131
2026-04-22 10:11:13 +00:00
Resham Joshi
d4e07de18f
Merge pull request #128 from getagentseal/chore/changelog-omp-model-alias
Some checks are pending
CI / semgrep (push) Waiting to run
docs: backfill 0.8.7 changelog with OMP provider and model-alias
2026-04-21 14:00:48 -07:00
iamtoruk
104ad85df6 docs: backfill 0.8.7 changelog with OMP provider and model-alias
The PR #59 merge landed on main (ac31883) before the 0.8.7 bump
(cb44cc6), so the code shipped in 0.8.7 but the initial changelog entry
only credited MiniMax and the menubar fixes. Adds three entries under
Added for the OMP provider, the model-alias command, and the built-in
Anthropic proxy aliases. Adds one entry under Fixed (CLI) for the
prototype-pollution guard in resolveAlias. Updates the CLI parity note
so users on 0.8.5 know whether they can stay there.

Filed before 0.8.7 hits npm.
2026-04-21 13:59:59 -07:00
Resham Joshi
2323587ab6
Merge pull request #127 from getagentseal/chore/bump-0.8.7
chore: bump to 0.8.7, align CLI and menubar release
2026-04-21 13:45:53 -07:00
iamtoruk
cb44cc6deb chore: bump version to 0.8.7, add changelog entry
Skips 0.8.6 to match mac-v0.8.7 and keep CLI + menubar versions aligned.
CLI change: MiniMax-M2.7 and MiniMax-M2.7-highspeed pricing. macOS menubar
change: three stability fixes culminating in the App Nap opt-out that keeps
the refresh loop ticking while the icon is idle in the background.
2026-04-21 13:43:49 -07:00
iamtoruk
33c7bb4d7a Merge remote-tracking branch 'origin/main' 2026-04-21 13:38:50 -07:00
Resham Joshi
2ffd5b46c1
Merge pull request #126 from getagentseal/fix/menubar-disable-appnap
fix(menubar): opt out of App Nap so refresh loop keeps ticking
2026-04-21 13:38:26 -07:00
iamtoruk
6ed0799b36 fix(menubar): opt out of App Nap so the refresh loop keeps ticking
Confirmed in the system log: while the menubar icon sits idle in the
background, macOS flips _kLSApplicationWouldBeTerminatedByTALKey to 1,
which is the Automatic Termination and App Nap subsystem declaring the
app a suspend candidate. Once that happens the 15s refresh Task's sleep
stretches arbitrarily, so the status bar label freezes until the user
clicks the icon (which triggers NSApp.activate and wakes everything up).

Hold a ProcessInfo.beginActivity handle for the life of the app with
.userInitiated + .automaticTerminationDisabled + .suddenTerminationDisabled
so macOS leaves the app alone. Released implicitly when the app exits.
2026-04-21 13:05:56 -07:00
Resham Joshi
90aa342a34
Merge pull request #125 from getagentseal/fix/menubar-force-redraw
Some checks are pending
CI / semgrep (push) Waiting to run
fix(menubar): force status bar redraw and lift subprocess QoS
2026-04-21 12:47:58 -07:00
iamtoruk
ac31883edc Merge PR #59: OMP provider and model alias mapping
Adds Oh My Pi support by parameterizing the Pi JSONL reader to accept a
providerName, so sessions at ~/.omp/agent/sessions/ are discovered and
tracked alongside Pi. Ships a model-alias CLI command plus five
built-in aliases for the anthropic--claude-X.Y-tier double-dash format
that some Anthropic-compatible proxies emit, so cost rows no longer
read $0.00 for those names.

Contributed by @cgrossde.
2026-04-21 11:52:13 -07:00
iamtoruk
4f1138290e Merge main into feat/omp-support-model-aliases
Second merge of main since the PR was opened. Main moved 30+ commits
(0.8.5 bump, plan tracking feature, MiniMax pricing, menubar
prefetchAll walk-back, aicrowd cache rewrite revert) so the branch
needed another reconciliation before merging to main.

Two new conflicts resolved. Took main's text in both cases per the
policy of favoring main when the feature work is neutral:

  README.md             Kept main's Node 20+ / better-sqlite3
                        Requirements wording and main's shorter src/
                        tree listing. Added OMP to the Requirements
                        line.

  src/providers/pi.ts   Main dropped the discovery-cache snapshot and
                        the rich source-metadata fields as part of the
                        aicrowd revert. Took main's simpler structure
                        and only kept the providerName parameter so
                        OMP sources still report the correct provider
                        in the session source and dedup key.

Earlier fixups carried forward from the prior merge commit:
  - Object.hasOwn guards in resolveAlias against prototype-pollution
    via a model literally named '__proto__'.
  - source.provider in the dedup key prefix so OMP rows no longer
    stamp 'pi:'.
  - Combined pi.js imports in providers/index.ts.
  - Trailing newline on pi.ts.
  - Unknown-model fallback in cursor-agent.ts from yesterday's PR #117
    fixup (preserved via main).

353 tests pass (count dropped from 378 because main deleted the
parse-progress / parser-cache / provider-colors / source-cache test
files alongside the cache-rewrite revert).

Feature work by @cgrossde.
2026-04-21 11:51:20 -07:00
iamtoruk
556f2bf78c fix(menubar): force status bar redraw and lift subprocess QoS
Two independent causes for the stuck-label / only-refreshes-on-click
behaviour, both fixed here.

1. NSStatusItem button defers the status bar paint for accessory apps
   that are not foreground, so after refreshStatusButton sets the new
   attributed title the menu bar visually froze until the user opened
   the popover (which triggers NSApp.activate and a forced redraw
   cycle). Explicit needsDisplay + display() forces the paint every
   cycle.

2. The codeburn subprocess inherited the accessory app's default QoS,
   which macOS background-throttles. That could stretch a sub-1-second
   parse into tens of seconds on large corpora and overrun the 15s
   refresh cadence. Set .userInitiated so the CLI runs at the same
   priority it does from a user-interactive terminal.
2026-04-21 11:50:28 -07:00
Resham Joshi
d69aa344ab
Merge pull request #123 from getagentseal/fix/menubar-remove-prefetchall
fix(menubar): drop prefetchAll to keep Today label fresh
2026-04-21 07:39:54 -07:00
iamtoruk
eb0d096c62 fix(menubar): drop prefetchAll to keep Today label fresh
The detached prefetch spawned four codeburn subprocesses (week, 30days,
month, all) that competed with the main refresh loop's Today fetch for
disk and parser time. On large session corpora that starved the Today
refresh for minutes at a time, and the status label drifted stale until
the prefetch queue finally drained. Users perceived this as the menubar
"stopping" until they clicked a provider tab, which coincided with the
queue clearing.

Drop prefetchAll. Period tabs in the popover now fetch lazily on first
click (3-10 seconds once per app lifetime per period), same as they did
in 0.8.1. Today's label stays fresh because nothing else is hammering
the parser in the background.
2026-04-21 07:36:00 -07:00
Resham Joshi
cdfda9507c
Merge pull request #122 from getagentseal/chore/firstlook-workflow-dispatch
chore: enable firstlook workflow_dispatch for backlog scans
2026-04-21 06:33:50 -07:00
iamtoruk
b3bb5efc58 chore: enable firstlook workflow_dispatch for backlog scans
Adds pr-number input and workflow_dispatch trigger so existing open PRs
can be scanned without waiting for a new push. Leave pr-number empty to
loop all open PRs; supply a number to rescan one.
2026-04-21 06:33:09 -07:00
Resham Joshi
41cc525e06
Merge pull request #121 from getagentseal/chore/add-firstlook-workflow
chore: add firstlook PR-author reputation check
2026-04-21 06:18:45 -07:00
iamtoruk
2ed1d5275c chore: add firstlook workflow for PR author reputation check
Runs on every PR open/reopen/synchronize against getagentseal/firstlook
and fails the check when the author's score is 'unknown' (new or
untracked accounts). Skips bot accounts so dependabot and renovate pass
through.

This screens the same drive-by pattern that landed in PR #118 (octo-patch,
fresh automation account) without requiring a manual tier check on every
submission.
2026-04-21 06:17:56 -07:00
Resham Joshi
a13c193075
Merge pull request #120 from getagentseal/feat/add-minimax-pricing
feat: add MiniMax-M2.7 model pricing
2026-04-21 05:52:47 -07:00
iamtoruk
81b5cda173 feat: add MiniMax-M2.7 and MiniMax-M2.7-highspeed model pricing
Adds FALLBACK_PRICING entries plus display names so MiniMax sessions
show up with the right cost and readable labels when users route MiniMax
through providers like OpenCode. Pricing verified against the live
MiniMax paygo page:

  MiniMax-M2.7           input $0.3/M  output $1.2/M  cache-read $0.06/M  cache-write $0.375/M
  MiniMax-M2.7-highspeed input $0.6/M  output $2.4/M  cache-read $0.06/M  cache-write $0.375/M
2026-04-21 05:50:52 -07:00
Resham Joshi
8ee84b0041
Merge pull request #119 from getagentseal/fix/revert-aicrowd-cache-rewrite
Revert source cache, fix stale Today totals
2026-04-21 05:24:06 -07:00
iamtoruk
2467578a52 fix(menubar): run prefetchAll in a detached task so the refresh loop starts immediately
prefetchAll was awaited inside the refresh loop after the first cycle.
On large corpora the All Time parse takes 60+ seconds and kept the Today
refresh blocked for that whole window, so the status label got stuck for
minutes at a time while the CLI was returning fresh numbers.

Detach prefetchAll into its own @MainActor task. The popover still gets
the benefit of pre-warmed period caches, the refresh loop ticks every 15
seconds regardless.
2026-04-21 05:22:34 -07:00
iamtoruk
f2a2b53ae7 Merge remote-tracking branch 'origin/main' into fix/revert-aicrowd-cache-rewrite 2026-04-21 05:08:31 -07:00
iamtoruk
5a4e14f0f6 docs: remove stray Unreleased heading, note removed --no-cache flag
Also adds a regression test for the midnight-straddle bucketing invariant
that was flagged by the pre-push review: if someone reverts the assistant-
timestamp bucketing back to user-timestamp, this test will catch it.
2026-04-21 04:54:50 -07:00
iamtoruk
07d2fb07aa chore: bump version to 0.8.5, add changelog entry explaining revert
Reverts the persistent source cache added in 0.8.2 back to v0.8.1's
full-reparse path for Claude sessions; keeps the plan pill, pricing fix,
cursor-agent provider, and the Mac menubar prefetch+timezone work added
between 0.8.2 and 0.8.4.
2026-04-21 04:44:23 -07:00
iamtoruk
b491a1f590 fix: bucket turns by assistant timestamp, filter at turn level
A turn that straddles midnight (user typed at 23:58, assistant responded
at 00:30) was bucketed and filtered inconsistently across call sites.
parseSessionFile filtered entries by timestamp, producing orphan assistant
calls that groupIntoTurns pushed as turns with empty timestamp. Some
downstream code counted those (buildPeriodData summing project totals)
and other code dropped them (renderStatusBar's empty-timestamp skip).

The menubar showed today = $32 while the terminal status showed today = $27
for the same dataset; each was internally consistent but used a different
turn-bucket rule.

Fix both: parseSessionFile now builds all turns first, then filters each
turn by its first assistant call timestamp (the moment cost was incurred).
renderStatusBar buckets the same way. day-aggregator.ts already bucketed
on assistant time, so it is now consistent too.

Net effect: a turn is counted in the day the API call actually ran in.
2026-04-21 04:40:44 -07:00