From 936845c232de530034f402b744ca14e9bf8d96cf Mon Sep 17 00:00:00 2001
From: merefield
Date: Mon, 12 Oct 2026 11:34:19 +0100
Subject: [PATCH 1/2] Price exact Codex responses and explain quota accounting
failures
---
README.md | 58 +++--
internal/codex/benchmark.go | 56 +++-
internal/codex/benchmark_test.go | 39 ++-
internal/codex/digbench.go | 9 +-
internal/codex/live_usage.go | 113 +++++++-
internal/codex/live_usage_accounting_test.go | 2 +-
internal/codex/live_usage_exact.go | 203 +++++++++++++++
internal/codex/live_usage_exact_test.go | 241 ++++++++++++++++++
internal/codex/service_tier.go | 44 +++-
internal/codex/service_tier_test.go | 29 ++-
internal/codex/usage_diagnostics.go | 78 ++++++
internal/ui/benchmark_quota.go | 137 ++++++++--
internal/ui/benchmark_quota_test.go | 37 ++-
internal/ui/english_snapshot_test.go | 4 +-
internal/ui/model.go | 5 +-
internal/ui/quota_api_eq.go | 81 +++++-
internal/ui/quota_api_eq_test.go | 60 +++++
internal/ui/view.go | 3 +
.../{index-Bd-Jwk4i.js => index-BWH3mrUB.js} | 55 ++--
internal/web/dist/assets/index-Bjr_1drg.css | 1 +
internal/web/dist/assets/index-GcuOkuuL.css | 1 -
internal/web/dist/index.html | 4 +-
internal/web/state.go | 11 +
internal/web/usage_diagnostics_test.go | 25 ++
web/src/Quota.svelte | 14 +
web/src/state.svelte.ts | 1 +
web/tests/browser.spec.ts | 47 ++++
27 files changed, 1238 insertions(+), 120 deletions(-)
create mode 100644 internal/codex/live_usage_exact.go
create mode 100644 internal/codex/live_usage_exact_test.go
create mode 100644 internal/codex/usage_diagnostics.go
rename internal/web/dist/assets/{index-Bd-Jwk4i.js => index-BWH3mrUB.js} (77%)
create mode 100644 internal/web/dist/assets/index-Bjr_1drg.css
delete mode 100644 internal/web/dist/assets/index-GcuOkuuL.css
create mode 100644 internal/web/usage_diagnostics_test.go
diff --git a/README.md b/README.md
index 2376a27..6bc4e89 100644
--- a/README.md
+++ b/README.md
@@ -706,17 +706,17 @@ narrower question: “At published API text-token prices, roughly what
would this observed mix of model work cost when mapped onto the movement in my
quota meter?”
-#### Fast mode and service-tier uncertainty
+#### Service tiers and pricing uncertainty
Codexometer prices each newly observed response separately. Standard token cost
-and the requested-tier premium are maintained independently; quota learning uses
+and the signed requested-tier adjustment are maintained independently; quota learning uses
their sum. For example, $1 at standard prices plus a $1 Fast premium over **5
percentage points** of quota movement implies roughly **$40 per 100%**, compared
with **$20 at standard prices**. It never multiplies the observed quota percentage
or applies today's `/fast` setting retroactively.
- `TIER*` means the estimate includes a **requested**, not billing-confirmed,
- Fast premium. The current Codex sources expose persisted
+ tier adjustment (a premium for Fast/Ultrafast or a discount for Flex). The current Codex sources expose persisted
`thread_settings_applied` settings, but neither local token events nor the
shared app-server's response-usage notifications expose the actual billed tier.
Settings are kept per session and captured for each turn; an in-flight turn
@@ -736,13 +736,17 @@ or applies today's `/fast` setting retroactively.
comparison** for the same sample windows. Narrower layouts omit that comparison.
- A known default setting has no premium. An explicitly unsupported tier/model
combination is unpriced and interrupts clean learning rather than silently
- applying an invented multiplier. Standard benchmark rankings are unchanged.
+ applying an invented multiplier. Benchmark comparisons continue to use Standard rates.
-Fast pricing was updated on **30 September 2026**: **GPT-6.1 Sol, GPT-6 (Astra, Sol, Luna) and GPT-5.6
+Tier pricing was reviewed on **12 October 2026**: **GPT-6.1 Sol, GPT-6 (Astra, Sol, Luna) and GPT-5.6
(Sol, Terra, Luna)** use **2× applicable standard API prices** for `fast` / the
-legacy `priority` alias. The premium is applied after the existing per-response
-long-context and cache-read/cache-write calculations; reasoning output is not
-counted twice. Other models' Fast prices are not yet maintained. See the official
+legacy `priority` alias. Astra and GPT-6.1 Sol **Ultrafast** use **6×** applicable standard API prices.
+**Flex** uses **½×** on the maintained GPT-6/GPT-5.6 models, GPT-5.2 and GPT-5.5.
+GPT-5.2 fallback pricing and published short-context Fast rates for GPT-5.2,
+GPT-5.3 Codex, GPT-5.4/Mini and GPT-5.5 are also maintained; GPT-5.5 Fast is 2.5×.
+Other explicit model/tier combinations and unpublished long-context Fast rates
+remain unavailable. Adjustments follow per-response long-context and cache
+calculations; reasoning output is not counted twice. See the official
[Astra pricing](https://developers.openai.com/api/docs/models/gpt-6-astra),
[Codex speed guidance](https://learn.chatgpt.com/docs/agent-configuration/speed),
and [API Fast-mode guide](https://developers.openai.com/api/docs/guides/fast-mode).
@@ -758,9 +762,21 @@ new evidence accumulates. Future improvement: consume the actual response
`service_tier` if Codex exposes it with matching per-response token usage, then
prefer that evidence to requested settings.
-Codexometer normally prices each newly completed local model call using the
-requested model durably recorded in its turn context. Current Codex rollout
-files do not persist transient model-reroute events, so a reroute cannot be
+Codexometer prefers Codex's durable **`token_usage_record`** entries for each
+newly completed response. Exact records are counted independently of cumulative
+context counters, with bounded response-ID deduplication; inherited parent
+records are excluded from a child's own usage. Startup establishes a historical
+baseline without charging past responses, using a bounded 4 MiB tail scan.
+An exact record switches that rollout to response accounting: subsequent
+`token_count` snapshots remain context/attribution baselines and never create
+another billable response. Older rollouts retain the legacy token-count reader. A replacement rollout for
+an existing thread establishes a new baseline rather than charging copied
+history again; session settings come from its newest observed rollout.
+
+The requested model remains the fallback when actual per-response model evidence
+is unavailable; durable usage records do not supply model or billed-tier fields.
+Diagnostics explicitly distinguish requested-model attribution from a matching
+live reroute. Current Codex rollout files do not persist transient model-reroute events, so a reroute cannot be
reconstructed from that source alone. When Codexometer and the CLI share the
managed daemon described above, Codexometer keeps a live subscription and
matches reroute and token-usage events to rollout calls by thread ID, turn ID,
@@ -779,7 +795,7 @@ cache-write input, and output are priced separately; requests above the
published 272,000-input-token threshold use the corresponding long-context
rates where OpenAI publishes them. Unknown models or missing price classes fail
closed as `UNPRICED USAGE` rather than being guessed or treated as free.
-Codex's context-window bookkeeping updates are recognised only when the window
+In the legacy reader, Codex's context-window bookkeeping updates are recognised only when the window
and both complete, explicit zero-token-class breakdowns match its synthetic fill record.
They rebase the local counter without adding response costs, token totals or
model-call graph pulses. Quota learning restarts as `LOCAL ACCOUNTING REBASED`.
@@ -788,20 +804,32 @@ the current baseline, including inherited child history and historical scans.
Missing input/output usage and inconsistent response/cumulative usage instead
restart as `MISSING RESPONSE USAGE` or `INCONSISTENT RESPONSE USAGE`; no costs
are guessed. Unknown model/tier or unavailable pricing remains `UNPRICED USAGE`.
+The terminal Quota view retains a bounded issue panel with the reason, originating
+session (including a child agent), model and its attribution basis, requested tier,
+effort, response/legacy/benchmark source, response ID and timestamp. The panel
+fits available terminal space; the browser Quota view shows the latest observed
+issue with wrapping. Diagnostics retain accounting metadata, not prompt/reply
+content, and are not persisted. A prior issue cannot be assigned to a later
+learning restart. Reserve (`gpt-reserve`), custom/preview and provider-specific
+model IDs stay unpriced where a price mapping is unverified; display aliases are
+not billing evidence.
Core, Extended, and DigBench trials use ephemeral threads that intentionally do
not appear in normal persisted session telemetry. While a subscription-funded
benchmark suite is active, Quota views replace the numeric API-equivalent
estimate with `SUBSCRIPTION BENCHMARK ACTIVE` instead of presenting partial
accounting. When each trial finishes, its authoritative benchmark usage is
-folded into the same process-local accounting used for quota learning; missing
-or unpriceable benchmark usage fails closed and restarts the learning anchor.
+folded into the same process-local accounting used for quota learning; missing,
+inconsistent or unpriceable benchmark usage fails closed with separate reasons
+and restarts the learning anchor. Complete raw response usage takes precedence
+over cumulative/context snapshots, each response retains its observed/requested
+model, and identical notification replays do not duplicate costs.
Benchmarks funded by `CODEXOMETER_BENCHMARK_API_KEY` are excluded because they
do not consume the displayed subscription quota. Benchmark threads remain
hidden from Sessions; hiding presentation does not exclude their aggregate
subscription impact from Quota views.
The embedded rates come from the
[official OpenAI API pricing page](https://developers.openai.com/api/docs/pricing)
-and were last updated on **2026-09-30**.
+and were last reviewed on **2026-10-12**.
Every Quota presentation repeats that retrieval date and a terminal hyperlink
to the source in its footer when the terminal is wide enough, matching the
Benchmark view and making stale compiled pricing conspicuous wherever a priced
diff --git a/internal/codex/benchmark.go b/internal/codex/benchmark.go
index 3470a52..a1e298a 100644
--- a/internal/codex/benchmark.go
+++ b/internal/codex/benchmark.go
@@ -33,7 +33,7 @@ const (
// the published rates compiled into this release. Keep both in sync whenever
// standardAPIPrices changes.
StandardAPIPricingSourceURL = "https://developers.openai.com/api/docs/pricing"
- StandardAPIPricingRetrievedOn = "2026-09-30"
+ StandardAPIPricingRetrievedOn = "2026-10-12"
)
// BenchmarkUsage is the app-server token breakdown for one isolated turn.
@@ -113,6 +113,7 @@ func (c Client) BenchmarkBillingSource() BenchmarkBillingSource {
// completion when the current Codex app-server exposes experimental raw events.
type BenchmarkResponseUsage struct {
ResponseID string
+ Model string
Usage BenchmarkUsage
}
@@ -930,7 +931,7 @@ func (s *appServerSession) runBenchmark(
Usage *BenchmarkUsage `json:"usage"`
}
if json.Unmarshal(params, &event) == nil && event.ThreadID == startedThread.Thread.ID && event.TurnID == startedTurn.Turn.ID {
- telemetry.recordRawResponse(event.ResponseID, event.Usage)
+ telemetry.recordRawResponseForModel(event.ResponseID, event.Usage, result.ActualModel)
}
case "model/rerouted":
var event struct {
@@ -1163,6 +1164,8 @@ func (s *appServerSession) interruptBenchmarkTurn(
}
func applyBenchmarkMeasurements(result *BenchmarkResult, telemetry *benchmarkTelemetry) {
+ result.CostUSD, result.CostKnown, result.CostIssue = 0, false, ""
+ result.UsageKnown, result.UsageIssue = false, ""
telemetry.apply(result)
if result.ToolUsed {
result.CostIssue = "tool use prohibited: " + result.ToolType
@@ -1170,7 +1173,11 @@ func applyBenchmarkMeasurements(result *BenchmarkResult, telemetry *benchmarkTel
if result.UsageSource == BenchmarkUsageRawResponses {
result.CostKnown = true
for _, response := range result.ResponseUsage {
- cost, known, issue := estimateSingleResponseAPICostWithIssue(result.ActualModel, response.Usage)
+ model := response.Model
+ if model == "" {
+ model = result.ActualModel
+ }
+ cost, known, issue := estimateSingleResponseAPICostWithIssue(model, response.Usage)
if !known {
result.CostUSD, result.CostKnown, result.CostIssue = 0, false, issue
break
@@ -1195,6 +1202,7 @@ type benchmarkTelemetry struct {
rawObserved bool
rawMissingUsage bool
issue string
+ cumulativeIssue string
}
func newBenchmarkTelemetry() *benchmarkTelemetry {
@@ -1204,10 +1212,10 @@ func newBenchmarkTelemetry() *benchmarkTelemetry {
func (t *benchmarkTelemetry) recordCumulative(usage BenchmarkUsage) {
t.cumulativeObserved = true
if issue := validateBenchmarkUsage(usage); issue != "" {
- t.setIssue("invalid cumulative usage: " + issue)
+ t.cumulativeIssue = "invalid cumulative usage: " + issue
}
if t.hasLastCumulative && !benchmarkUsageAtLeast(usage, t.lastCumulative) {
- t.setIssue("cumulative usage regressed")
+ t.cumulativeIssue = "cumulative usage regressed"
}
t.cumulative = usage
t.lastCumulative = usage
@@ -1221,7 +1229,19 @@ func (t *benchmarkTelemetry) recordRawResponse(responseID string, usage *Benchma
return
}
if _, duplicate := t.rawIDs[responseID]; duplicate {
- t.setIssue("duplicate raw response usage: " + responseID)
+ for _, previous := range t.rawResponses {
+ if previous.ResponseID == responseID {
+ if usage != nil && previous.Usage == *usage {
+ return
+ }
+ t.setIssue("conflicting duplicate raw response usage: " + responseID)
+ return
+ }
+ }
+ if usage == nil {
+ return
+ } // Identical replay of an already missing usage payload.
+ t.setIssue("conflicting duplicate raw response usage: " + responseID)
return
}
t.rawIDs[responseID] = struct{}{}
@@ -1257,13 +1277,18 @@ func (t *benchmarkTelemetry) apply(result *BenchmarkResult) {
result.UsageIssue = "invalid raw response total: " + issue
return
}
- if t.cumulativeObserved && rawTotal != t.cumulative {
- result.UsageIssue = "raw and cumulative usage disagree"
- return
- }
+
result.Usage, result.UsageKnown, result.UsageSource = rawTotal, true, BenchmarkUsageRawResponses
return
}
+ if t.rawObserved && t.rawMissingUsage {
+ result.UsageIssue = "raw response omitted usage"
+ return
+ }
+ if t.cumulativeIssue != "" {
+ result.UsageIssue = t.cumulativeIssue
+ return
+ }
if t.cumulativeObserved {
result.Usage, result.UsageKnown, result.UsageSource = t.cumulative, true, BenchmarkUsageCumulative
return
@@ -1609,6 +1634,7 @@ type apiPrice struct {
}
var standardAPIPrices = map[string]apiPrice{
+ "gpt-5.2": {input: 1.75, cached: 0.175, output: 14.00},
"gpt-6.1-sol": {input: 2.00, cached: 0.10, cacheWrite: 2.50, cacheWriteKnown: true, output: 10.00, longInput: 4.00, longCached: 0.20, longCacheWrite: 5.00, longOutput: 15.00, longKnown: true},
"gpt-6-sol": {input: 2.00, cached: 0.20, cacheWrite: 2.50, cacheWriteKnown: true, output: 10.00, longInput: 4.00, longCached: 0.40, longCacheWrite: 5.00, longOutput: 15.00, longKnown: true},
"gpt-6-luna": {input: 0.10, cached: 0.01, cacheWrite: 0.125, cacheWriteKnown: true, output: 0.50, longInput: 0.20, longCached: 0.02, longCacheWrite: 0.25, longOutput: 0.75, longKnown: true},
@@ -1640,7 +1666,7 @@ func estimateSingleResponseAPICostWithIssue(model string, usage BenchmarkUsage)
}
price, ok := priceForModel(model)
if !ok {
- return 0, false, "no published price for model " + strings.TrimSpace(model)
+ return 0, false, "no maintained standard API price for model " + strings.TrimSpace(model)
}
if usage.CacheWriteInputTokens > 0 && !price.cacheWriteKnown {
return 0, false, "no published cache-write price for model " + strings.TrimSpace(model)
@@ -1697,3 +1723,11 @@ func pricedModelName(model string) string {
}
return ""
}
+
+func (t *benchmarkTelemetry) recordRawResponseForModel(id string, usage *BenchmarkUsage, model string) {
+ before := len(t.rawResponses)
+ t.recordRawResponse(id, usage)
+ if len(t.rawResponses) > before {
+ t.rawResponses[len(t.rawResponses)-1].Model = model
+ }
+}
diff --git a/internal/codex/benchmark_test.go b/internal/codex/benchmark_test.go
index 249caeb..84f47f0 100644
--- a/internal/codex/benchmark_test.go
+++ b/internal/codex/benchmark_test.go
@@ -628,12 +628,8 @@ func TestBenchmarkTelemetryRejectsInconsistentStreams(t *testing.T) {
state.recordCumulative(valid)
state.recordCumulative(BenchmarkUsage{TotalTokens: 55, InputTokens: 50, OutputTokens: 5})
}, want: "regressed"},
- {name: "raw mismatch", record: func(state *benchmarkTelemetry) {
- state.recordRawResponse("response-1", &valid)
- state.recordCumulative(BenchmarkUsage{TotalTokens: 120, InputTokens: 100, OutputTokens: 20})
- }, want: "disagree"},
{name: "duplicate response", record: func(state *benchmarkTelemetry) {
- state.recordRawResponse("response-1", nil)
+ state.recordRawResponse("response-1", &valid)
state.recordRawResponse("response-1", nil)
}, want: "duplicate"},
{name: "raw aggregate overflow", record: func(state *benchmarkTelemetry) {
@@ -654,15 +650,15 @@ func TestBenchmarkTelemetryRejectsInconsistentStreams(t *testing.T) {
}
}
-func TestBenchmarkTelemetryFallsBackWhenRawUsageIsOmitted(t *testing.T) {
+func TestBenchmarkTelemetryRejectsIncompleteRawUsageEvenWithCumulativeSnapshot(t *testing.T) {
valid := BenchmarkUsage{TotalTokens: 110, InputTokens: 100, OutputTokens: 10}
state := newBenchmarkTelemetry()
state.recordRawResponse("response-1", nil)
state.recordCumulative(valid)
var result BenchmarkResult
state.apply(&result)
- if !result.UsageObserved || !result.UsageKnown || result.UsageSource != BenchmarkUsageCumulative || result.Usage != valid || result.UsageIssue != "" {
- t.Fatalf("valid cumulative fallback was not used: %#v", result)
+ if !result.UsageObserved || result.UsageKnown || result.UsageIssue != "raw response omitted usage" {
+ t.Fatalf("missing exact response usage was hidden by a context snapshot: %#v", result)
}
}
@@ -1212,6 +1208,7 @@ func TestEstimateAPICostUsesCachedAndOutputRates(t *testing.T) {
func TestStandardAPIPricesMatchPublishedRates(t *testing.T) {
want := map[string]apiPrice{
+ "gpt-5.2": {input: 1.75, cached: 0.175, output: 14.00},
"gpt-6.1-sol": {input: 2.00, cached: 0.10, cacheWrite: 2.50, cacheWriteKnown: true, output: 10.00, longInput: 4.00, longCached: 0.20, longCacheWrite: 5.00, longOutput: 15.00, longKnown: true},
"gpt-6-sol": {input: 2.00, cached: 0.20, cacheWrite: 2.50, cacheWriteKnown: true, output: 10.00, longInput: 4.00, longCached: 0.40, longCacheWrite: 5.00, longOutput: 15.00, longKnown: true},
"gpt-6-luna": {input: 0.10, cached: 0.01, cacheWrite: 0.125, cacheWriteKnown: true, output: 0.50, longInput: 0.20, longCached: 0.02, longCacheWrite: 0.25, longOutput: 0.75, longKnown: true},
@@ -1373,3 +1370,29 @@ func TestFormatIntervalsAndReferenceMerge(t *testing.T) {
t.Fatal("reference merge mutated input")
}
}
+
+func TestBenchmarkExactResponsesOverrideSyntheticSnapshotsAndRetainModels(t *testing.T) {
+ telemetry := newBenchmarkTelemetry()
+ first := BenchmarkUsage{InputTokens: 100, OutputTokens: 10, TotalTokens: 110}
+ second := BenchmarkUsage{InputTokens: 200, OutputTokens: 20, TotalTokens: 220}
+ telemetry.recordRawResponseForModel("one", &first, "gpt-6-astra")
+ telemetry.recordCumulative(BenchmarkUsage{TotalTokens: 128000}) // Context bookkeeping, not billable usage.
+ telemetry.recordRawResponseForModel("two", &second, "gpt-5.2")
+ telemetry.recordRawResponseForModel("two", &second, "gpt-5.2") // Identical transport replay.
+ result := BenchmarkResult{ActualModel: "gpt-5.2"}
+ applyBenchmarkMeasurements(&result, telemetry)
+ a, _, _ := EstimateStandardAPIEqCost("gpt-6-astra", first)
+ b, _, _ := EstimateStandardAPIEqCost("gpt-5.2", second)
+ if !result.CostKnown || !result.UsageKnown || result.Usage.TotalTokens != 330 || len(result.ResponseUsage) != 2 || math.Abs(result.CostUSD-a-b) > 1e-12 {
+ t.Fatal("exact usage depended on synthetic snapshots/final model", result)
+ }
+ applyBenchmarkMeasurements(&result, telemetry)
+ if math.Abs(result.CostUSD-a-b) > 1e-12 {
+ t.Fatal("repeated measurement added cost twice", result)
+ }
+ telemetry.recordRawResponse("two", &first)
+ applyBenchmarkMeasurements(&result, telemetry)
+ if result.UsageKnown || result.CostKnown || !strings.Contains(result.UsageIssue, "conflicting duplicate") {
+ t.Fatal("conflicting response ID was accepted", result)
+ }
+}
diff --git a/internal/codex/digbench.go b/internal/codex/digbench.go
index 38f72c8..d9d917f 100644
--- a/internal/codex/digbench.go
+++ b/internal/codex/digbench.go
@@ -484,7 +484,7 @@ func (s *appServerSession) runDigBench(
Usage *BenchmarkUsage `json:"usage"`
}
if json.Unmarshal(envelope.Params, &event) == nil && event.ThreadID == startedThread.Thread.ID && event.TurnID == startedTurn.Turn.ID {
- telemetry.recordRawResponse(event.ResponseID, event.Usage)
+ telemetry.recordRawResponseForModel(event.ResponseID, event.Usage, result.ActualModel)
}
case "model/rerouted":
var event struct {
@@ -1008,6 +1008,7 @@ func digBenchFinalResponse(params json.RawMessage, threadID, turnID string, sens
}
func applyDigBenchMeasurements(result *DigBenchResult, telemetry *benchmarkTelemetry) {
+ result.CostUSD, result.CostKnown, result.CostIssue = 0, false, ""
var measurements BenchmarkResult
telemetry.apply(&measurements)
result.Usage = measurements.Usage
@@ -1026,7 +1027,11 @@ func applyDigBenchMeasurements(result *DigBenchResult, telemetry *benchmarkTelem
}
result.CostKnown = true
for _, response := range result.ResponseUsage {
- cost, known, issue := estimateSingleResponseAPICostWithIssue(result.ActualModel, response.Usage)
+ model := response.Model
+ if model == "" {
+ model = result.ActualModel
+ }
+ cost, known, issue := estimateSingleResponseAPICostWithIssue(model, response.Usage)
if !known {
result.CostUSD, result.CostKnown, result.CostIssue = 0, false, issue
return
diff --git a/internal/codex/live_usage.go b/internal/codex/live_usage.go
index b4ea1ad..c09684b 100644
--- a/internal/codex/live_usage.go
+++ b/internal/codex/live_usage.go
@@ -25,10 +25,11 @@ const (
)
// LiveUsageSnapshot is a process-local accounting view built from token-count
-// events appended to locally persisted Codex rollouts. Finalized API-equivalent
+// events or exact response records appended to local Codex rollouts. Finalized API-equivalent
// totals increase monotonically; APIEqPendingCalls is an instantaneous count
// kept separate until daemon model resolution or requested-model fallback.
-// APIEqUSD remains standard cost. Quota learning adds APIEqTierPremiumUSD;
+// APIEqUSD remains standard cost. Quota learning adds the signed requested-tier
+// adjustment in APIEqTierPremiumUSD (negative for Flex);
// APIEqUnknownTierCalls identifies standard fallbacks with missing tier evidence.
// Missing/inconsistent response usage has separate monotonic counters from
// unavailable pricing. AccountingAdjustments counts recognised synthetic context
@@ -50,6 +51,7 @@ type LiveUsageSnapshot struct {
APIEqPendingCalls int64
APIEqTierPremiumUSD float64
APIEqUnknownTierCalls int64
+ APIEqDiagnostics []APIEqDiagnostic
}
// LiveUsageSession is one independently started local Codex session. Token
@@ -100,6 +102,13 @@ type LiveModelCall struct {
APIEqKnown bool
APIEqIssue string
apiEqFinalized bool
+ issueKind APIEqIssueKind
+ SessionID string
+ TurnID string
+ ResponseID string
+ Effort string
+ UsageSource string
+ ModelBasis string
RequestedServiceTier string
APIEqTierPremiumUSD float64
}
@@ -140,6 +149,7 @@ type LiveUsageReader struct {
apiEqMissingUsageCalls int64
apiEqInconsistentUsageCalls int64
apiEqAccountingAdjustments int64
+ apiEqDiagnostics []APIEqDiagnostic
lastActivity time.Time
nextEventSequence uint64
daemonObservationSequence uint64
@@ -169,6 +179,10 @@ type rolloutCursor struct {
modelCalls []LiveModelCall
turnTimings []LiveTurnTiming
attention sessionAttentionState
+ exactUsage bool
+ exactResponses map[string]BenchmarkUsage
+ exactConflicts map[string]bool
+ exactResponseOrder []string
}
type pendingModelResolution struct {
@@ -177,6 +191,7 @@ type pendingModelResolution struct {
turnID string
usage BenchmarkUsage
cumulativeTotal int64
+ exact bool
}
type sessionAttentionState int
@@ -204,6 +219,7 @@ type rolloutEvent struct {
}
type rolloutTokenUsage struct {
+ schemaIssue string
InputTokens *int64 `json:"input_tokens"`
CachedInputTokens *int64 `json:"cached_input_tokens"`
CacheWriteInputTokens int64 `json:"cache_write_input_tokens"`
@@ -227,6 +243,7 @@ func (u rolloutTokenUsage) benchmarkUsage() BenchmarkUsage {
OutputTokens: optionalRolloutTokens(u.OutputTokens),
ReasoningOutputTokens: optionalRolloutTokens(u.ReasoningOutputTokens),
TotalTokens: optionalRolloutTokens(u.TotalTokens),
+ schemaIssue: u.schemaIssue,
}
}
@@ -422,6 +439,7 @@ func (r *LiveUsageReader) fetchTokenUsage(ctx context.Context, forceFullDiscover
APIEqPendingCalls: int64(len(r.pendingModelResolutions)),
APIEqTierPremiumUSD: r.apiEqTierPremiumUSD,
APIEqUnknownTierCalls: r.apiEqUnknownTierCalls,
+ APIEqDiagnostics: append([]APIEqDiagnostic(nil), r.apiEqDiagnostics...),
}, nil
}
@@ -547,7 +565,18 @@ func (r *LiveUsageReader) addFile(path string, info os.FileInfo) error {
cursor.attention = attention
cursor.preview = latestSessionContext(path, cursor)
}
- if !r.initialized || !rolloutCreatedAfter(path, r.startedAt) {
+ // A new rollout filename can be a reverted/replaced history of an existing
+ // thread, not a new thread. Its copied responses are a baseline, not spend.
+ existingThread := false
+ if r.initialized && cursor.threadID != "" {
+ for _, known := range r.files {
+ if known.threadID == cursor.threadID {
+ existingThread = true
+ break
+ }
+ }
+ }
+ if !r.initialized || existingThread || !rolloutCreatedAfter(path, r.startedAt) {
model, modelErr := latestRolloutModel(path, cursor)
if modelErr != nil {
return modelErr
@@ -563,7 +592,14 @@ func (r *LiveUsageReader) addFile(path string, info os.FileInfo) error {
return err
}
cursor.totalTokens = total
- cursor.offset = info.Size()
+ baseline, err := restoreExactUsageBaseline(path, cursor, info.Size())
+ if err != nil {
+ return err
+ }
+ cursor.offset = baseline
+ if existingThread {
+ r.apiEqAccountingAdjustments++
+ }
}
r.files[path] = cursor
return nil
@@ -611,6 +647,11 @@ func (r *LiveUsageReader) consume(path string, cursor *rolloutCursor) error {
}
cursor.attention = attention
cursor.preview = latestSessionContext(path, cursor)
+ baseline, err := restoreExactUsageBaseline(path, cursor, info.Size())
+ if err != nil {
+ return err
+ }
+ cursor.offset = baseline
return nil
}
if info.Size() == cursor.offset {
@@ -648,7 +689,17 @@ func (r *LiveUsageReader) consume(path string, cursor *rolloutCursor) error {
tokenRecordIsOwned(ordinal, cursor.subagentHistoryStartOrdinal, at, cursor.nonRoot, cursor.startedAt) {
cursor.attention = attention
}
+ if record, ok := exactUsageRecord(line); ok {
+ r.consumeExactUsage(cursor, record)
+ }
if record, ok := tokenUsageRecord(line); ok {
+ if cursor.exactUsage {
+ if tokenRecordIsOwned(record.ordinal, cursor.subagentHistoryStartOrdinal, record.at, cursor.nonRoot, cursor.startedAt) {
+ r.attachExactCheckpoint(cursor, record)
+ }
+ cursor.totalTokens = record.total
+ continue
+ }
if !tokenRecordIsOwned(record.ordinal, cursor.subagentHistoryStartOrdinal, record.at, cursor.nonRoot, cursor.startedAt) {
// Legacy child rollouts copy the parent's cumulative token
// events. Preserve the latest inherited value as the child's
@@ -695,6 +746,10 @@ func (r *LiveUsageReader) consume(path string, cursor *rolloutCursor) error {
Sequence: r.nextEventSequence, At: record.at, OutputTokens: record.outputTokens,
OutputAvailable: record.outputKnown, Model: model,
RequestedServiceTier: cursor.currentServiceTier,
+ SessionID: cursor.threadID, TurnID: cursor.currentTurnID, Effort: cursor.modelSettings.ReasoningEffort, UsageSource: "legacy token snapshot", ModelBasis: "requested",
+ }
+ if resolved {
+ call.ModelBasis = "live reroute"
}
if usageMatchesDelta && (!resolutionPending || resolved) {
r.finalizeCallPricing(&call, pricingUsage)
@@ -702,8 +757,10 @@ func (r *LiveUsageReader) consume(path string, cursor *rolloutCursor) error {
call.apiEqFinalized = true
if !record.usageAvailable {
call.APIEqIssue = "missing response input/output usage"
+ call.issueKind = UsageIssueMissing
r.apiEqMissingUsageCalls++
} else {
+ call.issueKind = UsageIssueInconsistent
call.APIEqIssue = validateBenchmarkUsage(record.usage)
if call.APIEqIssue == "" {
call.APIEqIssue = "cumulative token increase does not match last response usage"
@@ -711,6 +768,9 @@ func (r *LiveUsageReader) consume(path string, cursor *rolloutCursor) error {
r.apiEqInconsistentUsageCalls++
}
}
+ if call.apiEqFinalized && call.APIEqIssue != "" {
+ r.rememberCallIssue(call)
+ }
cursor.modelCalls = appendBounded(cursor.modelCalls, call, telemetryHistoryMax)
if resolutionDeferred {
r.pendingModelResolutions = append(r.pendingModelResolutions, pendingModelResolution{
@@ -772,18 +832,30 @@ func (r *LiveUsageReader) reconcilePendingModelResolutions() {
// The response aged out before model resolution; the loss is a
// usage-coverage issue, not evidence of an unsupported model.
r.apiEqMissingUsageCalls++
+ source := "legacy token snapshot"
+ if pending.exact {
+ source = "exact response"
+ }
+ r.rememberCallIssue(LiveModelCall{SessionID: pending.threadID, TurnID: pending.turnID, UsageSource: source, issueKind: UsageIssueMissing, APIEqIssue: "response aged out before model resolution"})
continue
}
if call.apiEqFinalized {
continue
}
observation, ok := r.takeResolvedModelObservation(pending.threadID, pending.turnID, pending.usage, pending.cumulativeTotal)
+ if !ok && pending.exact && pending.cumulativeTotal < 0 {
+ observation, ok = r.takeUniqueExactModelObservation(pending.threadID, pending.turnID, pending.usage)
+ }
pricingUsage := pending.usage
if ok {
call.Model = observation.Model
+ call.ModelBasis = "live reroute"
pricingUsage = observation.Usage
}
r.finalizeCallPricing(call, pricingUsage)
+ if call.APIEqIssue != "" {
+ r.rememberCallIssue(*call)
+ }
}
r.pendingModelResolutions = nil
}
@@ -978,7 +1050,7 @@ func tokenUsageRecord(line []byte) (rolloutTokenRecord, bool) {
// Require every core token field in both breakdowns. Missing legacy
// telemetry must never be mistaken for Codex's synthetic full-context event.
zeroClasses := func(u rolloutTokenUsage) bool {
- return u.InputTokens != nil && *u.InputTokens == 0 &&
+ return u.schemaIssue == "" && u.InputTokens != nil && *u.InputTokens == 0 &&
u.OutputTokens != nil && *u.OutputTokens == 0 &&
u.CachedInputTokens != nil && *u.CachedInputTokens == 0 &&
u.ReasoningOutputTokens != nil && *u.ReasoningOutputTokens == 0 &&
@@ -1249,7 +1321,10 @@ func (r *LiveUsageReader) sessionSnapshots(now time.Time, liveWriters map[string
byID := make(map[string]*rolloutCursor, len(r.files))
for _, cursor := range r.files {
if cursor.threadID != "" {
- byID[cursor.threadID] = cursor
+ previous := byID[cursor.threadID]
+ if previous == nil || cursor.lastModified.After(previous.lastModified) {
+ byID[cursor.threadID] = cursor
+ }
}
}
@@ -1485,3 +1560,29 @@ func contextErr(ctx context.Context) error {
return nil
}
}
+
+func (u *rolloutTokenUsage) UnmarshalJSON(data []byte) error {
+ type wire rolloutTokenUsage
+ var value wire
+ if err := json.Unmarshal(data, &value); err != nil {
+ return err
+ }
+ var fields map[string]json.RawMessage
+ if err := json.Unmarshal(data, &fields); err != nil {
+ return err
+ }
+ *u = rolloutTokenUsage(value)
+ var unknown []string
+ for key := range fields {
+ switch key {
+ case "input_tokens", "cached_input_tokens", "cache_write_input_tokens", "output_tokens", "reasoning_output_tokens", "total_tokens", "codex_rollout_budget_units":
+ default:
+ unknown = append(unknown, key)
+ }
+ }
+ sort.Strings(unknown)
+ if len(unknown) > 0 {
+ u.schemaIssue = "unknown usage fields: " + strings.Join(unknown, ", ")
+ }
+ return nil
+}
diff --git a/internal/codex/live_usage_accounting_test.go b/internal/codex/live_usage_accounting_test.go
index d5b2c61..e4ce133 100644
--- a/internal/codex/live_usage_accounting_test.go
+++ b/internal/codex/live_usage_accounting_test.go
@@ -143,7 +143,7 @@ func TestResponseUsageProblemsAreSeparateFromUnknownPrices(t *testing.T) {
case "unknown-model":
event = turnContextLine(now, "gpt-6-astra-preview") + "\n" + event
case "unsupported-tier":
- event = tierSettingsLine(now, `"flex"`) + "\n" + turnContextLine(now, "gpt-6-astra") + "\n" + event
+ event = tierSettingsLine(now, `"unadvertised-tier"`) + "\n" + turnContextLine(now, "gpt-6-astra") + "\n" + event
}
appendRollout(t, path, event+"\n")
usage, err := r.FetchTokenUsage(context.Background())
diff --git a/internal/codex/live_usage_exact.go b/internal/codex/live_usage_exact.go
new file mode 100644
index 0000000..260d092
--- /dev/null
+++ b/internal/codex/live_usage_exact.go
@@ -0,0 +1,203 @@
+package codex
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "io"
+ "os"
+ "strings"
+ "time"
+)
+
+// Codex added durable, exact response records on 2026-08-31. Context token
+// snapshots remain useful as baselines, but are not response billing records.
+type rolloutExactUsage struct {
+ Timestamp time.Time `json:"timestamp"`
+ Ordinal *uint64 `json:"ordinal"`
+ Type string `json:"type"`
+ Payload struct {
+ ThreadID string `json:"thread_id"`
+ TurnID string `json:"turn_id"`
+ ResponseID string `json:"response_id"`
+ Usage *rolloutTokenUsage `json:"usage"`
+ } `json:"payload"`
+}
+
+func exactUsageRecord(line []byte) (rolloutExactUsage, bool) {
+ var record rolloutExactUsage
+ if !bytes.Contains(line, []byte(`"token_usage_record"`)) || json.Unmarshal(line, &record) != nil || record.Type != "token_usage_record" {
+ return record, false
+ }
+ return record, true
+}
+
+func (c *rolloutCursor) ownsExactRecord(record rolloutExactUsage) bool {
+ return record.Payload.ThreadID == c.threadID && tokenRecordIsOwned(record.Ordinal, c.subagentHistoryStartOrdinal, record.Timestamp, c.nonRoot, c.startedAt)
+}
+
+func (c *rolloutCursor) rememberExactResponse(id string, usage BenchmarkUsage) bool {
+ if c.exactResponses == nil {
+ c.exactResponses = make(map[string]BenchmarkUsage)
+ }
+ if _, exists := c.exactResponses[id]; exists {
+ return false
+ }
+ c.exactResponses[id] = usage
+ c.exactResponseOrder = append(c.exactResponseOrder, id)
+ if len(c.exactResponseOrder) > telemetryHistoryMax {
+ delete(c.exactResponses, c.exactResponseOrder[0])
+ delete(c.exactConflicts, c.exactResponseOrder[0])
+ c.exactResponseOrder = c.exactResponseOrder[1:]
+ }
+ return true
+}
+
+// Establish the source and recent replay identities without counting history.
+// Bound startup IO independently of the file's potentially large transcript.
+func restoreExactUsageBaseline(path string, cursor *rolloutCursor, baselineOffset int64) (int64, error) {
+ file, err := os.Open(path)
+ if err != nil {
+ return 0, err
+ }
+ defer file.Close()
+ info, err := file.Stat()
+ if err != nil {
+ return 0, err
+ }
+ end := min(info.Size(), baselineOffset)
+ size := min(end, int64(4*1024*1024))
+ start := end - size
+ data := make([]byte, size)
+ _, err = file.ReadAt(data, start)
+ if err != nil && !errors.Is(err, io.EOF) {
+ return 0, err
+ }
+ // A writer can be midway through a small exact record at discovery. Leave
+ // its partial bytes for the incremental reader, rather than skipping them.
+ if last := bytes.LastIndexByte(data, '\n'); last >= 0 && last < len(data)-1 {
+ end = end - size + int64(last) + 1
+ data = data[:last+1]
+ }
+ lines := bytes.Split(data, []byte{'\n'})
+ if start > 0 {
+ lines = lines[1:]
+ }
+ for _, line := range lines {
+ record, ok := exactUsageRecord(line)
+ if !ok || !cursor.ownsExactRecord(record) {
+ continue
+ }
+ cursor.exactUsage = true
+ if id := strings.TrimSpace(record.Payload.ResponseID); id != "" {
+ usage := BenchmarkUsage{}
+ if record.Payload.Usage != nil {
+ usage = record.Payload.Usage.benchmarkUsage()
+ }
+ cursor.rememberExactResponse(id, usage)
+ }
+ }
+ return end, nil
+}
+
+func (r *LiveUsageReader) consumeExactUsage(cursor *rolloutCursor, record rolloutExactUsage) {
+ if !cursor.ownsExactRecord(record) {
+ return
+ }
+ cursor.exactUsage = true
+ id := strings.TrimSpace(record.Payload.ResponseID)
+ usage := BenchmarkUsage{}
+ if record.Payload.Usage != nil {
+ usage = record.Payload.Usage.benchmarkUsage()
+ }
+ if previous, seen := cursor.exactResponses[id]; id != "" && seen {
+ if previous != usage && !cursor.exactConflicts[id] {
+ if cursor.exactConflicts == nil {
+ cursor.exactConflicts = make(map[string]bool)
+ }
+ cursor.exactConflicts[id] = true
+ r.apiEqInconsistentUsageCalls++
+ r.rememberCallIssue(LiveModelCall{At: record.Timestamp, SessionID: cursor.threadID, Model: cursor.currentModel, RequestedServiceTier: cursor.currentServiceTier, ResponseID: id, UsageSource: "exact response", Effort: cursor.modelSettings.ReasoningEffort, issueKind: UsageIssueInconsistent, APIEqIssue: "response ID replayed with conflicting usage"})
+ }
+ return
+ }
+ if id != "" {
+ cursor.rememberExactResponse(id, usage)
+ }
+ r.nextEventSequence++
+ at := record.Timestamp
+ if at.IsZero() {
+ at = time.Now()
+ }
+ call := LiveModelCall{Sequence: r.nextEventSequence, At: at, Model: cursor.currentModel,
+ SessionID: cursor.threadID, TurnID: record.Payload.TurnID, ResponseID: id,
+ Effort: cursor.modelSettings.ReasoningEffort, UsageSource: "exact response", ModelBasis: "requested", RequestedServiceTier: cursor.currentServiceTier}
+ call.OutputAvailable = record.Payload.Usage != nil && record.Payload.Usage.OutputTokens != nil
+ call.OutputTokens = usage.OutputTokens
+ if id == "" {
+ call.issueKind = UsageIssueInconsistent
+ call.APIEqIssue = "exact response record omitted response ID"
+ call.apiEqFinalized = true
+ r.apiEqInconsistentUsageCalls++
+ } else if record.Payload.Usage == nil || record.Payload.Usage.InputTokens == nil || record.Payload.Usage.OutputTokens == nil || record.Payload.Usage.TotalTokens == nil || record.Payload.Usage.CachedInputTokens == nil || record.Payload.Usage.ReasoningOutputTokens == nil {
+ call.issueKind = UsageIssueMissing
+ call.APIEqIssue = "exact response record omitted required token breakdown fields"
+ call.apiEqFinalized = true
+ r.apiEqMissingUsageCalls++
+ } else if issue := validateBenchmarkUsage(usage); issue != "" {
+ call.issueKind = UsageIssueInconsistent
+ call.APIEqIssue = issue
+ call.apiEqFinalized = true
+ r.apiEqInconsistentUsageCalls++
+ } else {
+ // Exact usage is counted independently of synthetic context-counter resets.
+ r.totalTokens += usage.TotalTokens
+ cursor.observedTokens += usage.TotalTokens
+ if usage.TotalTokens > 0 && at.After(r.lastActivity) {
+ r.lastActivity = at
+ }
+ _, subscribed := r.daemonSubscribedThreads[cursor.threadID]
+ if subscribed && call.TurnID != "" {
+ r.pendingModelResolutions = append(r.pendingModelResolutions, pendingModelResolution{
+ callSequence: call.Sequence, threadID: call.SessionID, turnID: call.TurnID, usage: usage, cumulativeTotal: -1, exact: true})
+ } else {
+ r.finalizeCallPricing(&call, usage)
+ }
+ }
+ if call.apiEqFinalized && call.APIEqIssue != "" {
+ r.rememberCallIssue(call)
+ }
+ cursor.modelCalls = appendBounded(cursor.modelCalls, call, telemetryHistoryMax)
+}
+
+// Exact records precede the corresponding context snapshot. Attach that
+// checkpoint when available; it is attribution evidence, not a billing gate.
+func (r *LiveUsageReader) attachExactCheckpoint(cursor *rolloutCursor, record rolloutTokenRecord) {
+ for i := len(r.pendingModelResolutions) - 1; i >= 0; i-- {
+ pending := &r.pendingModelResolutions[i]
+ if pending.exact && pending.threadID == cursor.threadID && (cursor.currentTurnID == "" || pending.turnID == cursor.currentTurnID) && pending.cumulativeTotal < 0 && sameBenchmarkUsage(pending.usage, record.usage) {
+ pending.cumulativeTotal = record.total
+ break
+ }
+ }
+}
+
+// Without a context checkpoint, accept only a unique matching live observation.
+// Repeated identical responses must not inherit an ambiguous rerouted model.
+func (r *LiveUsageReader) takeUniqueExactModelObservation(threadID, turnID string, usage BenchmarkUsage) (resolvedModelObservation, bool) {
+ index := -1
+ for i, observation := range r.resolvedObservations {
+ if observation.ThreadID == threadID && observation.TurnID == turnID && sameBenchmarkUsage(observation.Usage, usage) {
+ if index >= 0 {
+ return resolvedModelObservation{}, false
+ }
+ index = i
+ }
+ }
+ if index < 0 {
+ return resolvedModelObservation{}, false
+ }
+ observation := r.resolvedObservations[index]
+ r.resolvedObservations = append(r.resolvedObservations[:index], r.resolvedObservations[index+1:]...)
+ return observation, true
+}
diff --git a/internal/codex/live_usage_exact_test.go b/internal/codex/live_usage_exact_test.go
new file mode 100644
index 0000000..73bdaa6
--- /dev/null
+++ b/internal/codex/live_usage_exact_test.go
@@ -0,0 +1,241 @@
+package codex
+
+import (
+ "context"
+ "encoding/json"
+ "math"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+ "time"
+)
+
+func exactLine(t *testing.T, at time.Time, thread, turn, response string, usage BenchmarkUsage) string {
+ t.Helper()
+ raw, err := json.Marshal(map[string]any{"type": "token_usage_record", "timestamp": at, "payload": map[string]any{
+ "thread_id": thread, "turn_id": turn, "response_id": response,
+ "usage": map[string]any{"input_tokens": usage.InputTokens, "cached_input_tokens": usage.CachedInputTokens,
+ "cache_write_input_tokens": usage.CacheWriteInputTokens, "output_tokens": usage.OutputTokens,
+ "reasoning_output_tokens": usage.ReasoningOutputTokens, "total_tokens": usage.TotalTokens}}})
+ if err != nil {
+ t.Fatal(err)
+ }
+ return string(raw)
+}
+
+func TestExactUsageIgnoresContextCountersAndDeduplicatesAcrossPolls(t *testing.T) {
+ r, path, now := astraUsageReader(t, 100)
+ r.statusProvider = nil
+ u := BenchmarkUsage{InputTokens: 1000, CachedInputTokens: 200, CacheWriteInputTokens: 30, OutputTokens: 100, ReasoningOutputTokens: 80, TotalTokens: 1100}
+ appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "r1", u)+"\n"+richTokenCountLine(now, 9000, 1000, 200, 30, 100)+"\n")
+ first, err := r.FetchTokenUsage(context.Background())
+ if err != nil {
+ t.Fatal(err)
+ }
+ want, _, _ := EstimateStandardAPIEqCost("gpt-6-astra", u)
+ if first.TotalTokens != 1100 || first.APIEqPricedCalls != 1 || first.APIEqUnpricedCalls != 0 || first.APIEqInconsistentUsageCalls != 0 || math.Abs(first.APIEqUSD-want) > 1e-12 {
+ t.Fatal("exact response depended on context counter", first)
+ }
+ appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "r1", u)+"\n"+contextFillLine(t, now, 128000, 119000)+"\n")
+ duplicate, err := r.FetchTokenUsage(context.Background())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if duplicate.TotalTokens != first.TotalTokens || duplicate.APIEqPricedCalls != 1 || duplicate.APIEqAccountingAdjustments != 0 || len(duplicate.Sessions[0].ModelCalls) != 1 {
+ t.Fatal("replay/bookkeeping affected exact accounting", duplicate)
+ }
+ appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "r2", u)+"\n")
+ next, err := r.FetchTokenUsage(context.Background())
+ if err != nil || next.TotalTokens != 2200 || next.APIEqPricedCalls != 2 || math.Abs(next.APIEqUSD-2*want) > 1e-12 {
+ t.Fatal("next exact response was lost", next, err)
+ }
+}
+
+func TestExactUsageStartupBetweenResponseAndContextSnapshot(t *testing.T) {
+ _, path, now := astraUsageReader(t, 100)
+ u := BenchmarkUsage{InputTokens: 1000, OutputTokens: 100, TotalTokens: 1100}
+ appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "old", u)+"\n")
+
+ home := strings.Split(path, string(filepath.Separator)+"sessions"+string(filepath.Separator))[0]
+ r, err := NewLiveUsageReader(home)
+ if err != nil {
+ t.Fatal(err)
+ }
+ r.statusProvider = nil
+ baseline, err := r.FetchTokenUsage(context.Background())
+ if err != nil || baseline.TotalTokens != 0 || baseline.APIEqPricedCalls != 0 {
+ t.Fatal("historical exact response counted", baseline, err)
+ }
+ appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "old", u)+"\n"+richTokenCountLine(now, 1200, 1000, 0, 0, 100)+"\n")
+ replay, err := r.FetchTokenUsage(context.Background())
+ if err != nil || replay.TotalTokens != 0 || replay.APIEqPricedCalls != 0 {
+ t.Fatal("startup replay/context duplicate counted", replay, err)
+ }
+ appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "new", u)+"\n")
+ fresh, err := r.FetchTokenUsage(context.Background())
+ if err != nil || fresh.TotalTokens != 1100 || fresh.APIEqPricedCalls != 1 {
+ t.Fatal("fresh exact response lost", fresh, err)
+ }
+
+}
+
+func TestExactUsageOwnedRecordsExcludeInheritedHistory(t *testing.T) {
+ r, path, now := astraUsageReader(t, 100)
+ r.statusProvider = nil
+ cursor := r.files[path]
+ ordinal := uint64(10)
+ cursor.nonRoot = true
+ cursor.subagentHistoryStartOrdinal = &ordinal
+ u := BenchmarkUsage{InputTokens: 1000, OutputTokens: 100, TotalTokens: 1100}
+ inherited := exactLine(t, now, "astra-accounting", "t", "inherited", u)
+ var frame map[string]any
+ _ = json.Unmarshal([]byte(inherited), &frame)
+ frame["ordinal"] = 9
+ raw, _ := json.Marshal(frame)
+ appendRollout(t, path, exactLine(t, now, "parent-thread", "t", "parent", u)+"\n"+string(raw)+"\n")
+ first, err := r.FetchTokenUsage(context.Background())
+ if err != nil || first.APIEqPricedCalls != 0 || first.TotalTokens != 0 {
+ t.Fatal("inherited response was charged", first, err)
+ }
+ frame["ordinal"] = 11
+ frame["payload"].(map[string]any)["response_id"] = "owned"
+ raw, _ = json.Marshal(frame)
+ appendRollout(t, path, string(raw)+"\n")
+ owned, err := r.FetchTokenUsage(context.Background())
+ if err != nil || owned.APIEqPricedCalls != 1 || owned.TotalTokens != 1100 {
+ t.Fatal("owned response was not charged", owned, err)
+ }
+}
+
+func TestExactUsageSeparatesMissingInvalidAndUnpricedWithDiagnostics(t *testing.T) {
+ for _, kind := range []string{"missing", "invalid", "unknown-field", "reserve"} {
+ t.Run(kind, func(t *testing.T) {
+ r, path, now := astraUsageReader(t, 100)
+ r.statusProvider = nil
+ u := BenchmarkUsage{InputTokens: 1000, OutputTokens: 100, TotalTokens: 1100}
+ line := exactLine(t, now, "astra-accounting", "t", "r", u)
+ var frame map[string]any
+ _ = json.Unmarshal([]byte(line), &frame)
+ fields := frame["payload"].(map[string]any)["usage"].(map[string]any)
+ switch kind {
+ case "missing":
+ delete(fields, "cached_input_tokens")
+ case "invalid":
+ fields["cached_input_tokens"] = 1001
+ case "unknown-field":
+ fields["future_billable_tokens"] = 20
+ case "reserve":
+ appendRollout(t, path, turnContextLine(now, "gpt-reserve")+"\n")
+ }
+ raw, _ := json.Marshal(frame)
+ appendRollout(t, path, string(raw)+"\n")
+ got, err := r.FetchTokenUsage(context.Background())
+ if err != nil {
+ t.Fatal(err)
+ }
+ wanted := UsageIssueInconsistent
+ if kind == "missing" {
+ wanted = UsageIssueMissing
+ }
+ if kind == "reserve" {
+ wanted = UsageIssueUnpriced
+ }
+ if len(got.APIEqDiagnostics) != 1 || got.APIEqDiagnostics[0].Kind != wanted || got.APIEqDiagnostics[0].SessionID != "astra-accounting" || got.APIEqDiagnostics[0].ResponseID != "r" || got.APIEqDiagnostics[0].Reason == "" {
+ t.Fatal("failure attribution lost", got)
+ }
+ if kind != "reserve" && got.APIEqUnpricedCalls != 0 {
+ t.Fatal("bad usage became missing pricing", got)
+ }
+ })
+ }
+}
+
+func TestExactUsageKeepsDaemonModelResolution(t *testing.T) {
+ r, path, now := astraUsageReader(t, 100)
+ u := BenchmarkUsage{InputTokens: 1000, OutputTokens: 100, TotalTokens: 1100}
+ r.statusProvider = stubSessionStatusProvider{subscribed: map[string]struct{}{"astra-accounting": {}}}
+ appendRollout(t, path, turnContextWithTurnIDLine(now, "turn", "gpt-6-astra")+"\n"+exactLine(t, now, "astra-accounting", "turn", "r", u)+"\n"+richTokenCountLine(now, 9999, 1000, 0, 0, 100)+"\n")
+ first, err := r.FetchTokenUsage(context.Background())
+ if err != nil || first.APIEqPendingCalls != 1 || first.APIEqPricedCalls != 0 {
+ t.Fatal("response did not wait for attribution", first, err)
+ }
+ r.statusProvider = stubSessionStatusProvider{subscribed: map[string]struct{}{"astra-accounting": {}}, observations: []resolvedModelObservation{{Sequence: 1, ThreadID: "astra-accounting", TurnID: "turn", Model: "gpt-5.2", Usage: u, CumulativeTotal: 9999}}}
+ resolved, err := r.FetchTokenUsage(context.Background())
+ if err != nil || resolved.APIEqPendingCalls != 0 || resolved.APIEqPricedCalls != 1 || resolved.Sessions[0].ModelCalls[0].Model != "gpt-5.2" {
+ t.Fatal("exact response lost reroute attribution", resolved, err)
+ }
+}
+
+func TestExactConflictingReplayIsReportedOnceWithoutAdditionalCost(t *testing.T) {
+ r, path, now := astraUsageReader(t, 100)
+ r.statusProvider = nil
+ u := BenchmarkUsage{InputTokens: 1000, OutputTokens: 100, TotalTokens: 1100}
+ appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "r", u)+"\n")
+ first, _ := r.FetchTokenUsage(context.Background())
+ u.InputTokens++
+ u.TotalTokens++
+ line := exactLine(t, now, "astra-accounting", "t", "r", u) + "\n"
+ appendRollout(t, path, line+line)
+ got, err := r.FetchTokenUsage(context.Background())
+ if err != nil || got.APIEqUSD != first.APIEqUSD || got.TotalTokens != first.TotalTokens || got.APIEqInconsistentUsageCalls != 1 || len(got.APIEqDiagnostics) != 1 || !strings.Contains(got.APIEqDiagnostics[0].Reason, "conflicting usage") {
+ t.Fatal("conflicting replay charged or hidden", got, err)
+ }
+}
+
+func TestExactDiscoveryDoesNotBaselineConcurrentAppendOrPartialRecord(t *testing.T) {
+ for _, partial := range []bool{false, true} {
+ r, path, now := astraUsageReader(t, 100)
+ r.statusProvider = nil
+ u := BenchmarkUsage{InputTokens: 1000, OutputTokens: 100, TotalTokens: 1100}
+ line := exactLine(t, now, "astra-accounting", "t", "concurrent", u) + "\n"
+ if partial {
+ appendRollout(t, path, line[:len(line)/2])
+ }
+ file, err := os.Stat(path)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if partial {
+ appendRollout(t, path, line[len(line)/2:])
+ } else {
+ appendRollout(t, path, line)
+ }
+ delete(r.files, path)
+ if err := r.addFile(path, file); err != nil {
+ t.Fatal(err)
+ }
+ got, err := r.FetchTokenUsage(context.Background())
+ if err != nil || got.APIEqPricedCalls != 1 || got.TotalTokens != 1100 {
+ t.Fatal("concurrent/partial append was silently baselined", partial, got, err)
+ }
+ }
+}
+
+func TestExactReplacementRolloutDoesNotBillCopiedThreadHistory(t *testing.T) {
+ r, path, now := astraUsageReader(t, 100)
+ r.statusProvider = nil
+ u := BenchmarkUsage{InputTokens: 1000, OutputTokens: 100, TotalTokens: 1100}
+ line := exactLine(t, now, "astra-accounting", "t", "old", u) + "\n"
+ appendRollout(t, path, line)
+ first, _ := r.FetchTokenUsage(context.Background())
+ home := strings.Split(path, string(filepath.Separator)+"sessions"+string(filepath.Separator))[0]
+ replacement := testRolloutPath(t, home, time.Now().Add(time.Second), "replacement-rollout")
+ writeRollout(t, replacement, sessionMetaLine("astra-accounting", `"cli"`, "/synthetic", nil)+"\n"+turnContextLine(now, "gpt-6-sol")+"\n"+line)
+ info, err := os.Stat(replacement)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := r.addFile(replacement, info); err != nil {
+ t.Fatal(err)
+ }
+ got, err := r.FetchTokenUsage(context.Background())
+ if err != nil || got.TotalTokens != first.TotalTokens || got.APIEqPricedCalls != 1 || got.APIEqAccountingAdjustments != 1 {
+ t.Fatal("replacement history billed again", got, err)
+ }
+ appendRollout(t, replacement, exactLine(t, now, "astra-accounting", "t", "new", u)+"\n")
+ next, err := r.FetchTokenUsage(context.Background())
+ if err != nil || next.TotalTokens != 2200 || next.APIEqPricedCalls != 2 || len(next.Sessions) != 1 || next.Sessions[0].TotalTokens != 2200 || next.Sessions[0].ModelSettings.Model != "gpt-6-sol" {
+ t.Fatal("fresh replacement response was lost", next, err)
+ }
+}
diff --git a/internal/codex/service_tier.go b/internal/codex/service_tier.go
index 39d3168..d46486e 100644
--- a/internal/codex/service_tier.go
+++ b/internal/codex/service_tier.go
@@ -10,28 +10,41 @@ import (
// FastAPIPricingRetrievedOn is separate from the standard-price review date.
// Sources: https://developers.openai.com/api/docs/pricing and
// https://learn.chatgpt.com/docs/agent-configuration/speed (GPT-5.6 API rates).
-const FastAPIPricingRetrievedOn = "2026-09-30"
+const FastAPIPricingRetrievedOn = "2026-10-12"
// requestedTierPremium prices a single response's requested tier. It does not
// claim that the backend delivered/billed that tier. Empty means unavailable,
// not confirmed standard. Unknown explicit tiers fail closed.
func requestedTierPremium(model, tier string, standard float64) (float64, bool) {
+ multiplier, known := requestedTierMultiplier(model, tier)
+ return standard * (multiplier - 1), known
+}
+
+// Only published model/tier combinations are maintained. The adjustment may
+// be negative for Flex; Standard totals remain independently monotonic.
+func requestedTierMultiplier(model, tier string) (float64, bool) {
+ name := pricedModelName(model)
switch strings.ToLower(strings.TrimSpace(tier)) {
case "", "default", "standard":
- return 0, true
+ return 1, true
case "fast", "priority":
- // Only apply verified model-specific rates, never subscription credit
- // multipliers. GPT-6 / GPT-5.6 Fast is 2x applicable rates, including long
- // context and both cache classes. Dated snapshots share base pricing.
- switch pricedModelName(model) {
- case "gpt-6-astra", "gpt-6.1-sol", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna":
- return standard, true
- default:
- return 0, false
+ switch name {
+ case "gpt-6-astra", "gpt-6.1-sol", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.2", "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex":
+ return 2, true
+ case "gpt-5.5":
+ return 2.5, true
+ }
+ case "ultrafast":
+ if name == "gpt-6-astra" || name == "gpt-6.1-sol" {
+ return 6, true
+ }
+ case "flex":
+ switch name {
+ case "gpt-6-astra", "gpt-6.1-sol", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.2", "gpt-5.5":
+ return 0.5, true
}
- default:
- return 0, false
}
+ return 1, false
}
// Codex persists settings separately from turn_context. A complete settings
@@ -66,12 +79,19 @@ func rolloutTierRecord(line []byte) (string, *uint64, time.Time, bool) {
func (r *LiveUsageReader) finalizeCallPricing(call *LiveModelCall, usage BenchmarkUsage) {
if issue := validateBenchmarkUsage(usage); issue != "" {
+ call.issueKind = UsageIssueInconsistent
call.APIEqIssue = issue
call.apiEqFinalized = true
r.apiEqInconsistentUsageCalls++
return
}
call.APIEqUSD, call.APIEqKnown, call.APIEqIssue = EstimateStandardAPIEqCost(call.Model, usage)
+ if call.APIEqKnown && usage.InputTokens > 272_000 &&
+ (strings.EqualFold(strings.TrimSpace(call.RequestedServiceTier), "fast") || strings.EqualFold(strings.TrimSpace(call.RequestedServiceTier), "priority")) &&
+ (pricedModelName(call.Model) == "gpt-5.4" || pricedModelName(call.Model) == "gpt-5.5") {
+ call.APIEqKnown = false
+ call.APIEqIssue = "no maintained long-context Fast price for model " + call.Model
+ }
if call.APIEqKnown {
call.APIEqTierPremiumUSD, call.APIEqKnown = requestedTierPremium(call.Model, call.RequestedServiceTier, call.APIEqUSD)
if !call.APIEqKnown {
diff --git a/internal/codex/service_tier_test.go b/internal/codex/service_tier_test.go
index 284bd20..85daf3d 100644
--- a/internal/codex/service_tier_test.go
+++ b/internal/codex/service_tier_test.go
@@ -29,9 +29,9 @@ func TestRequestedTierPremium(t *testing.T) {
{" GPT-6-ASTRA-2026-09-01 ", " PRIORITY ", 3, true},
{"gpt-6-astra", "default", 0, true},
{"gpt-6-astra", "", 0, true},
- {"gpt-6-astra", "flex", 0, false},
+ {"gpt-6-astra", "flex", -1.5, true},
{"gpt-6-astra-preview", "fast", 0, false},
- {"gpt-5.4", "fast", 0, false},
+ {"gpt-5.4", "fast", 3, true},
{"unknown", "fast", 0, false},
} {
t.Run(test.model+test.tier, func(t *testing.T) {
@@ -206,3 +206,28 @@ func TestTierAccountingIsPerSession(t *testing.T) {
}
}
}
+
+func TestVerifiedTierPricingForAstraAndFallbacks(t *testing.T) {
+ for _, input := range []int64{272000, 272001} {
+ u := BenchmarkUsage{InputTokens: input, CachedInputTokens: 1000, CacheWriteInputTokens: 2000, OutputTokens: 100, ReasoningOutputTokens: 80, TotalTokens: input + 100}
+ standard, _, _ := EstimateStandardAPIEqCost("gpt-6-astra", u)
+ for tier, factor := range map[string]float64{"default": 1, "fast": 2, "ultrafast": 6, "flex": 0.5} {
+ r := &LiveUsageReader{}
+ call := LiveModelCall{Model: "gpt-6-astra", RequestedServiceTier: tier}
+ r.finalizeCallPricing(&call, u)
+ if !call.APIEqKnown || r.apiEqUnknownCalls != 0 || math.Abs((r.apiEqUSD+r.apiEqTierPremiumUSD)-standard*factor) > 1e-12 {
+ t.Fatal("tier lost token classes or context boundary", input, tier, call)
+ }
+ }
+ }
+ u := BenchmarkUsage{InputTokens: 1000, CachedInputTokens: 100, OutputTokens: 100, TotalTokens: 1100}
+ cost, known, _ := EstimateStandardAPIEqCost("gpt-5.2-2025-12-11", u)
+ if !known || math.Abs(cost-(900*1.75+100*.175+100*14)/1e6) > 1e-12 {
+ t.Fatal("fallback snapshot not priced", cost, known)
+ }
+ for _, model := range []string{"gpt-reserve", "openai.gpt-6-astra", "gpt-6-astra-preview"} {
+ if _, known, _ := EstimateStandardAPIEqCost(model, u); known {
+ t.Fatal("unverified model/provider mapping guessed", model)
+ }
+ }
+}
diff --git a/internal/codex/usage_diagnostics.go b/internal/codex/usage_diagnostics.go
new file mode 100644
index 0000000..bab07d1
--- /dev/null
+++ b/internal/codex/usage_diagnostics.go
@@ -0,0 +1,78 @@
+package codex
+
+import (
+ "strings"
+ "time"
+)
+
+type APIEqIssueKind string
+
+const (
+ UsageIssueUnpriced APIEqIssueKind = "UNPRICED USAGE"
+ UsageIssueMissing APIEqIssueKind = "MISSING RESPONSE USAGE"
+ UsageIssueInconsistent APIEqIssueKind = "INCONSISTENT RESPONSE USAGE"
+)
+
+// A bounded, process-local diagnostic contains accounting metadata only.
+// Counter belongs to Kind; it prevents old failures attaching to new intervals.
+type APIEqDiagnostic struct {
+ Kind APIEqIssueKind
+ ObservedAt time.Time
+ At time.Time
+ Counter int64
+ SessionID string
+ Model string
+ ModelBasis string
+ Tier string
+ Effort string
+ Source string
+ ResponseID string
+ Reason string
+}
+
+func (r *LiveUsageReader) rememberCallIssue(call LiveModelCall) {
+ kind := call.issueKind
+ if kind == "" {
+ kind = UsageIssueUnpriced
+ }
+ counter := r.apiEqUnknownCalls
+ if kind == UsageIssueMissing {
+ counter = r.apiEqMissingUsageCalls
+ }
+ if kind == UsageIssueInconsistent {
+ counter = r.apiEqInconsistentUsageCalls
+ }
+ r.apiEqDiagnostics = appendBounded(r.apiEqDiagnostics, APIEqDiagnostic{
+ Kind: kind, Counter: counter, ObservedAt: time.Now(), At: call.At, SessionID: call.SessionID, Model: call.Model, ModelBasis: call.ModelBasis, Tier: call.RequestedServiceTier,
+ Effort: call.Effort, Source: call.UsageSource, ResponseID: call.ResponseID, Reason: call.APIEqIssue}, 32)
+}
+
+// DiagnosticText is safe for terminal output and browser text. Preserve model
+// and tier identifiers without retaining request content or arbitrary errors.
+func DiagnosticText(issue APIEqDiagnostic) string {
+ field := func(value string, limit int) string {
+ value = strings.Join(strings.Fields(SanitizeSessionContext(value)), " ")
+ runes := []rune(value)
+ if len(runes) > limit {
+ value = string(runes[:limit]) + "…"
+ }
+ if value == "" {
+ return "unknown"
+ }
+ return value
+ }
+ basis := issue.ModelBasis
+ if basis == "" {
+ basis = "requested"
+ }
+ result := string(issue.Kind) + " // " + field(issue.Reason, 180) + "\n" +
+ "MODEL " + field(issue.Model, 96) + " (" + field(basis, 32) + ") // TIER " + field(issue.Tier, 32) + " // EFFORT " + field(issue.Effort, 16) + "\n" +
+ "SESSION " + field(issue.SessionID, 12) + " // SOURCE " + field(issue.Source, 48)
+ if issue.ResponseID != "" {
+ result += " // RESPONSE " + field(issue.ResponseID, 16)
+ }
+ if !issue.At.IsZero() {
+ result += " // AT " + issue.At.UTC().Format(time.RFC3339)
+ }
+ return result
+}
diff --git a/internal/ui/benchmark_quota.go b/internal/ui/benchmark_quota.go
index 4c3eeca..8ac0c8a 100644
--- a/internal/ui/benchmark_quota.go
+++ b/internal/ui/benchmark_quota.go
@@ -4,6 +4,7 @@ import (
"fmt"
"math"
"strings"
+ "time"
"charm.land/lipgloss/v2"
@@ -19,15 +20,18 @@ type benchmarkBillingProvider interface {
// ephemeral benchmark calls. These calls never enter the persisted rollout
// reader, but subscription-funded calls do move the account quota windows.
type benchmarkQuotaAccounting struct {
- billingSource codex.BenchmarkBillingSource
- revision uint64
- runSequence uint64
- active bool
- settling bool
- costUSD float64
- pricedCalls int64
- unpricedCalls int64
- accounted map[string]struct{}
+ billingSource codex.BenchmarkBillingSource
+ revision uint64
+ runSequence uint64
+ active bool
+ settling bool
+ costUSD float64
+ pricedCalls int64
+ unpricedCalls int64
+ missingCalls int64
+ inconsistentCalls int64
+ diagnostics []codex.APIEqDiagnostic
+ accounted map[string]struct{}
}
func benchmarkQuotaAccountingFor(runner BenchmarkRunner) benchmarkQuotaAccounting {
@@ -62,11 +66,15 @@ func (a *benchmarkQuotaAccounting) settle() {
a.settling = false
}
-func (a *benchmarkQuotaAccounting) abandonActiveResult() {
+func (a *benchmarkQuotaAccounting) abandonActiveResult(results ...codex.BenchmarkResult) {
if a.billingSource != codex.BenchmarkBillingSubscription || !a.active {
return
}
- a.unpricedCalls++
+ result := codex.BenchmarkResult{}
+ if len(results) > 0 {
+ result = results[0]
+ }
+ a.recordIssue(result, codex.UsageIssueMissing, "benchmark cancelled before measured usage was available")
a.revision++
}
@@ -80,7 +88,7 @@ func (a *benchmarkQuotaAccounting) observe(result codex.BenchmarkResult) {
}
a.accounted[key] = struct{}{}
- cost, known := benchmarkQuotaCost(result)
+ cost, known, kind, reason := benchmarkQuotaCostDetail(result)
calls := int64(len(result.ResponseUsage))
if calls == 0 {
calls = 1
@@ -91,34 +99,95 @@ func (a *benchmarkQuotaAccounting) observe(result codex.BenchmarkResult) {
a.revision++
return
}
- a.unpricedCalls += calls
+ for i := int64(0); i < calls; i++ {
+ a.recordIssue(result, kind, reason)
+ }
a.revision++
}
-func benchmarkQuotaCost(result codex.BenchmarkResult) (float64, bool) {
- if result.CostKnown && validBenchmarkQuotaCost(result.CostUSD) {
- return result.CostUSD, true
+func benchmarkQuotaCostDetail(result codex.BenchmarkResult) (float64, bool, codex.APIEqIssueKind, string) {
+ if result.CostKnown {
+ if validBenchmarkQuotaCost(result.CostUSD) {
+ return result.CostUSD, true, "", ""
+ }
+ return 0, false, codex.UsageIssueInconsistent, "benchmark returned an invalid measured cost"
}
model := strings.TrimSpace(result.ActualModel)
if model == "" {
model = result.Model
}
if !result.UsageKnown {
- return 0, false
+ if result.UsageIssue != "" {
+ kind := codex.UsageIssueInconsistent
+ if strings.Contains(result.UsageIssue, "omitted") || strings.Contains(result.UsageIssue, "not observed") {
+ kind = codex.UsageIssueMissing
+ }
+ return 0, false, kind, result.UsageIssue
+ }
+ return 0, false, codex.UsageIssueMissing, "benchmark omitted validated response usage"
}
if result.UsageSource == codex.BenchmarkUsageRawResponses && len(result.ResponseUsage) > 0 {
var total float64
for _, response := range result.ResponseUsage {
- cost, known, _ := codex.EstimateStandardAPIEqCost(model, response.Usage)
+ responseModel := response.Model
+ if responseModel == "" {
+ responseModel = model
+ }
+ cost, known, issue := codex.EstimateStandardAPIEqCost(responseModel, response.Usage)
if !known {
- return 0, false
+ return 0, false, benchmarkCostIssueKind(issue), issue
}
total += cost
}
- return total, validBenchmarkQuotaCost(total)
+ return total, validBenchmarkQuotaCost(total), codex.UsageIssueInconsistent, "benchmark cost total was not finite"
+ }
+ cost, known, issue := codex.EstimateStandardAPIEqAggregateCost(model, result.Usage)
+ return cost, known && validBenchmarkQuotaCost(cost), benchmarkCostIssueKind(issue), issue
+}
+
+func benchmarkCostIssueKind(reason string) codex.APIEqIssueKind {
+ if strings.HasPrefix(reason, "invalid usage:") {
+ return codex.UsageIssueInconsistent
+ }
+ return codex.UsageIssueUnpriced
+}
+
+func (a *benchmarkQuotaAccounting) recordIssue(result codex.BenchmarkResult, kind codex.APIEqIssueKind, reason string) {
+ var counter int64
+ switch kind {
+ case codex.UsageIssueMissing:
+ a.missingCalls++
+ counter = a.missingCalls
+ case codex.UsageIssueInconsistent:
+ a.inconsistentCalls++
+ counter = a.inconsistentCalls
+ default:
+ kind = codex.UsageIssueUnpriced
+ a.unpricedCalls++
+ counter = a.unpricedCalls
+ }
+ model := result.ActualModel
+ if model == "" {
+ model = result.Model
+ }
+ responseID := ""
+ if !result.CostKnown && result.UsageKnown && result.UsageSource == codex.BenchmarkUsageRawResponses {
+ for _, response := range result.ResponseUsage {
+ responseModel := response.Model
+ if responseModel == "" {
+ responseModel = model
+ }
+ if _, known, _ := codex.EstimateStandardAPIEqCost(responseModel, response.Usage); !known {
+ model = responseModel
+ responseID = response.ResponseID
+ break
+ }
+ }
+ }
+ a.diagnostics = append(a.diagnostics, codex.APIEqDiagnostic{Kind: kind, Counter: counter, ObservedAt: time.Now(), At: time.Now(), SessionID: "benchmark", Model: model, Effort: result.Effort, Source: "subscription benchmark", ResponseID: responseID, Reason: reason})
+ if len(a.diagnostics) > 32 {
+ a.diagnostics = a.diagnostics[len(a.diagnostics)-32:]
}
- cost, known, _ := codex.EstimateStandardAPIEqAggregateCost(model, result.Usage)
- return cost, known && validBenchmarkQuotaCost(cost)
}
func validBenchmarkQuotaCost(cost float64) bool {
@@ -134,7 +203,31 @@ func (a benchmarkQuotaAccounting) combine(usage codex.LiveUsageSnapshot) codex.L
// Benchmark results remain a standard-price comparison; their service
// tier is not established by the benchmark result contract.
usage.APIEqUnknownTierCalls += a.pricedCalls
+ all := append(append([]codex.APIEqDiagnostic(nil), usage.APIEqDiagnostics...), a.diagnostics...)
+ usage.APIEqMissingUsageCalls += a.missingCalls
+ usage.APIEqInconsistentUsageCalls += a.inconsistentCalls
usage.APIEqUnpricedCalls += a.unpricedCalls
+ usage.APIEqDiagnostics = nil
+ for _, kind := range []codex.APIEqIssueKind{codex.UsageIssueUnpriced, codex.UsageIssueMissing, codex.UsageIssueInconsistent} {
+ var latest codex.APIEqDiagnostic
+ for _, diagnostic := range all {
+ if diagnostic.Kind == kind && (latest.Kind == "" || diagnostic.ObservedAt.After(latest.ObservedAt)) {
+ latest = diagnostic
+ }
+ }
+ if latest.Kind == "" {
+ continue
+ }
+ switch kind {
+ case codex.UsageIssueMissing:
+ latest.Counter = usage.APIEqMissingUsageCalls
+ case codex.UsageIssueInconsistent:
+ latest.Counter = usage.APIEqInconsistentUsageCalls
+ default:
+ latest.Counter = usage.APIEqUnpricedCalls
+ }
+ usage.APIEqDiagnostics = append(usage.APIEqDiagnostics, latest)
+ }
if a.active {
usage.APIEqPendingCalls++
}
diff --git a/internal/ui/benchmark_quota_test.go b/internal/ui/benchmark_quota_test.go
index 5075de7..02770cb 100644
--- a/internal/ui/benchmark_quota_test.go
+++ b/internal/ui/benchmark_quota_test.go
@@ -55,6 +55,7 @@ func TestSubscriptionBenchmarkAccountingFailsClosedForUnknownCost(t *testing.T)
accounting.start()
accounting.observe(codex.BenchmarkResult{
TaskID: codex.BenchmarkDigBench, TaskName: "DIGBENCH P-6", Model: "future-model", Effort: "high",
+ UsageKnown: true, Usage: codex.BenchmarkUsage{InputTokens: 100, OutputTokens: 10, TotalTokens: 110},
})
accounting.finish()
combined := accounting.combine(codex.LiveUsageSnapshot{})
@@ -72,7 +73,7 @@ func TestSubscriptionBenchmarkAccountingRejectsInvalidKnownCost(t *testing.T) {
})
accounting.finish()
combined := accounting.combine(codex.LiveUsageSnapshot{})
- if combined.APIEqUSD != 0 || combined.APIEqPricedCalls != 0 || combined.APIEqUnpricedCalls != 1 {
+ if combined.APIEqUSD != 0 || combined.APIEqPricedCalls != 0 || combined.APIEqInconsistentUsageCalls != 1 || combined.APIEqUnpricedCalls != 0 {
t.Fatalf("invalid known benchmark cost was accepted: %#v", combined)
}
}
@@ -89,7 +90,7 @@ func TestSubscriptionBenchmarkAccountingRejectsUnvalidatedResponseUsage(t *testi
})
accounting.finish()
combined := accounting.combine(codex.LiveUsageSnapshot{})
- if combined.APIEqUSD != 0 || combined.APIEqPricedCalls != 0 || combined.APIEqUnpricedCalls != 1 {
+ if combined.APIEqUSD != 0 || combined.APIEqPricedCalls != 0 || combined.APIEqMissingUsageCalls != 1 || combined.APIEqUnpricedCalls != 0 {
t.Fatalf("unvalidated response usage was accepted: %#v", combined)
}
}
@@ -115,8 +116,8 @@ func TestSubscriptionBenchmarkAccountingFailsClosedForAbandonedActiveResult(t *t
accounting.abandonActiveResult()
accounting.finish()
combined := accounting.combine(codex.LiveUsageSnapshot{})
- if combined.APIEqUnpricedCalls != 1 || combined.APIEqPricedCalls != 0 || combined.APIEqUSD != 0 {
- t.Fatalf("abandoned benchmark result was not marked unpriced: %#v", combined)
+ if combined.APIEqMissingUsageCalls != 1 || combined.APIEqUnpricedCalls != 0 || combined.APIEqPricedCalls != 0 || combined.APIEqUSD != 0 {
+ t.Fatalf("abandoned benchmark result was not marked as missing response usage: %#v", combined)
}
}
@@ -249,3 +250,31 @@ func TestSubscriptionBenchmarkRerunIsAccountedAgain(t *testing.T) {
t.Fatalf("rerun accounting = %#v", combined)
}
}
+
+func TestBenchmarkDiagnosticDoesNotMaskNewerSessionFailure(t *testing.T) {
+ a := benchmarkQuotaAccounting{billingSource: codex.BenchmarkBillingSubscription}
+ a.start()
+ a.observe(codex.BenchmarkResult{Model: "unknown-benchmark", UsageKnown: true, Usage: codex.BenchmarkUsage{InputTokens: 100, OutputTokens: 10, TotalTokens: 110}})
+ old := a.diagnostics[0].ObservedAt
+ current := codex.APIEqDiagnostic{Kind: codex.UsageIssueUnpriced, Counter: 1, Model: "unknown-live", SessionID: "live", Source: "exact response", ObservedAt: old.Add(time.Second)}
+ combined := a.combine(codex.LiveUsageSnapshot{APIEqUnpricedCalls: 1, APIEqDiagnostics: []codex.APIEqDiagnostic{current}})
+ if len(combined.APIEqDiagnostics) != 1 || combined.APIEqDiagnostics[0].Model != "unknown-live" || combined.APIEqDiagnostics[0].Counter != 2 {
+ t.Fatal("stale benchmark masked live failure", combined)
+ }
+}
+
+func TestBenchmarkFailureIdentifiesEarlierResponseModelAndCancellationTrial(t *testing.T) {
+ a := benchmarkQuotaAccounting{billingSource: codex.BenchmarkBillingSubscription}
+ a.start()
+ usage := codex.BenchmarkUsage{InputTokens: 100, OutputTokens: 10, TotalTokens: 110}
+ a.observe(codex.BenchmarkResult{Model: "gpt-6-astra", ActualModel: "gpt-6-astra", Effort: "xhigh", UsageKnown: true, UsageSource: codex.BenchmarkUsageRawResponses, ResponseUsage: []codex.BenchmarkResponseUsage{{ResponseID: "failed", Model: "gpt-reserve", Usage: usage}, {ResponseID: "later", Model: "gpt-6-astra", Usage: usage}}})
+ issue := a.diagnostics[len(a.diagnostics)-1]
+ if issue.Model != "gpt-reserve" || issue.ResponseID != "failed" {
+ t.Fatal("failure attributed to final model rather than offending response", issue)
+ }
+ a.abandonActiveResult(codex.BenchmarkResult{Model: "gpt-6-astra", Effort: "xhigh"})
+ issue = a.diagnostics[len(a.diagnostics)-1]
+ if issue.Kind != codex.UsageIssueMissing || issue.Model != "gpt-6-astra" || issue.Effort != "xhigh" {
+ t.Fatal("cancellation lost known trial metadata", issue)
+ }
+}
diff --git a/internal/ui/english_snapshot_test.go b/internal/ui/english_snapshot_test.go
index bfab44d..0c93121 100644
--- a/internal/ui/english_snapshot_test.go
+++ b/internal/ui/english_snapshot_test.go
@@ -38,8 +38,8 @@ func TestEnglishPresentationSnapshot(t *testing.T) {
got := fmt.Sprintf("%x", hash.Sum(nil))
// Baseline includes Pace graph controls, explicit panel/border
// backgrounds and Sessions Zero/Close All; every theme, view and size
- // remains covered.
- const want = "19ec27af5176579e3145b5af72749d86f293f9ab00e7d3358970eeee0b513e50"
+ // remains covered. The displayed pricing review date is now 2026-10-12.
+ const want = "fc7b2b5381dd43bac332748c9fca6ac4c53abfacb130bfa49de64e76fe27f4ba"
if got != want {
t.Fatalf("English presentation changed: got %s, want %s", got, want)
}
diff --git a/internal/ui/model.go b/internal/ui/model.go
index 0c31655..5c6585b 100644
--- a/internal/ui/model.go
+++ b/internal/ui/model.go
@@ -1224,7 +1224,7 @@ func (m Model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
case benchmarkEventMsg:
if !message.ok {
if m.benchmarkActive != nil {
- m.benchmarkQuotaAccounting.abandonActiveResult()
+ m.benchmarkQuotaAccounting.abandonActiveResult(*m.benchmarkActive)
}
if m.benchmarkState == benchmarkStopping {
m.benchmarkState = benchmarkStopped
@@ -1288,7 +1288,7 @@ func (m Model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
}
if event.Done {
if m.benchmarkActive != nil && event.Result == nil {
- m.benchmarkQuotaAccounting.abandonActiveResult()
+ m.benchmarkQuotaAccounting.abandonActiveResult(*m.benchmarkActive)
}
if event.Stopped {
m.benchmarkState = benchmarkStopped
@@ -1620,6 +1620,7 @@ func (m Model) dashboardLayout() dashboardGeometry {
const footerHeight = 2
extraHeight := 0
extraHeight += m.resetNoticeHeight(contentWidth)
+ extraHeight += m.quotaAPIDiagnosticHeight(contentWidth)
if m.err != nil && m.meterView != viewUsage {
extraHeight += framedErrorHeight
}
diff --git a/internal/ui/quota_api_eq.go b/internal/ui/quota_api_eq.go
index 2464bea..0470c7e 100644
--- a/internal/ui/quota_api_eq.go
+++ b/internal/ui/quota_api_eq.go
@@ -60,6 +60,7 @@ type quotaAPIAnchor struct {
inconsistentUsageCalls int64
accountingAdjustments int64
restartReason string
+ restartIssue codex.APIEqDiagnostic
}
const (
@@ -144,7 +145,7 @@ func (m *Model) observeQuotaAPIEq(snapshot codex.Snapshot, usage codex.LiveUsage
continue
}
if current.costUSD < anchor.costUSD || current.pricedCalls < anchor.pricedCalls ||
- current.unpricedCalls < anchor.unpricedCalls || current.premiumUSD < anchor.premiumUSD ||
+ current.unpricedCalls < anchor.unpricedCalls ||
current.unknownTierCalls < anchor.unknownTierCalls ||
current.missingUsageCalls < anchor.missingUsageCalls ||
current.inconsistentUsageCalls < anchor.inconsistentUsageCalls ||
@@ -164,6 +165,7 @@ func (m *Model) observeQuotaAPIEq(snapshot codex.Snapshot, usage codex.LiveUsage
}
if current.unpricedCalls > anchor.unpricedCalls {
current.restartReason = quotaAPIRestartUnpricedUsage
+ current.restartIssue = latestIntervalDiagnostic(usage, codex.UsageIssueUnpriced, anchor.unpricedCalls)
m.quotaAPIAnchors[key] = current
m.quotaAPIIssues[key] = ""
continue
@@ -171,8 +173,10 @@ func (m *Model) observeQuotaAPIEq(snapshot codex.Snapshot, usage codex.LiveUsage
switch {
case current.missingUsageCalls > anchor.missingUsageCalls:
current.restartReason = quotaAPIRestartMissingUsage
+ current.restartIssue = latestIntervalDiagnostic(usage, codex.UsageIssueMissing, anchor.missingUsageCalls)
case current.inconsistentUsageCalls > anchor.inconsistentUsageCalls:
current.restartReason = quotaAPIRestartInconsistentUsage
+ current.restartIssue = latestIntervalDiagnostic(usage, codex.UsageIssueInconsistent, anchor.inconsistentUsageCalls)
case current.accountingAdjustments > anchor.accountingAdjustments:
current.restartReason = quotaAPIRestartAccountingRebased
}
@@ -272,7 +276,7 @@ func validQuotaAPISamples(samples []quotaAPISample, now time.Time) []quotaAPISam
sample.DeltaPercent < quotaAPIMinimumDelta || !positiveFinite(sample.CapacityUSD) ||
!positiveFinite(sample.LowUSD) || !positiveFinite(sample.HighUSD) ||
math.IsNaN(sample.PremiumCapacityUSD) || math.IsInf(sample.PremiumCapacityUSD, 0) ||
- sample.PremiumCapacityUSD < 0 || sample.PremiumCapacityUSD >= sample.CapacityUSD ||
+ sample.PremiumCapacityUSD >= sample.CapacityUSD ||
sample.LowUSD > sample.CapacityUSD || sample.CapacityUSD > sample.HighUSD {
continue
}
@@ -329,7 +333,7 @@ func (m Model) quotaAPIEstimate(snapshot codex.Snapshot, meter codex.Meter) (quo
highs = append(highs, sample.HighUSD)
centers = append(centers, sample.CapacityUSD)
standardCenters = append(standardCenters, sample.CapacityUSD-sample.PremiumCapacityUSD)
- hasPremium = hasPremium || sample.PremiumCapacityUSD > 0
+ hasPremium = hasPremium || sample.PremiumCapacityUSD != 0
unknownTier = unknownTier || sample.UnknownTier
totalDelta += sample.DeltaPercent
}
@@ -515,3 +519,74 @@ func formatUSD(value float64) string {
return fmt.Sprintf("$%.0f", value)
}
}
+
+func latestIntervalDiagnostic(usage codex.LiveUsageSnapshot, kind codex.APIEqIssueKind, after int64) codex.APIEqDiagnostic {
+ for i := len(usage.APIEqDiagnostics) - 1; i >= 0; i-- {
+ issue := usage.APIEqDiagnostics[i]
+ if issue.Kind == kind && issue.Counter > after {
+ return issue
+ }
+ }
+ return codex.APIEqDiagnostic{}
+}
+
+func (m Model) quotaAPIDiagnostic() codex.APIEqDiagnostic {
+ if !m.meterView.isQuota() {
+ return codex.APIEqDiagnostic{}
+ }
+ for _, meter := range m.snapshot.Meters() {
+ if quotaAPIMeterEligible(m.snapshot, meter) {
+ if issue := m.quotaAPIAnchors[quotaAPIKey(m.snapshot, meter)].restartIssue; issue.Kind != "" {
+ return issue
+ }
+ }
+ }
+ return codex.APIEqDiagnostic{}
+}
+
+func (m Model) renderQuotaAPIDiagnostic(width int) string {
+ issue := m.quotaAPIDiagnostic()
+ if issue.Kind == "" {
+ return ""
+ }
+ c := paletteFor(m.theme)
+ text := codex.DiagnosticText(issue)
+ lines := strings.Split(ansi.Hardwrap(text, max(width-4, 1), true), "\n")
+ // A diagnostic must not push the footer off a short terminal. Preserve the
+ // reason first, with bounded metadata rows; the browser retains the full text.
+ height := m.height
+ if height == 0 {
+ height = 24
+ }
+ header := 3
+ if width < 64 {
+ header = 2
+ }
+ tabs := 2
+ if isQuotaGraph(m.meterView) {
+ tabs++
+ }
+ meters := len(m.snapshot.Meters())
+ columns := meterGridColumns(width, max(height-2, 1), meters, m.meterView)
+ minimumMeters := ((meters + columns - 1) / columns) * 3
+ available := height - 2 - header - 1 - tabs - 2 - minimumMeters - m.resetNoticeHeight(width)
+ if m.err != nil {
+ available -= 3
+ }
+ if available < 3 {
+ return ""
+ }
+ limit := min(max(height/3-2, 1), available-2)
+ if len(lines) > limit {
+ lines = lines[:limit]
+ lines[len(lines)-1] = ansi.Truncate(lines[len(lines)-1], max(width-5, 1), "") + "…"
+ }
+ return frame(width, "API-EQ ISSUE", c.label().Render(strings.Join(lines, "\n")), c.primary, c)
+}
+
+func (m Model) quotaAPIDiagnosticHeight(width int) int {
+ if view := m.renderQuotaAPIDiagnostic(width); view != "" {
+ return strings.Count(view, "\n") + 1
+ }
+ return 0
+}
diff --git a/internal/ui/quota_api_eq_test.go b/internal/ui/quota_api_eq_test.go
index 883f559..4916e2b 100644
--- a/internal/ui/quota_api_eq_test.go
+++ b/internal/ui/quota_api_eq_test.go
@@ -433,3 +433,63 @@ func TestQuotaAccountingBracketIncludesUsageIssuesAndAdjustments(t *testing.T) {
}
}
}
+
+func TestQuotaFlexDiscountLearnsWithoutFalseRebase(t *testing.T) {
+ now := time.Now()
+ reset := now.Add(4 * time.Hour).Unix()
+ m := New(nil, time.Minute)
+ m.snapshot = apiEqSnapshot(10, reset)
+ m.observeQuotaAPIEq(m.snapshot, codex.LiveUsageSnapshot{}, now)
+ m.snapshot = apiEqSnapshot(15, reset)
+ m.observeQuotaAPIEq(m.snapshot, codex.LiveUsageSnapshot{APIEqUSD: 2, APIEqTierPremiumUSD: -1, APIEqPricedCalls: 1}, now.Add(time.Minute))
+ estimate, ok := m.quotaAPIEstimate(m.snapshot, m.snapshot.Meters()[0])
+ if !ok || !estimate.hasPremium || math.Abs(estimate.standardFull-40) > 1e-12 {
+ t.Fatal("discount mistaken for accounting regression", m.quotaAPIAnchors, estimate)
+ }
+ if !strings.Contains(m.quotaAPILine(m.snapshot.Meters()[0], 120), "TIER*") {
+ t.Fatal("discount lost requested-tier qualifier")
+ }
+}
+
+func TestQuotaFailureDiagnosticRetainsSourceAndRejectsOldAttribution(t *testing.T) {
+ now := time.Now()
+ reset := now.Add(4 * time.Hour).Unix()
+ m := New(nil, time.Minute)
+ m.width, m.height = 100, 35
+ m.loading = false
+ m.snapshot = apiEqSnapshot(10, reset)
+ m.observeQuotaAPIEq(m.snapshot, codex.LiveUsageSnapshot{APIEqUnpricedCalls: 1}, now)
+ m.snapshot = apiEqSnapshot(12, reset)
+ issue := codex.APIEqDiagnostic{Kind: codex.UsageIssueUnpriced, Counter: 2, SessionID: "child-agent", Model: "gpt-reserve", Tier: "fast", Effort: "xhigh", Source: "exact response", Reason: "no maintained standard API price for model gpt-reserve"}
+ m.observeQuotaAPIEq(m.snapshot, codex.LiveUsageSnapshot{APIEqUnpricedCalls: 2, APIEqDiagnostics: []codex.APIEqDiagnostic{issue}}, now.Add(time.Minute))
+ view := ansi.Strip(m.render())
+ for _, want := range []string{"UNPRICED USAGE", "child-agent", "gpt-reserve", "fast", "xhigh", "exact response", "no maintained standard API price"} {
+ if !strings.Contains(view, want) {
+ t.Fatal("diagnostic omitted", want, view)
+ }
+ }
+ m.snapshot = apiEqSnapshot(13, reset)
+ m.observeQuotaAPIEq(m.snapshot, codex.LiveUsageSnapshot{APIEqUnpricedCalls: 3, APIEqDiagnostics: []codex.APIEqDiagnostic{issue}}, now.Add(2*time.Minute))
+ if m.quotaAPIDiagnostic().Kind != "" {
+ t.Fatal("old diagnostic assigned to a new failure")
+ }
+}
+
+func TestQuotaDiagnosticPreservesFooterAcrossTerminalSizes(t *testing.T) {
+ now := time.Now()
+ reset := now.Add(time.Hour).Unix()
+ for _, size := range [][2]int{{40, 16}, {80, 18}, {80, 24}, {120, 35}} {
+ m := New(nil, time.Minute)
+ m.width, m.height = size[0], size[1]
+ m.loading = false
+ m.snapshot = apiEqSnapshot(10, reset)
+ m.observeQuotaAPIEq(m.snapshot, codex.LiveUsageSnapshot{}, now)
+ m.snapshot = apiEqSnapshot(12, reset)
+ issue := codex.APIEqDiagnostic{Kind: codex.UsageIssueUnpriced, Counter: 1, SessionID: "child", Model: "gpt-reserve", Tier: "fast", Source: "exact response", Reason: "no maintained standard API price for model gpt-reserve"}
+ m.observeQuotaAPIEq(m.snapshot, codex.LiveUsageSnapshot{APIEqUnpricedCalls: 1, APIEqDiagnostics: []codex.APIEqDiagnostic{issue}}, now.Add(time.Second))
+ view := ansi.Strip(m.render())
+ if strings.Count(view, "\n")+1 > size[1] {
+ t.Fatal("diagnostic pushed controls off screen", size, view)
+ }
+ }
+}
diff --git a/internal/ui/view.go b/internal/ui/view.go
index 4406add..f1d4fd3 100644
--- a/internal/ui/view.go
+++ b/internal/ui/view.go
@@ -67,6 +67,9 @@ func (m Model) render() string {
if m.meterView.isQuota() && m.resetNotice != "" {
parts = append(parts, m.renderResetNotice(contentWidth))
}
+ if diagnostic := m.renderQuotaAPIDiagnostic(contentWidth); diagnostic != "" {
+ parts = append(parts, diagnostic)
+ }
meters := m.snapshot.Meters()
if m.meterView.isQuota() && m.meterView != viewResets && m.meterView != viewThresholds {
meters = m.quotaMetersWithInsights(contentWidth)
diff --git a/internal/web/dist/assets/index-Bd-Jwk4i.js b/internal/web/dist/assets/index-BWH3mrUB.js
similarity index 77%
rename from internal/web/dist/assets/index-Bd-Jwk4i.js
rename to internal/web/dist/assets/index-BWH3mrUB.js
index ea7c245..96305c6 100644
--- a/internal/web/dist/assets/index-Bd-Jwk4i.js
+++ b/internal/web/dist/assets/index-BWH3mrUB.js
@@ -5,41 +5,42 @@
observation.
`),xa=J(`
`),Sa=J(`
The longest Codex quota window selects one active model profile. ASK
creates a per-session review; AUTO applies the profile on the next
eligible check.
`,1),Ca=J(`
No threshold-based model steps were configured at launch.
`),No=J(``);function Po(e,t){let n=Pr();Ue(t,!0);let r=e=>{var t=Nr();Xr(B(t),19,()=>K(fe),e=>e.id,(e,t,r)=>{var i=so();let o;var s=z(i),c=V(s,!0),l=H(s),u=V(l),d=H(l),f=e=>{var n=oo(),r=V(n,!0);U(()=>X(r,K(t).help)),Y(e,n)};Z(d,e=>{(K(v)?.path===``||K(A))&&e(f)}),P(i),U((e,s)=>{Q(i,`id`,`${n}-${K(r)}`),Q(i,`role`,K(A)?`option`:void 0),Q(i,`aria-selected`,K(A)?K(T)===K(r):void 0),Q(i,`tabindex`,K(A)?-1:void 0),i.disabled=K(g)||K(he)&&!a(),Q(i,`title`,K(t).help),Q(i,`aria-label`,e),o=ci(i,1,`svelte-7bfwr9`,null,o,{suggested:K(T)===K(r)}),X(c,K(t).label),X(u,`${K(A)&&K(t).selected?` // CURRENT`:``}${s??``}`)},[()=>K(t).label+(K(A)&&K(t).selected?` // CURRENT`:``)+ie(K(t)),()=>ie(K(t))]),xr(`focus`,i,()=>{K(A)||_e(K(r))}),q(`click`,i,()=>{_e(K(r)),ye(K(t))}),Y(e,i)}),Y(e,t)},i=Wi(t,`query`,3,``),a=Wi(t,`localOnly`,3,!1),o=Wi(t,`oncopy`,3,()=>{}),s=Wi(t,`onchange`,3,()=>{}),c=Wi(t,`oncomplete`,3,e=>{}),l=[`statusline`,`usage`,`copy`,`theme`,`exit`,`quit`];function u(){return[{id:`local-statusline`,label:`/statusline`,help:`Choose fields for Codexometer’s detail footer.`,next:`statusline`},{id:`local-usage`,label:`/usage`,help:`Open Codexometer’s usage history. Quota and reset views remain available.`,next:`usage`},{id:`local-copy`,label:`/copy`,help:`Copy the selected session’s observed reply or activity with its Copy control.`,next:`copy`},{id:`local-theme`,label:`/theme`,help:`Open the existing Codexometer theme selector. Saved browser display preferences only.`,next:`theme`},{id:`local-exit`,label:`/exit`,help:`Leave session detail and return to Sessions. The local server remains running.`,next:`exit`},{id:`local-quit`,label:`/quit`,help:`Alias for /exit: return to Sessions. The local server remains running.`,next:`quit`}]}function d(){return{title:`/ COMMANDS`,help:`Local Codexometer commands remain available without session control.`,path:``,revision:``,choices:u()}}function f(){R(b,``),R(O,``),R(x,0),R(k,[],!0)}function p(){w++,R(g,!1),R(h,!1),R(E,i()),f(),R(_,``),K(ue)?s()():c()(i())}async function m(e){if(!l.includes(e))return!1;if(e===`copy`&&!ao($.data?.sessions.find(e=>e.id===t.session)))return R(_,`No reply or activity text is available to copy for this session.`),!0;if(e===`copy`){let e=o()();p(),await e}else p(),e===`usage`?location.hash=`/usage`:e===`theme`?sa.requests++:e===`statusline`?oa.open=!0:location.hash=`/sessions`;return!0}let h=L(!1),g=L(!1),_=L(``),v=L(null),y=L(null),b=L(``),x=L(0),S=L(Yt(Date.now())),C=L(``),w=0,T=L(0),E=L(null),D=L(void 0),ee=L(void 0),te=L(void 0),O=L(``),k=L(Yt([])),ne=F(()=>K(v)?.path.startsWith(`rename/`)||K(v)?.path.startsWith(`cd/`)),re=F(()=>!!K(y)&&!K(ne)||!!K(O)||K(k).length>0);function ie(e){return e.unavailable?e.unavailable.startsWith(`Waiting for idle.`)?` // WAITING FOR IDLE`:` // UNAVAILABLE`:e.next?` →`:e.action?``:` // HELP`}async function ae(e){K(v)&&!(K(ge)&&K(de))&&R(k,[...K(k),{path:K(v).path,index:K(T),input:K(C)}],!0),await N(e)}async function oe(){if(!K(re))return;if(w++,R(g,!1),R(b,``),R(x,0),R(_,``),K(O)){R(O,``),K(D)?.focus();return}if(K(y)&&!K(ne)){R(y,null),await lr(),K(D)?.focus();return}let e=K(k).at(-1);e&&(R(k,K(k).slice(0,-1),!0),await N(e.path,e))}function se(){K(v)&&K(C).trim()&&!K(g)&&!K(he)&&ae(K(v).path+`/`+encodeURIComponent(K(C).trim()))}let A=F(()=>K(h)&&!!K(v)?.picker&&!K(y)),ce=F(()=>K(h)&&!K(v)?.input&&!K(y)),le=setInterval(()=>{R(S,Date.now(),!0)},1e3);Ki(()=>{clearInterval(le),w++});let ue=F(()=>i().trim().startsWith(`/`)&&!i().trim().startsWith(`//`)),de=F(()=>K(v)?.path===``&&K(ue)?i().trim().slice(1).toLowerCase():``),fe=F(()=>(K(v)?.choices||[]).filter(e=>!K(de)||e.label.toLowerCase().startsWith(`/`+K(de)))),j=F(()=>K(y)||K(fe)[K(T)]),pe=F(()=>!!K(b)&&K(S)K(fe).find(e=>e.id===K(O))),he=F(()=>!$.connected||!!$.data?.sessionsError),ge=F(()=>K(h)&&K(ue)&&(!K(v)||K(v).path===``)&&!K(y));vn(()=>{i(),R(T,0)}),vn(()=>{let e=K(T);K(fe),K(ce)&&lr().then(()=>{let t=K(D)?.children[e];if(!t||!K(D))return;let n=K(D).getBoundingClientRect(),r=t.getBoundingClientRect();r.topn.bottom&&(K(D).scrollTop+=r.bottom-n.bottom)})});function _e(e){K(T)!==e&&K(v)?.picker&&(R(O,``),R(b,``),R(x,0),R(_,``),w++),R(T,e,!0)}function M(){w++,R(g,!1),R(h,!1),R(E,i()),f(),c()(i())}function ve(e){let t=!!K(ee)?.contains(e.target);if(!K(h)||!K(ce)&&!K(y)&&!K(v)?.input||!K(ue)&&!t||K(he)&&!a()||e.isComposing||e.ctrlKey||e.metaKey||e.altKey)return;if(K(v)?.input){e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),M());return}let n=e.key===`ArrowLeft`,r=e.key.toLowerCase()===`f`,i=e.key.toLowerCase()===`c`;if((i||r||n)&&!t||![`ArrowUp`,`ArrowDown`,`Tab`,`Enter`,`Escape`].includes(e.key)&&!i&&!r&&!n||e.key===`Tab`&&(K(y)||K(v)?.path!==``||e.shiftKey)||e.key===`Enter`&&e.target instanceof Element&&e.target.closest(`button`)&&!K(D)?.contains(e.target)&&!e.target.closest(`[data-command-confirm]`)||K(y)&&!t||K(y)&&[`ArrowUp`,`ArrowDown`].includes(e.key))return;if(e.preventDefault(),e.stopPropagation(),e.key===`Escape`){M();return}if(K(g)||e.repeat&&i)return;if(n){K(re)&&oe();return}if(r){N(K(v)?.path||``);return}if(i){(K(y)?.action||K(A)&&K(O))&&xe();return}if(K(y)){e.key===`Enter`&&K(y).action&&!K(pe)&&!K(_)&&be(K(y));return}if(e.key===`ArrowUp`||e.key===`ArrowDown`){_e(Math.min(Math.max(K(T)+(e.key===`ArrowUp`?-1:1),0),Math.max(K(fe).length-1,0))),!K(A)&&K(D)?.contains(e.target)&&lr().then(()=>(K(D)?.children[K(T)])?.focus());return}let o=K(fe)[K(T)];o&&(e.key===`Tab`?c()(o.label):K(A)?be(o):ye(o))}vn(()=>{K(he)&&!a()&&(w++,R(g,!1),f(),K(h)&&(R(h,!1),R(E,i())),R(v,null),R(y,null))}),vn(()=>{K(ue)&&!K(h)&&i()!==K(E)&&(!K(he)||a())&&(f(),R(h,!0),N(``))});async function N(e,n){let r=++w;if(K(v)&&R(v,{...K(v),path:e},!0),n&&R(C,n.input,!0),R(g,!0),R(y,null),R(O,``),R(b,``),R(x,0),R(_,``),a()){R(v,d(),!0),R(T,n?.index??0,!0),R(g,!1);return}try{let i=await va(`commands`,{session:t.session,command:{mode:`list`,path:e}});r===w&&((e===``||e===`help`)&&(i.choices=[...i.choices.filter(e=>!l.includes(e.label.replace(/^\//,``))),...u()]),R(v,i,!0),R(T,n?Math.min(n.index,Math.max(i.choices.length-1,0)):i.picker?Math.max(i.choices.findIndex(e=>e.selected),0):0,!0),i.picker&&lr().then(()=>K(D)?.focus()),R(C,n?.input??i.value??``,!0),n&&lr().then(()=>{i.input?K(ee)?.querySelector(`input`)?.focus():K(D)?.focus()}),(i.path.startsWith(`rename/`)||i.path.startsWith(`cd/`))&&i.choices.length===1&&(R(g,!1),ye(i.choices[0])))}catch{r===w&&(R(_,`Command catalogue unavailable. Use Codex.`),e===``||e===`help`?(R(v,d(),!0),R(_,``)):R(v,{title:`/`+e,help:``,path:e,revision:``,choices:[]},!0))}finally{r===w&&R(g,!1)}}async function ye(e){if(!(e.unavailable||K(g))&&!(e.next&&await m(e.next))&&!K(_)){if(K(v)?.picker){_e(K(fe).findIndex(t=>t.id===e.id)),K(D)?.focus();return}if(e.next){await ae(e.next);return}await be(e)}}async function be(e){if(K(g)||K(he)||!K(v)||e.unavailable||K(_))return;if(K(v).picker){if(K(pe)&&K(O)===e.id)return;R(O,e.id,!0)}else R(y,e,!0),lr().then(()=>K(te)?.focus());if(R(b,``),R(x,0),R(_,``),!e.action)return;let n=++w;R(g,!0);try{let r=await va(`commands`,{session:t.session,command:{mode:`prepare`,path:K(v).path,revision:K(v).revision,choice:e.id}});if(n===w){let e=Date.parse(r.expires);if(!r.confirmation||!Number.isFinite(e)||Date.now()>=e)throw Error(`Review confirmation unavailable`);R(b,r.confirmation,!0),R(x,e,!0)}}catch{n===w&&R(_,`Option changed or unavailable. Refresh before retrying.`)}finally{n===w&&R(g,!1)}}async function xe(){if(!K(b)||K(he)||K(g)||Date.now()>=K(x)||!K(v)||K(v).picker&&K(O)!==K(fe)[K(T)]?.id)return;let e=K(b);R(b,``),R(g,!0);let n=++w;try{let r=await va(`commands`,{session:t.session,confirmation:e,command:{mode:`commit`,path:K(v).path}});n===w&&(R(_,r.message,!0),R(h,!1),R(v,null),R(y,null),f(),R(E,null),s()())}catch{n===w&&R(_,`Change unconfirmed. Check Codex before retrying.`)}finally{n===w&&R(g,!1)}}var Se={handleKey:ve},Ce=No(),we=z(Ce),Te=H(we,2),Ee=e=>{var t=co(),n=V(t,!0);U(()=>X(n,K(_))),Y(e,t)};Z(Te,e=>{K(_)&&!K(h)&&e(Ee)});var De=H(Te,2),Oe=e=>{var i=Mo();let o;var s=z(i),c=e=>{var t=lo(),n=B(t),r=V(n,!0),i=V(H(n,2),!0);U(()=>{X(r,K(v)?.title||`/ COMMANDS`),X(i,K(v)?.help||`Loading live options…`)}),Y(e,t)};Z(s,e=>{K(ge)||e(c)});var l=H(s,2),u=e=>{var t=uo(),n=V(t,!0);U(()=>X(n,K(_))),Y(e,t)};Z(l,e=>{K(_)&&e(u)});var d=H(l,2),f=e=>{Y(e,fo())};Z(d,e=>{K(g)&&e(f)});var p=H(d,2),m=e=>{var t=po(),r=z(t),i=z(r),o=H(i);xi(o),P(r),P(t),U(e=>{Q(t,`id`,`${n}-input`),X(i,`${e??``} `),Q(o,`aria-label`,K(v).inputLabel||`Session name`),Q(o,`maxlength`,K(v).inputLimit||512),o.disabled=K(g)||K(he)&&!a()},[()=>(K(v).inputLabel||`Session name`).toUpperCase()]),xr(`submit`,t,e=>{e.preventDefault(),se()}),Ei(o,()=>K(C),e=>R(C,e)),Y(e,t)},h=e=>{var n=ho(),r=z(n),i=V(r,!0),a=H(r,2),o=V(a,!0),s=H(a,2),c=e=>{var n=mo(),r=z(n),i=H(r),a=e=>{Y(e,Mr(`Only this session's saved
name changes.`))},o=F(()=>K(v)?.path.startsWith(`rename/`)),s=e=>{Y(e,Mr(`Only this session’s
directory changes; project configuration is not reloaded.`))},c=F(()=>K(v)?.path.startsWith(`cd/`)),l=e=>{Y(e,Mr(`No change sent yet. Model, reasoning and speed settings can
change token usage and cost. Changes affect subsequent turns of
this session, not global defaults. Automatic quota thresholds
- may later supersede model settings.`))};Z(i,e=>{K(o)?e(a):K(c)?e(s,1):e(l,-1)}),P(n),U(()=>X(r,`TARGET // ${t.session??``}. `)),Y(e,n)};Z(s,e=>{K(y).action&&e(c)}),P(n),Ii(n,e=>R(te,e),()=>K(te)),U(()=>{X(i,K(y).label),X(o,K(y).help||`No additional help supplied by Codex.`)}),Y(e,n)},w=e=>{var t=xo(),i=B(t),a=e=>{var t=ho(),i=z(t);r(i),P(t),Ii(t,e=>R(D,e),()=>K(D)),U(()=>Q(t,`aria-activedescendant`,`${n}-${K(T)}`)),Y(e,t)},o=e=>{var t=go();let n;var i=z(t);r(i),P(t),Ii(t,e=>R(D,e),()=>K(D)),U(()=>n=ci(t,1,`command-options svelte-7bfwr9`,null,n,{vertical:K(ge)})),Y(e,t)};Z(i,e=>{K(A)?e(a):e(o,-1)});var s=H(i,2),c=e=>{var t=yo(),n=B(t),r=V(n,!0),i=H(n,2),a=e=>{var t=vo(),n=B(t),r=V(n),i=H(n,2),a=e=>{Y(e,_o())};Z(i,e=>{K(b)&&K(S)>=K(x)&&e(a)}),U(()=>X(r,`REVIEW // ${K(me).label??``}. No change sent yet.`)),Y(e,t)};Z(i,e=>{K(me)&&e(a)}),U(()=>X(r,K(fe)[K(T)]?.help)),Y(e,t)};Z(s,e=>{K(A)&&e(c)});var l=H(s,2),u=e=>{Y(e,bo())};Z(l,e=>{!K(g)&&!K(fe).length&&e(u)}),Y(e,t)};Z(p,e=>{K(v)?.input?e(m):K(y)?e(h,1):e(w,-1)});var E=H(p,2),O=e=>{var t=So(),n=V(t,!0);U(()=>X(n,K(j).unavailable)),Y(e,t)};Z(E,e=>{K(j)?.unavailable&&e(O)});var k=H(E,2),ne=e=>{Y(e,Co())};Z(k,e=>{K(b)&&K(S)>=K(x)&&!K(A)&&e(ne)});var ie=H(k,2),ae=z(ie),ce=e=>{var t=Nr(),r=B(t),i=e=>{var t=wo();U(e=>{Q(t,`form`,`${n}-input`),t.disabled=e},[()=>K(g)||K(he)||!K(C).trim()]),Y(e,t)},o=e=>{var t=Nr(),n=B(t),r=e=>{var t=To();U(()=>t.disabled=K(g)||K(he)&&!a()),q(`click`,t,xe),Y(e,t)},i=e=>{var t=Eo();U(()=>t.disabled=K(g)||K(he)&&!a()),q(`click`,t,()=>{K(j)&&be(K(j))}),Y(e,t)};Z(n,e=>{K(pe)?e(r):e(i,-1)}),Y(e,t)},s=e=>{var t=Do(),n=V(t);U(()=>{t.disabled=K(g)||K(he)&&!a(),X(n,`ENTER ${K(j).next?`OPEN`:`HELP`}`)}),q(`click`,t,()=>{K(j)&&ye(K(j))}),Y(e,t)};Z(r,e=>{K(v)?.input?e(i):K(j)?.action&&!K(j).unavailable?e(o,1):!K(y)&&K(j)&&!K(j).unavailable&&e(s,2)}),Y(e,t)};Z(ae,e=>{K(_)||e(ce)});var le=H(ae,2),ue=e=>{var t=Oo();U(()=>t.disabled=K(g)),q(`click`,t,oe),Y(e,t)};Z(le,e=>{K(re)&&e(ue)});var de=H(le,2),_e=e=>{var t=ko();U(()=>t.disabled=K(g)),q(`click`,t,()=>N(K(v)?.path||``)),Y(e,t)};Z(de,e=>{K(ge)||e(_e)});var Se=H(de,2);P(ie);var Ce=H(ie,2),we=e=>{var t=Ao(),n=V(t);U(()=>X(n,`↑/↓ select${K(ge)?` · Tab complete`:``}`)),Y(e,t)};Z(Ce,e=>{!K(v)?.input&&!K(y)&&e(we)}),P(i),Ii(i,e=>R(ee,e),()=>K(ee)),U(()=>{Q(i,`aria-label`,K(ge)?`Slash command suggestions`:`Session command options`),o=ci(i,1,`svelte-7bfwr9`,null,o,{"command-popup":K(ge)})}),q(`keydown`,i,ve),q(`click`,Se,M),Y(e,i)};return Z(De,e=>{K(h)&&e(Oe)}),P(Ce),U(()=>we.disabled=K(he)&&!a()||K(g)),q(`click`,we,()=>{R(h,!K(h)),R(E,K(h)?null:i(),!0),R(b,``),K(h)?(R(k,[],!0),N(``)):M()}),Y(e,Ce),We(Se)}Sr([`click`,`keydown`]);var Po=J(``,1),Fo=J(`
Type one of these choices exactly. Your answer stays masked.
`),ps=J(` `,1),ms=J(`
`),hs=J(`
`,1),gs=J(` `,1),_s=J(``),vs=J(`
`,1),ys=J(`
`);function bs(e,t){Ue(t,!0);let n=[],r=Wi(t,`observedCommand`,3,``),i=Wi(t,`observedFileChanges`,19,()=>[]),a=Wi(t,`review`,3,``),o=Wi(t,`suspended`,3,!1),s=Wi(t,`openScheduler`,3,!1),c=Wi(t,`onProtectedChange`,3,e=>{}),l=Wi(t,`oncopy`,3,()=>{}),u=L(null),d=L(Yt([])),f=L(null),p=L(``),m=L(0),h=L(Yt(Date.now())),g=L(!1),_=L(``),v=L(!1),y=L(!1),b=L(``),x=L(!1),S=L(``),C=L(!1),w=L(``),T=L(`now`),E=L(60),D=L(``),ee=L(!1),te=L(``),O=L(Yt([])),k=F(()=>K(O).find(e=>e.status!==`sent`)),ne=L(void 0),re=L(void 0);function ie(e){if(K(x)){lr().then(()=>K(ne)?.focus());return}if(e.status!==`pending`||K(g)||!K(u)?.id||K(u).kind!==`prompt`||K(u).questions?.length)return;R(x,!0),R(S,e.id,!0),lr().then(()=>K(ne)?.focus()),R(d,[e.text],!0),R(T,e.trigger===`quota`?`quota`:`at`,!0),R(p,``),R(w,``);let t=new Date(e.at);e.trigger!==`quota`&&R(D,new Date(t.getTime()-t.getTimezoneOffset()*6e4).toISOString().slice(0,16),!0)}vn(()=>{s()&&K(k)&&!K(C)&&K(u)?.id&&K(u).kind===`prompt`&&!K(u).questions?.length&&(R(C,!0),ie(K(k)))});async function ae(){if(!a())try{R(O,await va(`schedules`,{session:t.session},M.signal),!0),K(x)&&!K(O).some(e=>e.id===K(S)&&e.status===`pending`)&&R(p,``),K(w)&&!K(O).some(e=>e.id===K(w)&&e.status===`pending`)&&(R(p,``),R(w,``))}catch{}}async function oe(e){try{R(O,await va(`schedules`,{session:t.session,cancelId:e},M.signal),!0),R(x,!1),R(p,``),R(w,``),R(d,[],!0)}catch(e){R(_,e instanceof Error?e.message:`Unable to cancel trigger.`,!0)}}vn(()=>(c()(K(g)||K(d).some(e=>e.length>0)),()=>c()(!1)));let se=F(()=>$.data?.sessions.find(e=>e.id===t.session)?.status),A=F(()=>!$.connected||!!$.data?.sessionsError),ce=F(()=>a()!==`profile`&&K(u)?.kind===`prompt`&&!K(u).questions?.length&&!!$.data?.profiles?.some(e=>e.session===t.session&&e.pending)),le=F(()=>!K(A)&&!K(y)&&!!K(u)?.id&&K(u).kind===`approval`&&K(b)!==K(u).id),ue=F(()=>K(le)?K(u).command:r()),de=F(()=>!!K(p)&&K(h)K(u)?.questions?.length?K(u).questions:[{text:`Follow-up message`,secret:!1,freeText:!0,options:[]}]),j=F(()=>K(u)?.kind===`approval`||K(u)?.kind===`profile`?K(f)!==null:K(d).length===K(fe).length&&K(d).every((e,t)=>e.trim().length>0&&(K(fe)[t].freeText||K(fe)[t].options?.includes(e)))),pe=F(()=>K(u)?.kind===`prompt`&&!K(u).questions?.length&&K(T)!==`now`),me=F(()=>K(T)===`delay`?K(h)+K(E)*6e4:Date.parse(K(D))),he=F(()=>{if(!K(pe))return``;if(K(x)&&!K(O).some(e=>e.id===K(S)&&e.status===`pending`))return`Trigger changed, removed or already sent. Go back and reopen it; your draft has not been saved.`;if(!K(d)[0]?.trim())return`Enter a message to schedule.`;if(K(T)===`quota`)return``;if(!Number.isFinite(K(me))||K(me)<=K(h))return`Choose a future date/time or a delay greater than zero.`;let e=new Date(K(h));return e.setFullYear(e.getFullYear()+1),K(me)>=e.getTime()?`Choose a time within one year.`:``});function ge(e){return new Date(e).toLocaleString([],{timeZoneName:`short`})}function _e(e){if(e.status!==`pending`)return e.status;if(e.trigger===`at`&&Date.parse(e.at)>K(h))return`Due in `+Math.ceil((Date.parse(e.at)-K(h))/6e4)+` min`;let t=K(A)?`waiting for a fresh connection`:e.waitingReason||(e.canSend?`ready; awaiting dispatch`:`waiting for quota and an eligible idle session`);return(e.trigger===`at`?`Time reached — `:``)+t}vn(()=>{(K(A)||o()||K(ce)||K(h)>=K(m))&&R(p,``)});let M=new AbortController;Gi(()=>{let e=e=>{e.ctrlKey&&e.key.toLowerCase()===`s`&&!a()&&K(k)&&(e.preventDefault(),ie(K(k)))};window.addEventListener(`keydown`,e);let n,r=setInterval(()=>{R(h,Date.now(),!0)},1e3);async function i(){await ae();try{let e=await va(`offer`,{session:t.session,...a()?{review:a()}:{}},M.signal);if(M.signal.aborted)return;R(y,!1),K(u)?.id!==e.id&&(R(p,``),R(f,null),R(d,Array(Math.max(1,e.questions?.length||0)).fill(``),!0)),R(u,e,!0),K(v)&&e.id&&e.id!==K(b)&&(R(_,``),R(v,!1))}catch{M.signal.aborted||(R(u,null),R(y,!0),R(p,``))}finally{M.signal.aborted||(n=setTimeout(i,2e3))}}return i(),()=>{window.removeEventListener(`keydown`,e),M.abort(),clearTimeout(n),clearInterval(r)}});async function ve(e){if(!e&&K(u)?.kind===`prompt`&&!K(u).questions?.length&&K(d)[0]?.trim().startsWith(`/`)&&!K(d)[0]?.trim().startsWith(`//`)){R(_,`Choose a slash command from COMMANDS; use // for literal slash text.`);return}if(!K(u)?.id||K(g)||K(A)||o()||K(ce)||(e?!e.canSend:!K(j)||K(he)))return;let n=K(u).id;R(g,!0),R(_,``),R(v,!1),R(p,``),R(w,e?.id||``,!0);try{let r=!e&&K(u).kind===`prompt`&&!K(u).questions?.length&&K(T)!==`now`?{trigger:K(T)===`quota`?`quota`:`at`,zone:Intl.DateTimeFormat().resolvedOptions().timeZone,...K(T)===`quota`?{}:{at:(K(T)===`delay`?new Date(Date.now()+K(E)*6e4):new Date(K(D))).toISOString()}}:void 0;R(ee,!!r),R(te,r?r.trigger===`quota`?`After fresh quota becomes available, when the session is idle`:ge(r.at)+` — not before this time; when quota and idle allow`:``,!0);let i=await va(`prepare`,{session:t.session,...a()?{review:a()}:{},offer:n,...e?{sendId:e.id}:{},...r?{schedule:r}:{},...r&&K(x)?{editId:K(S)}:{},...K(u).kind===`approval`||K(u).kind===`profile`?{choice:K(f)}:{answers:e?[e.text]:[...K(d)]}},M.signal);K(u)?.id===n&&!M.signal.aborted&&!K(A)&&!o()&&!K(ce)&&(R(p,i.confirmation,!0),R(m,Date.parse(i.expires),!0))}catch(e){M.signal.aborted||R(_,e instanceof Error?e.message:`Unable to prepare action.`,!0)}finally{R(g,!1)}}async function N(){if(!K(u)?.id||K(g)||o()||K(ce)||!K(de))return;let e=K(u).id,n=K(u).kind,r=K(p);R(p,``),R(g,!0),R(b,e,!0);try{await va(`commit`,{session:t.session,...a()?{review:a()}:{},offer:e,confirmation:r},M.signal),R(v,!0),R(x,!1),K(ee)&&(R(b,``),await ae()),R(_,K(ee)?`Trigger set. Closing Codexometer cancels it.`:n===`profile`?`Profile decision completed.`:n===`approval`?`Decision sent.`:`Text sent.`,!0)}catch(e){R(_,e instanceof ga?e.message:`Outcome uncertain. Check Codex before taking another action; nothing was retried.`,!0)}finally{R(g,!1),R(w,``),await ae(),R(d,[],!0),R(f,null)}}var ye=Xo(),be=B(ye),Se=e=>{var t=Nr();Xr(B(t),17,()=>K(O).filter(e=>e.status!==`sent`),e=>e.id,(e,t)=>{var n=Vo(),r=z(n),i=V(r,!0),a=H(r,2),s=V(a),c=H(a,2),l=V(c,!0),d=H(c,2),f=V(d,!0),m=H(d,2),h=V(m,!0),v=H(m,2),y=e=>{var t=Ro(),n=V(t,!0);U(()=>X(n,K(_))),Y(e,t)};Z(v,e=>{K(_)&&e(y)});var b=H(v,4),x=H(b,2),S=H(x,2),C=e=>{var n=zo(),r=H(B(n),2),i=H(r,2);U(()=>r.disabled=K(g)||K(A)||!K(t).canSend),q(`click`,r,N),q(`click`,i,()=>{R(p,``),R(w,``)}),Y(e,n)},T=e=>{var n=Bo();U(()=>n.disabled=K(g)||K(A)||!K(t).canSend||o()),q(`click`,n,()=>ve(K(t))),Y(e,n)};Z(S,e=>{K(de)&&K(w)===K(t).id?e(C):e(T,-1)}),P(n),U((e,n)=>{X(i,K(t).status===`uncertain`?`CHECK TRIGGER — outcome uncertain; not retried`:`SCHEDULED FOLLOW-UP`),X(s,`TARGET // ${K(t).session??``}`),X(l,e),X(f,n),X(h,K(t).text),b.disabled=K(g)||!K(u)?.id||K(u).kind!==`prompt`||!!K(u).questions?.length||K(t).status!==`pending`,x.disabled=K(g)||K(t).status===`sending`},[()=>K(t).trigger===`quota`?`After confirmed quota recovery, when idle`:`Not before ${ge(K(t).at)}`,()=>_e(K(t))]),q(`click`,b,()=>ie(K(t))),q(`click`,x,()=>oe(K(t).id)),Y(e,n)}),Y(e,t)},Ce=F(()=>!a()&&K(u)?.kind!==`approval`&&!K(u)?.questions?.length&&![`APPROVAL NEEDED`,`INPUT NEEDED`].includes(K(se)||``));Z(be,e=>{K(Ce)&&e(Se)});var we=H(be,2),Te=e=>{var r=ys(),o=z(r),s=V(o,!0),c=H(o,2),S=e=>{var t=Ho(),n=B(t),r=V(n),i=H(n,6),a=V(i,!0),o=V(H(i,6),!0);xe(2),U(()=>{X(r,`Your ${K(u).profile.threshold??``}% quota threshold has been reached. Review
- the profile for subsequent turns.`),X(a,K(u).profile.current),X(o,K(u).profile.proposed)}),Y(e,t)};Z(c,e=>{K(u)?.profile&&!K(A)&&!K(y)&&e(S)});var C=H(c,2),w=e=>{var t=Uo();let n;var r=V(t,!0);U(()=>{n=ci(t,1,`svelte-1oupzfc`,null,n,{notice:!K(v),sent:K(v)}),X(r,K(_))}),Y(e,t)};Z(C,e=>{K(_)&&e(w)});var O=H(C,2),k=e=>{Lo(e,{get lines(){return K(u).fileChanges}})},ie=e=>{Lo(e,{get lines(){return i()}})},ae=e=>{var t=Wo(),n=B(t),r=V(n,!0),i=V(H(n,2),!0);U(()=>{X(r,K(le)?`EXACT COMMAND`:`LAST OBSERVED COMMAND`),X(i,K(ue))}),Y(e,t)},oe=e=>{Y(e,Go())};Z(O,e=>{K(u)?.fileChanges?.length&&!K(A)&&!K(y)?e(k):i().length?e(ie,1):K(ue)?e(ae,2):a()!==`profile`&&K(se)===`APPROVAL NEEDED`&&!K(v)&&e(oe,3)});var ce=H(O,2),pe=e=>{Y(e,Ko())},_e=e=>{Y(e,qo())},M=e=>{var t=Xo(),n=B(t),r=e=>{var t=Jo(),n=V(t,!0);U(e=>X(n,e),[()=>K(se)===`WORKING`?`Codex is working — nothing to respond to.`:[`APPROVAL NEEDED`,`INPUT NEEDED`].includes(K(se)||``)?`Respond in Codex for this request.`:`Nothing needs a response right now.`]),Y(e,t)};Z(n,e=>{(K(se)===`WORKING`||!K(v)&&!K(g))&&e(r)});var i=H(n,2),a=e=>{Y(e,Yo())},o=F(()=>[`APPROVAL NEEDED`,`INPUT NEEDED`].includes(K(se)||``)&&!K(v));Z(i,e=>{K(o)&&e(a)}),Y(e,t)},ye=e=>{var r=vs(),i=B(r),o=V(i),s=H(i,2),c=z(s),_=V(c,!0),v=H(c,2),y=e=>{var r=Nr();Xr(B(r),17,()=>K(u).choices||[],Kr,(e,r,i)=>{var o=$o(),s=z(o);xi(s),s.value=s.__value=i;var c=H(s),l=H(c),u=e=>{var t=Zo(),n=V(t,!0);U(()=>X(n,K(r).detail)),Y(e,t)};Z(l,e=>{K(r).detail&&e(u)});var d=H(l,2),p=e=>{Y(e,Qo())};Z(d,e=>{K(r).persistent&&e(p)}),P(o),U(()=>{Q(s,`name`,`decision-`+t.session+`-`+a()),X(c,` ${K(r).label??``} `)}),Oi(n,[],s,()=>K(f),e=>R(f,e)),Y(e,o)}),Y(e,r)},b=e=>{var n=Xo(),r=B(n),i=e=>{var t=os(),n=B(t),r=H(z(n)),i=z(r),a=e=>{var t=es();t.value=t.__value=`now`,Y(e,t)};Z(i,e=>{K(x)||e(a)});var o=H(i);o.value=o.__value=`quota`;var s=H(o);s.value=s.__value=`delay`;var c=H(s);c.value=c.__value=`at`,P(r),mi(r),P(n);var l=H(n,2),u=e=>{var t=ts(),n=H(z(t));xi(n),P(t),Ei(n,()=>K(E),e=>R(E,e)),Y(e,t)};Z(l,e=>{K(T)===`delay`&&e(u)});var d=H(l,2),f=e=>{var t=ns(),n=H(z(t));xi(n),P(t),Ei(n,()=>K(D),e=>R(D,e)),Y(e,t)};Z(d,e=>{K(T)===`at`&&e(f)});var p=H(d,2),m=e=>{var t=is(),n=B(t),r=V(n),i=H(n,2),a=e=>{Y(e,rs())};Z(i,e=>{K(T)!==`quota`&&e(a)});var o=H(i,2);o.textContent=`Timezone: ${Intl.DateTimeFormat().resolvedOptions().timeZone??``}.
+ may later supersede model settings.`))};Z(i,e=>{K(o)?e(a):K(c)?e(s,1):e(l,-1)}),P(n),U(()=>X(r,`TARGET // ${t.session??``}. `)),Y(e,n)};Z(s,e=>{K(y).action&&e(c)}),P(n),Ii(n,e=>R(te,e),()=>K(te)),U(()=>{X(i,K(y).label),X(o,K(y).help||`No additional help supplied by Codex.`)}),Y(e,n)},w=e=>{var t=So(),i=B(t),a=e=>{var t=go(),i=z(t);r(i),P(t),Ii(t,e=>R(D,e),()=>K(D)),U(()=>Q(t,`aria-activedescendant`,`${n}-${K(T)}`)),Y(e,t)},o=e=>{var t=_o();let n;var i=z(t);r(i),P(t),Ii(t,e=>R(D,e),()=>K(D)),U(()=>n=ci(t,1,`command-options svelte-7bfwr9`,null,n,{vertical:K(ge)})),Y(e,t)};Z(i,e=>{K(A)?e(a):e(o,-1)});var s=H(i,2),c=e=>{var t=bo(),n=B(t),r=V(n,!0),i=H(n,2),a=e=>{var t=yo(),n=B(t),r=V(n),i=H(n,2),a=e=>{Y(e,vo())};Z(i,e=>{K(b)&&K(S)>=K(x)&&e(a)}),U(()=>X(r,`REVIEW // ${K(me).label??``}. No change sent yet.`)),Y(e,t)};Z(i,e=>{K(me)&&e(a)}),U(()=>X(r,K(fe)[K(T)]?.help)),Y(e,t)};Z(s,e=>{K(A)&&e(c)});var l=H(s,2),u=e=>{Y(e,xo())};Z(l,e=>{!K(g)&&!K(fe).length&&e(u)}),Y(e,t)};Z(p,e=>{K(v)?.input?e(m):K(y)?e(h,1):e(w,-1)});var E=H(p,2),O=e=>{var t=Co(),n=V(t,!0);U(()=>X(n,K(j).unavailable)),Y(e,t)};Z(E,e=>{K(j)?.unavailable&&e(O)});var k=H(E,2),ne=e=>{Y(e,wo())};Z(k,e=>{K(b)&&K(S)>=K(x)&&!K(A)&&e(ne)});var ie=H(k,2),ae=z(ie),ce=e=>{var t=Nr(),r=B(t),i=e=>{var t=To();U(e=>{Q(t,`form`,`${n}-input`),t.disabled=e},[()=>K(g)||K(he)||!K(C).trim()]),Y(e,t)},o=e=>{var t=Nr(),n=B(t),r=e=>{var t=Eo();U(()=>t.disabled=K(g)||K(he)&&!a()),q(`click`,t,xe),Y(e,t)},i=e=>{var t=Do();U(()=>t.disabled=K(g)||K(he)&&!a()),q(`click`,t,()=>{K(j)&&be(K(j))}),Y(e,t)};Z(n,e=>{K(pe)?e(r):e(i,-1)}),Y(e,t)},s=e=>{var t=Oo(),n=V(t);U(()=>{t.disabled=K(g)||K(he)&&!a(),X(n,`ENTER ${K(j).next?`OPEN`:`HELP`}`)}),q(`click`,t,()=>{K(j)&&ye(K(j))}),Y(e,t)};Z(r,e=>{K(v)?.input?e(i):K(j)?.action&&!K(j).unavailable?e(o,1):!K(y)&&K(j)&&!K(j).unavailable&&e(s,2)}),Y(e,t)};Z(ae,e=>{K(_)||e(ce)});var le=H(ae,2),ue=e=>{var t=ko();U(()=>t.disabled=K(g)),q(`click`,t,oe),Y(e,t)};Z(le,e=>{K(re)&&e(ue)});var de=H(le,2),_e=e=>{var t=Ao();U(()=>t.disabled=K(g)),q(`click`,t,()=>N(K(v)?.path||``)),Y(e,t)};Z(de,e=>{K(ge)||e(_e)});var Se=H(de,2);P(ie);var Ce=H(ie,2),we=e=>{var t=jo(),n=V(t);U(()=>X(n,`↑/↓ select${K(ge)?` · Tab complete`:``}`)),Y(e,t)};Z(Ce,e=>{!K(v)?.input&&!K(y)&&e(we)}),P(i),Ii(i,e=>R(ee,e),()=>K(ee)),U(()=>{Q(i,`aria-label`,K(ge)?`Slash command suggestions`:`Session command options`),o=ci(i,1,`svelte-7bfwr9`,null,o,{"command-popup":K(ge)})}),q(`keydown`,i,ve),q(`click`,Se,M),Y(e,i)};return Z(De,e=>{K(h)&&e(Oe)}),P(Ce),U(()=>we.disabled=K(he)&&!a()||K(g)),q(`click`,we,()=>{R(h,!K(h)),R(E,K(h)?null:i(),!0),R(b,``),K(h)?(R(k,[],!0),N(``)):M()}),Y(e,Ce),We(Se)}Sr([`click`,`keydown`]);var Fo=J(``,1),Io=J(`
Type one of these choices exactly. Your answer stays masked.
`),ms=J(` `,1),hs=J(`
`),gs=J(`
`,1),_s=J(` `,1),vs=J(``),ys=J(`
`,1),bs=J(`
`);function xs(e,t){Ue(t,!0);let n=[],r=Wi(t,`observedCommand`,3,``),i=Wi(t,`observedFileChanges`,19,()=>[]),a=Wi(t,`review`,3,``),o=Wi(t,`suspended`,3,!1),s=Wi(t,`openScheduler`,3,!1),c=Wi(t,`onProtectedChange`,3,e=>{}),l=Wi(t,`oncopy`,3,()=>{}),u=L(null),d=L(Yt([])),f=L(null),p=L(``),m=L(0),h=L(Yt(Date.now())),g=L(!1),_=L(``),v=L(!1),y=L(!1),b=L(``),x=L(!1),S=L(``),C=L(!1),w=L(``),T=L(`now`),E=L(60),D=L(``),ee=L(!1),te=L(``),O=L(Yt([])),k=F(()=>K(O).find(e=>e.status!==`sent`)),ne=L(void 0),re=L(void 0);function ie(e){if(K(x)){lr().then(()=>K(ne)?.focus());return}if(e.status!==`pending`||K(g)||!K(u)?.id||K(u).kind!==`prompt`||K(u).questions?.length)return;R(x,!0),R(S,e.id,!0),lr().then(()=>K(ne)?.focus()),R(d,[e.text],!0),R(T,e.trigger===`quota`?`quota`:`at`,!0),R(p,``),R(w,``);let t=new Date(e.at);e.trigger!==`quota`&&R(D,new Date(t.getTime()-t.getTimezoneOffset()*6e4).toISOString().slice(0,16),!0)}vn(()=>{s()&&K(k)&&!K(C)&&K(u)?.id&&K(u).kind===`prompt`&&!K(u).questions?.length&&(R(C,!0),ie(K(k)))});async function ae(){if(!a())try{R(O,await va(`schedules`,{session:t.session},M.signal),!0),K(x)&&!K(O).some(e=>e.id===K(S)&&e.status===`pending`)&&R(p,``),K(w)&&!K(O).some(e=>e.id===K(w)&&e.status===`pending`)&&(R(p,``),R(w,``))}catch{}}async function oe(e){try{R(O,await va(`schedules`,{session:t.session,cancelId:e},M.signal),!0),R(x,!1),R(p,``),R(w,``),R(d,[],!0)}catch(e){R(_,e instanceof Error?e.message:`Unable to cancel trigger.`,!0)}}vn(()=>(c()(K(g)||K(d).some(e=>e.length>0)),()=>c()(!1)));let se=F(()=>$.data?.sessions.find(e=>e.id===t.session)?.status),A=F(()=>!$.connected||!!$.data?.sessionsError),ce=F(()=>a()!==`profile`&&K(u)?.kind===`prompt`&&!K(u).questions?.length&&!!$.data?.profiles?.some(e=>e.session===t.session&&e.pending)),le=F(()=>!K(A)&&!K(y)&&!!K(u)?.id&&K(u).kind===`approval`&&K(b)!==K(u).id),ue=F(()=>K(le)?K(u).command:r()),de=F(()=>!!K(p)&&K(h)K(u)?.questions?.length?K(u).questions:[{text:`Follow-up message`,secret:!1,freeText:!0,options:[]}]),j=F(()=>K(u)?.kind===`approval`||K(u)?.kind===`profile`?K(f)!==null:K(d).length===K(fe).length&&K(d).every((e,t)=>e.trim().length>0&&(K(fe)[t].freeText||K(fe)[t].options?.includes(e)))),pe=F(()=>K(u)?.kind===`prompt`&&!K(u).questions?.length&&K(T)!==`now`),me=F(()=>K(T)===`delay`?K(h)+K(E)*6e4:Date.parse(K(D))),he=F(()=>{if(!K(pe))return``;if(K(x)&&!K(O).some(e=>e.id===K(S)&&e.status===`pending`))return`Trigger changed, removed or already sent. Go back and reopen it; your draft has not been saved.`;if(!K(d)[0]?.trim())return`Enter a message to schedule.`;if(K(T)===`quota`)return``;if(!Number.isFinite(K(me))||K(me)<=K(h))return`Choose a future date/time or a delay greater than zero.`;let e=new Date(K(h));return e.setFullYear(e.getFullYear()+1),K(me)>=e.getTime()?`Choose a time within one year.`:``});function ge(e){return new Date(e).toLocaleString([],{timeZoneName:`short`})}function _e(e){if(e.status!==`pending`)return e.status;if(e.trigger===`at`&&Date.parse(e.at)>K(h))return`Due in `+Math.ceil((Date.parse(e.at)-K(h))/6e4)+` min`;let t=K(A)?`waiting for a fresh connection`:e.waitingReason||(e.canSend?`ready; awaiting dispatch`:`waiting for quota and an eligible idle session`);return(e.trigger===`at`?`Time reached — `:``)+t}vn(()=>{(K(A)||o()||K(ce)||K(h)>=K(m))&&R(p,``)});let M=new AbortController;Gi(()=>{let e=e=>{e.ctrlKey&&e.key.toLowerCase()===`s`&&!a()&&K(k)&&(e.preventDefault(),ie(K(k)))};window.addEventListener(`keydown`,e);let n,r=setInterval(()=>{R(h,Date.now(),!0)},1e3);async function i(){await ae();try{let e=await va(`offer`,{session:t.session,...a()?{review:a()}:{}},M.signal);if(M.signal.aborted)return;R(y,!1),K(u)?.id!==e.id&&(R(p,``),R(f,null),R(d,Array(Math.max(1,e.questions?.length||0)).fill(``),!0)),R(u,e,!0),K(v)&&e.id&&e.id!==K(b)&&(R(_,``),R(v,!1))}catch{M.signal.aborted||(R(u,null),R(y,!0),R(p,``))}finally{M.signal.aborted||(n=setTimeout(i,2e3))}}return i(),()=>{window.removeEventListener(`keydown`,e),M.abort(),clearTimeout(n),clearInterval(r)}});async function ve(e){if(!e&&K(u)?.kind===`prompt`&&!K(u).questions?.length&&K(d)[0]?.trim().startsWith(`/`)&&!K(d)[0]?.trim().startsWith(`//`)){R(_,`Choose a slash command from COMMANDS; use // for literal slash text.`);return}if(!K(u)?.id||K(g)||K(A)||o()||K(ce)||(e?!e.canSend:!K(j)||K(he)))return;let n=K(u).id;R(g,!0),R(_,``),R(v,!1),R(p,``),R(w,e?.id||``,!0);try{let r=!e&&K(u).kind===`prompt`&&!K(u).questions?.length&&K(T)!==`now`?{trigger:K(T)===`quota`?`quota`:`at`,zone:Intl.DateTimeFormat().resolvedOptions().timeZone,...K(T)===`quota`?{}:{at:(K(T)===`delay`?new Date(Date.now()+K(E)*6e4):new Date(K(D))).toISOString()}}:void 0;R(ee,!!r),R(te,r?r.trigger===`quota`?`After fresh quota becomes available, when the session is idle`:ge(r.at)+` — not before this time; when quota and idle allow`:``,!0);let i=await va(`prepare`,{session:t.session,...a()?{review:a()}:{},offer:n,...e?{sendId:e.id}:{},...r?{schedule:r}:{},...r&&K(x)?{editId:K(S)}:{},...K(u).kind===`approval`||K(u).kind===`profile`?{choice:K(f)}:{answers:e?[e.text]:[...K(d)]}},M.signal);K(u)?.id===n&&!M.signal.aborted&&!K(A)&&!o()&&!K(ce)&&(R(p,i.confirmation,!0),R(m,Date.parse(i.expires),!0))}catch(e){M.signal.aborted||R(_,e instanceof Error?e.message:`Unable to prepare action.`,!0)}finally{R(g,!1)}}async function N(){if(!K(u)?.id||K(g)||o()||K(ce)||!K(de))return;let e=K(u).id,n=K(u).kind,r=K(p);R(p,``),R(g,!0),R(b,e,!0);try{await va(`commit`,{session:t.session,...a()?{review:a()}:{},offer:e,confirmation:r},M.signal),R(v,!0),R(x,!1),K(ee)&&(R(b,``),await ae()),R(_,K(ee)?`Trigger set. Closing Codexometer cancels it.`:n===`profile`?`Profile decision completed.`:n===`approval`?`Decision sent.`:`Text sent.`,!0)}catch(e){R(_,e instanceof ga?e.message:`Outcome uncertain. Check Codex before taking another action; nothing was retried.`,!0)}finally{R(g,!1),R(w,``),await ae(),R(d,[],!0),R(f,null)}}var ye=Zo(),be=B(ye),Se=e=>{var t=Nr();Xr(B(t),17,()=>K(O).filter(e=>e.status!==`sent`),e=>e.id,(e,t)=>{var n=Ho(),r=z(n),i=V(r,!0),a=H(r,2),s=V(a),c=H(a,2),l=V(c,!0),d=H(c,2),f=V(d,!0),m=H(d,2),h=V(m,!0),v=H(m,2),y=e=>{var t=zo(),n=V(t,!0);U(()=>X(n,K(_))),Y(e,t)};Z(v,e=>{K(_)&&e(y)});var b=H(v,4),x=H(b,2),S=H(x,2),C=e=>{var n=Bo(),r=H(B(n),2),i=H(r,2);U(()=>r.disabled=K(g)||K(A)||!K(t).canSend),q(`click`,r,N),q(`click`,i,()=>{R(p,``),R(w,``)}),Y(e,n)},T=e=>{var n=Vo();U(()=>n.disabled=K(g)||K(A)||!K(t).canSend||o()),q(`click`,n,()=>ve(K(t))),Y(e,n)};Z(S,e=>{K(de)&&K(w)===K(t).id?e(C):e(T,-1)}),P(n),U((e,n)=>{X(i,K(t).status===`uncertain`?`CHECK TRIGGER — outcome uncertain; not retried`:`SCHEDULED FOLLOW-UP`),X(s,`TARGET // ${K(t).session??``}`),X(l,e),X(f,n),X(h,K(t).text),b.disabled=K(g)||!K(u)?.id||K(u).kind!==`prompt`||!!K(u).questions?.length||K(t).status!==`pending`,x.disabled=K(g)||K(t).status===`sending`},[()=>K(t).trigger===`quota`?`After confirmed quota recovery, when idle`:`Not before ${ge(K(t).at)}`,()=>_e(K(t))]),q(`click`,b,()=>ie(K(t))),q(`click`,x,()=>oe(K(t).id)),Y(e,n)}),Y(e,t)},Ce=F(()=>!a()&&K(u)?.kind!==`approval`&&!K(u)?.questions?.length&&![`APPROVAL NEEDED`,`INPUT NEEDED`].includes(K(se)||``));Z(be,e=>{K(Ce)&&e(Se)});var we=H(be,2),Te=e=>{var r=bs(),o=z(r),s=V(o,!0),c=H(o,2),S=e=>{var t=Uo(),n=B(t),r=V(n),i=H(n,6),a=V(i,!0),o=V(H(i,6),!0);xe(2),U(()=>{X(r,`Your ${K(u).profile.threshold??``}% quota threshold has been reached. Review
+ the profile for subsequent turns.`),X(a,K(u).profile.current),X(o,K(u).profile.proposed)}),Y(e,t)};Z(c,e=>{K(u)?.profile&&!K(A)&&!K(y)&&e(S)});var C=H(c,2),w=e=>{var t=Wo();let n;var r=V(t,!0);U(()=>{n=ci(t,1,`svelte-1oupzfc`,null,n,{notice:!K(v),sent:K(v)}),X(r,K(_))}),Y(e,t)};Z(C,e=>{K(_)&&e(w)});var O=H(C,2),k=e=>{Ro(e,{get lines(){return K(u).fileChanges}})},ie=e=>{Ro(e,{get lines(){return i()}})},ae=e=>{var t=Go(),n=B(t),r=V(n,!0),i=V(H(n,2),!0);U(()=>{X(r,K(le)?`EXACT COMMAND`:`LAST OBSERVED COMMAND`),X(i,K(ue))}),Y(e,t)},oe=e=>{Y(e,Ko())};Z(O,e=>{K(u)?.fileChanges?.length&&!K(A)&&!K(y)?e(k):i().length?e(ie,1):K(ue)?e(ae,2):a()!==`profile`&&K(se)===`APPROVAL NEEDED`&&!K(v)&&e(oe,3)});var ce=H(O,2),pe=e=>{Y(e,qo())},_e=e=>{Y(e,Jo())},M=e=>{var t=Zo(),n=B(t),r=e=>{var t=Yo(),n=V(t,!0);U(e=>X(n,e),[()=>K(se)===`WORKING`?`Codex is working — nothing to respond to.`:[`APPROVAL NEEDED`,`INPUT NEEDED`].includes(K(se)||``)?`Respond in Codex for this request.`:`Nothing needs a response right now.`]),Y(e,t)};Z(n,e=>{(K(se)===`WORKING`||!K(v)&&!K(g))&&e(r)});var i=H(n,2),a=e=>{Y(e,Xo())},o=F(()=>[`APPROVAL NEEDED`,`INPUT NEEDED`].includes(K(se)||``)&&!K(v));Z(i,e=>{K(o)&&e(a)}),Y(e,t)},ye=e=>{var r=ys(),i=B(r),o=V(i),s=H(i,2),c=z(s),_=V(c,!0),v=H(c,2),y=e=>{var r=Nr();Xr(B(r),17,()=>K(u).choices||[],Kr,(e,r,i)=>{var o=es(),s=z(o);xi(s),s.value=s.__value=i;var c=H(s),l=H(c),u=e=>{var t=Qo(),n=V(t,!0);U(()=>X(n,K(r).detail)),Y(e,t)};Z(l,e=>{K(r).detail&&e(u)});var d=H(l,2),p=e=>{Y(e,$o())};Z(d,e=>{K(r).persistent&&e(p)}),P(o),U(()=>{Q(s,`name`,`decision-`+t.session+`-`+a()),X(c,` ${K(r).label??``} `)}),Oi(n,[],s,()=>K(f),e=>R(f,e)),Y(e,o)}),Y(e,r)},b=e=>{var n=Zo(),r=B(n),i=e=>{var t=ss(),n=B(t),r=H(z(n)),i=z(r),a=e=>{var t=ts();t.value=t.__value=`now`,Y(e,t)};Z(i,e=>{K(x)||e(a)});var o=H(i);o.value=o.__value=`quota`;var s=H(o);s.value=s.__value=`delay`;var c=H(s);c.value=c.__value=`at`,P(r),mi(r),P(n);var l=H(n,2),u=e=>{var t=ns(),n=H(z(t));xi(n),P(t),Ei(n,()=>K(E),e=>R(E,e)),Y(e,t)};Z(l,e=>{K(T)===`delay`&&e(u)});var d=H(l,2),f=e=>{var t=rs(),n=H(z(t));xi(n),P(t),Ei(n,()=>K(D),e=>R(D,e)),Y(e,t)};Z(d,e=>{K(T)===`at`&&e(f)});var p=H(d,2),m=e=>{var t=as(),n=B(t),r=V(n),i=H(n,2),a=e=>{Y(e,is())};Z(i,e=>{K(T)!==`quota`&&e(a)});var o=H(i,2);o.textContent=`Timezone: ${Intl.DateTimeFormat().resolvedOptions().timeZone??``}.
One pending request per session; saving replaces it. Memory
only; Codexometer must stay running. Uses session model,
- reasoning and speed.`,U(e=>X(r,`Will send: ${e??``}`),[()=>K(T)===`quota`?`when quota is available and this session is idle`:Number.isFinite(K(me))?ge(K(me)):`choose a date and time`]),Y(e,t)};Z(p,e=>{K(T)!==`now`&&e(m)});var h=H(p,2),g=e=>{Y(e,as())};Z(h,e=>{K(x)&&e(g)}),hi(r,()=>K(T),e=>R(T,e)),Y(e,t)};Z(r,e=>{K(u).questions?.length||e(i)}),Xr(H(r,2),17,()=>K(fe),Kr,(e,n,r)=>{var i=ps(),o=B(i),s=e=>{{let n=F(()=>K(d)[0]||``);Ii(No(e,{get session(){return t.session},get oncopy(){return l()},get query(){return K(n)},oncomplete:e=>{R(d,[e],!0),lr().then(()=>K(ne)?.focus())},onchange:()=>{R(d,[``],!0),lr().then(()=>K(ne)?.focus())}}),e=>R(re,e,!0),()=>K(re))}};Z(o,e=>{r===0&&a()!==`profile`&&K(u).kind===`prompt`&&!K(u).questions?.length&&e(s)});var c=H(o,2),f=z(c),p=H(f),m=e=>{var t=ss();xi(t),Ei(t,()=>K(d)[r],e=>K(d)[r]=e),Y(e,t)},h=e=>{var t=ls(),i=z(t);i.value=i.__value=``,Xr(H(i),17,()=>K(n).options||[],Kr,(e,t)=>{var n=cs(),r=V(n,!0),i={};U(()=>{X(r,K(t)),i!==(i=K(t))&&(n.value=(n.__value=i)??``)}),Y(e,n)}),P(t),mi(t),hi(t,()=>K(d)[r],e=>K(d)[r]=e),Y(e,t)},g=e=>{var t=us(),i=B(t);tt(i),Ii(i,e=>R(ne,e),()=>K(ne));var a=H(i,2),o=e=>{var t=Jo(),r=V(t);U(e=>X(r,`Suggested answers: ${e??``}`),[()=>K(n).options.join(` · `)]),Y(e,t)};Z(a,e=>{K(n).options?.length&&e(o)}),q(`keydown`,i,e=>{K(u)?.kind===`prompt`&&!K(u).questions?.length&&K(re)?.handleKey(e)}),Ei(i,()=>K(d)[r],e=>K(d)[r]=e),Y(e,t)};Z(p,e=>{K(n).secret?e(m):K(n).freeText?e(g,-1):e(h,1)}),P(c);var _=H(c,2),v=e=>{var t=fs(),r=H(z(t),4);Xr(r,21,()=>K(n).options||[],Kr,(e,t)=>{var n=ds(),r=V(n,!0);U(()=>X(r,K(t))),Y(e,n)}),P(r),P(t),Y(e,t)};Z(_,e=>{K(n).secret&&!K(n).freeText&&e(v)}),U(()=>X(f,`${K(n).text??``} `)),Y(e,i)}),Y(e,n)};Z(v,e=>{K(u).kind===`approval`||K(u).kind===`profile`?e(y):e(b,-1)}),P(s);var S=H(s,2),C=e=>{var t=hs(),n=B(t),r=e=>{var t=ms(),n=V(t);U(()=>X(n,`TRIGGER // ${K(te)??``}`)),Y(e,t)};Z(n,e=>{K(ee)&&e(r)});var i=H(n,2),a=V(i),o=H(i,2),s=V(o),c=H(o,2);U(e=>{X(a,`Check the target and ${K(u).kind===`profile`?`profile above`:K(u).kind===`approval`?K(u).fileChanges?.length?`proposed file changes above`:`exact command and permission scope`:`message above`}. ${K(ee)?`This schedules a follow-up that will send automatically when eligible`:`This will send to Codex`}; it may start work using your quota.
- Confirmation expires in ${e??``}s.`),o.disabled=K(g)||K(A),X(s,`CONFIRM ${(K(u).kind===`approval`||K(u).kind===`profile`?K(u).choices?.[K(f)]?.label:K(ee)?K(x)?`SAVE CHANGES`:`SCHEDULE`:`SEND`)??``}`)},[()=>Math.max(0,Math.ceil((K(m)-K(h))/1e3))]),q(`click`,o,N),q(`click`,c,()=>{R(p,``)}),Y(e,t)},w=e=>{var t=gs(),n=B(t),r=e=>{var t=Ro(),n=V(t,!0);U(()=>X(n,K(he))),Y(e,t)};Z(n,e=>{K(he)&&e(r)});var i=H(n,2),a=V(i,!0);U(()=>{i.disabled=K(g)||K(A)||!K(j)||!!K(he),X(a,K(g)?`SENDING…`:K(x)?`REVIEW CHANGES`:`REVIEW BEFORE SENDING`)}),q(`click`,i,()=>ve()),Y(e,t)};Z(S,e=>{K(de)?e(C):e(w,-1)});var O=H(S,2),k=e=>{var t=_s();q(`click`,t,()=>{R(x,!1),R(p,``),R(d,[],!0)}),Y(e,t)};Z(O,e=>{K(x)&&e(k)}),U(()=>{X(o,`TARGET // ${K(u).thread??``} // ${(K(u).directory||`Directory unavailable`)??``}`),s.disabled=K(g)||K(de)||K(A),X(_,K(u).kind===`approval`||K(u).kind===`profile`?`Choose a decision`:K(x)?`EDIT SCHEDULED FOLLOW-UP`:`Reply to this session`)}),Y(e,r)};Z(ce,e=>{K(A)||K(y)?e(pe):K(u)?K(u).id?K(b)!==K(u).id&&e(ye,3):e(M,2):e(_e,1)}),P(r),U(()=>X(s,a()===`profile`?`QUOTA THRESHOLD`:`SESSION CONTROL // EXPERIMENTAL`)),Y(e,r)};Z(we,e=>{!K(ce)&&(!K(k)||K(x)||a()||K(u)?.kind!==`prompt`||K(u).questions?.length)&&e(Te)}),Y(e,ye),We()}Sr([`click`,`keydown`]);var xs=J(` `,1),Ss=J(`
`),Cs=J(`
STATUS LINE // CODEXOMETER
Choose multiple fields and their order. These display preferences do not
- change Codex CLI configuration. Missing values are omitted.
`);function Ds(e,t){Ue(t,!0);let n=Wi(t,`active`,3,!1),r=F(()=>io(t.session)),i=F(()=>!!K(r)),a=L(!1),o=L(``),s=L(!1);vn(()=>{if(!K(s))return;let e=setTimeout(()=>{R(s,!1)},150);return()=>clearTimeout(e)}),vn(()=>{K(r),t.session.status,R(o,``)});async function c(){if(!K(i)||K(a))return;let e=K(r);R(a,!0),R(s,!0),R(o,``);try{await navigator.clipboard.writeText(e),K(r)===e&&R(o,`Copied.`)}catch{K(r)===e&&R(o,`Clipboard unavailable. Select the visible text and copy it manually.`)}finally{R(a,!1)}}function l(e){!n()||!K(i)||e.defaultPrevented||e.repeat||e.ctrlKey||e.metaKey||e.altKey||e.key.toLowerCase()!==`c`||e.target instanceof Element&&e.target.closest(`input, textarea, select, [contenteditable]`)||(e.preventDefault(),c())}var u={copy:c},d=Nr();xr(`keydown`,Qt,l);var f=B(d),p=e=>{var t=Es(),n=z(t),r=V(n,!0),i=H(n,2);let l;P(t),U(()=>{X(r,K(o)),i.disabled=K(a),l=ci(i,1,`svelte-543j00`,null,l,{flashed:K(s)})}),q(`click`,i,c),Y(e,t)};return Z(f,e=>{K(i)&&e(p)}),Y(e,d),We(u)}Sr([`click`]);var Os=J(`
`,1),ks=J(`
LATEST GUIDANCE
`,1),As=J(`
CONTEXT
`,1),js=J(`
`),Ms=J(`
`),Ns=J(`
`),Ps=J(`
`,1),Fs=J(`
`),Is=J(`
Command unavailable from this observation. Open Codex to inspect the
- request.
`),Ls=J(`
`,1),Rs=J(`
`),zs=J(` `,1),Bs=J(`
`),Vs=J(`
Session connection or refresh unavailable. Context and telemetry may be
- stale.
`),Hs=J(`
Some quota profile checks are unavailable. Only sessions with freshly
+ reasoning and speed.`,U(e=>X(r,`Will send: ${e??``}`),[()=>K(T)===`quota`?`when quota is available and this session is idle`:Number.isFinite(K(me))?ge(K(me)):`choose a date and time`]),Y(e,t)};Z(p,e=>{K(T)!==`now`&&e(m)});var h=H(p,2),g=e=>{Y(e,os())};Z(h,e=>{K(x)&&e(g)}),hi(r,()=>K(T),e=>R(T,e)),Y(e,t)};Z(r,e=>{K(u).questions?.length||e(i)}),Xr(H(r,2),17,()=>K(fe),Kr,(e,n,r)=>{var i=ms(),o=B(i),s=e=>{{let n=F(()=>K(d)[0]||``);Ii(Po(e,{get session(){return t.session},get oncopy(){return l()},get query(){return K(n)},oncomplete:e=>{R(d,[e],!0),lr().then(()=>K(ne)?.focus())},onchange:()=>{R(d,[``],!0),lr().then(()=>K(ne)?.focus())}}),e=>R(re,e,!0),()=>K(re))}};Z(o,e=>{r===0&&a()!==`profile`&&K(u).kind===`prompt`&&!K(u).questions?.length&&e(s)});var c=H(o,2),f=z(c),p=H(f),m=e=>{var t=cs();xi(t),Ei(t,()=>K(d)[r],e=>K(d)[r]=e),Y(e,t)},h=e=>{var t=us(),i=z(t);i.value=i.__value=``,Xr(H(i),17,()=>K(n).options||[],Kr,(e,t)=>{var n=ls(),r=V(n,!0),i={};U(()=>{X(r,K(t)),i!==(i=K(t))&&(n.value=(n.__value=i)??``)}),Y(e,n)}),P(t),mi(t),hi(t,()=>K(d)[r],e=>K(d)[r]=e),Y(e,t)},g=e=>{var t=ds(),i=B(t);tt(i),Ii(i,e=>R(ne,e),()=>K(ne));var a=H(i,2),o=e=>{var t=Yo(),r=V(t);U(e=>X(r,`Suggested answers: ${e??``}`),[()=>K(n).options.join(` · `)]),Y(e,t)};Z(a,e=>{K(n).options?.length&&e(o)}),q(`keydown`,i,e=>{K(u)?.kind===`prompt`&&!K(u).questions?.length&&K(re)?.handleKey(e)}),Ei(i,()=>K(d)[r],e=>K(d)[r]=e),Y(e,t)};Z(p,e=>{K(n).secret?e(m):K(n).freeText?e(g,-1):e(h,1)}),P(c);var _=H(c,2),v=e=>{var t=ps(),r=H(z(t),4);Xr(r,21,()=>K(n).options||[],Kr,(e,t)=>{var n=fs(),r=V(n,!0);U(()=>X(r,K(t))),Y(e,n)}),P(r),P(t),Y(e,t)};Z(_,e=>{K(n).secret&&!K(n).freeText&&e(v)}),U(()=>X(f,`${K(n).text??``} `)),Y(e,i)}),Y(e,n)};Z(v,e=>{K(u).kind===`approval`||K(u).kind===`profile`?e(y):e(b,-1)}),P(s);var S=H(s,2),C=e=>{var t=gs(),n=B(t),r=e=>{var t=hs(),n=V(t);U(()=>X(n,`TRIGGER // ${K(te)??``}`)),Y(e,t)};Z(n,e=>{K(ee)&&e(r)});var i=H(n,2),a=V(i),o=H(i,2),s=V(o),c=H(o,2);U(e=>{X(a,`Check the target and ${K(u).kind===`profile`?`profile above`:K(u).kind===`approval`?K(u).fileChanges?.length?`proposed file changes above`:`exact command and permission scope`:`message above`}. ${K(ee)?`This schedules a follow-up that will send automatically when eligible`:`This will send to Codex`}; it may start work using your quota.
+ Confirmation expires in ${e??``}s.`),o.disabled=K(g)||K(A),X(s,`CONFIRM ${(K(u).kind===`approval`||K(u).kind===`profile`?K(u).choices?.[K(f)]?.label:K(ee)?K(x)?`SAVE CHANGES`:`SCHEDULE`:`SEND`)??``}`)},[()=>Math.max(0,Math.ceil((K(m)-K(h))/1e3))]),q(`click`,o,N),q(`click`,c,()=>{R(p,``)}),Y(e,t)},w=e=>{var t=_s(),n=B(t),r=e=>{var t=zo(),n=V(t,!0);U(()=>X(n,K(he))),Y(e,t)};Z(n,e=>{K(he)&&e(r)});var i=H(n,2),a=V(i,!0);U(()=>{i.disabled=K(g)||K(A)||!K(j)||!!K(he),X(a,K(g)?`SENDING…`:K(x)?`REVIEW CHANGES`:`REVIEW BEFORE SENDING`)}),q(`click`,i,()=>ve()),Y(e,t)};Z(S,e=>{K(de)?e(C):e(w,-1)});var O=H(S,2),k=e=>{var t=vs();q(`click`,t,()=>{R(x,!1),R(p,``),R(d,[],!0)}),Y(e,t)};Z(O,e=>{K(x)&&e(k)}),U(()=>{X(o,`TARGET // ${K(u).thread??``} // ${(K(u).directory||`Directory unavailable`)??``}`),s.disabled=K(g)||K(de)||K(A),X(_,K(u).kind===`approval`||K(u).kind===`profile`?`Choose a decision`:K(x)?`EDIT SCHEDULED FOLLOW-UP`:`Reply to this session`)}),Y(e,r)};Z(ce,e=>{K(A)||K(y)?e(pe):K(u)?K(u).id?K(b)!==K(u).id&&e(ye,3):e(M,2):e(_e,1)}),P(r),U(()=>X(s,a()===`profile`?`QUOTA THRESHOLD`:`SESSION CONTROL // EXPERIMENTAL`)),Y(e,r)};Z(we,e=>{!K(ce)&&(!K(k)||K(x)||a()||K(u)?.kind!==`prompt`||K(u).questions?.length)&&e(Te)}),Y(e,ye),We()}Sr([`click`,`keydown`]);var Ss=J(` `,1),Cs=J(`
`),ws=J(`
STATUS LINE // CODEXOMETER
Choose multiple fields and their order. These display preferences do not
+ change Codex CLI configuration. Missing values are omitted.
`);function Os(e,t){Ue(t,!0);let n=Wi(t,`active`,3,!1),r=F(()=>ao(t.session)),i=F(()=>!!K(r)),a=L(!1),o=L(``),s=L(!1);vn(()=>{if(!K(s))return;let e=setTimeout(()=>{R(s,!1)},150);return()=>clearTimeout(e)}),vn(()=>{K(r),t.session.status,R(o,``)});async function c(){if(!K(i)||K(a))return;let e=K(r);R(a,!0),R(s,!0),R(o,``);try{await navigator.clipboard.writeText(e),K(r)===e&&R(o,`Copied.`)}catch{K(r)===e&&R(o,`Clipboard unavailable. Select the visible text and copy it manually.`)}finally{R(a,!1)}}function l(e){!n()||!K(i)||e.defaultPrevented||e.repeat||e.ctrlKey||e.metaKey||e.altKey||e.key.toLowerCase()!==`c`||e.target instanceof Element&&e.target.closest(`input, textarea, select, [contenteditable]`)||(e.preventDefault(),c())}var u={copy:c},d=Nr();xr(`keydown`,Qt,l);var f=B(d),p=e=>{var t=Ds(),n=z(t),r=V(n,!0),i=H(n,2);let l;P(t),U(()=>{X(r,K(o)),i.disabled=K(a),l=ci(i,1,`svelte-543j00`,null,l,{flashed:K(s)})}),q(`click`,i,c),Y(e,t)};return Z(f,e=>{K(i)&&e(p)}),Y(e,d),We(u)}Sr([`click`]);var ks=J(`
`,1),As=J(`
LATEST GUIDANCE
`,1),js=J(`
CONTEXT
`,1),Ms=J(`
`),Ns=J(`
`),Ps=J(`
`),Fs=J(`
`,1),Is=J(`
`),Ls=J(`
Command unavailable from this observation. Open Codex to inspect the
+ request.
`),Rs=J(`
`,1),zs=J(`
`),Bs=J(` `,1),Vs=J(`
`),Hs=J(`
Session connection or refresh unavailable. Context and telemetry may be
+ stale.
`),Us=J(`
Some quota profile checks are unavailable. Only sessions with freshly
verified quota and settings can be updated; previous outcome notices remain
- visible.
↑ ↓ SELECT SESSION // ← LESS DETAIL // → MORE DETAIL // ESC BACK
`,1),fc=J(`
SESSION TOTALS
`,1);function pc(e,t){Ue(t,!0);let n=(e,t=f,n,r)=>{let i=pt(()=>g(n?.(),!0)),a=pt(()=>g(r?.(),!1));var o=Bs(),s=B(o),c=e=>{var n=ks(),r=B(n),i=V(r,!0),a=V(H(r,2),!0);U(()=>{X(i,t().contextKind===`LAST REPLY`&&!t().streaming?`TASK`:`CURRENT TASK`),X(a,t().currentTask)}),Y(e,n)};Z(s,e=>{t().currentTask&&e(c)});var l=H(s,2),u=e=>{var n=As(),r=V(H(B(n),2),!0);U(()=>X(r,t().latestGuidance)),Y(e,n)};Z(l,e=>{t().latestGuidance&&e(u)});var d=H(l,2),p=e=>{var n=js(),r=V(H(B(n),2),!0);xe(2),U(()=>X(r,t().approvalContext)),Y(e,n)};Z(d,e=>{K(a)&&t().contextKind===`APPROVAL REQUEST`&&t().approvalContext&&e(p)});var m=H(d,2),h=e=>{var n=Ms();let r;var i=V(n,!0);U(e=>{r=ci(n,1,`attention-note`,null,r,{inferred:t().status===`CHECK SESSION`}),X(i,e)},[()=>w(t())]),Y(e,n)},_=F(()=>w(t())&&(!K(a)||K(v)||t().status===`CHECK SESSION`));Z(m,e=>{K(_)&&e(h)});var y=H(m,2),b=e=>{var n=Ns(),r=V(n,!0);U(e=>X(r,e),[()=>T(t())]),Y(e,n)};Z(y,e=>{K(i)&&e(b)});var x=H(y,2),S=e=>{var n=Ps(),r=V(n,!0);U(()=>X(r,t().text||`No session context available.`)),Y(e,n)};Z(x,e=>{(t().text||!t().workingCommand)&&e(S)});var C=H(x,2),E=e=>{var n=Fs(),r=H(B(n),2),i=z(r),a=H(i),o=e=>{var n=Mr();U(()=>X(n,`// +${(t().runningCommands||0)-+(t().commandStatus===`running`)} RUNNING`)),Y(e,n)};Z(a,e=>{!K(v)&&(t().runningCommands||0)>+(t().commandStatus===`running`)&&e(o)});var s=H(a,2),c=e=>{Y(e,Mr(`+`))};Z(s,e=>{t().runningLimited&&e(c)}),P(r);var l=V(H(r,2),!0);U(e=>{X(i,`COMMAND // ${e??``} `),X(l,t().workingCommand)},[()=>K(v)?`UNKNOWN`:(t().commandStatus||`unknown`).toUpperCase()]),Y(e,n)};Z(C,e=>{t().workingCommand&&e(E)});var D=H(C,2),ee=e=>{Ro(e,{get lines(){return t().fileChanges}})},te=e=>{var n=Rs(),r=H(B(n),2),i=V(r,!0),a=H(r,2),o=e=>{var n=Is(),r=V(n,!0);U(()=>X(r,t().command)),Y(e,n)},s=e=>{Y(e,Ls())};Z(a,e=>{t().command?e(o):e(s,-1)}),U(()=>X(i,K(v)||t().status!==`APPROVAL NEEDED`?`LAST OBSERVED COMMAND`:$.data?.control?`COMMAND REQUEST`:`COMMAND TO APPROVE IN CODEX`)),Y(e,n)};Z(D,e=>{(!K(a)||!$.data?.control)&&t().fileChanges?.length?e(ee):(!K(a)||!$.data?.control)&&(t().command||t().status===`APPROVAL NEEDED`)&&e(te,1)});var O=H(D,2),k=e=>{var n=zs(),r=V(n);U(()=>X(r,`CONTEXT SOURCE // ${(t().source||`LOCAL`)??``} // OBSERVATION`)),Y(e,n)};Z(O,e=>{K(a)||e(k)}),Y(e,o)},r=L(void 0),i=Wi(t,`params`,19,()=>({})),a=F(()=>$.data?.sessions||[]),o=F(()=>$.data?.control&&$.data.profiles||[]),s=F(()=>($.data?.triggers||[]).filter(e=>K(a).some(t=>t.id===e.session)));function c(e,t){if(i().id&&i().id!==t&&K(u)){e.preventDefault();return}x(t)}function l(e){return[`TURN COMPLETE`,`IDLE`,`ACTIVE`].includes(e.status)&&K(s).some(t=>t.session===e.id)?`TRIGGER SET`:e.status}let u=L(!1);function d(e,t){if(i().id&&i().id!==t&&K(u)){e.preventDefault();return}x(t)}vn(()=>{let e=i().id;e&&fr(()=>{aa.selected=e,fa(e,2)})});let p=F(()=>K(a).find(e=>e.id===i().id)),m=F(()=>new URLSearchParams(Yi.querystring).get(`review`)===`profile`&&K(o).some(e=>e.session===i().id&&e.pending)),h=F(()=>K(a).some(e=>e.id===aa.selected)?aa.selected:K(a)[0]?.id),v=F(()=>!$.connected||!!$.data?.sessionsError),y=F(()=>[[`OBSERVED TOKENS`,pa(K(a).reduce((e,t)=>e+t.tokens,0))],[`LISTED SESSIONS`,pa(K(a).length)],...[[`WORKING`,`WORKING`],[`AWAITING APPROVAL`,`APPROVAL NEEDED`],[`AWAITING INPUT`,`INPUT NEEDED`],[`CHECK · INFERRED`,`CHECK SESSION`]].map(([e,t])=>[e,K(v)?`—`:pa(K(a).filter(e=>e.status===t).length)])]),b=F(()=>K(a).filter(e=>[`INPUT NEEDED`,`APPROVAL NEEDED`,`CHECK SESSION`].includes(e.status)));function x(e){aa.selected=e,lr().then(()=>document.querySelector(`.session-row.selected`)?.scrollIntoView({block:`nearest`}))}function S(e,t){if(x(e),i().id){t<0&&(fa(e,2),location.hash=`/sessions`);return}let n=ua(e)+t;n>2?location.hash=`/sessions/`+encodeURIComponent(e):fa(e,n)}function C(e){let t=e.target;if(!(e.altKey||e.ctrlKey||e.metaKey||e.shiftKey||t.closest(`input, textarea, select, [contenteditable="true"]`))){if(e.key===`Escape`&&i().id)e.preventDefault(),S(i().id,-1);else if([`ArrowLeft`,`ArrowRight`].includes(e.key)&&(i().id||K(h)))e.preventDefault(),S(i().id||K(h),e.key===`ArrowLeft`?-1:1);else if(!i().id&&[`ArrowUp`,`ArrowDown`].includes(e.key)&&K(a).length){e.preventDefault();let t=K(a).findIndex(e=>e.id===K(h));x(K(a)[Math.max(0,Math.min(K(a).length-1,t+(e.key===`ArrowUp`?-1:1)))].id)}}}function w(e){return K(v)?`Last observation only — refresh unavailable. Check Codex for current state.`:e.status===`CHECK SESSION`?`INFERRED INACTIVITY — a quiet session, not a confirmed input or approval request. Local tools may still be running.`:$.data?.control&&[`APPROVAL NEEDED`,`INPUT NEEDED`].includes(e.status)?`Open full detail for supported live controls; otherwise reply in Codex.`:e.status===`APPROVAL NEEDED`?`OBSERVED APPROVAL SIGNAL — approve or decline in Codex.`:e.status===`INPUT NEEDED`?`OBSERVED INPUT SIGNAL — reply in Codex.`:e.status===`TURN COMPLETE`?`OBSERVED TURN COMPLETION — informational, not an approval request.`:``}function T(e){return e.streaming&&e.contextKind===`LAST REPLY`?`REPLY // STREAMING`:e.contextKind||`LAST ACTIVITY`}var E=fc();xr(`keydown`,Qt,C);var D=B(E),ee=V(H(z(D),2));P(D);var te=H(D,2);let O;Xr(te,21,()=>K(y),Kr,(e,t)=>{var n=F(()=>_(K(t),2));let r=()=>K(n)[0],i=()=>K(n)[1];var a=Vs(),o=z(a),s=V(o,!0),c=V(H(o,2),!0);P(a),U(()=>{X(s,r()),X(c,i())}),Y(e,a)}),P(te);var k=H(te,2),ne=V(k),re=H(k,2),ie=e=>{Y(e,Hs())};Z(re,e=>{K(v)&&e(ie)});var ae=H(re,2),oe=e=>{Y(e,Us())};Z(ae,e=>{$.data?.profileError&&e(oe)});var se=H(ae,2),A=e=>{var t=qs(),n=z(t);Xr(n,17,()=>K(b),Kr,(e,t)=>{var n=Ws();let r;var i=V(n);U((e,a)=>{r=ci(n,1,`button`,null,r,{approval:K(t).status===`APPROVAL NEEDED`}),Q(n,`href`,e),X(i,`${K(t).status??``}
+ ${a??``} // ${(K(t).name||K(t).directory||K(t).id)??``}`)},[()=>`#/sessions/`+encodeURIComponent(K(t).id),()=>Array.from(K(t).id).slice(-5).join(``).toUpperCase()]),q(`click`,n,()=>x(K(t).id)),Y(e,n)});var r=H(n,2);Xr(r,17,()=>K(o).filter(e=>e.pending&&K(a).some(t=>t.id===e.session)),Kr,(e,t)=>{var n=Gs(),r=V(n);U((e,a,o)=>{Q(n,`title`,i().id&&i().id!==K(t).session&&K(u)?`Finish sending or clear your current draft before switching sessions.`:`Review this session’s quota threshold`),Q(n,`href`,e),X(r,`QUOTA THRESHOLD ${a??``} // ${o??``}`)},[()=>`#/sessions/`+encodeURIComponent(K(t).session)+`?review=profile`,()=>Array.from(K(t).session).slice(-5).join(``).toUpperCase(),()=>K(a).find(e=>e.id===K(t).session)?.name||K(a).find(e=>e.id===K(t).session)?.directory||K(t).session]),q(`click`,n,e=>d(e,K(t).session)),Y(e,n)}),Xr(H(r,2),17,()=>K(s),Kr,(e,t)=>{var n=Ks(),r=V(n);U((e,t,i)=>{Q(n,`href`,e),X(r,`TRIGGER SET ${t??``} // ${i??``}`)},[()=>`#/sessions/`+encodeURIComponent(K(t).session),()=>Array.from(K(t).session).slice(-5).join(``).toUpperCase(),()=>K(a).find(e=>e.id===K(t).session)?.name||K(a).find(e=>e.id===K(t).session)?.directory]),q(`click`,n,e=>c(e,K(t).session)),Y(e,n)}),P(t),Y(e,t)},ce=F(()=>(K(b).length||K(o).some(e=>e.pending)||K(s).length)&&!K(v));Z(se,e=>{K(ce)&&e(A)});var le=H(se,2),ue=e=>{var t=Nr(),a=B(t),s=e=>{var t=Qs(),a=z(t),s=z(a),c=z(s);let d;var f=H(c);P(s);var h=H(s,2);P(a);var g=H(a,2),_=e=>{var t=zs(),n=V(t,!0);U(()=>X(n,K(p).directory)),Y(e,t)};Z(g,e=>{K(p).name&&K(p).directory&&e(_)});var y=H(g,2),b=V(y),S=H(y,2);let C;var w=z(S),T=z(w);n(T,()=>K(p),()=>!0,()=>!0),P(w);var E=H(w,2),D=e=>{var t=Nr();Gr(B(t),()=>K(p).id,e=>{{let t=F(()=>new URLSearchParams(Yi.querystring).get(`schedule`)===`edit`),n=F(()=>K(p).fileChanges||[]);xs(e,{get session(){return K(p).id},oncopy:()=>K(r)?.copy(),get openScheduler(){return K(t)},get observedCommand(){return K(p).command},get observedFileChanges(){return K(n)},get suspended(){return K(m)},onProtectedChange:e=>{R(u,e,!0)}})}}),Y(e,t)},ee=e=>{var t=Js();Gr(H(z(t),2),()=>K(p).id,e=>{Po(e,{get session(){return K(p).id},localOnly:!0,oncopy:()=>K(r)?.copy()})}),P(t),Y(e,t)};Z(E,e=>{$.data?.control?e(D):e(ee,-1)}),P(S);var te=H(S,2);Xr(te,17,()=>K(o).filter(e=>e.session===K(p).id),e=>e.session,(e,t)=>{var n=Zs(),r=z(n),i=e=>{var n=Ys(),r=V(n,!0);U(()=>X(r,K(t).notice)),Y(e,n)};Z(r,e=>{K(t).notice&&e(i)});var a=H(r,2),o=e=>{xs(e,{get session(){return K(p).id},review:`profile`})},s=e=>{var t=Xs();U(e=>Q(t,`href`,e),[()=>`#/sessions/`+encodeURIComponent(K(p).id)+`?review=profile`]),Y(e,t)};Z(a,e=>{K(t).pending&&K(m)?e(o):K(t).pending&&e(s,1)}),P(n),U(()=>Q(n,`id`,`quota-profile-`+K(p).id)),Y(e,n)});var O=H(te,2),k=e=>{var t=Nr();Gr(B(t),()=>K(p).id,e=>{Ii(Os(e,{get session(){return K(p)},active:!0}),e=>R(r,e,!0),()=>K(r))}),Y(e,t)};Z(O,e=>{K(m)||e(k)}),Gr(H(O,2),()=>K(p).id,e=>{Es(e,{get session(){return K(p)},get stale(){return K(v)}})}),P(t),U((e,t)=>{d=ci(c,1,`lamp lit`,null,d,{working:K(p).status===`WORKING`&&!K(v)}),X(f,`${e??``} // ${(K(p).name||K(p).directory)??``}`),X(b,`${t??``} TOKENS // ${K(p).id??``} // CONTEXT SOURCE // ${(K(p).source||`LOCAL`)??``}`),C=ui(S,``,C,{display:K(m)?`none`:void 0})},[()=>K(v)?`STALE`:K(m)?`QUOTA THRESHOLD`:l(K(p)),()=>pa(K(p).tokens)]),q(`click`,h,()=>{x(i().id),fa(i().id,2)}),Y(e,t)},c=e=>{Y(e,$s())};Z(a,e=>{K(p)?e(s):e(c,-1)}),Y(e,t)},de=e=>{var t=dc(),r=B(t),i=H(z(r),2),s=z(i),c=H(s,2);P(i),P(r);var u=H(r,2);Xr(u,17,()=>K(a),e=>e.id,(e,t)=>{let r=F(()=>ua(K(t).id));var i=lc();let a;var s=z(i),c=z(s),u=e=>{var n=ec(),r=z(n),i=V(r);P(n),U(e=>{Q(r,`aria-pressed`,K(h)===K(t).id),X(i,`${e??``} // ${K(t).name??``}`)},[()=>Array.from(K(t).id).slice(-5).join(``).toUpperCase()]),q(`click`,r,()=>x(K(t).id)),Y(e,n)};Z(c,e=>{K(t).name&&e(u)});var f=H(c,2),p=z(f),m=z(p);let g;var _=H(m,1,!0);P(p),P(f);var y=H(f,2),b=e=>{var n=tc(),r=V(n,!0);U(()=>{Q(n,`aria-pressed`,K(h)===K(t).id),X(r,K(t).directory||K(t).id)}),q(`click`,n,()=>x(K(t).id)),Y(e,n)};Z(y,e=>{K(t).name||e(b)});var C=H(y,2),w=z(C);xe(),P(C);var E=H(C,2),D=e=>{var n=zs(),r=V(n,!0);U(()=>X(r,K(t).directory)),Y(e,n)};Z(E,e=>{K(t).name&&K(t).directory&&e(D)});var ee=H(E,2),te=V(ee),O=H(ee,2),k=V(O),ne=H(O,2),re=z(ne),ie=H(re,2),ae=V(ie,!0),oe=H(ie,2);P(ne);var se=H(ne,2),A=H(se,2),ce=e=>{var n=nc(),r=V(n,!0);U(()=>X(r,K(t).status===`CHECK SESSION`?`INFERRED INACTIVITY`:$.data?.control?`OPEN FULL DETAIL OR REPLY IN CODEX`:K(t).status===`APPROVAL NEEDED`?`APPROVE OR DECLINE IN CODEX`:`REPLY IN CODEX`)),Y(e,n)},le=F(()=>!K(v)&&[`APPROVAL NEEDED`,`INPUT NEEDED`,`CHECK SESSION`].includes(K(t).status));Z(A,e=>{K(le)&&e(ce)}),P(s);var ue=H(s,2),de=e=>{var r=sc(),i=z(r),a=z(i),s=V(a,!0),c=H(a,2),l=e=>{var n=rc(),r=V(n,!0);U(e=>{Q(n,`href`,e),X(r,$.data?.control?`REVIEW IN FULL DETAIL ↗`:`APPROVAL IN CODEX ↗`)},[()=>`#/sessions/`+encodeURIComponent(K(t).id)]),Y(e,n)};Z(c,e=>{!K(v)&&K(t).status===`APPROVAL NEEDED`&&e(l)}),P(i);var u=H(i,2);n(u,()=>K(t),()=>!1);var f=H(u,2);Xr(f,17,()=>K(o).filter(e=>e.session===K(t).id),Kr,(e,n)=>{var r=oc(),i=B(r),a=e=>{var t=ic(),r=V(t,!0);U(()=>X(r,K(n).notice)),Y(e,t)};Z(i,e=>{K(n).notice&&e(a)});var o=H(i,2),s=e=>{var n=ac();U(e=>Q(n,`href`,e),[()=>`#/sessions/`+encodeURIComponent(K(t).id)+`?review=profile`]),q(`click`,n,e=>d(e,K(t).id)),Y(e,n)};Z(o,e=>{K(n).pending&&e(s)}),Y(e,r)});var p=H(f,2);{let e=F(()=>K(h)===K(t).id);Os(p,{get session(){return K(t)},get active(){return K(e)}})}P(r),U(e=>X(s,e),[()=>T(K(t))]),Y(e,r)};Z(ue,e=>{K(r)>0&&e(de)});var fe=H(ue,2),j=e=>{var n=cc(),r=H(z(n),2);{let e=F(()=>(K(t).samples||[]).map(e=>e.tokens));io(r,{get values(){return K(e)},capacity:120})}var i=V(H(r,2));P(n),U(()=>X(i,`LAST ${(K(t).samples?.length||0)??``} SAMPLES // AUTO SCALE`)),Y(e,n)};Z(fe,e=>{K(r)<2&&e(j)}),P(i),U((e,n,o,s,c)=>{a=ci(i,1,`session-row`,null,a,{selected:K(h)===K(t).id,wide:K(r)===2,split:K(r)===1}),Q(i,`aria-label`,`Session `+(K(t).name||K(t).directory||K(t).id)),Q(p,`href`,e),g=ci(m,1,`lamp lit`,null,g,{working:K(t).status===`WORKING`&&!K(v)}),X(_,n),X(w,`${o??``} `),X(te,`${K(t).agents??``} LINKED AGENTS`),X(k,`ACTIVE // ${s??``}`),re.disabled=K(r)===0,Q(ie,`aria-expanded`,K(r)>0),X(ae,K(r)?`HIDE DETAIL`:`SHOW DETAIL`),Q(se,`href`,c)},[()=>`#/sessions/`+encodeURIComponent(K(t).id),()=>K(v)?`STALE`:l(K(t)),()=>pa(K(t).tokens),()=>ma(K(t).activity),()=>`#/sessions/`+encodeURIComponent(K(t).id)]),q(`click`,p,()=>x(K(t).id)),q(`click`,re,()=>S(K(t).id,-1)),q(`click`,ie,()=>{x(K(t).id),fa(K(t).id,+!K(r))}),q(`click`,oe,()=>S(K(t).id,1)),q(`click`,se,()=>x(K(t).id)),Y(e,i)});var f=H(u,2),p=e=>{Y(e,uc())};Z(f,e=>{K(a).length||e(p)}),q(`click`,s,()=>da(1)),q(`click`,c,()=>da(0)),Y(e,t)};Z(le,e=>{i().id?e(ue):e(de,-1)}),U(e=>{X(ee,`OBSERVED ${e??``}`),O=ci(te,1,`session-totals`,null,O,{stale:K(v)}),X(ne,`${K(v)?`LAST KNOWN TOTALS — live state counts unavailable. `:``}Tokens
observed since this server started for currently listed sessions; linked
agents are already included. Totals can decrease when a session leaves the
- list. History samples every 30 seconds. Not account-wide totals.`)},[()=>ma($.data?.sessionsAt)]),Y(e,E),We()}Sr([`click`]);var pc=J(`
`),mc=J(`
Relative usage/credits are not tokens or quota percentages. Groupings
- describe the same usage, not additional consumption.
`,1),hc=J(`// APPROXIMATE`),gc=J(`
Partial accounting: totals may still change.
`),_c=J(`
Percentage of this period's historical allowance, not today's limit. May
- exceed 100%. This is not a manual/automatic reset log.
`,1),vc=J(`
`,1),yc=J(`
This optional account report is unavailable. Token history remains
- available; missing data does not mean zero usage.
`),bc=J(`
`),xc=J(`
`),Sc=J(`
No usage reported for this day.
`),Cc=J(`
Selected breakdown unavailable; missing does not mean zero.
`),wc=J(`
`,1);function Tc(e,t){Ue(t,!0);let n=L(`surface`),r=L(0),i=F(()=>t.reports?.daily),a=F(()=>t.reports?.plan),o=F(()=>t.mode===`breakdown`?K(i)?.days.length||0:K(a)?.periods.length||0),s=F(()=>Math.min(K(r),Math.max(0,K(o)-1))),c=F(()=>K(i)?.days[(K(i)?.days.length||0)-1-K(s)]),l=F(()=>K(a)?.periods[K(s)]),u=F(()=>t.mode===`breakdown`?K(i)?.units||``:`%`),d=F(()=>{let e=Object.create(null);if(t.mode===`breakdown`)e=K(c)?.groups[K(n)]||{};else{let t=K(n)===`feature`?`thread_source`:K(n)===`task start`?`turn_trigger`:K(n);for(let n of K(l)?.breakdowns||[])if(n.dimension===t)for(let t of n.rows)e[t.key]=(e[t.key]||0)+t.basis_points/100}return Object.entries(e).sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0]))}),f=F(()=>t.mode===`breakdown`?K(c)?.total:K(l)?.used_basis_points==null?null:K(l).used_basis_points/100),p=F(()=>Math.max(1,K(f)||0,...K(d).map(([,e])=>e))),m=e=>e==null?`UNKNOWN`:e.toLocaleString(`en-GB`,{maximumFractionDigits:2});var h=wc(),g=B(h),v=z(g),y=H(z(v)),b=z(y);b.value=b.__value=`surface`;var x=H(b);x.value=x.__value=`model`;var S=H(x);S.value=S.__value=`feature`;var C=H(S);C.value=C.__value=`task start`,P(y),mi(y),P(v);var w=H(v,2),T=H(w,2),E=V(H(T,2),!0);P(g);var D=H(g,2),ee=z(D),te=V(ee,!0),O=H(ee,2),k=V(O),ne=H(O,2),re=e=>{var t=mc(),n=B(t),r=V(n),a=H(n,2),o=e=>{var t=pc(),n=V(t);U(()=>X(n,`Data as of ${K(i).dataAsOf??``}`)),Y(e,t)};Z(a,e=>{K(i).dataAsOf&&e(o)});var s=V(H(a,2));xe(2),U((e,t)=>{X(r,`Latest fetch ${e??``} // queried ${K(i).from??``} → ${K(i).through??``}.
+ list. History samples every 30 seconds. Not account-wide totals.`)},[()=>ma($.data?.sessionsAt)]),Y(e,E),We()}Sr([`click`]);var mc=J(`
`),hc=J(`
Relative usage/credits are not tokens or quota percentages. Groupings
+ describe the same usage, not additional consumption.
`,1),gc=J(`// APPROXIMATE`),_c=J(`
Partial accounting: totals may still change.
`),vc=J(`
Percentage of this period's historical allowance, not today's limit. May
+ exceed 100%. This is not a manual/automatic reset log.
`,1),yc=J(`
`,1),bc=J(`
This optional account report is unavailable. Token history remains
+ available; missing data does not mean zero usage.
`),xc=J(`
`),Sc=J(`
`),Cc=J(`
No usage reported for this day.
`),wc=J(`
Selected breakdown unavailable; missing does not mean zero.
`),Tc=J(`
`,1);function Ec(e,t){Ue(t,!0);let n=L(`surface`),r=L(0),i=F(()=>t.reports?.daily),a=F(()=>t.reports?.plan),o=F(()=>t.mode===`breakdown`?K(i)?.days.length||0:K(a)?.periods.length||0),s=F(()=>Math.min(K(r),Math.max(0,K(o)-1))),c=F(()=>K(i)?.days[(K(i)?.days.length||0)-1-K(s)]),l=F(()=>K(a)?.periods[K(s)]),u=F(()=>t.mode===`breakdown`?K(i)?.units||``:`%`),d=F(()=>{let e=Object.create(null);if(t.mode===`breakdown`)e=K(c)?.groups[K(n)]||{};else{let t=K(n)===`feature`?`thread_source`:K(n)===`task start`?`turn_trigger`:K(n);for(let n of K(l)?.breakdowns||[])if(n.dimension===t)for(let t of n.rows)e[t.key]=(e[t.key]||0)+t.basis_points/100}return Object.entries(e).sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0]))}),f=F(()=>t.mode===`breakdown`?K(c)?.total:K(l)?.used_basis_points==null?null:K(l).used_basis_points/100),p=F(()=>Math.max(1,K(f)||0,...K(d).map(([,e])=>e))),m=e=>e==null?`UNKNOWN`:e.toLocaleString(`en-GB`,{maximumFractionDigits:2});var h=Tc(),g=B(h),v=z(g),y=H(z(v)),b=z(y);b.value=b.__value=`surface`;var x=H(b);x.value=x.__value=`model`;var S=H(x);S.value=S.__value=`feature`;var C=H(S);C.value=C.__value=`task start`,P(y),mi(y),P(v);var w=H(v,2),T=H(w,2),E=V(H(T,2),!0);P(g);var D=H(g,2),ee=z(D),te=V(ee,!0),O=H(ee,2),k=V(O),ne=H(O,2),re=e=>{var t=hc(),n=B(t),r=V(n),a=H(n,2),o=e=>{var t=mc(),n=V(t);U(()=>X(n,`Data as of ${K(i).dataAsOf??``}`)),Y(e,t)};Z(a,e=>{K(i).dataAsOf&&e(o)});var s=V(H(a,2));xe(2),U((e,t)=>{X(r,`Latest fetch ${e??``} // queried ${K(i).from??``} → ${K(i).through??``}.
Reports are fetched from OpenAI and are not saved between runs.`),X(s,`${(K(c)?.date||`No daily buckets reported`)??``} // ${t??``}
- ${K(u)??``}`)},[()=>ma(K(i).fetchedAt),()=>m(K(f))]),Y(e,t)},ie=e=>{var t=vc(),n=B(t),r=z(n);let i;var o=V(r,!0),s=H(r),c=e=>{Y(e,hc())};Z(s,e=>{K(a).approximate&&e(c)});var u=H(s);P(n);var d=H(n,2),p=z(d),h=H(p),g=e=>{var t=Mr();U(()=>X(t,`// Boundary tolerance ${K(a).boundary_tolerance_seconds??``}s`)),Y(e,t)};Z(h,e=>{K(a).boundary_tolerance_seconds!=null&&e(g)}),P(d);var _=H(d,2),v=e=>{var t=_c(),n=B(t),r=z(n),i=H(r);let a;var o=V(i);P(n);var s=H(n,2),c=V(s),u=H(s,2),d=e=>{Y(e,gc())};Z(u,e=>{K(l).accounting_complete||e(d)}),xe(2),U(e=>{X(r,`${K(l).window_minutes??``} MIN // ${K(l).plan_type??``} // `),a=ci(i,1,`svelte-1fbui7h`,null,a,{muted:K(f)==null,"quota-near":K(f)!=null&&K(f)>=80&&K(f)<100,"quota-full":K(f)!=null&&K(f)>=100}),X(o,`USED ${e??``}${K(f)==null?``:`%`}`),X(c,`${K(l).starts_at??``} → ${K(l).ends_at??``}`)},[()=>m(K(f))]),Y(e,t)};Z(_,e=>{K(l)&&e(v)}),U(e=>{i=ci(r,1,`svelte-1fbui7h`,null,i,{"quality-warning":!K(a).coverage_complete}),X(o,K(a).coverage_complete?`Reported range complete`:`Partial coverage`),X(u,` // Latest fetch ${e??``}`),X(p,`Coverage starts ${(K(a).coverage_start||`unknown`)??``} // Data as of ${(K(a).data_as_of||`unknown`)??``}`)},[()=>ma(K(a).fetchedAt)]),Y(e,t)},ae=e=>{Y(e,yc())};Z(ne,e=>{t.mode===`breakdown`&&K(i)?e(re):t.mode===`periods`&&K(a)?e(ie,1):e(ae,-1)});var oe=H(ne,2),se=e=>{var n=xc(),r=z(n),i=V(H(z(r),2),!0);P(r),Xr(H(r,2),17,()=>K(d),Kr,(e,n,r)=>{var i=F(()=>_(K(n),2));let a=()=>K(i)[0],o=()=>K(i)[1];var s=bc();let c;var l=z(s),u=V(l,!0),d=H(l,2),f=z(d);let h;P(d);var g=V(H(d,2));P(s),U((e,n,i)=>{c=ci(s,1,`report-row svelte-1fbui7h`,null,c,{unknown:e,alternate:r%2==1}),Q(l,`title`,a()),X(u,a()),h=ui(f,``,h,{width:n}),X(g,`${i??``}${t.mode===`periods`?`%`:``}`)},[()=>a().trim().toLowerCase()===`unknown`,()=>`${Math.max(0,100*o()/K(p))}%`,()=>m(o())]),Y(e,s)}),P(n),U(()=>X(i,t.mode===`breakdown`?K(u):`QUOTA USED`)),Y(e,n)},A=e=>{Y(e,Sc())},ce=e=>{Y(e,Cc())};Z(oe,e=>{K(d).length?e(se):t.mode===`breakdown`&&K(c)?.total===0&&K(c)?.groups[K(n)]!=null?e(A,1):(K(i)&&t.mode===`breakdown`||K(a)&&t.mode===`periods`)&&e(ce,2)}),P(D),U(()=>{w.disabled=K(s)>=K(o)-1,T.disabled=K(s)===0,X(E,K(o)?`${K(s)+1} / ${K(o)}`:`NO DATA`),X(te,t.mode===`breakdown`?`DAILY BREAKDOWN`:`QUOTA WINDOWS`),X(k,`${(t.mode===`breakdown`?t.reports?.dailyStatus||`UNAVAILABLE`:t.reports?.planStatus||`UNAVAILABLE`)??``} // UTC`)}),hi(y,()=>K(n),e=>R(n,e)),q(`click`,w,()=>R(r,K(s)+1)),q(`click`,T,()=>R(r,K(s)-1)),Y(e,h),We()}Sr([`click`]);var Ec=864e5;function Dc(e,t){let n=new Date(e);n.setUTCDate(1),n.setUTCMonth(n.getUTCMonth()+t);let r=new Date(Date.UTC(n.getUTCFullYear(),n.getUTCMonth()+1,0)).getUTCDate();return n.setUTCDate(Math.min(e.getUTCDate(),r)),n}function Oc(e,t,n){let r=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()));for(let e=0;;e++){let i=Dc(r,-t),a=new Date(i.getTime()+Ec);if(e===n)return{start:a,end:r};r=i}}var kc=J(``),Ac=J(``,1),jc=J(`
History refresh failed. Any displayed history is the last successful
- observation.
`),Mc=J(`
Token history unavailable; other reports may still be available.
`),Nc=J(``),Pc=J(``),Fc=J(`
LESS ░ ▒ ▓ █ MORE // HOVER FOR DATE AND TOKENS
`,1),Ic=J(`
`,1),Lc=J(`
`),Rc=J(`
LIFETIME TOKENS
PEAK DAY
CURRENT STREAK
DAYS
LONGEST TURN
SECONDS
LONGEST STREAK
DAYS
OPENAI // UTC
Accessible data table
Date (UTC)
Tokens
`,1),zc=J(`
History unavailable or awaiting a matching account observation. Missing
- history is not treated as zero usage.
`),Bc=J(`
USAGE // ACCOUNT HISTORY
Account-wide history reported by Codex, not the local Sessions counter. Dates
+ ${K(u)??``}`)},[()=>ma(K(i).fetchedAt),()=>m(K(f))]),Y(e,t)},ie=e=>{var t=yc(),n=B(t),r=z(n);let i;var o=V(r,!0),s=H(r),c=e=>{Y(e,gc())};Z(s,e=>{K(a).approximate&&e(c)});var u=H(s);P(n);var d=H(n,2),p=z(d),h=H(p),g=e=>{var t=Mr();U(()=>X(t,`// Boundary tolerance ${K(a).boundary_tolerance_seconds??``}s`)),Y(e,t)};Z(h,e=>{K(a).boundary_tolerance_seconds!=null&&e(g)}),P(d);var _=H(d,2),v=e=>{var t=vc(),n=B(t),r=z(n),i=H(r);let a;var o=V(i);P(n);var s=H(n,2),c=V(s),u=H(s,2),d=e=>{Y(e,_c())};Z(u,e=>{K(l).accounting_complete||e(d)}),xe(2),U(e=>{X(r,`${K(l).window_minutes??``} MIN // ${K(l).plan_type??``} // `),a=ci(i,1,`svelte-1fbui7h`,null,a,{muted:K(f)==null,"quota-near":K(f)!=null&&K(f)>=80&&K(f)<100,"quota-full":K(f)!=null&&K(f)>=100}),X(o,`USED ${e??``}${K(f)==null?``:`%`}`),X(c,`${K(l).starts_at??``} → ${K(l).ends_at??``}`)},[()=>m(K(f))]),Y(e,t)};Z(_,e=>{K(l)&&e(v)}),U(e=>{i=ci(r,1,`svelte-1fbui7h`,null,i,{"quality-warning":!K(a).coverage_complete}),X(o,K(a).coverage_complete?`Reported range complete`:`Partial coverage`),X(u,` // Latest fetch ${e??``}`),X(p,`Coverage starts ${(K(a).coverage_start||`unknown`)??``} // Data as of ${(K(a).data_as_of||`unknown`)??``}`)},[()=>ma(K(a).fetchedAt)]),Y(e,t)},ae=e=>{Y(e,bc())};Z(ne,e=>{t.mode===`breakdown`&&K(i)?e(re):t.mode===`periods`&&K(a)?e(ie,1):e(ae,-1)});var oe=H(ne,2),se=e=>{var n=Sc(),r=z(n),i=V(H(z(r),2),!0);P(r),Xr(H(r,2),17,()=>K(d),Kr,(e,n,r)=>{var i=F(()=>_(K(n),2));let a=()=>K(i)[0],o=()=>K(i)[1];var s=xc();let c;var l=z(s),u=V(l,!0),d=H(l,2),f=z(d);let h;P(d);var g=V(H(d,2));P(s),U((e,n,i)=>{c=ci(s,1,`report-row svelte-1fbui7h`,null,c,{unknown:e,alternate:r%2==1}),Q(l,`title`,a()),X(u,a()),h=ui(f,``,h,{width:n}),X(g,`${i??``}${t.mode===`periods`?`%`:``}`)},[()=>a().trim().toLowerCase()===`unknown`,()=>`${Math.max(0,100*o()/K(p))}%`,()=>m(o())]),Y(e,s)}),P(n),U(()=>X(i,t.mode===`breakdown`?K(u):`QUOTA USED`)),Y(e,n)},A=e=>{Y(e,Cc())},ce=e=>{Y(e,wc())};Z(oe,e=>{K(d).length?e(se):t.mode===`breakdown`&&K(c)?.total===0&&K(c)?.groups[K(n)]!=null?e(A,1):(K(i)&&t.mode===`breakdown`||K(a)&&t.mode===`periods`)&&e(ce,2)}),P(D),U(()=>{w.disabled=K(s)>=K(o)-1,T.disabled=K(s)===0,X(E,K(o)?`${K(s)+1} / ${K(o)}`:`NO DATA`),X(te,t.mode===`breakdown`?`DAILY BREAKDOWN`:`QUOTA WINDOWS`),X(k,`${(t.mode===`breakdown`?t.reports?.dailyStatus||`UNAVAILABLE`:t.reports?.planStatus||`UNAVAILABLE`)??``} // UTC`)}),hi(y,()=>K(n),e=>R(n,e)),q(`click`,w,()=>R(r,K(s)+1)),q(`click`,T,()=>R(r,K(s)-1)),Y(e,h),We()}Sr([`click`]);var Dc=864e5;function Oc(e,t){let n=new Date(e);n.setUTCDate(1),n.setUTCMonth(n.getUTCMonth()+t);let r=new Date(Date.UTC(n.getUTCFullYear(),n.getUTCMonth()+1,0)).getUTCDate();return n.setUTCDate(Math.min(e.getUTCDate(),r)),n}function kc(e,t,n){let r=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()));for(let e=0;;e++){let i=Oc(r,-t),a=new Date(i.getTime()+Dc);if(e===n)return{start:a,end:r};r=i}}var Ac=J(``),jc=J(``,1),Mc=J(`
History refresh failed. Any displayed history is the last successful
+ observation.
`),Nc=J(`
Token history unavailable; other reports may still be available.
`),Pc=J(``),Fc=J(``),Ic=J(`
LESS ░ ▒ ▓ █ MORE // HOVER FOR DATE AND TOKENS
`,1),Lc=J(`
`,1),Rc=J(`
`),zc=J(`
LIFETIME TOKENS
PEAK DAY
CURRENT STREAK
DAYS
LONGEST TURN
SECONDS
LONGEST STREAK
DAYS
OPENAI // UTC
Accessible data table
Date (UTC)
Tokens
`,1),Bc=J(`
History unavailable or awaiting a matching account observation. Missing
+ history is not treated as zero usage.
`),Vc=J(`
USAGE // ACCOUNT HISTORY
Account-wide history reported by Codex, not the local Sessions counter. Dates
use UTC. Allowance history is approximate where indicated; reset causes are
- not provided.