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..f658769 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. @@ -111,9 +111,14 @@ func (c Client) BenchmarkBillingSource() BenchmarkBillingSource { // BenchmarkResponseUsage is the exact upstream usage for one Responses API // completion when the current Codex app-server exposes experimental raw events. +// Missing or conflicting usage retains response identity for diagnostics; +// UsageMissing distinguishes an omitted payload from valid all-zero usage. type BenchmarkResponseUsage struct { - ResponseID string - Usage BenchmarkUsage + ResponseID string + Model string + Usage BenchmarkUsage + UsageMissing bool + UsageIssue string } type BenchmarkInteractionKind string @@ -930,7 +935,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 +1168,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 +1177,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 @@ -1191,23 +1202,24 @@ type benchmarkTelemetry struct { lastCumulative BenchmarkUsage hasLastCumulative bool rawResponses []BenchmarkResponseUsage - rawIDs map[string]struct{} + rawIDs map[string]int rawObserved bool rawMissingUsage bool issue string + cumulativeIssue string } func newBenchmarkTelemetry() *benchmarkTelemetry { - return &benchmarkTelemetry{rawIDs: make(map[string]struct{})} + return &benchmarkTelemetry{rawIDs: make(map[string]int)} } 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 @@ -1215,30 +1227,54 @@ func (t *benchmarkTelemetry) recordCumulative(usage BenchmarkUsage) { } func (t *benchmarkTelemetry) recordRawResponse(responseID string, usage *BenchmarkUsage) { + t.recordRawResponseForModel(responseID, usage, "") +} + +func (t *benchmarkTelemetry) recordRawResponseForModel(id string, usage *BenchmarkUsage, model string) { t.rawObserved = true - if strings.TrimSpace(responseID) == "" { - t.setIssue("raw response usage omitted response id") - return + response := BenchmarkResponseUsage{ResponseID: id, Model: model, UsageMissing: usage == nil} + if usage == nil { + response.UsageIssue = "raw response omitted usage" + } else { + response.Usage = *usage + if issue := validateBenchmarkUsage(*usage); issue != "" { + response.UsageIssue = "invalid raw response usage: " + issue + } } - if _, duplicate := t.rawIDs[responseID]; duplicate { - t.setIssue("duplicate raw response usage: " + responseID) + if strings.TrimSpace(id) == "" { + response.UsageIssue = "raw response usage omitted response id" + t.setIssue(response.UsageIssue) + t.rawResponses = append(t.rawResponses, response) return } - t.rawIDs[responseID] = struct{}{} - if usage == nil { - t.rawMissingUsage = true + if index, duplicate := t.rawIDs[id]; duplicate { + previous := &t.rawResponses[index] + if previous.Model == model && previous.UsageMissing == response.UsageMissing && previous.Usage == response.Usage { + return + } + previous.UsageIssue = "conflicting duplicate raw response usage: " + id + if previous.Model != model { + previous.UsageIssue = fmt.Sprintf("conflicting duplicate raw response model: %q versus %q", previous.Model, model) + } + t.setIssue(previous.UsageIssue) return } - if issue := validateBenchmarkUsage(*usage); issue != "" { - t.setIssue("invalid raw response usage: " + issue) + t.rawIDs[id] = len(t.rawResponses) + t.rawResponses = append(t.rawResponses, response) + if response.UsageMissing { + t.rawMissingUsage = true + } else if response.UsageIssue != "" { + t.setIssue(response.UsageIssue) } - t.rawResponses = append(t.rawResponses, BenchmarkResponseUsage{ResponseID: responseID, Usage: *usage}) } func (t *benchmarkTelemetry) apply(result *BenchmarkResult) { result.UsageObserved = t.cumulativeObserved || t.rawObserved result.UsageSource = BenchmarkUsageUnavailable result.ResponseUsage = append([]BenchmarkResponseUsage(nil), t.rawResponses...) + if t.rawObserved { + result.UsageSource = BenchmarkUsageRawResponses + } if t.issue != "" { result.UsageIssue = t.issue return @@ -1257,13 +1293,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 +1650,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 +1682,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) diff --git a/internal/codex/benchmark_test.go b/internal/codex/benchmark_test.go index 249caeb..3d480b0 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,67 @@ 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) + } +} + +func TestBenchmarkRawMissingUsageRetainsAttribution(t *testing.T) { + telemetry := newBenchmarkTelemetry() + usage := BenchmarkUsage{InputTokens: 100, OutputTokens: 10, TotalTokens: 110} + telemetry.recordRawResponseForModel("missing", nil, "gpt-reserve") + telemetry.recordRawResponseForModel("missing", nil, "gpt-reserve") + telemetry.recordRawResponseForModel("later", &usage, "gpt-6-astra") + result := BenchmarkResult{ActualModel: "gpt-6-astra"} + applyBenchmarkMeasurements(&result, telemetry) + if result.UsageKnown || result.CostKnown || len(result.ResponseUsage) != 2 || result.UsageSource != BenchmarkUsageRawResponses { + t.Fatal("missing raw usage was priced or lost", result) + } + response := result.ResponseUsage[0] + if response.ResponseID != "missing" || response.Model != "gpt-reserve" || !response.UsageMissing || response.UsageIssue != "raw response omitted usage" { + t.Fatal("missing usage attribution lost", response) + } +} + +func TestBenchmarkRawReplayRejectsModelConflicts(t *testing.T) { + for _, missing := range []bool{false, true} { + telemetry := newBenchmarkTelemetry() + usage := &BenchmarkUsage{InputTokens: 100, OutputTokens: 10, TotalTokens: 110} + if missing { + usage = nil + } + telemetry.recordRawResponseForModel("same-response", usage, "gpt-6-astra") + telemetry.recordRawResponseForModel("same-response", usage, "gpt-6-astra") + if len(telemetry.rawResponses) != 1 || telemetry.issue != "" { + t.Fatal("identical replay was not idempotent", telemetry) + } + telemetry.recordRawResponseForModel("same-response", usage, "gpt-5.2") + result := BenchmarkResult{ActualModel: "gpt-5.2"} + applyBenchmarkMeasurements(&result, telemetry) + if result.UsageKnown || result.CostKnown || (!strings.Contains(result.UsageIssue, "gpt-6-astra") || !strings.Contains(result.UsageIssue, "gpt-5.2") || !strings.Contains(result.UsageIssue, "conflicting duplicate")) || len(result.ResponseUsage) != 1 || result.ResponseUsage[0].UsageIssue != result.UsageIssue { + t.Fatal("conflicting model replay was silently retained", missing, 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..619cb0f 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,11 @@ type rolloutCursor struct { modelCalls []LiveModelCall turnTimings []LiveTurnTiming attention sessionAttentionState + exactUsage bool + exactUsageUncertain bool + exactResponses map[string]BenchmarkUsage + exactConflicts map[string]bool + exactResponseOrder []string } type pendingModelResolution struct { @@ -177,6 +192,7 @@ type pendingModelResolution struct { turnID string usage BenchmarkUsage cumulativeTotal int64 + exact bool } type sessionAttentionState int @@ -204,6 +220,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 +244,7 @@ func (u rolloutTokenUsage) benchmarkUsage() BenchmarkUsage { OutputTokens: optionalRolloutTokens(u.OutputTokens), ReasoningOutputTokens: optionalRolloutTokens(u.ReasoningOutputTokens), TotalTokens: optionalRolloutTokens(u.TotalTokens), + schemaIssue: u.schemaIssue, } } @@ -422,6 +440,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 +566,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 +593,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 +648,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 +690,21 @@ 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 || cursor.exactUsageUncertain { + if tokenRecordIsOwned(record.ordinal, cursor.subagentHistoryStartOrdinal, record.at, cursor.nonRoot, cursor.startedAt) { + r.attachExactCheckpoint(cursor, record) + if cursor.exactUsageUncertain && record.total != cursor.totalTokens { + r.apiEqMissingUsageCalls++ + r.rememberCallIssue(LiveModelCall{At: record.at, SessionID: cursor.threadID, Model: cursor.currentModel, RequestedServiceTier: cursor.currentServiceTier, Effort: cursor.modelSettings.ReasoningEffort, UsageSource: "rollout mode discovery", issueKind: UsageIssueMissing, APIEqIssue: "historical scan exceeded 4 MiB without establishing response usage mode; context snapshots cannot be billed until an exact response record arrives"}) + } + } + 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 +751,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 +762,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 +773,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 +837,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 +1055,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 +1326,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 +1565,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..731c2be --- /dev/null +++ b/internal/codex/live_usage_exact.go @@ -0,0 +1,207 @@ +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. +// A truncated scan cannot prove the absence of older exact records. In that +// case suppress legacy billing until an owned exact record establishes the mode. +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) + } + } + cursor.exactUsageUncertain = start > 0 && !cursor.exactUsage + return end, nil +} + +func (r *LiveUsageReader) consumeExactUsage(cursor *rolloutCursor, record rolloutExactUsage) { + if !cursor.ownsExactRecord(record) { + return + } + cursor.exactUsage = true + cursor.exactUsageUncertain = false + 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..eac8339 --- /dev/null +++ b/internal/codex/live_usage_exact_test.go @@ -0,0 +1,280 @@ +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) + } +} + +func TestExactUsageOlderThanStartupTailCannotEnableLegacyBilling(t *testing.T) { + for _, historicalExact := range []bool{false, true} { + _, path, now := astraUsageReader(t, 100) + u := BenchmarkUsage{InputTokens: 1000, OutputTokens: 100, TotalTokens: 1100} + if historicalExact { + appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "old", u)+"\n") + } + // The last owned exact response, if present, is outside the discovery + // window. An otherwise identical large legacy file is also uncertain. + padding := `{"type":"response_item","payload":"` + strings.Repeat("x", 4096) + `"}` + "\n" + appendRollout(t, path, strings.Repeat(padding, 1100)) + 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 + if _, err := r.FetchTokenUsage(context.Background()); err != nil { + t.Fatal(err) + } + checkpoint := richTokenCountLine(now, 1200, 1000, 0, 0, 100) + "\n" + appendRollout(t, path, checkpoint+checkpoint) + uncertain, err := r.FetchTokenUsage(context.Background()) + if err != nil || uncertain.TotalTokens != 0 || uncertain.APIEqPricedCalls != 0 || uncertain.APIEqUSD != 0 || uncertain.APIEqMissingUsageCalls != 1 || len(uncertain.APIEqDiagnostics) != 1 || !strings.Contains(uncertain.APIEqDiagnostics[0].Reason, "without establishing response usage mode") { + t.Fatal("truncated baseline enabled legacy billing or hid uncertainty", historicalExact, uncertain, err) + } + appendRollout(t, path, richTokenCountLine(now, 2300, 1000, 0, 0, 100)+"\n") + continued, err := r.FetchTokenUsage(context.Background()) + if err != nil || continued.APIEqMissingUsageCalls != 2 || continued.APIEqPricedCalls != 0 { + t.Fatal("ongoing uncertain usage failed to invalidate quota learning", continued, err) + } + appendRollout(t, path, exactLine(t, now, "astra-accounting", "t", "fresh", u)+"\n"+richTokenCountLine(now, 3400, 1000, 0, 0, 100)+"\n") + fresh, err := r.FetchTokenUsage(context.Background()) + if err != nil || fresh.APIEqPricedCalls != 1 || fresh.TotalTokens != 1100 || fresh.APIEqMissingUsageCalls != 2 || r.files[path].exactUsageUncertain { + t.Fatal("exact record did not restore reliable accounting", fresh, 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..0380a83 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,45 +88,132 @@ func (a *benchmarkQuotaAccounting) observe(result codex.BenchmarkResult) { } a.accounted[key] = struct{}{} - cost, known := benchmarkQuotaCost(result) - calls := int64(len(result.ResponseUsage)) - if calls == 0 { - calls = 1 - } - if known { - a.costUSD += cost - a.pricedCalls += calls - a.revision++ - return + cost, pricedCalls, issues := benchmarkQuotaCostDetail(result) + a.costUSD += cost + a.pricedCalls += pricedCalls + for _, issue := range issues { + if issue.response != nil { + a.recordIssue(result, issue.kind, issue.reason, *issue.response) + } else { + a.recordIssue(result, issue.kind, issue.reason) + } } - a.unpricedCalls += calls a.revision++ } -func benchmarkQuotaCost(result codex.BenchmarkResult) (float64, bool) { - if result.CostKnown && validBenchmarkQuotaCost(result.CostUSD) { - return result.CostUSD, true +type benchmarkQuotaIssue struct { + kind codex.APIEqIssueKind + reason string + response *codex.BenchmarkResponseUsage +} + +func benchmarkQuotaCostDetail(result codex.BenchmarkResult) (float64, int64, []benchmarkQuotaIssue) { + aggregateIssue := func(kind codex.APIEqIssueKind, reason string) (float64, int64, []benchmarkQuotaIssue) { + return 0, 0, []benchmarkQuotaIssue{{kind: kind, reason: reason}} + } + if result.CostKnown { + if validBenchmarkQuotaCost(result.CostUSD) { + return result.CostUSD, int64(max(len(result.ResponseUsage), 1)), nil + } + return aggregateIssue(codex.UsageIssueInconsistent, "benchmark returned an invalid measured cost") } model := strings.TrimSpace(result.ActualModel) if model == "" { model = result.Model } + var issues []benchmarkQuotaIssue + for i := range result.ResponseUsage { + response := &result.ResponseUsage[i] + if response.UsageIssue != "" { + issues = append(issues, benchmarkQuotaIssue{kind: benchmarkUsageIssueKind(response.UsageIssue), reason: response.UsageIssue, response: response}) + } else if response.UsageMissing { + issues = append(issues, benchmarkQuotaIssue{kind: codex.UsageIssueMissing, reason: "raw response omitted usage", response: response}) + } + } + if len(issues) > 0 { + return 0, 0, issues + } if !result.UsageKnown { - return 0, false + if result.UsageIssue != "" { + return aggregateIssue(benchmarkUsageIssueKind(result.UsageIssue), result.UsageIssue) + } + return aggregateIssue(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) + var pricedCalls int64 + for i := range result.ResponseUsage { + response := &result.ResponseUsage[i] + responseModel := response.Model + if responseModel == "" { + responseModel = model + } + cost, known, reason := codex.EstimateStandardAPIEqCost(responseModel, response.Usage) if !known { - return 0, false + issues = append(issues, benchmarkQuotaIssue{kind: benchmarkCostIssueKind(reason), reason: reason, response: response}) + continue } total += cost + pricedCalls++ + } + if !validBenchmarkQuotaCost(total) { + return aggregateIssue(codex.UsageIssueInconsistent, "benchmark cost total was not finite") } - return total, validBenchmarkQuotaCost(total) + return total, pricedCalls, issues + } + cost, known, reason := codex.EstimateStandardAPIEqAggregateCost(model, result.Usage) + if !known { + return aggregateIssue(benchmarkCostIssueKind(reason), reason) + } + if !validBenchmarkQuotaCost(cost) { + return aggregateIssue(codex.UsageIssueInconsistent, "benchmark cost total was not finite") + } + return cost, 1, nil +} + +func benchmarkUsageIssueKind(reason string) codex.APIEqIssueKind { + if strings.Contains(reason, "omitted") || strings.Contains(reason, "not observed") { + return codex.UsageIssueMissing + } + return codex.UsageIssueInconsistent +} + +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, responses ...codex.BenchmarkResponseUsage) { + 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 len(responses) > 0 { + responseID = responses[0].ResponseID + if responses[0].Model != "" { + model = responses[0].Model + } + } + 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 +229,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..b4ea478 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,81 @@ 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" || a.unpricedCalls != 1 || len(a.diagnostics) != 1 || a.pricedCalls != 1 { + 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) + } +} + +func TestBenchmarkMissingUsageDiagnosticIdentifiesOriginatingResponse(t *testing.T) { + a := benchmarkQuotaAccounting{billingSource: codex.BenchmarkBillingSubscription} + a.start() + usage := codex.BenchmarkUsage{InputTokens: 100, OutputTokens: 10, TotalTokens: 110} + result := codex.BenchmarkResult{Model: "gpt-6-astra", ActualModel: "gpt-6-astra", UsageSource: codex.BenchmarkUsageRawResponses, UsageIssue: "raw response omitted usage", ResponseUsage: []codex.BenchmarkResponseUsage{ + {ResponseID: "missing", Model: "gpt-reserve", UsageMissing: true, UsageIssue: "raw response omitted usage"}, + {ResponseID: "later", Model: "gpt-6-astra", Usage: usage}, + }} + a.observe(result) + a.observe(result) + if a.missingCalls != 1 || a.unpricedCalls != 0 || a.pricedCalls != 0 || a.costUSD != 0 || len(a.diagnostics) != 1 { + t.Fatal("missing response inflated counters or priced incomplete telemetry", a) + } + issue := a.diagnostics[0] + if issue.Kind != codex.UsageIssueMissing || issue.Model != "gpt-reserve" || issue.ResponseID != "missing" { + t.Fatal("missing benchmark attributed to final response", issue) + } +} + +func TestBenchmarkAccountingReportsOnlyFailingResponses(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", UsageKnown: true, UsageSource: codex.BenchmarkUsageRawResponses, ResponseUsage: []codex.BenchmarkResponseUsage{ + {ResponseID: "unknown", Model: "gpt-reserve", Usage: usage}, + {ResponseID: "known", Model: "gpt-6-astra", Usage: usage}, + {ResponseID: "another-unknown", Model: "unknown-provider", Usage: usage}, + }}) + want, _, _ := codex.EstimateStandardAPIEqCost("gpt-6-astra", usage) + if a.unpricedCalls != 2 || a.pricedCalls != 1 || math.Abs(a.costUSD-want) > 1e-12 || len(a.diagnostics) != 2 || a.diagnostics[0].ResponseID != "unknown" || a.diagnostics[1].ResponseID != "another-unknown" || a.diagnostics[1].Model != "unknown-provider" { + t.Fatal("mixed responses duplicated failures or discarded known cost", a) + } +} + +func TestBenchmarkAggregateFailureIsRecordedOnce(t *testing.T) { + for _, invalidMeasuredCost := range []bool{false, true} { + a := benchmarkQuotaAccounting{billingSource: codex.BenchmarkBillingSubscription} + a.start() + result := codex.BenchmarkResult{Model: "gpt-6-astra", UsageIssue: "invalid raw response total: totalTokens overflowed", ResponseUsage: []codex.BenchmarkResponseUsage{{ResponseID: "one"}, {ResponseID: "two"}}} + if invalidMeasuredCost { + result.CostKnown = true + result.CostUSD = math.Inf(1) + } + a.observe(result) + if a.inconsistentCalls != 1 || len(a.diagnostics) != 1 || a.diagnostics[0].ResponseID != "" || a.pricedCalls != 0 || a.costUSD != 0 { + t.Fatal("aggregate failure attributed to each response", a) + } + } +} 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.

`);function wa(e,t){Ue(t,!1),Ri();var n=Nr(),r=B(n),i=e=>{var t=Sa(),n=B(t),r=V(n),i=H(n,2),a=e=>{Y(e,ba())};Z(i,e=>{$.data.quotaError&&e(a)});var o=H(i,2),s=z(o),c=V(s),l=H(s,4);Xr(l,5,()=>$.data.thresholds,Kr,(e,t)=>{var n=xa();let r;var i=z(n),a=V(i),o=H(i,2),s=z(o),c=V(s,!0),l=V(H(s,2));P(o);var u=H(o,2),d=V(u,!0),f=V(H(u,2));P(n),U((e,i)=>{r=ci(n,1,``,null,r,{active:K(t).state===`ACTIVE`,next:K(t).state===`NEXT`}),X(a,`${K(t).threshold??``}%`),X(c,K(t).model),X(l,`${e??``} REASONING // ${i??``} - SPEED`),X(d,K(t).mode),X(f,`${K(t).state??``}${K(t).state===`NEXT`?` // ${K(t).remaining||0} PP TO GO`:``}`)},[()=>K(t).effort.toUpperCase(),()=>K(t).speed.toUpperCase()]),Y(e,n)}),P(l),P(o),U(e=>{X(r,`MODEL STEP POLICY // OBSERVED ${e??``}`),X(c,`THRESHOLDS // ${$.data.thresholds.length??``} CONFIGURED`)},[()=>ma($.data.quotaAt)]),Y(e,t)},a=e=>{Y(e,Ca())};Z(r,e=>{$.data?.thresholds?.length?e(i):e(a,-1)}),Y(e,n),We()}var Ta=jr(` `,1),Ea=jr(` `,1),Da=jr(` `,1),Oa=jr(` `,1),ka=J(`
`,1),Aa=J(` `),ja=J(`
Quota observations
Observed atPeriod elapsedConsumedTrail segment
`),Ma=J(`
OBSERVATION DATA
`),Na=J(`
CONSUMPTIONQUOTA PERIOD ELAPSED
`,1);function Pa(e,t){let n=Pr();Ue(t,!0);let r=Wi(t,`trail`,19,()=>[]),i=L(!1),a=L(!0),o=L(`window`),s=[0,25,50,75,100],c={off:0,halfHour:30,hour:60,day:1440,window:0},l=L(400),u=L(240),d=F(()=>K(l)-24),f=F(()=>K(u)-48),p=F(()=>Math.max(1,K(d)-48)),m=F(()=>Math.max(1,K(f)-20)),h=F(()=>48+Math.max(0,Math.min(100,t.elapsed))/100*K(p));function g(e){return K(f)-(e-0)/100*K(m)}let _=F(()=>g(t.used)),v=F(()=>t.used-t.elapsed),y=F(()=>r().map((e,t)=>`${t===0||e.break?`M`:`L`}${48+e.elapsed/100*K(p)} ${g(e.used)}`).join(` `)),b=F(()=>{let e=0;for(let t=r().length-1;t>0;t--)if(r()[t].break){e=t;break}return r().slice(e)}),x=F(()=>K(b).length<2?0:Math.max(0,Date.parse(K(b).at(-1).at)-Date.parse(K(b)[0].at)));function S(e){if(K(x)Date.parse(e.at)>=t).length>=2}let C=F(()=>({off:!0,halfHour:S(18e5),hour:S(36e5),day:S(864e5),window:Number.isFinite(t.elapsed)&&t.elapsed>0&&Number.isFinite(t.used)}));vn(()=>{K(o)!==`window`&&!K(C)[K(o)]&&R(o,`window`)});function w(e){if(e===`off`||!K(C)[e])return[];let t=c[e]*6e4,n=Date.parse(K(b).at(-1).at)-t,r=K(b).findIndex(e=>Date.parse(e.at)>=n);return r<0?[]:K(b).slice(r)}function T(e){if(e.length<2)return null;let t=e.reduce((e,t)=>e+t.elapsed,0)/e.length,n=e.reduce((e,t)=>e+t.used,0)/e.length,r=0,i=0;for(let a of e)r+=(a.elapsed-t)*(a.used-n),i+=(a.elapsed-t)**2;return i>0?Math.max(0,r/i):null}let E=F(()=>{let e=K(o)===`window`&&K(C).window?t.used/t.elapsed:T(w(K(o)));if(e===null||!t.duration)return null;let n=t.used+e*(100-t.elapsed),r=K(o)===`window`?0:t.used-e*t.elapsed,i=e,a=Math.max(0,t.elapsed-c[K(o)]/t.duration*100);K(o)===`window`&&(a=0);let s=100;if(i!==0){let e=(0-r)/i,t=(100-r)/i;a=Math.max(a,Math.min(e,t)),s=Math.min(100,Math.max(e,t))}if(a>s)return null;let l=r+i*a,u=r+i*s,d=Math.hypot((s-a)/100*K(p),(u-l)/100*K(m)),f=Math.max(3,Math.min(9,Math.floor(d/65)+2));return{path:`M${Array.from({length:f},(e,t)=>{let n=a+(s-a)*t/(f-1),r=l+(u-l)*t/(f-1);return`${48+n/100*K(p)} ${g(r)}`}).join(` L`)}`,projected:n,safe:n<=100}}),D=F(()=>{if(K(b).length===0)return`NO OBSERVATIONS`;if(K(b).length===1)return`ONE OBSERVATION`;let e=Math.floor(K(x)/6e4);if(e<60)return`${e} MIN CONTINUOUS`;let t=Math.floor(e/60);return t<24?`${t}H CONTINUOUS`:`${Math.floor(t/24)}D ${t%24}H CONTINUOUS`});var ee=Na(),te=B(ee),O=z(te);let k;var ne=z(O),re=z(ne),ie=H(re);P(ne);var ae=H(ne),oe=H(ae);Xr(oe,17,()=>s,Kr,(e,t)=>{var n=Ta(),r=B(n),i=H(r),a=V(i);U(()=>{Q(r,`x1`,48+K(t)/100*K(p)),Q(r,`x2`,48+K(t)/100*K(p)),Q(r,`y2`,K(f)),Q(i,`x`,48+K(t)/100*K(p)),Q(i,`y`,K(f)+20),X(a,`${K(t)??``}%`)}),Y(e,n)});var se=H(oe);Xr(se,17,()=>s,Kr,(e,t)=>{var n=Ea(),r=B(n),i=H(r),a=V(i);U((e,n,o)=>{Q(r,`y1`,e),Q(r,`x2`,K(d)),Q(r,`y2`,n),Q(i,`y`,o),X(a,`${K(t)??``}%`)},[()=>g(K(t)),()=>g(K(t)),()=>g(K(t))+4]),Y(e,n)});var A=H(se),ce=H(A),le=H(ce),ue=e=>{var t=Da(),n=B(t),i=H(n),a=H(i),o=V(z(a));P(a),U((e,t)=>{Q(n,`d`,K(y)),Q(i,`d`,K(y)),Q(a,`cx`,48+r()[0].elapsed/100*K(p)),Q(a,`cy`,e),X(o,`First observation: ${t??``}`)},[()=>g(r()[0].used),()=>ma(r()[0].at)]),Y(e,t)};Z(le,e=>{K(a)&&r().length&&e(ue)});var de=H(le),fe=e=>{var t=Oa(),r=B(t),i=H(r),a=V(z(i));P(i),U(e=>{Q(r,`d`,K(E).path),Q(i,`d`,K(E).path),Q(i,`marker-mid`,`url(#${n}-trend-arrow)`),X(a,`${K(o)===`window`?`Window-average pace`:`Recent consumption trajectory`} projects ${e??``}% at reset if continued`)},[()=>K(E).projected.toFixed(1)]),Y(e,t)};Z(de,e=>{K(E)&&e(fe)});var j=H(de,2),pe=H(j),me=H(pe),he=V(z(me));P(me),P(O),P(te);var ge=H(te,2),_e=z(ge),M=z(_e),ve=H(M,3),N=V(ve,!0),ye=H(ve,2),be=e=>{var t=ka(),n=V(H(B(t)));U(e=>X(n,`TREND // ${e??``}`),[()=>K(E).projected>=100?`QUOTA EXHAUSTION PROJECTED`:`${K(E).projected.toFixed(1)}% PROJECTED AT RESET`]),Y(e,t)};Z(ye,e=>{K(E)&&e(be)}),P(_e);var Se=H(_e,2),Ce=z(Se),we=z(Ce);xi(we),xe(),P(Ce);var Te=H(Ce,2),Ee=H(z(Te),2),De=z(Ee);De.value=De.__value=`off`;var Oe=H(De),ke=V(Oe);Oe.value=Oe.__value=`halfHour`;var Ae=H(Oe),je=V(Ae);Ae.value=Ae.__value=`hour`;var Me=H(Ae),Ne=V(Me);Me.value=Me.__value=`day`;var Pe=H(Me),Fe=V(Pe);Pe.value=Pe.__value=`window`,P(Ee),mi(Ee),P(Te);var Ie=V(H(Te,2));P(Se),P(ge);var Le=H(ge,2),Re=e=>{var t=Ma(),n=H(z(t),2),a=e=>{var t=ja(),n=z(t),i=H(z(n),2);Xr(i,21,r,Kr,(e,t,n)=>{var r=Aa(),i=z(r),a=z(i),o=V(a,!0);P(i);var s=H(i),c=V(s),l=H(s),u=V(l),d=V(H(l),!0);P(r),U((e,r)=>{Q(a,`datetime`,K(t).at),X(o,e),X(c,`${r??``}%`),X(u,`${K(t).used??``}%`),X(d,n===0?`First observation`:K(t).break?`Gap before this observation`:`Connected to previous observation`)},[()=>ma(K(t).at),()=>K(t).elapsed.toFixed(1)]),Y(e,r)}),P(i),P(n),P(t),Y(e,t)};Z(n,e=>{K(i)&&e(a)}),P(t),Li(`open`,`toggle`,t,e=>R(i,e),()=>K(i)),Y(e,t)};Z(Le,e=>{r().length&&e(Re)}),U((e,r,i,a,o,s)=>{Q(O,`viewBox`,`0 0 ${K(l)} ${K(u)}`),Q(O,`aria-label`,e),k=ui(O,``,k,{"--trend-color":K(E)?.safe?`#115b35`:`#7f1825`}),Q(re,`id`,n),Q(ie,`id`,n+`-trend-arrow`),Q(ae,`width`,K(p)),Q(ae,`height`,K(m)),Q(ae,`fill`,`url(#${n})`),Q(A,`d`,`M48 20 V${K(f)} H${K(d)}`),Q(ce,`y1`,r),Q(ce,`x2`,K(d)),Q(ce,`y2`,i),Q(j,`x`,48+K(p)/2),Q(j,`y`,K(u)-5),Q(pe,`cx`,K(h)),Q(pe,`cy`,K(_)),Q(me,`cx`,K(h)),Q(me,`cy`,K(_)),X(he,`${t.used??``}% consumed // ${a??``}% of period elapsed`),X(M,`${t.used??``}% USED // ${o??``}% TIME ELAPSED`),X(N,s),Oe.disabled=!K(C).halfHour,X(ke,`LAST 30 MINUTES${K(C).halfHour?``:` — UNAVAILABLE`}`),Ae.disabled=!K(C).hour,X(je,`LAST HOUR${K(C).hour?``:` — UNAVAILABLE`}`),Me.disabled=!K(C).day,X(Ne,`LAST 24 HOURS${K(C).day?``:` — UNAVAILABLE`}`),Pe.disabled=!K(C).window,X(Fe,`FROM WINDOW START${K(C).window?``:` — NO TIME ELAPSED`}`),X(Ie,`HISTORY // ${K(D)??``}`)},[()=>`Pace: ${t.used}% consumed, ${t.elapsed.toFixed(1)}% of quota period elapsed. ${K(v)>0?`Above`:K(v)<0?`Below`:`On`} the steady-consumption line.${K(a)&&r().length?` Trace path contains ${r().length} ${r().length===1?`observation`:`observations`}; gaps are not interpolated.`:``}`,()=>g(0),()=>g(100),()=>t.elapsed.toFixed(1),()=>t.elapsed.toFixed(1),()=>Math.abs(K(v))<.05?`ON PACE`:K(v)>0?`ABOVE THE LINE — CONSUMING FASTER THAN TIME`:`BELOW THE LINE — WITHIN PACE`]),Pi(te,`clientWidth`,e=>R(l,e)),Pi(te,`clientHeight`,e=>R(u,e)),ki(we,()=>K(a),e=>R(a,e)),hi(Ee,()=>K(o),e=>R(o,e)),Y(e,ee),We()}var Fa=J(` `),Ia=J(`

Quota refresh failed. Values below are the last successful observation.

`),La=J(`

Expiry details unavailable. No listed expiry does not mean no expiry.

`),Ra=J(`

`),za=J(`

Read-only preview. Use the terminal to redeem a reset.

The backend may return only some credits. This list does not establish - redemption order.

`),Ba=J(` `,1),Va=jr(``),Ha=jr(``),Ua=J(`
`),Wa=J(`

Cycle duration or reset date unavailable — position cannot be - plotted.

`),Ga=J(`
EMPTYFULL
`),Ka=J(`

`,1),qa=J(`
`,1),Ja=J(`

`),Ya=J(`

`),Xa=J(`

No quota windows reported yet.

`),Za=J(`
`,1),Qa=J(`

All reported windows are shown. API-equivalent learning and quota status - scoring remain in the terminal for this first preview.

`,1),$a=J(` `,1);function eo(e,t){Ue(t,!0);let n=Wi(t,`params`,19,()=>({})),r=F(()=>ea.filter(e=>e!==`thresholds`||!!$.data?.thresholds?.length)),i=L(Yt(Date.now())),a=F(()=>K(r).includes(ta(n().view))?ta(n().view):`bars`);Gi(()=>{let e=setInterval(()=>R(i,Date.now(),!0),1e3);return()=>clearInterval(e)});function o(e){return!e.duration||e.duration<=0||!e.reset?null:Math.max(0,Math.min(100,100*(1-(e.reset*1e3-K(i))/(e.duration*6e4))))}vn(()=>{aa.view=K(a),(n().view===`zone`||n().view===`consumption-pace`)&&Zi(`/quota/pace`)});function s(e){let t=e/100*Math.PI*2;return`M60 60 L60 14 A46 46 0 ${+(e>50)} 1 ${60+46*Math.sin(t)} ${60-46*Math.cos(t)} Z`}var c=$a(),l=B(c);Xr(l,21,()=>K(r),Kr,(e,t)=>{var n=Fa();let r;var i=V(n,!0);U(e=>{Q(n,`href`,`#/quota/`+K(t)),Q(n,`aria-current`,K(a)===K(t)?`page`:void 0),r=ci(n,1,``,null,r,{active:K(a)===K(t)}),X(i,e)},[()=>K(t)===`fuel`?`FUEL TANK`:K(t).toUpperCase()]),Y(e,n)}),P(l);var u=H(l,2),d=e=>{var t=Qa(),n=B(t),r=e=>{Y(e,Ia())};Z(n,e=>{$.data.quotaError&&e(r)});var i=H(n,2),c=V(i),l=H(i,2),u=e=>{wa(e,{})},d=e=>{var t=za(),n=z(t),r=V(n),i=H(n,4),a=e=>{Y(e,La())};Z(i,e=>{$.data.credits.length||e(a)}),Xr(H(i,2),17,()=>$.data.credits,Kr,(e,t)=>{var n=Ra(),r=z(n),i=V(r),a=V(H(r,2),!0);P(n),U(e=>{X(i,`${(K(t).title||`Quota reset`)??``} // ${K(t).status??``}`),X(a,e)},[()=>K(t).expiryKnown?K(t).expires?`EXPIRES `+ma(K(t).expires):`Does not expire`:`Expiry information unavailable`]),Y(e,n)}),xe(2),P(t),U(()=>X(r,`RESET INVENTORY // ${$.data.creditCount??``} AVAILABLE`)),Y(e,t)},f=e=>{var t=Za(),n=B(t);let r;Xr(n,21,()=>$.data.meters,Kr,(e,t)=>{let n=F(()=>o(K(t)));var r=Ya(),i=z(r),c=V(i,!0),l=H(i,2),u=z(l),d=e=>{var n=Ba(),r=B(n),i=V(r),a=V(H(r));U(()=>{X(i,`FREE ${100-K(t).used}%`),X(a,`USED ${K(t).used??``}%`)}),Y(e,n)},f=e=>{var n=Ba(),r=B(n),i=V(r),a=V(H(r));U(()=>{X(i,`USED ${K(t).used??``}%`),X(a,`FREE ${100-K(t).used}%`)}),Y(e,n)};Z(u,e=>{K(a)===`fuel`?e(d):e(f,-1)}),P(l);var p=H(l,2);let m;var h=z(p),g=e=>{var n=Ua(),r=z(n),i=H(z(r)),a=e=>{Y(e,Va())},o=e=>{var n=Ha();U(e=>Q(n,`d`,e),[()=>s(K(t).used)]),Y(e,n)};Z(i,e=>{K(t).used>=100?e(a):K(t).used>0&&e(o,1)}),P(r),P(n),U(()=>Q(r,`aria-label`,`${K(t).used}% quota used`)),Y(e,n)},_=e=>{var r=Nr(),i=B(r),a=e=>{{let r=F(()=>K(t).trail||[]);Pa(e,{get used(){return K(t).used},get elapsed(){return K(n)},get trail(){return K(r)},get duration(){return K(t).duration}})}},o=e=>{Y(e,Wa())};Z(i,e=>{K(n)===null?e(o,-1):e(a)}),Y(e,r)},v=e=>{var r=qa(),i=B(r),o=z(i);let s;P(i);var c=H(i,2),l=e=>{Y(e,Ga())};Z(c,e=>{K(a)===`fuel`&&e(l)});var u=H(c,2),d=e=>{var t=Ka(),r=B(t),i=V(r),o=H(r,2),s=z(o);let c;P(o),U(e=>{X(i,`RESET CYCLE // ${e??``}% ELAPSED`),c=ui(s,``,c,{width:`${K(a)===`fuel`?100-K(n):K(n)}%`})},[()=>Math.floor(K(n))]),Y(e,t)};Z(u,e=>{K(n)!==null&&e(d)}),U(()=>{Q(i,`aria-label`,K(a)===`fuel`?`Fuel remaining`:`Quota used`),Q(i,`aria-valuenow`,K(a)===`fuel`?100-K(t).used:K(t).used),s=ui(o,``,s,{width:`${K(a)===`fuel`?100-K(t).used:K(t).used}%`})}),Y(e,r)};Z(h,e=>{K(a)===`pie`?e(g):K(a)===`pace`?e(_,1):e(v,-1)}),P(p);var y=H(p,2),b=V(y),x=H(y,2),S=e=>{var n=Ja(),r=V(n,!0);U(()=>X(r,K(t).details)),Y(e,n)};Z(x,e=>{K(t).details&&e(S)}),P(r),U(e=>{X(c,K(t).name),m=ci(p,1,`meter-graphic`,null,m,{"bar-graphic":K(a)===`bars`||K(a)===`fuel`}),X(b,`RESETS // ${e??``}`)},[()=>ma(K(t).reset)]),Y(e,r)}),P(n);var i=H(n,2),c=e=>{Y(e,Xa())};Z(i,e=>{$.data.meters.length||e(c)}),U(()=>r=ci(n,1,`quota-grid`,null,r,{radial:K(a)===`pie`,zone:K(a)===`pace`})),Y(e,t)};Z(l,e=>{K(a)===`thresholds`?e(u):K(a)===`resets`?e(d,1):e(f,-1)}),xe(2),U(e=>X(c,`QUOTA // OBSERVED ${e??``}`),[()=>ma($.data.quotaAt)]),Y(e,t)};Z(u,e=>{$.data&&e(d)}),Y(e,c),We()}var to=J(`
`),no=J(`

`,1);function ro(e,t){Ue(t,!0);let n=Wi(t,`values`,19,()=>[]),r=Wi(t,`label`,3,`Token activity`),i=Wi(t,`capacity`,3,0),a=F(()=>Math.max(0,...n())),o=F(()=>i()>n().length?[...Array(i()-n().length).fill(0),...n()]:n());var s=no(),c=B(s),l=V(c),u=H(c,2);Xr(u,21,()=>K(o),Kr,(e,t)=>{var n=to();let r;U((e,t)=>{Q(n,`title`,e),r=ui(n,``,r,{height:t})},[()=>K(t).toLocaleString(`en-GB`)+` tokens`,()=>`${100*K(t)/Math.max(1,K(a))}%`]),Y(e,n)}),P(u),U((e,t)=>{X(l,`SCALE // 0 — ${e??``} TOKENS`),Q(u,`aria-label`,t)},[()=>K(a).toLocaleString(`en-GB`),()=>`${r()}. Peak ${K(a).toLocaleString(`en-GB`)} tokens.`]),Y(e,s),We()}function io(e){if(!e||![`LAST REPLY`,`LAST ACTIVITY`].includes(e.contextKind))return``;let t=e.text||e.contextKind===`LAST ACTIVITY`&&e.workingCommand||``;return t.trim()?t:``}var ao=J(` `),oo=J(``),so=J(`

`),co=J(`

`,1),lo=J(`

`),uo=J(`

Loading / sending…

`),fo=J(`
`),po=J(`

`),mo=J(`

 
`),ho=J(`
`),go=J(`
`),_o=J(`

Review expired. Press Enter to review again.

`),vo=J(`

`,1),yo=J(`

`,1),bo=J(`

No available matching commands.

`),xo=J(` `,1),So=J(`

`),Co=J(`

Review expired. Review the option again.

`),wo=J(``),To=J(``),Eo=J(``),Do=J(``),Oo=J(``),ko=J(``),Ao=J(``),jo=J(`
`),Mo=J(`
`);function No(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=oo();let o;var s=z(i),c=V(s,!0),l=H(s),u=V(l),d=H(l),f=e=>{var n=ao(),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`&&!io($.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=Mo(),we=z(Ce),Te=H(we,2),Ee=e=>{var t=so(),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=jo();let o;var s=z(i),c=e=>{var t=co(),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=lo(),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,uo())};Z(d,e=>{K(g)&&e(f)});var p=H(d,2),m=e=>{var t=fo(),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=mo(),r=z(n),i=V(r,!0),a=H(r,2),o=V(a,!0),s=H(a,2),c=e=>{var n=po(),r=z(n),i=H(r),a=e=>{Y(e,Mr(`Only this session's saved + SPEED`),X(d,K(t).mode),X(f,`${K(t).state??``}${K(t).state===`NEXT`?` // ${K(t).remaining||0} PP TO GO`:``}`)},[()=>K(t).effort.toUpperCase(),()=>K(t).speed.toUpperCase()]),Y(e,n)}),P(l),P(o),U(e=>{X(r,`MODEL STEP POLICY // OBSERVED ${e??``}`),X(c,`THRESHOLDS // ${$.data.thresholds.length??``} CONFIGURED`)},[()=>ma($.data.quotaAt)]),Y(e,t)},a=e=>{Y(e,Ca())};Z(r,e=>{$.data?.thresholds?.length?e(i):e(a,-1)}),Y(e,n),We()}var Ta=jr(` `,1),Ea=jr(` `,1),Da=jr(` `,1),Oa=jr(` `,1),ka=J(`
`,1),Aa=J(` `),ja=J(`
Quota observations
Observed atPeriod elapsedConsumedTrail segment
`),Ma=J(`
OBSERVATION DATA
`),Na=J(`
CONSUMPTIONQUOTA PERIOD ELAPSED
`,1);function Pa(e,t){let n=Pr();Ue(t,!0);let r=Wi(t,`trail`,19,()=>[]),i=L(!1),a=L(!0),o=L(`window`),s=[0,25,50,75,100],c={off:0,halfHour:30,hour:60,day:1440,window:0},l=L(400),u=L(240),d=F(()=>K(l)-24),f=F(()=>K(u)-48),p=F(()=>Math.max(1,K(d)-48)),m=F(()=>Math.max(1,K(f)-20)),h=F(()=>48+Math.max(0,Math.min(100,t.elapsed))/100*K(p));function g(e){return K(f)-(e-0)/100*K(m)}let _=F(()=>g(t.used)),v=F(()=>t.used-t.elapsed),y=F(()=>r().map((e,t)=>`${t===0||e.break?`M`:`L`}${48+e.elapsed/100*K(p)} ${g(e.used)}`).join(` `)),b=F(()=>{let e=0;for(let t=r().length-1;t>0;t--)if(r()[t].break){e=t;break}return r().slice(e)}),x=F(()=>K(b).length<2?0:Math.max(0,Date.parse(K(b).at(-1).at)-Date.parse(K(b)[0].at)));function S(e){if(K(x)Date.parse(e.at)>=t).length>=2}let C=F(()=>({off:!0,halfHour:S(18e5),hour:S(36e5),day:S(864e5),window:Number.isFinite(t.elapsed)&&t.elapsed>0&&Number.isFinite(t.used)}));vn(()=>{K(o)!==`window`&&!K(C)[K(o)]&&R(o,`window`)});function w(e){if(e===`off`||!K(C)[e])return[];let t=c[e]*6e4,n=Date.parse(K(b).at(-1).at)-t,r=K(b).findIndex(e=>Date.parse(e.at)>=n);return r<0?[]:K(b).slice(r)}function T(e){if(e.length<2)return null;let t=e.reduce((e,t)=>e+t.elapsed,0)/e.length,n=e.reduce((e,t)=>e+t.used,0)/e.length,r=0,i=0;for(let a of e)r+=(a.elapsed-t)*(a.used-n),i+=(a.elapsed-t)**2;return i>0?Math.max(0,r/i):null}let E=F(()=>{let e=K(o)===`window`&&K(C).window?t.used/t.elapsed:T(w(K(o)));if(e===null||!t.duration)return null;let n=t.used+e*(100-t.elapsed),r=K(o)===`window`?0:t.used-e*t.elapsed,i=e,a=Math.max(0,t.elapsed-c[K(o)]/t.duration*100);K(o)===`window`&&(a=0);let s=100;if(i!==0){let e=(0-r)/i,t=(100-r)/i;a=Math.max(a,Math.min(e,t)),s=Math.min(100,Math.max(e,t))}if(a>s)return null;let l=r+i*a,u=r+i*s,d=Math.hypot((s-a)/100*K(p),(u-l)/100*K(m)),f=Math.max(3,Math.min(9,Math.floor(d/65)+2));return{path:`M${Array.from({length:f},(e,t)=>{let n=a+(s-a)*t/(f-1),r=l+(u-l)*t/(f-1);return`${48+n/100*K(p)} ${g(r)}`}).join(` L`)}`,projected:n,safe:n<=100}}),D=F(()=>{if(K(b).length===0)return`NO OBSERVATIONS`;if(K(b).length===1)return`ONE OBSERVATION`;let e=Math.floor(K(x)/6e4);if(e<60)return`${e} MIN CONTINUOUS`;let t=Math.floor(e/60);return t<24?`${t}H CONTINUOUS`:`${Math.floor(t/24)}D ${t%24}H CONTINUOUS`});var ee=Na(),te=B(ee),O=z(te);let k;var ne=z(O),re=z(ne),ie=H(re);P(ne);var ae=H(ne),oe=H(ae);Xr(oe,17,()=>s,Kr,(e,t)=>{var n=Ta(),r=B(n),i=H(r),a=V(i);U(()=>{Q(r,`x1`,48+K(t)/100*K(p)),Q(r,`x2`,48+K(t)/100*K(p)),Q(r,`y2`,K(f)),Q(i,`x`,48+K(t)/100*K(p)),Q(i,`y`,K(f)+20),X(a,`${K(t)??``}%`)}),Y(e,n)});var se=H(oe);Xr(se,17,()=>s,Kr,(e,t)=>{var n=Ea(),r=B(n),i=H(r),a=V(i);U((e,n,o)=>{Q(r,`y1`,e),Q(r,`x2`,K(d)),Q(r,`y2`,n),Q(i,`y`,o),X(a,`${K(t)??``}%`)},[()=>g(K(t)),()=>g(K(t)),()=>g(K(t))+4]),Y(e,n)});var A=H(se),ce=H(A),le=H(ce),ue=e=>{var t=Da(),n=B(t),i=H(n),a=H(i),o=V(z(a));P(a),U((e,t)=>{Q(n,`d`,K(y)),Q(i,`d`,K(y)),Q(a,`cx`,48+r()[0].elapsed/100*K(p)),Q(a,`cy`,e),X(o,`First observation: ${t??``}`)},[()=>g(r()[0].used),()=>ma(r()[0].at)]),Y(e,t)};Z(le,e=>{K(a)&&r().length&&e(ue)});var de=H(le),fe=e=>{var t=Oa(),r=B(t),i=H(r),a=V(z(i));P(i),U(e=>{Q(r,`d`,K(E).path),Q(i,`d`,K(E).path),Q(i,`marker-mid`,`url(#${n}-trend-arrow)`),X(a,`${K(o)===`window`?`Window-average pace`:`Recent consumption trajectory`} projects ${e??``}% at reset if continued`)},[()=>K(E).projected.toFixed(1)]),Y(e,t)};Z(de,e=>{K(E)&&e(fe)});var j=H(de,2),pe=H(j),me=H(pe),he=V(z(me));P(me),P(O),P(te);var ge=H(te,2),_e=z(ge),M=z(_e),ve=H(M,3),N=V(ve,!0),ye=H(ve,2),be=e=>{var t=ka(),n=V(H(B(t)));U(e=>X(n,`TREND // ${e??``}`),[()=>K(E).projected>=100?`QUOTA EXHAUSTION PROJECTED`:`${K(E).projected.toFixed(1)}% PROJECTED AT RESET`]),Y(e,t)};Z(ye,e=>{K(E)&&e(be)}),P(_e);var Se=H(_e,2),Ce=z(Se),we=z(Ce);xi(we),xe(),P(Ce);var Te=H(Ce,2),Ee=H(z(Te),2),De=z(Ee);De.value=De.__value=`off`;var Oe=H(De),ke=V(Oe);Oe.value=Oe.__value=`halfHour`;var Ae=H(Oe),je=V(Ae);Ae.value=Ae.__value=`hour`;var Me=H(Ae),Ne=V(Me);Me.value=Me.__value=`day`;var Pe=H(Me),Fe=V(Pe);Pe.value=Pe.__value=`window`,P(Ee),mi(Ee),P(Te);var Ie=V(H(Te,2));P(Se),P(ge);var Le=H(ge,2),Re=e=>{var t=Ma(),n=H(z(t),2),a=e=>{var t=ja(),n=z(t),i=H(z(n),2);Xr(i,21,r,Kr,(e,t,n)=>{var r=Aa(),i=z(r),a=z(i),o=V(a,!0);P(i);var s=H(i),c=V(s),l=H(s),u=V(l),d=V(H(l),!0);P(r),U((e,r)=>{Q(a,`datetime`,K(t).at),X(o,e),X(c,`${r??``}%`),X(u,`${K(t).used??``}%`),X(d,n===0?`First observation`:K(t).break?`Gap before this observation`:`Connected to previous observation`)},[()=>ma(K(t).at),()=>K(t).elapsed.toFixed(1)]),Y(e,r)}),P(i),P(n),P(t),Y(e,t)};Z(n,e=>{K(i)&&e(a)}),P(t),Li(`open`,`toggle`,t,e=>R(i,e),()=>K(i)),Y(e,t)};Z(Le,e=>{r().length&&e(Re)}),U((e,r,i,a,o,s)=>{Q(O,`viewBox`,`0 0 ${K(l)} ${K(u)}`),Q(O,`aria-label`,e),k=ui(O,``,k,{"--trend-color":K(E)?.safe?`#115b35`:`#7f1825`}),Q(re,`id`,n),Q(ie,`id`,n+`-trend-arrow`),Q(ae,`width`,K(p)),Q(ae,`height`,K(m)),Q(ae,`fill`,`url(#${n})`),Q(A,`d`,`M48 20 V${K(f)} H${K(d)}`),Q(ce,`y1`,r),Q(ce,`x2`,K(d)),Q(ce,`y2`,i),Q(j,`x`,48+K(p)/2),Q(j,`y`,K(u)-5),Q(pe,`cx`,K(h)),Q(pe,`cy`,K(_)),Q(me,`cx`,K(h)),Q(me,`cy`,K(_)),X(he,`${t.used??``}% consumed // ${a??``}% of period elapsed`),X(M,`${t.used??``}% USED // ${o??``}% TIME ELAPSED`),X(N,s),Oe.disabled=!K(C).halfHour,X(ke,`LAST 30 MINUTES${K(C).halfHour?``:` — UNAVAILABLE`}`),Ae.disabled=!K(C).hour,X(je,`LAST HOUR${K(C).hour?``:` — UNAVAILABLE`}`),Me.disabled=!K(C).day,X(Ne,`LAST 24 HOURS${K(C).day?``:` — UNAVAILABLE`}`),Pe.disabled=!K(C).window,X(Fe,`FROM WINDOW START${K(C).window?``:` — NO TIME ELAPSED`}`),X(Ie,`HISTORY // ${K(D)??``}`)},[()=>`Pace: ${t.used}% consumed, ${t.elapsed.toFixed(1)}% of quota period elapsed. ${K(v)>0?`Above`:K(v)<0?`Below`:`On`} the steady-consumption line.${K(a)&&r().length?` Trace path contains ${r().length} ${r().length===1?`observation`:`observations`}; gaps are not interpolated.`:``}`,()=>g(0),()=>g(100),()=>t.elapsed.toFixed(1),()=>t.elapsed.toFixed(1),()=>Math.abs(K(v))<.05?`ON PACE`:K(v)>0?`ABOVE THE LINE — CONSUMING FASTER THAN TIME`:`BELOW THE LINE — WITHIN PACE`]),Pi(te,`clientWidth`,e=>R(l,e)),Pi(te,`clientHeight`,e=>R(u,e)),ki(we,()=>K(a),e=>R(a,e)),hi(Ee,()=>K(o),e=>R(o,e)),Y(e,ee),We()}var Fa=J(` `),Ia=J(`

Quota refresh failed. Values below are the last successful observation.

`),La=J(`

`),Ra=J(`

Expiry details unavailable. No listed expiry does not mean no expiry.

`),za=J(`

`),Ba=J(`

Read-only preview. Use the terminal to redeem a reset.

The backend may return only some credits. This list does not establish + redemption order.

`),Va=J(` `,1),Ha=jr(``),Ua=jr(``),Wa=J(`
`),Ga=J(`

Cycle duration or reset date unavailable — position cannot be + plotted.

`),Ka=J(`
EMPTYFULL
`),qa=J(`

`,1),Ja=J(`
`,1),Ya=J(`

`),Xa=J(`

`),Za=J(`

No quota windows reported yet.

`),Qa=J(`
`,1),$a=J(`

All reported windows are shown. API-equivalent learning and quota status + scoring remain in the terminal for this first preview.

`,1),eo=J(` `,1);function to(e,t){Ue(t,!0);let n=Wi(t,`params`,19,()=>({})),r=F(()=>ea.filter(e=>e!==`thresholds`||!!$.data?.thresholds?.length)),i=L(Yt(Date.now())),a=F(()=>K(r).includes(ta(n().view))?ta(n().view):`bars`);Gi(()=>{let e=setInterval(()=>R(i,Date.now(),!0),1e3);return()=>clearInterval(e)});function o(e){return!e.duration||e.duration<=0||!e.reset?null:Math.max(0,Math.min(100,100*(1-(e.reset*1e3-K(i))/(e.duration*6e4))))}vn(()=>{aa.view=K(a),(n().view===`zone`||n().view===`consumption-pace`)&&Zi(`/quota/pace`)});function s(e){let t=e/100*Math.PI*2;return`M60 60 L60 14 A46 46 0 ${+(e>50)} 1 ${60+46*Math.sin(t)} ${60-46*Math.cos(t)} Z`}var c=eo(),l=B(c);Xr(l,21,()=>K(r),Kr,(e,t)=>{var n=Fa();let r;var i=V(n,!0);U(e=>{Q(n,`href`,`#/quota/`+K(t)),Q(n,`aria-current`,K(a)===K(t)?`page`:void 0),r=ci(n,1,``,null,r,{active:K(a)===K(t)}),X(i,e)},[()=>K(t)===`fuel`?`FUEL TANK`:K(t).toUpperCase()]),Y(e,n)}),P(l);var u=H(l,2),d=e=>{var t=$a(),n=B(t),r=e=>{Y(e,Ia())};Z(n,e=>{$.data.quotaError&&e(r)});var i=H(n,2),c=e=>{var t=La(),n=V(t);U(()=>X(n,`Last usage accounting issue: + ${$.data.usageDiagnostic??``}`)),Y(e,t)};Z(i,e=>{$.data.usageDiagnostic&&e(c)});var l=H(i,2),u=V(l),d=H(l,2),f=e=>{wa(e,{})},p=e=>{var t=Ba(),n=z(t),r=V(n),i=H(n,4),a=e=>{Y(e,Ra())};Z(i,e=>{$.data.credits.length||e(a)}),Xr(H(i,2),17,()=>$.data.credits,Kr,(e,t)=>{var n=za(),r=z(n),i=V(r),a=V(H(r,2),!0);P(n),U(e=>{X(i,`${(K(t).title||`Quota reset`)??``} // ${K(t).status??``}`),X(a,e)},[()=>K(t).expiryKnown?K(t).expires?`EXPIRES `+ma(K(t).expires):`Does not expire`:`Expiry information unavailable`]),Y(e,n)}),xe(2),P(t),U(()=>X(r,`RESET INVENTORY // ${$.data.creditCount??``} AVAILABLE`)),Y(e,t)},m=e=>{var t=Qa(),n=B(t);let r;Xr(n,21,()=>$.data.meters,Kr,(e,t)=>{let n=F(()=>o(K(t)));var r=Xa(),i=z(r),c=V(i,!0),l=H(i,2),u=z(l),d=e=>{var n=Va(),r=B(n),i=V(r),a=V(H(r));U(()=>{X(i,`FREE ${100-K(t).used}%`),X(a,`USED ${K(t).used??``}%`)}),Y(e,n)},f=e=>{var n=Va(),r=B(n),i=V(r),a=V(H(r));U(()=>{X(i,`USED ${K(t).used??``}%`),X(a,`FREE ${100-K(t).used}%`)}),Y(e,n)};Z(u,e=>{K(a)===`fuel`?e(d):e(f,-1)}),P(l);var p=H(l,2);let m;var h=z(p),g=e=>{var n=Wa(),r=z(n),i=H(z(r)),a=e=>{Y(e,Ha())},o=e=>{var n=Ua();U(e=>Q(n,`d`,e),[()=>s(K(t).used)]),Y(e,n)};Z(i,e=>{K(t).used>=100?e(a):K(t).used>0&&e(o,1)}),P(r),P(n),U(()=>Q(r,`aria-label`,`${K(t).used}% quota used`)),Y(e,n)},_=e=>{var r=Nr(),i=B(r),a=e=>{{let r=F(()=>K(t).trail||[]);Pa(e,{get used(){return K(t).used},get elapsed(){return K(n)},get trail(){return K(r)},get duration(){return K(t).duration}})}},o=e=>{Y(e,Ga())};Z(i,e=>{K(n)===null?e(o,-1):e(a)}),Y(e,r)},v=e=>{var r=Ja(),i=B(r),o=z(i);let s;P(i);var c=H(i,2),l=e=>{Y(e,Ka())};Z(c,e=>{K(a)===`fuel`&&e(l)});var u=H(c,2),d=e=>{var t=qa(),r=B(t),i=V(r),o=H(r,2),s=z(o);let c;P(o),U(e=>{X(i,`RESET CYCLE // ${e??``}% ELAPSED`),c=ui(s,``,c,{width:`${K(a)===`fuel`?100-K(n):K(n)}%`})},[()=>Math.floor(K(n))]),Y(e,t)};Z(u,e=>{K(n)!==null&&e(d)}),U(()=>{Q(i,`aria-label`,K(a)===`fuel`?`Fuel remaining`:`Quota used`),Q(i,`aria-valuenow`,K(a)===`fuel`?100-K(t).used:K(t).used),s=ui(o,``,s,{width:`${K(a)===`fuel`?100-K(t).used:K(t).used}%`})}),Y(e,r)};Z(h,e=>{K(a)===`pie`?e(g):K(a)===`pace`?e(_,1):e(v,-1)}),P(p);var y=H(p,2),b=V(y),x=H(y,2),S=e=>{var n=Ya(),r=V(n,!0);U(()=>X(r,K(t).details)),Y(e,n)};Z(x,e=>{K(t).details&&e(S)}),P(r),U(e=>{X(c,K(t).name),m=ci(p,1,`meter-graphic`,null,m,{"bar-graphic":K(a)===`bars`||K(a)===`fuel`}),X(b,`RESETS // ${e??``}`)},[()=>ma(K(t).reset)]),Y(e,r)}),P(n);var i=H(n,2),c=e=>{Y(e,Za())};Z(i,e=>{$.data.meters.length||e(c)}),U(()=>r=ci(n,1,`quota-grid`,null,r,{radial:K(a)===`pie`,zone:K(a)===`pace`})),Y(e,t)};Z(d,e=>{K(a)===`thresholds`?e(f):K(a)===`resets`?e(p,1):e(m,-1)}),xe(2),U(e=>X(u,`QUOTA // OBSERVED ${e??``}`),[()=>ma($.data.quotaAt)]),Y(e,t)};Z(u,e=>{$.data&&e(d)}),Y(e,c),We()}var no=J(`
`),ro=J(`

`,1);function io(e,t){Ue(t,!0);let n=Wi(t,`values`,19,()=>[]),r=Wi(t,`label`,3,`Token activity`),i=Wi(t,`capacity`,3,0),a=F(()=>Math.max(0,...n())),o=F(()=>i()>n().length?[...Array(i()-n().length).fill(0),...n()]:n());var s=ro(),c=B(s),l=V(c),u=H(c,2);Xr(u,21,()=>K(o),Kr,(e,t)=>{var n=no();let r;U((e,t)=>{Q(n,`title`,e),r=ui(n,``,r,{height:t})},[()=>K(t).toLocaleString(`en-GB`)+` tokens`,()=>`${100*K(t)/Math.max(1,K(a))}%`]),Y(e,n)}),P(u),U((e,t)=>{X(l,`SCALE // 0 — ${e??``} TOKENS`),Q(u,`aria-label`,t)},[()=>K(a).toLocaleString(`en-GB`),()=>`${r()}. Peak ${K(a).toLocaleString(`en-GB`)} tokens.`]),Y(e,s),We()}function ao(e){if(!e||![`LAST REPLY`,`LAST ACTIVITY`].includes(e.contextKind))return``;let t=e.text||e.contextKind===`LAST ACTIVITY`&&e.workingCommand||``;return t.trim()?t:``}var oo=J(` `),so=J(``),co=J(`

`),lo=J(`

`,1),uo=J(`

`),fo=J(`

Loading / sending…

`),po=J(`
`),mo=J(`

`),ho=J(`

 
`),go=J(`
`),_o=J(`
`),vo=J(`

Review expired. Press Enter to review again.

`),yo=J(`

`,1),bo=J(`

`,1),xo=J(`

No available matching commands.

`),So=J(` `,1),Co=J(`

`),wo=J(`

Review expired. Review the option again.

`),To=J(``),Eo=J(``),Do=J(``),Oo=J(``),ko=J(``),Ao=J(``),jo=J(``),Mo=J(`
`),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(`
`),Io=J(`
/
`);function Lo(e,t){Ue(t,!0);let n=F(()=>t.lines.filter(e=>e.kind===`addition`).length),r=F(()=>t.lines.filter(e=>e.kind===`removal`).length);var i=Io(),a=z(i),o=z(a),s=V(o),c=V(H(o,2));P(a),Xr(H(a,2),17,()=>t.lines,Kr,(e,t)=>{var n=Fo();let r;var i=z(n),a=e=>{var n=Po(),r=B(n),i=V(r,!0),a=V(H(r),!0);U(()=>{X(i,K(t).old||``),X(a,K(t).new||``)}),Y(e,n)};Z(i,e=>{K(t).kind!==`heading`&&K(t).kind!==`metadata`&&e(a)});var o=V(H(i),!0);P(n),U(()=>{r=ci(n,1,`diff-line svelte-x4gtb6`,null,r,{added:K(t).kind===`addition`,removed:K(t).kind===`removal`,heading:K(t).kind===`heading`}),X(o,K(t).text)}),Y(e,n)}),P(i),U(()=>{Q(a,`aria-label`,`${K(n)} lines added, ${K(r)} lines removed`),X(s,`+${K(n)??``}`),X(c,`−${K(r)??``}`)}),Y(e,i),We()}var Ro=J(`

`),zo=J(`

Send this saved prompt now? This starts Codex work and consumes quota.

`,1),Bo=J(``),Vo=J(`

 

In memory only. Follows session model, reasoning and speed. Closing - Codexometer cancels pending work.

`),Ho=J(`

CURRENT PROFILE

MODEL / REASONING LEVEL / SPEED

 

PROPOSED PROFILE

MODEL / REASONING LEVEL / SPEED

 

Applied settings remain after Codexometer closes.

`,1),Uo=J(`

`),Wo=J(`

 
`,1),Go=J(`

Command unavailable from this observation. Open Codex to inspect the - request.

`),Ko=J(`

Session controls temporarily unavailable. Check Codex for current state.

`),qo=J(`

Checking session controls…

`),Jo=J(`

`),Yo=J(`
About browser controls

Controls require a supported live request from a connected shared - app-server session. Local observations alone cannot provide them.

`),Xo=J(` `,1),Zo=J(` `),Qo=J(`Grants permission beyond this one action. Check the scope - carefully.`),$o=J(``),es=J(``),ts=J(``),ns=J(``),rs=J(`

Not before this time; when quota and idle allow.

`),is=J(`

`,1),as=J(`

The existing trigger remains active until saved or deleted. If - it changes or sends while you edit, saving is blocked.

`),os=J(` `,1),ss=J(``),cs=J(``),ls=J(``),us=J(` `,1),ds=J(`
  • `),fs=J(`
    View fixed choices

    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(`
      `),Lo=J(`
      /
      `);function Ro(e,t){Ue(t,!0);let n=F(()=>t.lines.filter(e=>e.kind===`addition`).length),r=F(()=>t.lines.filter(e=>e.kind===`removal`).length);var i=Lo(),a=z(i),o=z(a),s=V(o),c=V(H(o,2));P(a),Xr(H(a,2),17,()=>t.lines,Kr,(e,t)=>{var n=Io();let r;var i=z(n),a=e=>{var n=Fo(),r=B(n),i=V(r,!0),a=V(H(r),!0);U(()=>{X(i,K(t).old||``),X(a,K(t).new||``)}),Y(e,n)};Z(i,e=>{K(t).kind!==`heading`&&K(t).kind!==`metadata`&&e(a)});var o=V(H(i),!0);P(n),U(()=>{r=ci(n,1,`diff-line svelte-x4gtb6`,null,r,{added:K(t).kind===`addition`,removed:K(t).kind===`removal`,heading:K(t).kind===`heading`}),X(o,K(t).text)}),Y(e,n)}),P(i),U(()=>{Q(a,`aria-label`,`${K(n)} lines added, ${K(r)} lines removed`),X(s,`+${K(n)??``}`),X(c,`−${K(r)??``}`)}),Y(e,i),We()}var zo=J(`

      `),Bo=J(`

      Send this saved prompt now? This starts Codex work and consumes quota.

      `,1),Vo=J(``),Ho=J(`

       

      In memory only. Follows session model, reasoning and speed. Closing + Codexometer cancels pending work.

      `),Uo=J(`

      CURRENT PROFILE

      MODEL / REASONING LEVEL / SPEED

       

      PROPOSED PROFILE

      MODEL / REASONING LEVEL / SPEED

       

      Applied settings remain after Codexometer closes.

      `,1),Wo=J(`

      `),Go=J(`

       
      `,1),Ko=J(`

      Command unavailable from this observation. Open Codex to inspect the + request.

      `),qo=J(`

      Session controls temporarily unavailable. Check Codex for current state.

      `),Jo=J(`

      Checking session controls…

      `),Yo=J(`

      `),Xo=J(`
      About browser controls

      Controls require a supported live request from a connected shared + app-server session. Local observations alone cannot provide them.

      `),Zo=J(` `,1),Qo=J(` `),$o=J(`Grants permission beyond this one action. Check the scope + carefully.`),es=J(``),ts=J(``),ns=J(``),rs=J(``),is=J(`

      Not before this time; when quota and idle allow.

      `),as=J(`

      `,1),os=J(`

      The existing trigger remains active until saved or deleted. If + it changes or sends while you edit, saving is blocked.

      `),ss=J(` `,1),cs=J(``),ls=J(``),us=J(``),ds=J(` `,1),fs=J(`
    • `),ps=J(`
      View fixed choices

      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.

        `),ws=J(`

        `,1);function Ts(e,t){Ue(t,!0);let n=Wi(t,`stale`,3,!1),r=L(Yt([])),i=L(!1),a=F(()=>$.data?.statusLineFields||[]),o=e=>[...new Set(e??K(a).filter(e=>e.default).map(e=>e.id))].filter(e=>K(a).some(t=>t.id===e)),s=e=>o(e).map(e=>e===`run-state`&&(n()||!$.connected||$.data?.sessionsError)?`STALE`:t.session.statusLine?.[e]).filter(Boolean).join(` · `),c=F(()=>[...K(r).map(e=>K(a).find(t=>t.id===e)).filter(Boolean),...K(a).filter(e=>!K(r).includes(e.id))]);vn(()=>{oa.open&&!K(i)?(R(r,o(aa.statusLine),!0),R(i,!0)):oa.open||R(i,!1)});function l(e,t){R(r,t?[...K(r),e]:K(r).filter(t=>t!==e),!0)}function u(e,t){let n=K(r).indexOf(e),i=n+t;if(n<0||i<0||i>=K(r).length)return;let a=[...K(r)];[a[n],a[i]]=[a[i],a[n]],R(r,a,!0)}var d=ws(),f=B(d),p=e=>{var t=Cs(),n=H(z(t),4);Xr(n,21,()=>K(c),e=>e.id,(e,t)=>{var n=Ss(),i=z(n),a=z(i);xi(a);var o=H(a,1,!0),s=V(H(o),!0);P(i);var c=H(i,2),d=e=>{var n=xs(),i=B(n),a=H(i,2);U((e,n)=>{Q(i,`aria-label`,`Move `+K(t).label+` earlier`),i.disabled=e,Q(a,`aria-label`,`Move `+K(t).label+` later`),a.disabled=n},[()=>K(r).indexOf(K(t).id)===0,()=>K(r).indexOf(K(t).id)===K(r).length-1]),q(`click`,i,()=>u(K(t).id,-1)),q(`click`,a,()=>u(K(t).id,1)),Y(e,n)},f=F(()=>K(r).includes(K(t).id));Z(c,e=>{K(f)&&e(d)}),P(n),U(e=>{Q(i,`title`,K(t).help),Si(a,e),X(o,K(t).label),X(s,K(t).help)},[()=>K(r).includes(K(t).id)]),q(`change`,a,e=>l(K(t).id,e.currentTarget.checked)),Y(e,n)}),P(n);var i=H(n,2),a=V(i),o=H(i,2),d=H(o,2);P(t),U(e=>X(a,`Preview // ${e??``}`),[()=>s(K(r))||`—`]),q(`click`,o,()=>{aa.statusLine=[...K(r)],ca(),oa.open=!1}),q(`click`,d,()=>{oa.open=!1}),Y(e,t)};Z(f,e=>{oa.open&&e(p)});var m=H(f,2),h=z(m),g=V(h,!0),_=H(h,2);P(m),U((e,t)=>{Q(h,`title`,e),X(g,t)},[()=>s(aa.statusLine),()=>s(aa.statusLine)]),q(`click`,_,()=>{oa.open=!oa.open}),Y(e,d),We()}Sr([`change`,`click`]);var Es=J(`
        `);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.

        `),Ts=J(`

        `,1);function Es(e,t){Ue(t,!0);let n=Wi(t,`stale`,3,!1),r=L(Yt([])),i=L(!1),a=F(()=>$.data?.statusLineFields||[]),o=e=>[...new Set(e??K(a).filter(e=>e.default).map(e=>e.id))].filter(e=>K(a).some(t=>t.id===e)),s=e=>o(e).map(e=>e===`run-state`&&(n()||!$.connected||$.data?.sessionsError)?`STALE`:t.session.statusLine?.[e]).filter(Boolean).join(` · `),c=F(()=>[...K(r).map(e=>K(a).find(t=>t.id===e)).filter(Boolean),...K(a).filter(e=>!K(r).includes(e.id))]);vn(()=>{oa.open&&!K(i)?(R(r,o(aa.statusLine),!0),R(i,!0)):oa.open||R(i,!1)});function l(e,t){R(r,t?[...K(r),e]:K(r).filter(t=>t!==e),!0)}function u(e,t){let n=K(r).indexOf(e),i=n+t;if(n<0||i<0||i>=K(r).length)return;let a=[...K(r)];[a[n],a[i]]=[a[i],a[n]],R(r,a,!0)}var d=Ts(),f=B(d),p=e=>{var t=ws(),n=H(z(t),4);Xr(n,21,()=>K(c),e=>e.id,(e,t)=>{var n=Cs(),i=z(n),a=z(i);xi(a);var o=H(a,1,!0),s=V(H(o),!0);P(i);var c=H(i,2),d=e=>{var n=Ss(),i=B(n),a=H(i,2);U((e,n)=>{Q(i,`aria-label`,`Move `+K(t).label+` earlier`),i.disabled=e,Q(a,`aria-label`,`Move `+K(t).label+` later`),a.disabled=n},[()=>K(r).indexOf(K(t).id)===0,()=>K(r).indexOf(K(t).id)===K(r).length-1]),q(`click`,i,()=>u(K(t).id,-1)),q(`click`,a,()=>u(K(t).id,1)),Y(e,n)},f=F(()=>K(r).includes(K(t).id));Z(c,e=>{K(f)&&e(d)}),P(n),U(e=>{Q(i,`title`,K(t).help),Si(a,e),X(o,K(t).label),X(s,K(t).help)},[()=>K(r).includes(K(t).id)]),q(`change`,a,e=>l(K(t).id,e.currentTarget.checked)),Y(e,n)}),P(n);var i=H(n,2),a=V(i),o=H(i,2),d=H(o,2);P(t),U(e=>X(a,`Preview // ${e??``}`),[()=>s(K(r))||`—`]),q(`click`,o,()=>{aa.statusLine=[...K(r)],ca(),oa.open=!1}),q(`click`,d,()=>{oa.open=!1}),Y(e,t)};Z(f,e=>{oa.open&&e(p)});var m=H(f,2),h=z(m),g=V(h,!0),_=H(h,2);P(m),U((e,t)=>{Q(h,`title`,e),X(g,t)},[()=>s(aa.statusLine),()=>s(aa.statusLine)]),q(`click`,_,()=>{oa.open=!oa.open}),Y(e,d),We()}Sr([`change`,`click`]);var Ds=J(`
        `);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.

        `),Us=J(` `),Ws=J(` `),Gs=J(` `),Ks=J(``),qs=J(`

        Read only — reply or approve in Codex.

        `),Js=J(`

        `),Ys=J(`QUOTA THRESHOLD // REVIEW PROFILE ↗`),Xs=J(`
        `),Zs=J(`
        `),Qs=J(`

        This session is no longer in the current observation. Return to sessions.

        `),$s=J(`

        `),ec=J(``),tc=J(`

        `),nc=J(` `),rc=J(`

        `),ic=J(`QUOTA THRESHOLD // REVIEW PROFILE ↗`),ac=J(` `,1),oc=J(`

        `),sc=J(`

        TOKEN ACTIVITY // 30 SECOND SAMPLES

        `),cc=J(`

        TOKENS

        FULL DETAIL →
        `),lc=J(`

        No locally observed sessions yet. Keep Codex running alongside - Codexometer.

        `),uc=J(`

        ↑ ↓ SELECT SESSION // ← LESS DETAIL // → MORE DETAIL // ESC BACK

        `,1),dc=J(`

        SESSION TOTALS

        `,1);function fc(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=zs(),s=B(o),c=e=>{var n=Os(),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=ks(),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=As(),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=js();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=Ms(),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=Ns(),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=Ps(),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=>{Lo(e,{get lines(){return t().fileChanges}})},te=e=>{var n=Ls(),r=H(B(n),2),i=V(r,!0),a=H(r,2),o=e=>{var n=Fs(),r=V(n,!0);U(()=>X(r,t().command)),Y(e,n)},s=e=>{Y(e,Is())};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=Rs(),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=dc();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=Bs(),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,Vs())};Z(re,e=>{K(v)&&e(ie)});var ae=H(re,2),oe=e=>{Y(e,Hs())};Z(ae,e=>{$.data?.profileError&&e(oe)});var se=H(ae,2),A=e=>{var t=Ks(),n=z(t);Xr(n,17,()=>K(b),Kr,(e,t)=>{var n=Us();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=Ws(),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=Gs(),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=Zs(),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=Rs(),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||[]);bs(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=qs();Gr(H(z(t),2),()=>K(p).id,e=>{No(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=Xs(),r=z(n),i=e=>{var n=Js(),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=>{bs(e,{get session(){return K(p).id},review:`profile`})},s=e=>{var t=Ys();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(Ds(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=>{Ts(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,Qs())};Z(a,e=>{K(p)?e(s):e(c,-1)}),Y(e,t)},de=e=>{var t=uc(),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=cc();let a;var s=z(i),c=z(s),u=e=>{var n=$s(),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=ec(),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=Rs(),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=tc(),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=oc(),i=z(r),a=z(i),s=V(a,!0),c=H(a,2),l=e=>{var n=nc(),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=ac(),i=B(r),a=e=>{var t=rc(),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=ic();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);Ds(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=sc(),r=H(z(n),2);{let e=F(()=>(K(t).samples||[]).map(e=>e.tokens));ro(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,lc())};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 + visible.

        `),Ws=J(` `),Gs=J(` `),Ks=J(` `),qs=J(``),Js=J(`

        Read only — reply or approve in Codex.

        `),Ys=J(`

        `),Xs=J(`QUOTA THRESHOLD // REVIEW PROFILE ↗`),Zs=J(`
        `),Qs=J(`
        `),$s=J(`

        This session is no longer in the current observation. Return to sessions.

        `),ec=J(`

        `),tc=J(``),nc=J(`

        `),rc=J(` `),ic=J(`

        `),ac=J(`QUOTA THRESHOLD // REVIEW PROFILE ↗`),oc=J(` `,1),sc=J(`

        `),cc=J(`

        TOKEN ACTIVITY // 30 SECOND SAMPLES

        `),lc=J(`

        TOKENS

        FULL DETAIL →
        `),uc=J(`

        No locally observed sessions yet. Keep Codex running alongside + Codexometer.

        `),dc=J(`

        ↑ ↓ 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.

        `,1);function Vc(e,t){Ue(t,!0);let n=L(`daily`),r=L(12),i=L(0),a=F(()=>{let e=$.data?.usage?.dailyUsageBuckets;if(!e)return[];let{start:t,end:n}=Oc(new Date,K(r),K(i)),a=new Map;for(let t of e)!Number.isFinite(t.tokens)||t.tokens<0||a.set(t.startDate,(a.get(t.startDate)||0)+t.tokens);let o=[];for(let e=t;e<=n;e=new Date(e.getTime()+864e5)){let t=e.toISOString().slice(0,10);o.push({date:t,tokens:a.get(t)||0})}return o}),o=F(()=>Math.max(1,...K(a).map(e=>e.tokens))),s=F(()=>K(a).length?new Date(K(a)[0].date+`T00:00:00Z`).getUTCDay():0),c=F(()=>{if(K(n)===`monthly`){let e=new Map;for(let t of K(a))e.set(t.date.slice(0,7),(e.get(t.date.slice(0,7))||0)+t.tokens);return[...e].map(([e,t])=>({date:e,tokens:t}))}let e=0;return K(a).map(t=>({date:t.date,tokens:e+=t.tokens}))});var l=Bc(),u=H(B(l),4);Xr(u,20,()=>[[`daily`,`Daily`],[`monthly`,`Monthly`],[`cumulative`,`Cumulative`],[`breakdown`,`Breakdown`],[`periods`,`Windows`]],Kr,(e,t)=>{var r=F(()=>_(t,2));let a=()=>K(r)[0],o=()=>K(r)[1];var s=kc();let c;var l=V(s,!0);U(()=>{Q(s,`aria-pressed`,K(n)===a()),c=ci(s,1,``,null,c,{active:K(n)===a()}),X(l,o())}),q(`click`,s,()=>{R(n,a(),!0),R(i,0)}),Y(e,s)}),P(u);var d=H(u,2),f=z(d),p=e=>{var t=Ac(),n=B(t),a=H(z(n)),o=z(a);o.value=o.__value=6;var s=H(o);s.value=s.__value=12,P(a),mi(a),P(n);var c=H(n),l=H(c);U(()=>l.disabled=K(i)===0),q(`change`,a,()=>R(i,0)),hi(a,()=>K(r),e=>R(r,e)),q(`click`,c,()=>Kt(i)),q(`click`,l,()=>Kt(i,-1)),Y(e,t)};Z(f,e=>{K(n)!==`breakdown`&&K(n)!==`periods`&&e(p)}),P(d);var m=H(d,2),h=e=>{Y(e,jc())};Z(m,e=>{$.data?.usageError&&e(h)});var g=H(m,2),v=e=>{Y(e,Mc())};Z(g,e=>{$.data?.usage?.tokenStatus===`UNAVAILABLE`&&K(n)!==`breakdown`&&K(n)!==`periods`&&e(v)});var y=H(g,2),b=e=>{var t=Nr();Gr(B(t),()=>K(n),e=>{{let t=F(()=>$.data?.usage?.reports);Tc(e,{get reports(){return K(t)},get mode(){return K(n)}})}}),Y(e,t)},x=e=>{var t=Rc(),r=B(t),i=z(r),l=V(H(z(i),2),!0);P(i);var u=H(i,2),d=V(H(z(u),2),!0);P(u);var f=H(u,2),p=H(z(f),2),m=z(p);xe(),P(p),P(f);var h=H(f,2),g=H(z(h),2),_=z(g);xe(),P(g),P(h);var v=H(h,2),y=H(z(v),2),b=z(y);xe(),P(y),P(v),P(r);var x=H(r,4),S=z(x),C=V(S),w=H(S,2),T=e=>{var t=Fc(),n=B(t),r=z(n),i=z(r);Xr(i,17,()=>Array(K(s)),Kr,(e,t)=>{Y(e,Nc())}),Xr(H(i,2),17,()=>K(a),Kr,(e,t)=>{var n=Pc();let r,i;U(e=>{r=ci(n,1,`heat-cell`,null,r,{zero:K(t).tokens===0}),Q(n,`title`,e),i=ui(n,``,i,{opacity:K(t).tokens?.25+.75*K(t).tokens/K(o):1})},[()=>`${K(t).date}: ${pa(K(t).tokens)} tokens`]),Y(e,n)}),P(r),P(n),xe(2),Y(e,t)},E=e=>{var t=Ic(),r=B(t);{let e=F(()=>K(c).map(e=>e.tokens)),t=F(()=>K(n)+` usage`);ro(r,{get values(){return K(e)},get label(){return K(t)}})}var i=H(r,2),a=z(i),o=V(a,!0),s=V(H(a),!0);P(i),U(e=>{X(o,K(c)[0]?.date),X(s,e)},[()=>K(c).at(-1)?.date]),Y(e,t)};Z(w,e=>{K(n)===`daily`?e(T):e(E,-1)});var D=H(w,2),ee=H(z(D),2),te=z(ee),O=H(z(te));Xr(O,21,()=>K(n)===`daily`?K(a):K(c),Kr,(e,t)=>{var n=Lc(),r=z(n),i=V(r,!0),a=V(H(r),!0);P(n),U(e=>{X(i,K(t).date),X(a,e)},[()=>pa(K(t).tokens)]),Y(e,n)}),P(O),P(te),P(ee),P(D),P(x);var k=V(H(x,2));U((e,t,n,r,i,o,s)=>{X(l,e),X(d,t),X(m,`${n??``} `),X(_,`${r??``} `),X(b,`${i??``} `),X(C,`${K(a)[0]?.date??``} — ${o??``}`),X(k,`OBSERVED ${s??``} // CUMULATIVE IS FOR THE SELECTED PERIOD`)},[()=>pa($.data.usage.summary.lifetimeTokens),()=>pa($.data.usage.summary.peakDailyTokens),()=>pa($.data.usage.summary.currentStreakDays),()=>pa($.data.usage.summary.longestRunningTurnSec),()=>pa($.data.usage.summary.longestStreakDays),()=>K(a).at(-1)?.date,()=>ma($.data.usageAt)]),Y(e,t)},S=e=>{Y(e,zc())};Z(y,e=>{K(n)===`breakdown`||K(n)===`periods`?e(b):$.data?.usage&&$.data.usage.dailyUsageBuckets!==null?e(x,1):e(S,-1)}),Y(e,l),We()}Sr([`click`,`change`]);var Hc=J(`

        Page not found

        Return to Quota

        `,1);function Uc(e){var t=Hc();xe(2),Y(e,t)}var Wc=`CODEXOMETER`,Gc=[`█▀▀ █▀█ █▀▄ █▀▀ ▀▄▀ █▀█ █▀▄▀█ █▀▀ ▀█▀ █▀▀ █▀█`,`█▄▄ █▄█ █▄▀ ██▄ █ █ █▄█ █ ▀ █ ██▄ █ ██▄ █▀▄`].flatMap(e=>[[...e].map(e=>e===`█`||e===`▀`),[...e].map(e=>e===`█`||e===`▄`)]),Kc=Gc[0].length,qc=Gc.length,Jc=0,Yc=[...Wc].map(e=>{let t=e===`M`?5:3,n={start:Jc,width:t};return Jc+=t+1,n}),Xc=`ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`,Zc=`010 101 111 101.110 111 101 110.111 100 100 111.110 101 101 110.111 100 110 111.111 100 110 100.111 100 101 111.101 101 111 101.111 010 010 111.001 001 101 111.101 110 110 101.100 100 100 111.101 111 101 101.101 111 111 101.111 101 101 111.111 101 111 100.111 101 111 001.111 101 110 101.111 100 001 111.111 010 010 010.101 101 101 111.101 101 101 010.101 101 111 101.101 010 010 101.101 101 010 010.111 001 100 111.111 101 101 111.110 010 010 111.111 001 110 111.111 011 001 111.101 101 111 001.111 110 001 111.100 111 101 111.111 001 010 010.111 111 101 111.111 101 111 001`.split(`.`).map(e=>e.split(` `));function Qc(e=Wc,t=-1,n=!1){let r=``;for(let i=0;i{e|=0,e=e+1831565813|0;let t=Math.imul(e^e>>>15,1|e);return t^=t+Math.imul(t^t>>>7,61|t),((t^t>>>14)>>>0)/4294967296}}function nl(){let e=$c[Math.floor(Math.random()*$c.length)],t=Math.floor(Math.random()*4294967296),n=tl(t),r=[...Wc].map((e,t)=>t);for(let e=r.length-1;e>0;e--){let t=Math.floor(n()*(e+1));[r[e],r[t]]=[r[t],r[e]]}return{variant:e,seed:t,order:r}}function rl(e,t){if(e.variant===`typing`){let e=t<1080,n=e?0:Math.min(Math.floor((t-1080)/90)+1,11);return{text:Wc.slice(0,n).padEnd(11),cursor:n,dot:e?Math.floor(t/180)%2==0:n<11}}if(e.variant===`shuffle`){let n=tl(e.seed^Math.floor(t/70)),r=[...Wc].map(e=>{let t;do t=Xc[Math.floor(n()*36)];while(t===e);return t}),i=Math.min(Math.floor(t/110),11);for(let t of e.order.slice(0,i))r[t]=Wc[t];return{text:r.join(``),cursor:-1,dot:!1}}return{text:Wc,cursor:-1,dot:!1}}var il=jr(``);function al(e,t){Ue(t,!0);let n=Wi(t,`text`,3,Wc),r=Wi(t,`cursor`,19,()=>-1),i=Wi(t,`dot`,3,!1),a=F(()=>Qc(n(),r(),i()));var o=il(),s=V(o);U(()=>{Q(o,`viewBox`,`0 0 ${Kc} ${qc}`),Q(o,`width`,Kc),Q(o,`height`,qc),Q(s,`d`,K(a))}),Y(e,o),We()}var ol=J(`
        `),sl=J(`
        `);function cl(e,t){Ue(t,!0);let n=L(void 0),r=L(0),i=L(Yt({width:0,height:0,pixelRatio:1})),a=L(Yt({x:0,y:0,width:0})),o=F(()=>K(n)?rl(K(n),K(r)):void 0),s=F(()=>{if(!K(n))return{x:0,y:0,width:0};let e=el[K(n).variant],t=Math.min(Math.max((K(r)-e-180)/800,0),1),o=t*t*(3-2*t),s=K(i).width+(K(a).width-K(i).width)*o,c=Math.max((K(i).height-K(i).width*qc/Kc)/2,0),l=(K(n).variant===`slide`&&K(r)Math.round(e*K(i).pixelRatio)/K(i).pixelRatio;return{x:d(l),y:d(u),width:d(s)}});Gi(()=>{let e=matchMedia(`(prefers-reduced-motion: reduce)`);if(e.matches){t.onfinish();return}R(n,nl(),!0);let o=el[K(n).variant]+180+800,s=0,c=!1,l=performance.now(),u=()=>{let e=t.target?.getBoundingClientRect();R(i,{width:window.innerWidth,height:window.innerHeight,pixelRatio:window.devicePixelRatio||1},!0),e&&R(a,{x:e.x,y:e.y,width:e.width},!0)},d=()=>{c||(c=!0,cancelAnimationFrame(s),t.onfinish())},f=e=>{e instanceof PointerEvent&&e.button!==0||e instanceof KeyboardEvent&&(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey)||e instanceof KeyboardEvent&&[`Shift`,`Control`,`Alt`,`Meta`].includes(e.key)||(e.preventDefault(),e.stopImmediatePropagation(),d())},p=()=>{e.matches&&d()},m=e=>{R(r,Math.max(e-l,0),!0),K(r)>=o?d():s=requestAnimationFrame(m)},h=new ResizeObserver(u);if(t.target){h.observe(t.target),t.target.parentElement&&h.observe(t.target.parentElement);let e=t.target.closest(`header`);e&&h.observe(e)}return u(),window.addEventListener(`resize`,u),document.addEventListener(`keydown`,f,!0),document.addEventListener(`pointerdown`,f,!0),e.addEventListener(`change`,p),s=requestAnimationFrame(m),()=>{c=!0,cancelAnimationFrame(s),h.disconnect(),window.removeEventListener(`resize`,u),document.removeEventListener(`keydown`,f,!0),document.removeEventListener(`pointerdown`,f,!0),e.removeEventListener(`change`,p)}});var c=sl(),l=z(c),u=e=>{var t=ol();let n;al(z(t),{get text(){return K(o).text},get cursor(){return K(o).cursor},get dot(){return K(o).dot}}),P(t),U(()=>{Q(t,`data-text`,K(o).text),Q(t,`data-cursor`,K(o).dot?K(o).cursor:void 0),n=ui(t,``,n,{left:`${K(s).x}px`,top:`${K(s).y}px`,width:`${K(s).width}px`})}),Y(e,t)};Z(l,e=>{K(o)&&e(u)});var d=H(l,2);P(c),U(()=>Q(c,`data-entrance`,K(n)?.variant)),q(`click`,d,function(...e){t.onfinish?.apply(this,e)}),Y(e,c),We()}Sr([`click`]);var ll=J(` `),ul=J(`

        `),dl=J(`

        Connecting to your local Codexometer…

        `),fl=J(``),pl=J(`

        Your quota. Your sessions. Your command centre.

        `);function ml(e,t){Ue(t,!0);let n={"/":eo,"/quota/:view?":eo,"/sessions/:id?":fc,"/usage":Vc,"*":Uc},r={quota:/^(?:\/|\/quota(?:\/[^/]+)?\/?)$/,sessions:/^\/sessions(?:\/[^/]+)?\/?$/,usage:/^\/usage\/?$/},i=L(`hacker`),a=L(!0),o=L(void 0);vn(()=>{sa.requests&&lr().then(()=>{K(o)?.focus(),K(o)?.scrollIntoView({block:`nearest`})})});let s=L(void 0),c=[`hacker`,`rust`,`blue-steel`,`ultraviolet`,`nightshade`];vn(()=>{ca()}),vn(()=>{if($.data)for(let[e,t]of Object.entries(r))t.test(Yi.location)&&(aa.tab=e)}),Gi(()=>{try{let e=localStorage.getItem(`codexometer.web.theme`);e&&c.includes(e)&&R(i,e,!0)}catch{}return ya()});function l(){try{localStorage.setItem(`codexometer.web.theme`,K(i))}catch{}}var u=pl(),d=z(u),f=z(d),p=z(f);al(z(p),{}),P(p),Ii(p,e=>R(s,e),()=>K(s)),xe(2),P(f);var m=H(f,2),h=z(m);let g;var v=H(h,1,!0),y=V(H(v));P(m),P(d);var b=H(d,2);Xr(b,21,()=>Object.entries(r),Kr,(e,t)=>{var n=F(()=>_(K(t),2));let r=()=>K(n)[0],i=()=>K(n)[1],a=F(()=>i().test(Yi.location));var o=ll();let s;var c=V(o,!0);U(e=>{Q(o,`href`,r()===`quota`?`#/quota/`+aa.view:`#/`+r()),Q(o,`aria-current`,K(a)?`page`:void 0),s=ci(o,1,``,null,s,{active:K(a)}),X(c,e)},[()=>r().toUpperCase()]),Y(e,o)}),P(b);var x=H(b,2),S=z(x),C=e=>{var t=ul(),n=V(t,!0);U(()=>X(n,$.error)),Y(e,t)};Z(S,e=>{$.error&&e(C)});var w=H(S,2),T=e=>{$i(e,{get routes(){return n}})},E=e=>{Y(e,dl())};Z(w,e=>{$.data?e(T):$.error||e(E,1)}),P(x);var D=H(x,2),ee=z(D),te=V(ee),O=H(ee,2),k=V(O,!0),ne=H(O,2),re=H(z(ne));Xr(re,21,()=>c,Kr,(e,t)=>{var n=fl(),r=V(n,!0),i={};U(e=>{X(r,e),i!==(i=K(t))&&(n.value=(n.__value=i)??``)},[()=>K(t).replace(`-`,` `).toUpperCase()]),Y(e,n)}),P(re),Ii(re,e=>R(o,e),()=>K(o)),mi(re),P(ne),P(D);var ie=H(D,2),ae=e=>{cl(e,{get target(){return K(s)},onfinish:()=>R(a,!1)})};Z(ie,e=>{K(a)&&e(ae)}),P(u),U(()=>{Q(u,`data-theme`,K(i)),Q(u,`data-starting`,K(a)),d.inert=K(a),g=ci(h,1,`lamp`,null,g,{lit:$.connected}),X(v,$.connected?`CONNECTED`:`OFFLINE`),X(y,`EXPERIMENTAL // ${$.data?.control?`SESSION CONTROL`:`READ ONLY`}`),b.inert=K(a),x.inert=K(a),D.inert=K(a),X(te,`v${($.data?.version||`…`)??``} // LOCAL ONLY`),X(k,$.data?.control?`Session control enabled. Stop the server to revoke access.`:`No actions can be sent from this preview.`)}),q(`change`,re,l),hi(re,()=>K(i),e=>R(i,e)),Y(e,u),We()}Sr([`change`]),zr(ml,{target:document.getElementById(`app`)}); \ No newline at end of file + not provided.

        `,1);function Hc(e,t){Ue(t,!0);let n=L(`daily`),r=L(12),i=L(0),a=F(()=>{let e=$.data?.usage?.dailyUsageBuckets;if(!e)return[];let{start:t,end:n}=kc(new Date,K(r),K(i)),a=new Map;for(let t of e)!Number.isFinite(t.tokens)||t.tokens<0||a.set(t.startDate,(a.get(t.startDate)||0)+t.tokens);let o=[];for(let e=t;e<=n;e=new Date(e.getTime()+864e5)){let t=e.toISOString().slice(0,10);o.push({date:t,tokens:a.get(t)||0})}return o}),o=F(()=>Math.max(1,...K(a).map(e=>e.tokens))),s=F(()=>K(a).length?new Date(K(a)[0].date+`T00:00:00Z`).getUTCDay():0),c=F(()=>{if(K(n)===`monthly`){let e=new Map;for(let t of K(a))e.set(t.date.slice(0,7),(e.get(t.date.slice(0,7))||0)+t.tokens);return[...e].map(([e,t])=>({date:e,tokens:t}))}let e=0;return K(a).map(t=>({date:t.date,tokens:e+=t.tokens}))});var l=Vc(),u=H(B(l),4);Xr(u,20,()=>[[`daily`,`Daily`],[`monthly`,`Monthly`],[`cumulative`,`Cumulative`],[`breakdown`,`Breakdown`],[`periods`,`Windows`]],Kr,(e,t)=>{var r=F(()=>_(t,2));let a=()=>K(r)[0],o=()=>K(r)[1];var s=Ac();let c;var l=V(s,!0);U(()=>{Q(s,`aria-pressed`,K(n)===a()),c=ci(s,1,``,null,c,{active:K(n)===a()}),X(l,o())}),q(`click`,s,()=>{R(n,a(),!0),R(i,0)}),Y(e,s)}),P(u);var d=H(u,2),f=z(d),p=e=>{var t=jc(),n=B(t),a=H(z(n)),o=z(a);o.value=o.__value=6;var s=H(o);s.value=s.__value=12,P(a),mi(a),P(n);var c=H(n),l=H(c);U(()=>l.disabled=K(i)===0),q(`change`,a,()=>R(i,0)),hi(a,()=>K(r),e=>R(r,e)),q(`click`,c,()=>Kt(i)),q(`click`,l,()=>Kt(i,-1)),Y(e,t)};Z(f,e=>{K(n)!==`breakdown`&&K(n)!==`periods`&&e(p)}),P(d);var m=H(d,2),h=e=>{Y(e,Mc())};Z(m,e=>{$.data?.usageError&&e(h)});var g=H(m,2),v=e=>{Y(e,Nc())};Z(g,e=>{$.data?.usage?.tokenStatus===`UNAVAILABLE`&&K(n)!==`breakdown`&&K(n)!==`periods`&&e(v)});var y=H(g,2),b=e=>{var t=Nr();Gr(B(t),()=>K(n),e=>{{let t=F(()=>$.data?.usage?.reports);Ec(e,{get reports(){return K(t)},get mode(){return K(n)}})}}),Y(e,t)},x=e=>{var t=zc(),r=B(t),i=z(r),l=V(H(z(i),2),!0);P(i);var u=H(i,2),d=V(H(z(u),2),!0);P(u);var f=H(u,2),p=H(z(f),2),m=z(p);xe(),P(p),P(f);var h=H(f,2),g=H(z(h),2),_=z(g);xe(),P(g),P(h);var v=H(h,2),y=H(z(v),2),b=z(y);xe(),P(y),P(v),P(r);var x=H(r,4),S=z(x),C=V(S),w=H(S,2),T=e=>{var t=Ic(),n=B(t),r=z(n),i=z(r);Xr(i,17,()=>Array(K(s)),Kr,(e,t)=>{Y(e,Pc())}),Xr(H(i,2),17,()=>K(a),Kr,(e,t)=>{var n=Fc();let r,i;U(e=>{r=ci(n,1,`heat-cell`,null,r,{zero:K(t).tokens===0}),Q(n,`title`,e),i=ui(n,``,i,{opacity:K(t).tokens?.25+.75*K(t).tokens/K(o):1})},[()=>`${K(t).date}: ${pa(K(t).tokens)} tokens`]),Y(e,n)}),P(r),P(n),xe(2),Y(e,t)},E=e=>{var t=Lc(),r=B(t);{let e=F(()=>K(c).map(e=>e.tokens)),t=F(()=>K(n)+` usage`);io(r,{get values(){return K(e)},get label(){return K(t)}})}var i=H(r,2),a=z(i),o=V(a,!0),s=V(H(a),!0);P(i),U(e=>{X(o,K(c)[0]?.date),X(s,e)},[()=>K(c).at(-1)?.date]),Y(e,t)};Z(w,e=>{K(n)===`daily`?e(T):e(E,-1)});var D=H(w,2),ee=H(z(D),2),te=z(ee),O=H(z(te));Xr(O,21,()=>K(n)===`daily`?K(a):K(c),Kr,(e,t)=>{var n=Rc(),r=z(n),i=V(r,!0),a=V(H(r),!0);P(n),U(e=>{X(i,K(t).date),X(a,e)},[()=>pa(K(t).tokens)]),Y(e,n)}),P(O),P(te),P(ee),P(D),P(x);var k=V(H(x,2));U((e,t,n,r,i,o,s)=>{X(l,e),X(d,t),X(m,`${n??``} `),X(_,`${r??``} `),X(b,`${i??``} `),X(C,`${K(a)[0]?.date??``} — ${o??``}`),X(k,`OBSERVED ${s??``} // CUMULATIVE IS FOR THE SELECTED PERIOD`)},[()=>pa($.data.usage.summary.lifetimeTokens),()=>pa($.data.usage.summary.peakDailyTokens),()=>pa($.data.usage.summary.currentStreakDays),()=>pa($.data.usage.summary.longestRunningTurnSec),()=>pa($.data.usage.summary.longestStreakDays),()=>K(a).at(-1)?.date,()=>ma($.data.usageAt)]),Y(e,t)},S=e=>{Y(e,Bc())};Z(y,e=>{K(n)===`breakdown`||K(n)===`periods`?e(b):$.data?.usage&&$.data.usage.dailyUsageBuckets!==null?e(x,1):e(S,-1)}),Y(e,l),We()}Sr([`click`,`change`]);var Uc=J(`

        Page not found

        Return to Quota

        `,1);function Wc(e){var t=Uc();xe(2),Y(e,t)}var Gc=`CODEXOMETER`,Kc=[`█▀▀ █▀█ █▀▄ █▀▀ ▀▄▀ █▀█ █▀▄▀█ █▀▀ ▀█▀ █▀▀ █▀█`,`█▄▄ █▄█ █▄▀ ██▄ █ █ █▄█ █ ▀ █ ██▄ █ ██▄ █▀▄`].flatMap(e=>[[...e].map(e=>e===`█`||e===`▀`),[...e].map(e=>e===`█`||e===`▄`)]),qc=Kc[0].length,Jc=Kc.length,Yc=0,Xc=[...Gc].map(e=>{let t=e===`M`?5:3,n={start:Yc,width:t};return Yc+=t+1,n}),Zc=`ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`,Qc=`010 101 111 101.110 111 101 110.111 100 100 111.110 101 101 110.111 100 110 111.111 100 110 100.111 100 101 111.101 101 111 101.111 010 010 111.001 001 101 111.101 110 110 101.100 100 100 111.101 111 101 101.101 111 111 101.111 101 101 111.111 101 111 100.111 101 111 001.111 101 110 101.111 100 001 111.111 010 010 010.101 101 101 111.101 101 101 010.101 101 111 101.101 010 010 101.101 101 010 010.111 001 100 111.111 101 101 111.110 010 010 111.111 001 110 111.111 011 001 111.101 101 111 001.111 110 001 111.100 111 101 111.111 001 010 010.111 111 101 111.111 101 111 001`.split(`.`).map(e=>e.split(` `));function $c(e=Gc,t=-1,n=!1){let r=``;for(let i=0;i{e|=0,e=e+1831565813|0;let t=Math.imul(e^e>>>15,1|e);return t^=t+Math.imul(t^t>>>7,61|t),((t^t>>>14)>>>0)/4294967296}}function rl(){let e=el[Math.floor(Math.random()*el.length)],t=Math.floor(Math.random()*4294967296),n=nl(t),r=[...Gc].map((e,t)=>t);for(let e=r.length-1;e>0;e--){let t=Math.floor(n()*(e+1));[r[e],r[t]]=[r[t],r[e]]}return{variant:e,seed:t,order:r}}function il(e,t){if(e.variant===`typing`){let e=t<1080,n=e?0:Math.min(Math.floor((t-1080)/90)+1,11);return{text:Gc.slice(0,n).padEnd(11),cursor:n,dot:e?Math.floor(t/180)%2==0:n<11}}if(e.variant===`shuffle`){let n=nl(e.seed^Math.floor(t/70)),r=[...Gc].map(e=>{let t;do t=Zc[Math.floor(n()*36)];while(t===e);return t}),i=Math.min(Math.floor(t/110),11);for(let t of e.order.slice(0,i))r[t]=Gc[t];return{text:r.join(``),cursor:-1,dot:!1}}return{text:Gc,cursor:-1,dot:!1}}var al=jr(``);function ol(e,t){Ue(t,!0);let n=Wi(t,`text`,3,Gc),r=Wi(t,`cursor`,19,()=>-1),i=Wi(t,`dot`,3,!1),a=F(()=>$c(n(),r(),i()));var o=al(),s=V(o);U(()=>{Q(o,`viewBox`,`0 0 ${qc} ${Jc}`),Q(o,`width`,qc),Q(o,`height`,Jc),Q(s,`d`,K(a))}),Y(e,o),We()}var sl=J(`
        `),cl=J(`
        `);function ll(e,t){Ue(t,!0);let n=L(void 0),r=L(0),i=L(Yt({width:0,height:0,pixelRatio:1})),a=L(Yt({x:0,y:0,width:0})),o=F(()=>K(n)?il(K(n),K(r)):void 0),s=F(()=>{if(!K(n))return{x:0,y:0,width:0};let e=tl[K(n).variant],t=Math.min(Math.max((K(r)-e-180)/800,0),1),o=t*t*(3-2*t),s=K(i).width+(K(a).width-K(i).width)*o,c=Math.max((K(i).height-K(i).width*Jc/qc)/2,0),l=(K(n).variant===`slide`&&K(r)Math.round(e*K(i).pixelRatio)/K(i).pixelRatio;return{x:d(l),y:d(u),width:d(s)}});Gi(()=>{let e=matchMedia(`(prefers-reduced-motion: reduce)`);if(e.matches){t.onfinish();return}R(n,rl(),!0);let o=tl[K(n).variant]+180+800,s=0,c=!1,l=performance.now(),u=()=>{let e=t.target?.getBoundingClientRect();R(i,{width:window.innerWidth,height:window.innerHeight,pixelRatio:window.devicePixelRatio||1},!0),e&&R(a,{x:e.x,y:e.y,width:e.width},!0)},d=()=>{c||(c=!0,cancelAnimationFrame(s),t.onfinish())},f=e=>{e instanceof PointerEvent&&e.button!==0||e instanceof KeyboardEvent&&(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey)||e instanceof KeyboardEvent&&[`Shift`,`Control`,`Alt`,`Meta`].includes(e.key)||(e.preventDefault(),e.stopImmediatePropagation(),d())},p=()=>{e.matches&&d()},m=e=>{R(r,Math.max(e-l,0),!0),K(r)>=o?d():s=requestAnimationFrame(m)},h=new ResizeObserver(u);if(t.target){h.observe(t.target),t.target.parentElement&&h.observe(t.target.parentElement);let e=t.target.closest(`header`);e&&h.observe(e)}return u(),window.addEventListener(`resize`,u),document.addEventListener(`keydown`,f,!0),document.addEventListener(`pointerdown`,f,!0),e.addEventListener(`change`,p),s=requestAnimationFrame(m),()=>{c=!0,cancelAnimationFrame(s),h.disconnect(),window.removeEventListener(`resize`,u),document.removeEventListener(`keydown`,f,!0),document.removeEventListener(`pointerdown`,f,!0),e.removeEventListener(`change`,p)}});var c=cl(),l=z(c),u=e=>{var t=sl();let n;ol(z(t),{get text(){return K(o).text},get cursor(){return K(o).cursor},get dot(){return K(o).dot}}),P(t),U(()=>{Q(t,`data-text`,K(o).text),Q(t,`data-cursor`,K(o).dot?K(o).cursor:void 0),n=ui(t,``,n,{left:`${K(s).x}px`,top:`${K(s).y}px`,width:`${K(s).width}px`})}),Y(e,t)};Z(l,e=>{K(o)&&e(u)});var d=H(l,2);P(c),U(()=>Q(c,`data-entrance`,K(n)?.variant)),q(`click`,d,function(...e){t.onfinish?.apply(this,e)}),Y(e,c),We()}Sr([`click`]);var ul=J(` `),dl=J(`

        `),fl=J(`

        Connecting to your local Codexometer…

        `),pl=J(``),ml=J(`

        Your quota. Your sessions. Your command centre.

        `);function hl(e,t){Ue(t,!0);let n={"/":to,"/quota/:view?":to,"/sessions/:id?":pc,"/usage":Hc,"*":Wc},r={quota:/^(?:\/|\/quota(?:\/[^/]+)?\/?)$/,sessions:/^\/sessions(?:\/[^/]+)?\/?$/,usage:/^\/usage\/?$/},i=L(`hacker`),a=L(!0),o=L(void 0);vn(()=>{sa.requests&&lr().then(()=>{K(o)?.focus(),K(o)?.scrollIntoView({block:`nearest`})})});let s=L(void 0),c=[`hacker`,`rust`,`blue-steel`,`ultraviolet`,`nightshade`];vn(()=>{ca()}),vn(()=>{if($.data)for(let[e,t]of Object.entries(r))t.test(Yi.location)&&(aa.tab=e)}),Gi(()=>{try{let e=localStorage.getItem(`codexometer.web.theme`);e&&c.includes(e)&&R(i,e,!0)}catch{}return ya()});function l(){try{localStorage.setItem(`codexometer.web.theme`,K(i))}catch{}}var u=ml(),d=z(u),f=z(d),p=z(f);ol(z(p),{}),P(p),Ii(p,e=>R(s,e),()=>K(s)),xe(2),P(f);var m=H(f,2),h=z(m);let g;var v=H(h,1,!0),y=V(H(v));P(m),P(d);var b=H(d,2);Xr(b,21,()=>Object.entries(r),Kr,(e,t)=>{var n=F(()=>_(K(t),2));let r=()=>K(n)[0],i=()=>K(n)[1],a=F(()=>i().test(Yi.location));var o=ul();let s;var c=V(o,!0);U(e=>{Q(o,`href`,r()===`quota`?`#/quota/`+aa.view:`#/`+r()),Q(o,`aria-current`,K(a)?`page`:void 0),s=ci(o,1,``,null,s,{active:K(a)}),X(c,e)},[()=>r().toUpperCase()]),Y(e,o)}),P(b);var x=H(b,2),S=z(x),C=e=>{var t=dl(),n=V(t,!0);U(()=>X(n,$.error)),Y(e,t)};Z(S,e=>{$.error&&e(C)});var w=H(S,2),T=e=>{$i(e,{get routes(){return n}})},E=e=>{Y(e,fl())};Z(w,e=>{$.data?e(T):$.error||e(E,1)}),P(x);var D=H(x,2),ee=z(D),te=V(ee),O=H(ee,2),k=V(O,!0),ne=H(O,2),re=H(z(ne));Xr(re,21,()=>c,Kr,(e,t)=>{var n=pl(),r=V(n,!0),i={};U(e=>{X(r,e),i!==(i=K(t))&&(n.value=(n.__value=i)??``)},[()=>K(t).replace(`-`,` `).toUpperCase()]),Y(e,n)}),P(re),Ii(re,e=>R(o,e),()=>K(o)),mi(re),P(ne),P(D);var ie=H(D,2),ae=e=>{ll(e,{get target(){return K(s)},onfinish:()=>R(a,!1)})};Z(ie,e=>{K(a)&&e(ae)}),P(u),U(()=>{Q(u,`data-theme`,K(i)),Q(u,`data-starting`,K(a)),d.inert=K(a),g=ci(h,1,`lamp`,null,g,{lit:$.connected}),X(v,$.connected?`CONNECTED`:`OFFLINE`),X(y,`EXPERIMENTAL // ${$.data?.control?`SESSION CONTROL`:`READ ONLY`}`),b.inert=K(a),x.inert=K(a),D.inert=K(a),X(te,`v${($.data?.version||`…`)??``} // LOCAL ONLY`),X(k,$.data?.control?`Session control enabled. Stop the server to revoke access.`:`No actions can be sent from this preview.`)}),q(`change`,re,l),hi(re,()=>K(i),e=>R(i,e)),Y(e,u),We()}Sr([`change`]),zr(hl,{target:document.getElementById(`app`)}); \ No newline at end of file diff --git a/internal/web/dist/assets/index-Bjr_1drg.css b/internal/web/dist/assets/index-Bjr_1drg.css new file mode 100644 index 0000000..85fdd1b --- /dev/null +++ b/internal/web/dist/assets/index-Bjr_1drg.css @@ -0,0 +1 @@ +.observation-details.svelte-1vgdi83{font-size:12px}summary.svelte-1vgdi83{cursor:pointer;color:var(--accent)}.observation-table.svelte-1vgdi83{max-height:240px;overflow:auto}.zone-canvas.svelte-1vgdi83{flex:1;min-height:170px;margin-top:6px;position:relative}svg.svelte-1vgdi83{width:100%;height:100%;display:block;position:absolute;inset:0}text.svelte-1vgdi83{fill:var(--ink);font:14px Cascadia Code,Consolas,monospace}.axis-title.svelte-1vgdi83{letter-spacing:.04em;font-size:12px}.grid.svelte-1vgdi83{stroke:#fff;stroke-opacity:.14;stroke-width:1px}.axes.svelte-1vgdi83{stroke:var(--ink);stroke-width:1.5px;fill:none}.pace-line.svelte-1vgdi83{stroke:#fff;stroke-width:2px;stroke-dasharray:6 4}.position-halo.svelte-1vgdi83{fill:#101820;stroke:#fff;stroke-width:1.5px}.position-dot.svelte-1vgdi83{fill:#fff}.observation-trail.svelte-1vgdi83{fill:none;stroke:#101820;stroke-width:2.5px;stroke-linejoin:round}.observation-trail-casing.svelte-1vgdi83{fill:none;stroke:#ffffff73;stroke-width:4.5px;stroke-linejoin:round}.trail-start.svelte-1vgdi83{fill:#101820;stroke:#ffffffb3;stroke-width:2px}.trend-line.svelte-1vgdi83{fill:none;stroke:var(--trend-color);stroke-width:2px;stroke-dasharray:3 6}.trend-arrow.svelte-1vgdi83{fill:var(--trend-color);stroke:#ffffff73;stroke-width:.5px}.trend-casing.svelte-1vgdi83{fill:none;stroke:#ffffff73;stroke-width:4px;stroke-dasharray:3 6}.zone-caption.svelte-1vgdi83{min-width:0;color:var(--accent);flex:auto;margin:0}.trend-summary.svelte-1vgdi83{color:var(--ink)}.zone-footer.svelte-1vgdi83{justify-content:space-between;align-items:flex-start;gap:12px;margin-top:4px;display:flex}.zone-controls.svelte-1vgdi83{color:var(--muted);text-align:right;flex-direction:column;align-items:flex-end;gap:5px;font-size:11px;display:flex}.trace-control.svelte-1vgdi83,.trend-control.svelte-1vgdi83{cursor:pointer;white-space:nowrap}.trace-control.svelte-1vgdi83 input:where(.svelte-1vgdi83){accent-color:var(--accent)}.trend-control.svelte-1vgdi83 select:where(.svelte-1vgdi83){border:1px solid var(--edge);background:var(--panel);max-width:min(230px,45vw);color:var(--ink);font:inherit}.trend-control.svelte-1vgdi83 option:where(.svelte-1vgdi83):disabled{color:var(--muted)}.zone-controls.svelte-1vgdi83 small:where(.svelte-1vgdi83){font-size:10px}@container (width<=560px){.zone-footer.svelte-1vgdi83{flex-direction:column}.zone-controls.svelte-1vgdi83{align-self:stretch;align-items:flex-end}}.usage-diagnostic.svelte-16u6dmb{white-space:pre-wrap;overflow-wrap:anywhere}.slash-commands.svelte-7bfwr9{margin:.4rem 0;position:relative}.command-popup.svelte-7bfwr9{z-index:5;box-sizing:border-box;border:1px solid var(--accent);background:var(--panel);width:min(40rem,100%);padding:.35rem;position:absolute;bottom:100%;left:0;box-shadow:0 .3rem 1rem #0006}.command-popup.svelte-7bfwr9 p:where(.svelte-7bfwr9){margin:.3rem 0;font-size:.8em}.command-options.vertical.svelte-7bfwr9{flex-flow:column;gap:.15rem;display:flex}.vertical.svelte-7bfwr9 button:where(.svelte-7bfwr9){text-align:left;white-space:nowrap;width:100%;min-width:0;color:var(--muted);background:var(--panel);border-color:#0000;flex:none;align-items:baseline;gap:.4rem;display:flex}.vertical.svelte-7bfwr9 .command-name:where(.svelte-7bfwr9),.vertical.svelte-7bfwr9 .command-tail:where(.svelte-7bfwr9){flex:none}.vertical.svelte-7bfwr9 .command-name:where(.svelte-7bfwr9){text-overflow:ellipsis;max-width:100%;overflow:hidden}.vertical.svelte-7bfwr9 button.suggested:where(.svelte-7bfwr9){outline:none}.command-options.svelte-7bfwr9 button.suggested:where(.svelte-7bfwr9) .command-name:where(.svelte-7bfwr9){color:var(--ink);font-weight:700}.command-options.svelte-7bfwr9 button:where(.svelte-7bfwr9):not(.suggested):hover .command-name:where(.svelte-7bfwr9){text-decoration:underline}.command-options.svelte-7bfwr9 button:where(.svelte-7bfwr9){color:var(--muted)}.vertical.svelte-7bfwr9 .command-help:where(.svelte-7bfwr9){min-width:0;max-width:none;color:var(--muted);flex:1}.command-options.svelte-7bfwr9{flex-wrap:wrap;gap:.35rem;max-height:35vh;display:flex;overflow:auto}.command-options.svelte-7bfwr9 .suggested:where(.svelte-7bfwr9){outline:none}.command-help.svelte-7bfwr9{text-overflow:ellipsis;white-space:nowrap;opacity:.75;max-width:32ch;font-size:.8em;display:block;overflow:hidden}.command-actions.svelte-7bfwr9{flex-wrap:wrap;gap:.35rem;margin-top:.4rem;display:flex}.availability.svelte-7bfwr9{font-weight:600}.navigation.svelte-7bfwr9{font-size:.8em}pre.svelte-7bfwr9{white-space:pre-wrap;overflow-wrap:anywhere;max-height:35vh;overflow:auto}.file-diff.svelte-x4gtb6{border:1px solid var(--muted);max-height:60vh;padding:.5rem;font-family:monospace;overflow:auto}.diff-line.svelte-x4gtb6{white-space:pre;min-height:1.3em;display:flex}.line-number.svelte-x4gtb6{text-align:right;opacity:.75;-webkit-user-select:none;user-select:none;flex:0 0 5ch;padding-right:1ch;display:inline-block}.added.svelte-x4gtb6{color:#67d391;background:#67d39112}.removed.svelte-x4gtb6{color:#ff6b83;background:#ff6b8312}.heading.svelte-x4gtb6{padding:.5rem 0;font-weight:700}.saved-prompt.svelte-1oupzfc{white-space:pre-wrap;overflow-wrap:anywhere}fieldset.svelte-1oupzfc{border:1px solid;margin:.5rem 0;padding:.35rem .6rem}.decision.svelte-1oupzfc,.answer.svelte-1oupzfc{margin:.3rem 0;display:block}.decision.svelte-1oupzfc code:where(.svelte-1oupzfc),.decision.svelte-1oupzfc span:where(.svelte-1oupzfc){overflow-wrap:anywhere;margin:.3rem 0 .3rem 1.5rem;display:block}textarea.svelte-1oupzfc,.answer.svelte-1oupzfc input:where(.svelte-1oupzfc),.answer.svelte-1oupzfc select:where(.svelte-1oupzfc){box-sizing:border-box;background:var(--bg);width:100%;color:inherit;font:inherit;border:1px solid;margin-top:.4rem;padding:.5rem;display:block}textarea.svelte-1oupzfc{resize:vertical;background:color-mix(in srgb, currentColor 8%, var(--bg))}button.svelte-1oupzfc{margin:.3rem .5rem .3rem 0}h3.svelte-1oupzfc,p.svelte-1oupzfc{margin-block:.4rem}.sent.svelte-1oupzfc{color:var(--accent)}.status-line.svelte-gprptn{align-items:center;gap:.5rem;min-width:0;margin-top:.5rem;display:flex}.status-line.svelte-gprptn p:where(.svelte-gprptn){white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;margin:0;font-size:.8rem;overflow:hidden}.configure.svelte-gprptn{padding:.15rem .35rem;font-size:.75rem}.status-picker.svelte-gprptn{border:1px solid var(--edge);margin:.5rem 0;padding:.6rem}.fields.svelte-gprptn{max-height:35vh;overflow:auto}.field.svelte-gprptn{align-items:center;gap:.35rem;display:flex}.field.svelte-gprptn label:where(.svelte-gprptn){flex:1;align-items:center;gap:.4rem;display:flex}.field.svelte-gprptn label:where(.svelte-gprptn) span:where(.svelte-gprptn){font-size:.75rem}.field.svelte-gprptn button:where(.svelte-gprptn){padding:.1rem .35rem}.session-copy.svelte-543j00{justify-content:flex-end;align-items:center;gap:8px;margin-top:auto;padding-top:6px;display:flex}span.svelte-543j00{color:var(--muted);overflow-wrap:anywhere;font-size:12px}button.svelte-543j00{color:var(--accent);flex-shrink:0;padding:3px 7px}button.svelte-543j00:hover,button.flashed.svelte-543j00{color:var(--bg);background:var(--accent)}h3.svelte-1fbui7h,.window-dates.svelte-1fbui7h,.report-value.svelte-1fbui7h{color:var(--accent);font-weight:700}.quality-warning.svelte-1fbui7h,.quota-near.svelte-1fbui7h{color:var(--approval)}.quota-full.svelte-1fbui7h{color:#ff6680}.alternate.svelte-1fbui7h .report-fill:where(.svelte-1fbui7h){background:radial-gradient(circle, var(--panel) .7px, transparent .9px) 0 0 / 3px 3px, var(--accent)}.unknown.svelte-1fbui7h,.unknown.svelte-1fbui7h .report-value:where(.svelte-1fbui7h){color:var(--muted)}.unknown.svelte-1fbui7h .report-fill:where(.svelte-1fbui7h){background:var(--muted);opacity:1}.report-bars.svelte-1fbui7h{grid-template-columns:minmax(5rem,1fr) minmax(2rem,3fr) auto;gap:.6rem;display:grid}.report-row.svelte-1fbui7h,.report-head.svelte-1fbui7h{grid-column:1/-1;grid-template-columns:subgrid;align-items:center;gap:.6rem;display:grid}.report-head.svelte-1fbui7h{color:var(--muted);font-size:.85rem}.report-head.svelte-1fbui7h>span:where(.svelte-1fbui7h):last-child,.report-value.svelte-1fbui7h{text-align:right}.report-row.svelte-1fbui7h>span:where(.svelte-1fbui7h):first-child{overflow-wrap:anywhere}.report-track.svelte-1fbui7h{background:var(--panel);height:1rem}.report-fill.svelte-1fbui7h{background:var(--accent);height:100%}svg.svelte-1jpy949{fill:currentColor;width:100%;height:auto;display:block}.startup.svelte-19xbbtg{z-index:100;background:var(--bg);color:var(--accent);position:fixed;inset:0;overflow:hidden}.wordmark.svelte-19xbbtg{position:absolute}button.svelte-19xbbtg{color:var(--muted);font:inherit;white-space:nowrap;background:0 0;border:0;font-size:12px;position:absolute;bottom:24px;left:50%;transform:translate(-50%)}:root{font-synthesis:none;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;background:#080e0c;font-family:Cascadia Code,SFMono-Regular,Consolas,monospace}*{box-sizing:border-box}body{margin:0}.shell{--accent:#80edac;--approval:#ffca58;--muted:#98aaa0;--edge:#31473a;--panel:#101c16;--bg:#080e0c;--ink:#e2eee5;background:var(--bg);height:100dvh;color:var(--ink);grid-template-rows:auto auto minmax(0,1fr) auto;padding:clamp(10px,1.2vw,20px);display:grid}.shell[data-theme=rust]{--approval:#ff8a3d;--accent:#ffbc75;--muted:#bfac95;--edge:#59412c;--panel:#261b14;--bg:#140e0a}.shell[data-theme=blue-steel]{--approval:#e8c46a;--accent:#85c8ff;--muted:#9cacc4;--edge:#334d69;--panel:#142235;--bg:#0b1421}.shell[data-theme=ultraviolet]{--approval:#f9a8d4;--accent:#c5adff;--muted:#b3a6c9;--edge:#4b3c68;--panel:#241a35;--bg:#140d22}.shell[data-theme=nightshade]{--approval:#8f7cff;--accent:#e59bff;--muted:#c6a7cf;--edge:#673976;--panel:#301739;--bg:#1c0b24}header,.spread,footer,.controls{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;display:flex}header{margin-bottom:10px}.shell[data-starting=true]>header,.shell[data-starting=true]>nav,.shell[data-starting=true]>main,.shell[data-starting=true]>footer{visibility:hidden}.brand{width:clamp(240px,32vw,405px);max-width:calc(100vw - 40px);color:var(--accent);text-decoration:none;display:block}header p{color:var(--muted);margin:3px 0 0;font-size:13px}.connection{color:var(--accent);text-align:right}small,.eyebrow{letter-spacing:.04em;font-size:12px}.connection small{color:var(--muted);margin-top:4px;display:block}.lamp{background:var(--muted);border-radius:50%;width:9px;height:9px;margin-right:9px;display:inline-block}.lamp.lit{background:var(--accent);box-shadow:0 0 8px color-mix(in srgb, var(--accent) 40%, transparent)}.working{animation:1.5s ease-in-out infinite pulse}@keyframes pulse{50%{opacity:.3}}nav{flex-wrap:wrap;gap:6px;margin-bottom:10px;display:flex}nav a,button,.button,select{font:inherit;color:var(--accent);border:1px solid var(--edge);background:var(--panel);cursor:pointer;border-radius:3px;padding:7px 11px;font-size:13px;text-decoration:none}button:hover,.button:hover,nav a:hover{border-color:var(--accent)}nav a.active,nav button.active{background:var(--accent);color:var(--bg);border-color:var(--accent)}:focus-visible{outline:2px solid var(--accent);outline-offset:4px}.secondary{margin-bottom:8px}.secondary a,.secondary button{padding:6px 10px;font-size:12px}main{scrollbar-gutter:stable;flex-direction:column;min-width:0;min-height:0;display:flex;overflow:auto}main>*{flex-shrink:0}.panel{border:1px solid var(--edge);border-top:2px solid var(--accent);background:var(--panel);border-radius:4px;min-width:0;padding:clamp(10px,1vw,16px)}h1{color:var(--accent);font-size:20px}h2{letter-spacing:.04em;color:var(--accent);overflow-wrap:anywhere;margin:0 0 10px;font-size:13px}h3{overflow-wrap:anywhere;font-size:13px}p{margin:6px 0;font-size:13px;line-height:1.45}a{color:var(--accent)}.muted,.eyebrow{color:var(--muted)}.notice{color:#ffe0aa;background:#332611;border-left:3px solid #ffc26e;padding:12px 16px}.empty{color:var(--muted);padding:35px 0}.quota-grid{flex:1 0 auto;grid-auto-rows:minmax(220px,1fr);gap:10px;display:grid}.quota-card{flex-direction:column;min-height:0;display:flex;container-type:inline-size}.quota-card>:not(.meter-graphic){flex-shrink:0}.meter-graphic{flex-direction:column;flex:1;min-height:100px;display:flex}.bar-graphic{min-height:65px}.quota-card .gauge{flex:2;height:auto;min-height:16px;margin:7px 0}.quota-card .timeline{flex:1;min-height:8px}.quota-grid.zone{grid-template-columns:repeat(auto-fit,minmax(min(100%,420px),1fr));grid-auto-rows:minmax(330px,1fr)}.quota-grid.radial{grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));grid-auto-rows:minmax(260px,1fr)}.gauge{background:var(--edge);height:35px;margin:15px 0;overflow:hidden}.gauge>div{background:repeating-linear-gradient(90deg, var(--accent) 0, var(--accent) 9px, transparent 9px, transparent 12px);height:100%;transition:width .5s}.gauge.timeline{height:14px}.pie-wrap{flex:1;min-height:100px;margin:6px 0;position:relative}.pie-wrap svg{width:100%;height:100%;position:absolute;inset:0}.pie-base{fill:var(--edge);stroke:var(--accent);stroke-width:1px}.pie-fill{fill:var(--accent)}.readout{overflow-wrap:anywhere;color:var(--accent);margin:18px 0;font-size:clamp(22px,3vw,34px)}.credit+.credit{border-top:1px solid var(--edge);padding-top:20px}.credit{margin-top:24px}.session-row{grid-template-columns:minmax(210px,1.1fr) minmax(0,1.2fr) minmax(0,1.5fr);align-items:stretch;gap:14px;margin:18px 0;display:grid}.session-totals{grid-template-columns:repeat(auto-fit,minmax(min(145px,100%),1fr));gap:8px;margin:8px 0;display:grid}.session-totals>div{border:1px solid var(--edge);min-width:0;padding:10px}.session-totals dt{color:var(--muted);font-size:11px}.session-totals dd{color:var(--accent);overflow-wrap:anywhere;margin:6px 0 0;font-size:24px}.session-totals.stale dd{color:var(--muted)}.session-row.selected{outline:1px solid var(--accent);outline-offset:4px}.session-row.wide .context{grid-column:2/-1}.detail-controls{flex-wrap:wrap;gap:6px;display:flex}.attention-summary{flex-wrap:wrap;gap:8px;margin-block:8px;display:flex}.attention-summary .approval{color:var(--approval);border-color:var(--approval)}.attention-summary .approval:hover{background:color-mix(in srgb, var(--approval) 12%, var(--panel))}.attention-summary .approval:focus-visible{outline-color:var(--approval)}.attention-note,.attention-badge{color:var(--accent);border-left:3px solid;padding-left:8px}.attention-note.inferred{color:var(--muted)}.attention-badge{font-size:12px}.session-select{text-align:left;overflow-wrap:anywhere;max-width:100%}.status-detail{color:inherit;text-decoration:none}.status-detail:hover{text-decoration:underline}button:disabled{opacity:.4;cursor:default}.session-row .graph-panel{flex-direction:column;grid-column:2/-1;display:flex}.session-row.split .graph-panel{grid-column:auto}.session-row .button,.session-row button{margin-top:8px;display:inline-block}.context pre{max-height:230px;overflow:auto}.session-row .context{flex-direction:column;display:flex}pre{font:inherit;white-space:pre-wrap;overflow-wrap:anywhere;font-size:13px;line-height:1.7}.full-detail{margin-top:6px}.detail-heading{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px 12px;display:flex}.detail-heading h2{flex:250px;min-width:0;margin:0}.detail-metadata{overflow-wrap:anywhere}.detail-workspace{border-top:1px solid var(--edge);flex-direction:column;gap:10px;margin-top:8px;padding-top:4px;display:flex}.detail-context,.detail-workspace .session-actions{min-width:0}.detail-workspace .session-actions{border-top:1px solid var(--edge);padding-top:6px}.full-detail h3{margin-block:8px}.full-detail pre{margin-block:8px;line-height:1.5}.full-detail hr{margin-block:12px}.full-detail .command,.full-detail .notice{padding:8px 10px}.command{background:var(--bg);border-left:3px solid var(--accent);padding:16px}hr{border:0;border-top:1px solid var(--edge);margin:24px 0}.chart{border-bottom:1px solid var(--muted);align-items:flex-end;gap:2px;height:clamp(120px,22vh,320px);margin-top:18px;display:flex}.chart-bar{background:var(--accent);flex:1;min-width:0;max-height:100%}.controls{justify-content:flex-start;margin:20px 0}.summary-grid{grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));gap:16px;margin:20px 0;display:grid}.thresholds-panel{padding:clamp(14px,2vw,22px)}.thresholds-panel h1{margin-top:0}.threshold-list{gap:8px;margin-top:16px;display:grid}.threshold-list article{border:1px solid var(--edge);grid-template-columns:minmax(64px,.5fr) minmax(220px,3fr) minmax(64px,.6fr) minmax(120px,1.2fr);align-items:center;gap:12px;padding:10px 12px;display:grid}.threshold-list article.active{border-color:var(--accent);box-shadow:inset 3px 0 0 var(--accent)}.threshold-list article.next{border-color:var(--approval);box-shadow:inset 3px 0 0 var(--approval)}.threshold-list p{color:var(--muted);margin:3px 0 0;font-size:12px}.threshold-trigger{color:var(--accent);font-size:22px;font-weight:800}.threshold-mode,.threshold-state{color:var(--muted);font-size:12px;font-weight:700}.threshold-list article.active .threshold-state{color:var(--accent)}.threshold-list article.next .threshold-state{color:var(--approval)}.heat-scroll{overflow-x:auto}.heatmap{grid-template-rows:repeat(7,13px);grid-auto-columns:minmax(9px,1fr);grid-auto-flow:column;gap:4px;min-width:620px;margin:25px 0;display:grid}.heat-cell{background:var(--accent);border-radius:2px}.heat-cell.zero{background:var(--edge)}.table-scroll{max-height:280px;overflow:auto}table{border-collapse:collapse;width:100%;margin-top:15px}th,td{text-align:left;border-bottom:1px solid var(--edge);padding:8px}summary{cursor:pointer;color:var(--accent);padding-top:14px}footer{border-top:1px solid var(--edge);color:var(--muted);margin-top:8px;padding-top:8px;font-size:11px}footer select{padding:6px}@media (width<=850px){.session-row{grid-template-columns:minmax(0,1fr)}.session-row.wide .context,.session-row .graph-panel{grid-column:auto}.connection{text-align:left}.threshold-list article{grid-template-columns:64px minmax(0,1fr)}.threshold-mode,.threshold-state{grid-column:2}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none!important;animation:none!important}} diff --git a/internal/web/dist/assets/index-GcuOkuuL.css b/internal/web/dist/assets/index-GcuOkuuL.css deleted file mode 100644 index 56ca040..0000000 --- a/internal/web/dist/assets/index-GcuOkuuL.css +++ /dev/null @@ -1 +0,0 @@ -.observation-details.svelte-1vgdi83{font-size:12px}summary.svelte-1vgdi83{cursor:pointer;color:var(--accent)}.observation-table.svelte-1vgdi83{max-height:240px;overflow:auto}.zone-canvas.svelte-1vgdi83{flex:1;min-height:170px;margin-top:6px;position:relative}svg.svelte-1vgdi83{width:100%;height:100%;display:block;position:absolute;inset:0}text.svelte-1vgdi83{fill:var(--ink);font:14px Cascadia Code,Consolas,monospace}.axis-title.svelte-1vgdi83{letter-spacing:.04em;font-size:12px}.grid.svelte-1vgdi83{stroke:#fff;stroke-opacity:.14;stroke-width:1px}.axes.svelte-1vgdi83{stroke:var(--ink);stroke-width:1.5px;fill:none}.pace-line.svelte-1vgdi83{stroke:#fff;stroke-width:2px;stroke-dasharray:6 4}.position-halo.svelte-1vgdi83{fill:#101820;stroke:#fff;stroke-width:1.5px}.position-dot.svelte-1vgdi83{fill:#fff}.observation-trail.svelte-1vgdi83{fill:none;stroke:#101820;stroke-width:2.5px;stroke-linejoin:round}.observation-trail-casing.svelte-1vgdi83{fill:none;stroke:#ffffff73;stroke-width:4.5px;stroke-linejoin:round}.trail-start.svelte-1vgdi83{fill:#101820;stroke:#ffffffb3;stroke-width:2px}.trend-line.svelte-1vgdi83{fill:none;stroke:var(--trend-color);stroke-width:2px;stroke-dasharray:3 6}.trend-arrow.svelte-1vgdi83{fill:var(--trend-color);stroke:#ffffff73;stroke-width:.5px}.trend-casing.svelte-1vgdi83{fill:none;stroke:#ffffff73;stroke-width:4px;stroke-dasharray:3 6}.zone-caption.svelte-1vgdi83{min-width:0;color:var(--accent);flex:auto;margin:0}.trend-summary.svelte-1vgdi83{color:var(--ink)}.zone-footer.svelte-1vgdi83{justify-content:space-between;align-items:flex-start;gap:12px;margin-top:4px;display:flex}.zone-controls.svelte-1vgdi83{color:var(--muted);text-align:right;flex-direction:column;align-items:flex-end;gap:5px;font-size:11px;display:flex}.trace-control.svelte-1vgdi83,.trend-control.svelte-1vgdi83{cursor:pointer;white-space:nowrap}.trace-control.svelte-1vgdi83 input:where(.svelte-1vgdi83){accent-color:var(--accent)}.trend-control.svelte-1vgdi83 select:where(.svelte-1vgdi83){border:1px solid var(--edge);background:var(--panel);max-width:min(230px,45vw);color:var(--ink);font:inherit}.trend-control.svelte-1vgdi83 option:where(.svelte-1vgdi83):disabled{color:var(--muted)}.zone-controls.svelte-1vgdi83 small:where(.svelte-1vgdi83){font-size:10px}@container (width<=560px){.zone-footer.svelte-1vgdi83{flex-direction:column}.zone-controls.svelte-1vgdi83{align-self:stretch;align-items:flex-end}}.slash-commands.svelte-7bfwr9{margin:.4rem 0;position:relative}.command-popup.svelte-7bfwr9{z-index:5;box-sizing:border-box;border:1px solid var(--accent);background:var(--panel);width:min(40rem,100%);padding:.35rem;position:absolute;bottom:100%;left:0;box-shadow:0 .3rem 1rem #0006}.command-popup.svelte-7bfwr9 p:where(.svelte-7bfwr9){margin:.3rem 0;font-size:.8em}.command-options.vertical.svelte-7bfwr9{flex-flow:column;gap:.15rem;display:flex}.vertical.svelte-7bfwr9 button:where(.svelte-7bfwr9){text-align:left;white-space:nowrap;width:100%;min-width:0;color:var(--muted);background:var(--panel);border-color:#0000;flex:none;align-items:baseline;gap:.4rem;display:flex}.vertical.svelte-7bfwr9 .command-name:where(.svelte-7bfwr9),.vertical.svelte-7bfwr9 .command-tail:where(.svelte-7bfwr9){flex:none}.vertical.svelte-7bfwr9 .command-name:where(.svelte-7bfwr9){text-overflow:ellipsis;max-width:100%;overflow:hidden}.vertical.svelte-7bfwr9 button.suggested:where(.svelte-7bfwr9){outline:none}.command-options.svelte-7bfwr9 button.suggested:where(.svelte-7bfwr9) .command-name:where(.svelte-7bfwr9){color:var(--ink);font-weight:700}.command-options.svelte-7bfwr9 button:where(.svelte-7bfwr9):not(.suggested):hover .command-name:where(.svelte-7bfwr9){text-decoration:underline}.command-options.svelte-7bfwr9 button:where(.svelte-7bfwr9){color:var(--muted)}.vertical.svelte-7bfwr9 .command-help:where(.svelte-7bfwr9){min-width:0;max-width:none;color:var(--muted);flex:1}.command-options.svelte-7bfwr9{flex-wrap:wrap;gap:.35rem;max-height:35vh;display:flex;overflow:auto}.command-options.svelte-7bfwr9 .suggested:where(.svelte-7bfwr9){outline:none}.command-help.svelte-7bfwr9{text-overflow:ellipsis;white-space:nowrap;opacity:.75;max-width:32ch;font-size:.8em;display:block;overflow:hidden}.command-actions.svelte-7bfwr9{flex-wrap:wrap;gap:.35rem;margin-top:.4rem;display:flex}.availability.svelte-7bfwr9{font-weight:600}.navigation.svelte-7bfwr9{font-size:.8em}pre.svelte-7bfwr9{white-space:pre-wrap;overflow-wrap:anywhere;max-height:35vh;overflow:auto}.file-diff.svelte-x4gtb6{border:1px solid var(--muted);max-height:60vh;padding:.5rem;font-family:monospace;overflow:auto}.diff-line.svelte-x4gtb6{white-space:pre;min-height:1.3em;display:flex}.line-number.svelte-x4gtb6{text-align:right;opacity:.75;-webkit-user-select:none;user-select:none;flex:0 0 5ch;padding-right:1ch;display:inline-block}.added.svelte-x4gtb6{color:#67d391;background:#67d39112}.removed.svelte-x4gtb6{color:#ff6b83;background:#ff6b8312}.heading.svelte-x4gtb6{padding:.5rem 0;font-weight:700}.saved-prompt.svelte-1oupzfc{white-space:pre-wrap;overflow-wrap:anywhere}fieldset.svelte-1oupzfc{border:1px solid;margin:.5rem 0;padding:.35rem .6rem}.decision.svelte-1oupzfc,.answer.svelte-1oupzfc{margin:.3rem 0;display:block}.decision.svelte-1oupzfc code:where(.svelte-1oupzfc),.decision.svelte-1oupzfc span:where(.svelte-1oupzfc){overflow-wrap:anywhere;margin:.3rem 0 .3rem 1.5rem;display:block}textarea.svelte-1oupzfc,.answer.svelte-1oupzfc input:where(.svelte-1oupzfc),.answer.svelte-1oupzfc select:where(.svelte-1oupzfc){box-sizing:border-box;background:var(--bg);width:100%;color:inherit;font:inherit;border:1px solid;margin-top:.4rem;padding:.5rem;display:block}textarea.svelte-1oupzfc{resize:vertical;background:color-mix(in srgb, currentColor 8%, var(--bg))}button.svelte-1oupzfc{margin:.3rem .5rem .3rem 0}h3.svelte-1oupzfc,p.svelte-1oupzfc{margin-block:.4rem}.sent.svelte-1oupzfc{color:var(--accent)}.status-line.svelte-gprptn{align-items:center;gap:.5rem;min-width:0;margin-top:.5rem;display:flex}.status-line.svelte-gprptn p:where(.svelte-gprptn){white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;margin:0;font-size:.8rem;overflow:hidden}.configure.svelte-gprptn{padding:.15rem .35rem;font-size:.75rem}.status-picker.svelte-gprptn{border:1px solid var(--edge);margin:.5rem 0;padding:.6rem}.fields.svelte-gprptn{max-height:35vh;overflow:auto}.field.svelte-gprptn{align-items:center;gap:.35rem;display:flex}.field.svelte-gprptn label:where(.svelte-gprptn){flex:1;align-items:center;gap:.4rem;display:flex}.field.svelte-gprptn label:where(.svelte-gprptn) span:where(.svelte-gprptn){font-size:.75rem}.field.svelte-gprptn button:where(.svelte-gprptn){padding:.1rem .35rem}.session-copy.svelte-543j00{justify-content:flex-end;align-items:center;gap:8px;margin-top:auto;padding-top:6px;display:flex}span.svelte-543j00{color:var(--muted);overflow-wrap:anywhere;font-size:12px}button.svelte-543j00{color:var(--accent);flex-shrink:0;padding:3px 7px}button.svelte-543j00:hover,button.flashed.svelte-543j00{color:var(--bg);background:var(--accent)}h3.svelte-1fbui7h,.window-dates.svelte-1fbui7h,.report-value.svelte-1fbui7h{color:var(--accent);font-weight:700}.quality-warning.svelte-1fbui7h,.quota-near.svelte-1fbui7h{color:var(--approval)}.quota-full.svelte-1fbui7h{color:#ff6680}.alternate.svelte-1fbui7h .report-fill:where(.svelte-1fbui7h){background:radial-gradient(circle, var(--panel) .7px, transparent .9px) 0 0 / 3px 3px, var(--accent)}.unknown.svelte-1fbui7h,.unknown.svelte-1fbui7h .report-value:where(.svelte-1fbui7h){color:var(--muted)}.unknown.svelte-1fbui7h .report-fill:where(.svelte-1fbui7h){background:var(--muted);opacity:1}.report-bars.svelte-1fbui7h{grid-template-columns:minmax(5rem,1fr) minmax(2rem,3fr) auto;gap:.6rem;display:grid}.report-row.svelte-1fbui7h,.report-head.svelte-1fbui7h{grid-column:1/-1;grid-template-columns:subgrid;align-items:center;gap:.6rem;display:grid}.report-head.svelte-1fbui7h{color:var(--muted);font-size:.85rem}.report-head.svelte-1fbui7h>span:where(.svelte-1fbui7h):last-child,.report-value.svelte-1fbui7h{text-align:right}.report-row.svelte-1fbui7h>span:where(.svelte-1fbui7h):first-child{overflow-wrap:anywhere}.report-track.svelte-1fbui7h{background:var(--panel);height:1rem}.report-fill.svelte-1fbui7h{background:var(--accent);height:100%}svg.svelte-1jpy949{fill:currentColor;width:100%;height:auto;display:block}.startup.svelte-19xbbtg{z-index:100;background:var(--bg);color:var(--accent);position:fixed;inset:0;overflow:hidden}.wordmark.svelte-19xbbtg{position:absolute}button.svelte-19xbbtg{color:var(--muted);font:inherit;white-space:nowrap;background:0 0;border:0;font-size:12px;position:absolute;bottom:24px;left:50%;transform:translate(-50%)}:root{font-synthesis:none;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;background:#080e0c;font-family:Cascadia Code,SFMono-Regular,Consolas,monospace}*{box-sizing:border-box}body{margin:0}.shell{--accent:#80edac;--approval:#ffca58;--muted:#98aaa0;--edge:#31473a;--panel:#101c16;--bg:#080e0c;--ink:#e2eee5;background:var(--bg);height:100dvh;color:var(--ink);grid-template-rows:auto auto minmax(0,1fr) auto;padding:clamp(10px,1.2vw,20px);display:grid}.shell[data-theme=rust]{--approval:#ff8a3d;--accent:#ffbc75;--muted:#bfac95;--edge:#59412c;--panel:#261b14;--bg:#140e0a}.shell[data-theme=blue-steel]{--approval:#e8c46a;--accent:#85c8ff;--muted:#9cacc4;--edge:#334d69;--panel:#142235;--bg:#0b1421}.shell[data-theme=ultraviolet]{--approval:#f9a8d4;--accent:#c5adff;--muted:#b3a6c9;--edge:#4b3c68;--panel:#241a35;--bg:#140d22}.shell[data-theme=nightshade]{--approval:#8f7cff;--accent:#e59bff;--muted:#c6a7cf;--edge:#673976;--panel:#301739;--bg:#1c0b24}header,.spread,footer,.controls{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;display:flex}header{margin-bottom:10px}.shell[data-starting=true]>header,.shell[data-starting=true]>nav,.shell[data-starting=true]>main,.shell[data-starting=true]>footer{visibility:hidden}.brand{width:clamp(240px,32vw,405px);max-width:calc(100vw - 40px);color:var(--accent);text-decoration:none;display:block}header p{color:var(--muted);margin:3px 0 0;font-size:13px}.connection{color:var(--accent);text-align:right}small,.eyebrow{letter-spacing:.04em;font-size:12px}.connection small{color:var(--muted);margin-top:4px;display:block}.lamp{background:var(--muted);border-radius:50%;width:9px;height:9px;margin-right:9px;display:inline-block}.lamp.lit{background:var(--accent);box-shadow:0 0 8px color-mix(in srgb, var(--accent) 40%, transparent)}.working{animation:1.5s ease-in-out infinite pulse}@keyframes pulse{50%{opacity:.3}}nav{flex-wrap:wrap;gap:6px;margin-bottom:10px;display:flex}nav a,button,.button,select{font:inherit;color:var(--accent);border:1px solid var(--edge);background:var(--panel);cursor:pointer;border-radius:3px;padding:7px 11px;font-size:13px;text-decoration:none}button:hover,.button:hover,nav a:hover{border-color:var(--accent)}nav a.active,nav button.active{background:var(--accent);color:var(--bg);border-color:var(--accent)}:focus-visible{outline:2px solid var(--accent);outline-offset:4px}.secondary{margin-bottom:8px}.secondary a,.secondary button{padding:6px 10px;font-size:12px}main{scrollbar-gutter:stable;flex-direction:column;min-width:0;min-height:0;display:flex;overflow:auto}main>*{flex-shrink:0}.panel{border:1px solid var(--edge);border-top:2px solid var(--accent);background:var(--panel);border-radius:4px;min-width:0;padding:clamp(10px,1vw,16px)}h1{color:var(--accent);font-size:20px}h2{letter-spacing:.04em;color:var(--accent);overflow-wrap:anywhere;margin:0 0 10px;font-size:13px}h3{overflow-wrap:anywhere;font-size:13px}p{margin:6px 0;font-size:13px;line-height:1.45}a{color:var(--accent)}.muted,.eyebrow{color:var(--muted)}.notice{color:#ffe0aa;background:#332611;border-left:3px solid #ffc26e;padding:12px 16px}.empty{color:var(--muted);padding:35px 0}.quota-grid{flex:1 0 auto;grid-auto-rows:minmax(220px,1fr);gap:10px;display:grid}.quota-card{flex-direction:column;min-height:0;display:flex;container-type:inline-size}.quota-card>:not(.meter-graphic){flex-shrink:0}.meter-graphic{flex-direction:column;flex:1;min-height:100px;display:flex}.bar-graphic{min-height:65px}.quota-card .gauge{flex:2;height:auto;min-height:16px;margin:7px 0}.quota-card .timeline{flex:1;min-height:8px}.quota-grid.zone{grid-template-columns:repeat(auto-fit,minmax(min(100%,420px),1fr));grid-auto-rows:minmax(330px,1fr)}.quota-grid.radial{grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));grid-auto-rows:minmax(260px,1fr)}.gauge{background:var(--edge);height:35px;margin:15px 0;overflow:hidden}.gauge>div{background:repeating-linear-gradient(90deg, var(--accent) 0, var(--accent) 9px, transparent 9px, transparent 12px);height:100%;transition:width .5s}.gauge.timeline{height:14px}.pie-wrap{flex:1;min-height:100px;margin:6px 0;position:relative}.pie-wrap svg{width:100%;height:100%;position:absolute;inset:0}.pie-base{fill:var(--edge);stroke:var(--accent);stroke-width:1px}.pie-fill{fill:var(--accent)}.readout{overflow-wrap:anywhere;color:var(--accent);margin:18px 0;font-size:clamp(22px,3vw,34px)}.credit+.credit{border-top:1px solid var(--edge);padding-top:20px}.credit{margin-top:24px}.session-row{grid-template-columns:minmax(210px,1.1fr) minmax(0,1.2fr) minmax(0,1.5fr);align-items:stretch;gap:14px;margin:18px 0;display:grid}.session-totals{grid-template-columns:repeat(auto-fit,minmax(min(145px,100%),1fr));gap:8px;margin:8px 0;display:grid}.session-totals>div{border:1px solid var(--edge);min-width:0;padding:10px}.session-totals dt{color:var(--muted);font-size:11px}.session-totals dd{color:var(--accent);overflow-wrap:anywhere;margin:6px 0 0;font-size:24px}.session-totals.stale dd{color:var(--muted)}.session-row.selected{outline:1px solid var(--accent);outline-offset:4px}.session-row.wide .context{grid-column:2/-1}.detail-controls{flex-wrap:wrap;gap:6px;display:flex}.attention-summary{flex-wrap:wrap;gap:8px;margin-block:8px;display:flex}.attention-summary .approval{color:var(--approval);border-color:var(--approval)}.attention-summary .approval:hover{background:color-mix(in srgb, var(--approval) 12%, var(--panel))}.attention-summary .approval:focus-visible{outline-color:var(--approval)}.attention-note,.attention-badge{color:var(--accent);border-left:3px solid;padding-left:8px}.attention-note.inferred{color:var(--muted)}.attention-badge{font-size:12px}.session-select{text-align:left;overflow-wrap:anywhere;max-width:100%}.status-detail{color:inherit;text-decoration:none}.status-detail:hover{text-decoration:underline}button:disabled{opacity:.4;cursor:default}.session-row .graph-panel{flex-direction:column;grid-column:2/-1;display:flex}.session-row.split .graph-panel{grid-column:auto}.session-row .button,.session-row button{margin-top:8px;display:inline-block}.context pre{max-height:230px;overflow:auto}.session-row .context{flex-direction:column;display:flex}pre{font:inherit;white-space:pre-wrap;overflow-wrap:anywhere;font-size:13px;line-height:1.7}.full-detail{margin-top:6px}.detail-heading{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px 12px;display:flex}.detail-heading h2{flex:250px;min-width:0;margin:0}.detail-metadata{overflow-wrap:anywhere}.detail-workspace{border-top:1px solid var(--edge);flex-direction:column;gap:10px;margin-top:8px;padding-top:4px;display:flex}.detail-context,.detail-workspace .session-actions{min-width:0}.detail-workspace .session-actions{border-top:1px solid var(--edge);padding-top:6px}.full-detail h3{margin-block:8px}.full-detail pre{margin-block:8px;line-height:1.5}.full-detail hr{margin-block:12px}.full-detail .command,.full-detail .notice{padding:8px 10px}.command{background:var(--bg);border-left:3px solid var(--accent);padding:16px}hr{border:0;border-top:1px solid var(--edge);margin:24px 0}.chart{border-bottom:1px solid var(--muted);align-items:flex-end;gap:2px;height:clamp(120px,22vh,320px);margin-top:18px;display:flex}.chart-bar{background:var(--accent);flex:1;min-width:0;max-height:100%}.controls{justify-content:flex-start;margin:20px 0}.summary-grid{grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));gap:16px;margin:20px 0;display:grid}.thresholds-panel{padding:clamp(14px,2vw,22px)}.thresholds-panel h1{margin-top:0}.threshold-list{gap:8px;margin-top:16px;display:grid}.threshold-list article{border:1px solid var(--edge);grid-template-columns:minmax(64px,.5fr) minmax(220px,3fr) minmax(64px,.6fr) minmax(120px,1.2fr);align-items:center;gap:12px;padding:10px 12px;display:grid}.threshold-list article.active{border-color:var(--accent);box-shadow:inset 3px 0 0 var(--accent)}.threshold-list article.next{border-color:var(--approval);box-shadow:inset 3px 0 0 var(--approval)}.threshold-list p{color:var(--muted);margin:3px 0 0;font-size:12px}.threshold-trigger{color:var(--accent);font-size:22px;font-weight:800}.threshold-mode,.threshold-state{color:var(--muted);font-size:12px;font-weight:700}.threshold-list article.active .threshold-state{color:var(--accent)}.threshold-list article.next .threshold-state{color:var(--approval)}.heat-scroll{overflow-x:auto}.heatmap{grid-template-rows:repeat(7,13px);grid-auto-columns:minmax(9px,1fr);grid-auto-flow:column;gap:4px;min-width:620px;margin:25px 0;display:grid}.heat-cell{background:var(--accent);border-radius:2px}.heat-cell.zero{background:var(--edge)}.table-scroll{max-height:280px;overflow:auto}table{border-collapse:collapse;width:100%;margin-top:15px}th,td{text-align:left;border-bottom:1px solid var(--edge);padding:8px}summary{cursor:pointer;color:var(--accent);padding-top:14px}footer{border-top:1px solid var(--edge);color:var(--muted);margin-top:8px;padding-top:8px;font-size:11px}footer select{padding:6px}@media (width<=850px){.session-row{grid-template-columns:minmax(0,1fr)}.session-row.wide .context,.session-row .graph-panel{grid-column:auto}.connection{text-align:left}.threshold-list article{grid-template-columns:64px minmax(0,1fr)}.threshold-mode,.threshold-state{grid-column:2}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none!important;animation:none!important}} diff --git a/internal/web/dist/index.html b/internal/web/dist/index.html index fddfcbf..07fb2a8 100644 --- a/internal/web/dist/index.html +++ b/internal/web/dist/index.html @@ -5,8 +5,8 @@ Codexometer // Experimental web - - + +
        diff --git a/internal/web/state.go b/internal/web/state.go index 6468ac3..222b100 100644 --- a/internal/web/state.go +++ b/internal/web/state.go @@ -106,6 +106,7 @@ type quotaThreshold struct { } type state struct { + UsageDiagnostic string `json:"usageDiagnostic,omitempty"` StatusLineFields []statusline.Field `json:"statusLineFields"` Triggers []triggerSummary `json:"triggers,omitempty"` Profiles []profileReview `json:"profiles,omitempty"` @@ -274,6 +275,16 @@ func (s *store) live(l codex.LiveUsageSnapshot, err error, now time.Time) { s.state.SessionsError = err != nil if err == nil { s.state.SessionsAt = now + s.state.UsageDiagnostic = "" + if len(l.APIEqDiagnostics) > 0 { + latest := l.APIEqDiagnostics[0] + for _, issue := range l.APIEqDiagnostics[1:] { + if !issue.ObservedAt.Before(latest.ObservedAt) { + latest = issue + } + } + s.state.UsageDiagnostic = codex.DiagnosticText(latest) + } if s.state.Control { s.contexts = make(map[string]codex.SessionContext, len(l.Sessions)) s.directories = make(map[string]string, len(l.Sessions)) diff --git a/internal/web/usage_diagnostics_test.go b/internal/web/usage_diagnostics_test.go new file mode 100644 index 0000000..3546eda --- /dev/null +++ b/internal/web/usage_diagnostics_test.go @@ -0,0 +1,25 @@ +package web + +import ( + "github.com/merefield/codexometer/internal/codex" + "strings" + "testing" + "time" +) + +func TestUsageDiagnosticProjectionIsBoundedSafeAndChoosesNewest(t *testing.T) { + s := newStore() + now := time.Now() + newer := codex.APIEqDiagnostic{Kind: codex.UsageIssueUnpriced, ObservedAt: now, Model: "gpt-reserve", Tier: "fast", Effort: "xhigh", SessionID: "child", Source: "exact response", Reason: "\x1b[31mprice missing \x1b[0m"} + older := codex.APIEqDiagnostic{Kind: codex.UsageIssueMissing, ObservedAt: now.Add(-time.Hour), Model: "old-model", Reason: "old failure"} + s.live(codex.LiveUsageSnapshot{APIEqDiagnostics: []codex.APIEqDiagnostic{newer, older}}, nil, now) + data, _ := s.snapshot() + text := string(data) + if strings.Contains(text, "old-model") || strings.Contains(text, `\u001b`) || !strings.Contains(text, "child") || !strings.Contains(text, "gpt-reserve") || !strings.Contains(text, "xhigh") { + t.Fatal("unsafe or stale projection", text) + } + s.live(codex.LiveUsageSnapshot{}, nil, now) + if s.state.UsageDiagnostic != "" { + t.Fatal("new source retained an old diagnostic") + } +} diff --git a/web/src/Quota.svelte b/web/src/Quota.svelte index 3a6aa9d..9546322 100644 --- a/web/src/Quota.svelte +++ b/web/src/Quota.svelte @@ -57,6 +57,13 @@ {#if live.data.quotaError}

        Quota refresh failed. Values below are the last successful observation.

        {/if} + {#if live.data.usageDiagnostic}

        + Last usage accounting issue: + {live.data.usageDiagnostic} +

        {/if}

        QUOTA // OBSERVED {date(live.data.quotaAt)}

        {#if view === 'thresholds'} @@ -174,3 +181,10 @@ scoring remain in the terminal for this first preview.

        {/if} + + diff --git a/web/src/state.svelte.ts b/web/src/state.svelte.ts index 51e97c8..c73eb01 100644 --- a/web/src/state.svelte.ts +++ b/web/src/state.svelte.ts @@ -105,6 +105,7 @@ export interface Threshold { remaining?: number; } export interface Snapshot { + usageDiagnostic?: string; statusLineFields?: { id: string; label: string; diff --git a/web/tests/browser.spec.ts b/web/tests/browser.spec.ts index 4b5e04e..eff53aa 100644 --- a/web/tests/browser.spec.ts +++ b/web/tests/browser.spec.ts @@ -4539,3 +4539,50 @@ for (const exit of ['commit', 'cancel', 'local'] as const) { await expect(list.getByRole('option')).toHaveCount(3); }); } + +test('Quota accounting diagnostics retain source details safely on narrow screens', async ({ + page, + pairingURL, +}) => { + const { snapshot } = await mockActions(page, 'prompt'); + await page.goto(pairingURL); + await page.evaluate( + (detail) => + window.dispatchEvent(new CustomEvent('test-snapshot', { detail })), + { + ...snapshot, + usageDiagnostic: + 'UNPRICED USAGE // no maintained standard API price for model gpt-reserve\nMODEL gpt-reserve (requested) // TIER fast // EFFORT xhigh\nSESSION child-agent // SOURCE exact response // RESPONSE response-one ', + }, + ); + await page.getByRole('link', { name: 'QUOTA', exact: true }).click(); + const notice = page + .getByRole('status') + .filter({ hasText: 'Last usage accounting issue:' }); + for (const detail of [ + 'UNPRICED USAGE', + 'gpt-reserve', + 'fast', + 'xhigh', + 'child-agent', + 'exact response', + 'response-one', + ]) + await expect(notice).toContainText(detail); + await page.setViewportSize({ width: 375, height: 700 }); + await expect(notice).toBeVisible(); + expect(await notice.evaluate((el) => el.scrollWidth <= el.clientWidth)).toBe( + true, + ); + expect( + await page.evaluate( + () => (window as unknown as { injection?: boolean }).injection, + ), + ).toBeUndefined(); + await page.evaluate( + (detail) => + window.dispatchEvent(new CustomEvent('test-snapshot', { detail })), + snapshot, + ); + await expect(notice).toHaveCount(0); +});