From 5531a6d233cc59a872d6c860845e34fceb50d084 Mon Sep 17 00:00:00 2001 From: Dmitriy Solodukha Date: Tue, 1 Sep 2026 19:02:08 +0300 Subject: [PATCH 1/3] feat(gemini): ask Gemini on a key Caprock never holds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The second paid feature. A user points Caprock at Google's Gemini with their own AI Studio key; Caprock makes the call and counts what it cost, and Google bills them directly. **The key is never stored.** It is read from GEMINI_API_KEY in the daemon's environment at call time — not written to config.json, not accepted by PUT /v1/settings, not returned by GET /v1/settings, and sent in a header rather than the query string so nothing that logs a URL can capture it. This is the direct answer to the objection in 17-teams.md: "a bug in Caprock shows a wrong number, and with a vault a bug in Caprock leaks credentials." A key held in the environment cannot leak from a database Caprock does not write. The cost is an honest one and the panel says it out loud: you set a variable and restart, which is a worse first run than pasting a key into a field. **The licence is checked on the server**, which the spend cap deliberately does not do. The cap spends nothing, so a React-only paywall costs a free user nothing to walk past; this spends their Gemini quota and opens an outbound connection, so the check runs in the handler before the request leaves. A test asserts an unlicensed ask never reaches the client. ADR-023 records the reasoning and keeps the precedent narrow: server-side gates belong to features that spend money or reach the network, not to features that draw a panel. Answers enter the same event stream as everything else — an ordinary turn.user + turn.assistant pair with source=gemini — so they are priced by the same table, searched by the same index, and filtered by the same agent column. Thinking tokens count as output because that is how Google bills them; leaving them out would under-report exactly the models that reason most. Eight Gemini text models added to pricing.json with their source and the date read. Three limits are stated in the notes rather than hidden: the introductory Flash rates expire 2026-12-31, Gemini has no per-token cache-write price (Google bills storage per hour), and the Pro models are tiered by prompt size so the =<200k rate under-reports a long prompt. Also mocks xterm in Session.test.tsx: mounting the terminal tab made jsdom print six unactionable canvas errors, and an error nobody can act on trains people to ignore the ones they can. Claude-Session: https://claude.ai/code/session_01DR8fggA2LRHcjNWUsqtDcF --- .ai/02-architecture.md | 2 +- .ai/03-contracts.md | 2 + .ai/08-decisions.md | 68 +++++ internal/api/agent_param_test.go | 4 +- internal/api/api.go | 9 +- .../{index-BZxreaR-.js => index-BNsMDMFw.js} | 10 +- internal/api/dist/assets/index-Y5As_TQv.css | 1 + internal/api/dist/assets/index-shYzKSwp.css | 1 - internal/api/dist/index.html | 4 +- internal/api/gemini.go | 80 +++++ internal/api/gemini_test.go | 170 +++++++++++ internal/daemon/daemon.go | 3 +- internal/daemon/gemini.go | 93 ++++++ internal/event/event.go | 5 + internal/gemini/gemini.go | 277 ++++++++++++++++++ internal/gemini/gemini_test.go | 134 +++++++++ pricing/pricing.json | 90 +++++- ui/src/components/Gemini.test.tsx | 54 ++++ ui/src/components/Gemini.tsx | 128 ++++++++ ui/src/components/PremiumModal.tsx | 14 +- ui/src/lib/api.ts | 29 ++ ui/src/screens/Cost.tsx | 10 + ui/src/screens/Session.test.tsx | 21 ++ 23 files changed, 1192 insertions(+), 17 deletions(-) rename internal/api/dist/assets/{index-BZxreaR-.js => index-BNsMDMFw.js} (81%) create mode 100644 internal/api/dist/assets/index-Y5As_TQv.css delete mode 100644 internal/api/dist/assets/index-shYzKSwp.css create mode 100644 internal/api/gemini.go create mode 100644 internal/api/gemini_test.go create mode 100644 internal/daemon/gemini.go create mode 100644 internal/gemini/gemini.go create mode 100644 internal/gemini/gemini_test.go create mode 100644 ui/src/components/Gemini.test.tsx create mode 100644 ui/src/components/Gemini.tsx diff --git a/.ai/02-architecture.md b/.ai/02-architecture.md index e7a1937..4391b13 100644 --- a/.ai/02-architecture.md +++ b/.ai/02-architecture.md @@ -127,7 +127,7 @@ type Event struct { } ``` -Append-only `events` table + materialized rollups (`session_stats`, `agent_stats`, `daily_stats`). DDL in [03-contracts.md § SQLite schema](03-contracts.md#sqlite-schema-ddl-v1). Note the DDL v1 `events` row carries `source` (`hook` | `transcript`) in addition to the fields above, because the same session is seen through both planes; the planes are reconciled by shared dedupe keys ([03-contracts.md § Hook shim](03-contracts.md#hook-shim)). One extra kind exists in code: `context.compact` (PreCompact hooks). `SessionStart` maps to `agent.spawn`, `SessionEnd` to `session.end`, `Stop`/`SubagentStop` to `agent.stop` (subagents carry `agent_id`). +Append-only `events` table + materialized rollups (`session_stats`, `agent_stats`, `daily_stats`). DDL in [03-contracts.md § SQLite schema](03-contracts.md#sqlite-schema-ddl-v1). Note the DDL v1 `events` row carries `source` (`hook` | `transcript`) in addition to the fields above, because the same session is seen through both planes; the planes are reconciled by shared dedupe keys ([03-contracts.md § Hook shim](03-contracts.md#hook-shim)). One extra kind exists in code: `context.compact` (PreCompact hooks). `SessionStart` maps to `agent.spawn`, `SessionEnd` to `session.end`, `Stop`/`SubagentStop` to `agent.stop` (subagents carry `agent_id`). Gemini answers are recorded as an ordinary `turn.user` + `turn.assistant` pair with `source = gemini`, so they are priced by the same table, searched by the same index and filtered by the same `agent` column as everything else ([ADR-023](08-decisions.md)). Every producer writes through one path — `internal/rollup.Recorder.Record` — which stores the event, upserts the session, prices assistant turns, updates `session_stats` / `daily_stats` / `session_files` in one transaction, then publishes `event` + `session` frames on the in-process bus (`internal/bus`) that feeds the WebSocket and the loop detector. diff --git a/.ai/03-contracts.md b/.ai/03-contracts.md index 0b6747e..5b7b0b6 100644 --- a/.ai/03-contracts.md +++ b/.ai/03-contracts.md @@ -130,6 +130,8 @@ Plan-limit windows relayed by `caprock statusline` are **validated before storag What that file holds bounds what may ever be said about it: a timestamp and two window percentages. **No tokens, no cost, no conversation content**, so this can never state what the desktop app cost — only how much of a window it consumed. It is also written only while the app runs (27 samples in a day on one real machine, against ~290 at its five-minute interval), so a reading older than 20 minutes is flagged `stale` and the UI says the app has been closed since. Nothing is stored and nothing is polled. +`GET /v1/gemini` reports whether asking Gemini is possible here: `{available, env_var, licensed, model}`. It performs **no network I/O** and **never returns the key** — `available` says only that one is present. `POST /v1/gemini/ask` takes `{prompt, model?}` and answers `{text, model, usage}`, where `usage` carries the response's own `promptTokenCount` / `candidatesTokenCount` / `cachedContentTokenCount` / `thoughtsTokenCount`. It is the one endpoint in the product that checks the licence **server-side** (402 without an active key) rather than leaving the paywall to the UI, because the call spends the user's Gemini quota and opens an outbound connection — the reasoning and its limits are in [ADR-023](08-decisions.md). With no key set it answers 412 with the variable to set, which is a different problem from 402 and is reported separately so the screen can say which. The key is read from `GEMINI_API_KEY` in the daemon's environment at call time; it is never stored, never accepted by `PUT /v1/settings`, and never present in `GET /v1/settings`. + `GET /v1/update` returns `{enabled, current, latest, update_available, command, url, checked_at, error, notes, notes_for}` from cache and **performs no network I/O** — a page load must never cause an outbound call. `POST /v1/update/check` performs one, and returns **403 while `update_checks` is false**: the opt-in is enforced by the server, not merely hidden in the UI, so no page or local script can make Caprock reach the network uninvited. Checks are throttled to once a day unless forced, the request carries no body or credentials, and a failure is reported in `error` rather than as an error status — not knowing about a release must not read as a broken dashboard. `command` is the upgrade command inferred from the running binary's path (Homebrew, Scoop, `go install`); when no package manager owns the binary it is empty and the UI offers `url` instead. `notes` is the published release's own description, taken from the same GitHub response as the tag — reading it costs no second request and no further exposure. It is trimmed to a dialog-sized excerpt (long bodies cut at a line boundary) and paired with `notes_for`, the version it describes, so a cached note can never be shown beside a different version after a failed check. `update_available` is never true for a `dev` or `git describe` build. Caprock does not install the update: replacing the running binary would mean the daemon killing the process executing the command, and running a package manager on the user's behalf from a web page is a surface a local tool should not open. **`PUT /v1/settings` is a patch, not a replace.** Fields are decoded as pointers, so a body changes only the keys it names and leaves the rest as they were; `PUT {}` is a no-op. An explicit `false` is still honoured, so nothing here is write-only. This is not a convenience: decoding into a plain struct made an absent field indistinguishable from a cleared one, so a short body — or a retry that dropped fields — answered 200 while resetting the stated plan *and* switching the release-check opt-in off. The plan decides what every cost figure on the dashboard claims to be, and `update_checks` gates rule 4's single outbound call; neither may be toggled by omission. diff --git a/.ai/08-decisions.md b/.ai/08-decisions.md index ea5fef0..7c204fc 100644 --- a/.ai/08-decisions.md +++ b/.ai/08-decisions.md @@ -354,3 +354,71 @@ switch on. Anything that needs our infrastructure — cross-machine aggregation, the weekly report's delivery — is enforced by that infrastructure and needs no key at all, which is the tier boundary [ADR-021](#adr-021--the-team-tier-is-self-hosted-and-the-free-product-is-not-carved-up) already draws. + +--- + +## ADR-023 — Gemini runs on a key Caprock never holds, read from the environment + +**Decided 2026-09-01.** *Second paid feature.* + +A user can point Caprock at Google's Gemini through their own Google AI Studio +key. Caprock makes the call; the user pays Google directly. Two decisions shape +it, and both exist to keep the product's foundation intact. + +**Caprock never stores the key.** It is read from `GEMINI_API_KEY` in the +daemon's environment, the way every CLI tool on the machine already does it — +never written to `config.json`, never accepted by `PUT /v1/settings`, never +returned by `GET /v1/settings`. This is the direct answer to the objection +recorded in [17-teams.md](17-teams.md) § Not a secret store: *"a bug in Caprock +shows a wrong number, and with a vault a bug in Caprock leaks credentials."* +A key held in the environment cannot leak from a database Caprock does not +write. It also rules out the alternative — an OS keychain across three +platforms — which is real work, a Windows CI surface, and still leaves Caprock +custodian of somebody's credential. + +The cost is honest and worth naming: the user sets an environment variable +before starting the daemon, which is a worse first run than pasting a key into +a field. That is the price of not being a secret store, and it is the right +trade for a tool whose whole argument is that it holds nothing. + +**Rule 4 gains its second exception, and it is opt-in per call.** [Rule +4](../CLAUDE.md) says all data stays on the machine, with the release check as +the only exception — an outbound call that carries nothing about the user. A +Gemini call carries both a credential and the user's own content, which is +categorically further than that exception reaches, so it is written down here +rather than assumed. What keeps it inside the spirit of the rule: nothing is +sent unless the user asks a question in that turn, no background call is ever +made, the destination is Google's documented endpoint and nowhere else, and +with the variable unset the feature does not exist — there is no default-on +path to disable. Caprock still sends nothing about the user to Caprock. + +**The gate is checked on the server, unlike the spend cap.** [ADR-022](#adr-022--the-licence-key-is-an-offline-string-with-an-expiry-and-nothing-more) +made the licence a convenience rather than a lock, and the spend cap follows +that: its paywall is a React component, and a free user who sets the threshold +by curl gets a working cap. Copying that here would be wrong. The cap spends +nothing; a Gemini call spends the user's quota and opens an outbound +connection, so an unpaid caller is not merely reading a screen they did not pay +for. `license.Parse(...).Active` is therefore checked in the handler before the +request leaves, which is a new precedent in this codebase and deliberately +narrow: it applies to features that spend money or reach the network, not to +features that draw a panel. + +**Usage is counted from the response, not from Google.** There is no per-key +billing API — Google's own answer is that per-key breakdowns "can't be done via +AI Studio usage dashboards", and the console reports per *project*. So the +figures come from `usageMetadata` on each response (`promptTokenCount`, +`candidatesTokenCount`, `cachedContentTokenCount`, `thoughtsTokenCount`), +priced through the same `pricing/` table as everything else and stamped with +the same basis. Two consequences are stated on screen rather than hidden: the +history starts when the feature is first used, because nothing before that +passed through Caprock, and the total is what Caprock sent, not what Google +billed. + +**Rules out:** storing the key in `config.json` or any Caprock-managed store; +an OS keychain; reading Google's usage dashboard; any background or speculative +call; presenting a Caprock-side total as the user's Google bill. + +**Revisit if** Google ships a per-key usage API (then the numbers can be +reconciled rather than only counted), or if setting an environment variable +proves to be the thing that stops people using the feature — in which case the +question is a better handoff, not a key Caprock keeps. diff --git a/internal/api/agent_param_test.go b/internal/api/agent_param_test.go index 9593c15..905c0d5 100644 --- a/internal/api/agent_param_test.go +++ b/internal/api/agent_param_test.go @@ -16,8 +16,10 @@ func TestAgentFilterParam(t *testing.T) { {"all", "", false}, {"claude", "claude", false}, {"opencode", "opencode", false}, + {"gemini", "gemini", false}, {"OpenCode", "", true}, // case matters; a near-miss must not silently widen - {"gemini", "", true}, + {"Gemini", "", true}, + {"cursor", "", true}, // an agent we do not support is an error, not "everything" {"'; DROP TABLE sessions--", "", true}, {"claude,opencode", "", true}, } diff --git a/internal/api/api.go b/internal/api/api.go index 5d158b7..4db1d75 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -58,6 +58,9 @@ type Deps struct { Token string // Shutdown is invoked by POST /v1/shutdown (caprock down). Shutdown func() + // AskGemini answers one prompt on the user's own key and records what it + // cost. nil ⇒ the endpoint returns 501. See ADR-023. + AskGemini func(ctx context.Context, model, prompt string) (any, error) // Agents is the Phase 1 owned-session manager (nil ⇒ endpoints return 501). Agents AgentController // Tasks is the Phase 2 hive-backed task board (nil ⇒ endpoints return 501). @@ -203,6 +206,8 @@ func New(d Deps) *Server { // rather than duplicated in the UI, so one edit in Go changes every place // a price appears. m.HandleFunc("GET /v1/premium", s.handlePremium) + m.HandleFunc("GET /v1/gemini", s.handleGeminiStatus) + m.HandleFunc("POST /v1/gemini/ask", s.handleGeminiAsk) m.HandleFunc("GET /v1/pricing", s.handlePricing) m.HandleFunc("GET /v1/live", s.ws.ServeHTTP) if d.Hook != nil { @@ -1396,9 +1401,9 @@ func agentFilter(v string) (store.AgentFilter, error) { switch v { case "", "all": return "", nil - case "claude", "opencode": + case "claude", "opencode", "gemini": return store.AgentFilter(v), nil default: - return "", fmt.Errorf("unknown agent %q: use claude, opencode, or omit for both", v) + return "", fmt.Errorf("unknown agent %q: use claude, opencode, gemini, or omit for all", v) } } diff --git a/internal/api/dist/assets/index-BZxreaR-.js b/internal/api/dist/assets/index-BNsMDMFw.js similarity index 81% rename from internal/api/dist/assets/index-BZxreaR-.js rename to internal/api/dist/assets/index-BNsMDMFw.js index 7eb71bd..6ed05ae 100644 --- a/internal/api/dist/assets/index-BZxreaR-.js +++ b/internal/api/dist/assets/index-BNsMDMFw.js @@ -6,9 +6,9 @@ var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);(function `+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{be=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?ye(n):``}function xe(e,t){switch(e.tag){case 26:case 27:case 5:return ye(e.type);case 16:return ye(`Lazy`);case 13:return e.child!==t&&t!==null?ye(`Suspense Fallback`):ye(`Suspense`);case 19:return ye(`SuspenseList`);case 0:case 15:return F(e.type,!1);case 11:return F(e.type.render,!1);case 1:return F(e.type,!0);case 31:return ye(`Activity`);default:return``}}function I(e){try{var t=``,n=null;do t+=xe(e,n),n=e,e=e.return;while(e);return t}catch(e){return` Error generating stack: `+e.message+` `+e.stack}}var Se=Object.prototype.hasOwnProperty,Ce=t.unstable_scheduleCallback,we=t.unstable_cancelCallback,Te=t.unstable_shouldYield,Ee=t.unstable_requestPaint,De=t.unstable_now,Oe=t.unstable_getCurrentPriorityLevel,ke=t.unstable_ImmediatePriority,Ae=t.unstable_UserBlockingPriority,je=t.unstable_NormalPriority,Me=t.unstable_LowPriority,Ne=t.unstable_IdlePriority,Pe=t.log,Fe=t.unstable_setDisableYieldValue,Ie=null,Le=null;function Re(e){if(typeof Pe==`function`&&Fe(e),Le&&typeof Le.setStrictMode==`function`)try{Le.setStrictMode(Ie,e)}catch{}}var ze=Math.clz32?Math.clz32:He,Be=Math.log,Ve=Math.LN2;function He(e){return e>>>=0,e===0?32:31-(Be(e)/Ve|0)|0}var Ue=256,We=262144,Ge=4194304;function Ke(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function qe(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Ke(n))):i=Ke(o):i=Ke(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Ke(n))):i=Ke(o)):i=Ke(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Je(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Ye(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Xe(){var e=Ge;return Ge<<=1,!(Ge&62914560)&&(Ge=4194304),e}function Ze(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Qe(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function $e(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),ln=!1;if(cn)try{var un={};Object.defineProperty(un,"passive",{get:function(){ln=!0}}),window.addEventListener(`test`,un,un),window.removeEventListener(`test`,un,un)}catch{ln=!1}var dn=null,fn=null,pn=null;function mn(){if(pn)return pn;var e,t=fn,n=t.length,r,i=`value`in dn?dn.value:dn.textContent,a=i.length;for(e=0;e=Kn),Yn=` `,Xn=!1;function Zn(e,t){switch(e){case`keyup`:return Wn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Qn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var $n=!1;function er(e,t){switch(e){case`compositionend`:return Qn(t);case`keypress`:return t.which===32?(Xn=!0,Yn):null;case`textInput`:return e=t.data,e===Yn&&Xn?null:e;default:return null}}function tr(e,t){if($n)return e===`compositionend`||!Gn&&Zn(e,t)?(e=mn(),pn=fn=dn=null,$n=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Cr(n)}}function Tr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Tr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Er(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Ft(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Ft(e.document)}return t}function Dr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Or=cn&&`documentMode`in document&&11>=document.documentMode,kr=null,Ar=null,jr=null,Mr=!1;function Nr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Mr||kr==null||kr!==Ft(r)||(r=kr,`selectionStart`in r&&Dr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),jr&&Sr(jr,r)||(jr=r,r=Td(Ar,`onSelect`),0>=o,i-=o,wi=1<<32-ze(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),o=a(_,o,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),V&&Ei(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(i,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(i,h),o=a(y,o,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(i,h),V&&Ei(i,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(i,v.value,l),v!==null&&(o=a(v,o,g),d===null?u=v:d.sibling=v,d=v);return V&&Ei(i,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,i,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),o=a(v,o,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(i,e)}),V&&Ei(i,g),u}function b(e,r,a,c){if(typeof a==`object`&&a&&a.type===y&&a.key===null&&(a=a.props.children),typeof a==`object`&&a){switch(a.$$typeof){case _:a:{for(var l=a.key;r!==null;){if(r.key===l){if(l=a.type,l===y){if(r.tag===7){n(e,r.sibling),c=i(r,a.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===E&&wa(l)===r.type){n(e,r.sibling),c=i(r,a.props),Aa(c,a),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}a.type===y?(c=di(a.props.children,e.mode,c,a.key),c.return=e,e=c):(c=ui(a.type,a.key,a.props,null,e.mode,c),Aa(c,a),c.return=e,e=c)}return o(e);case v:a:{for(l=a.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===a.containerInfo&&r.stateNode.implementation===a.implementation){n(e,r.sibling),c=i(r,a.children||[]),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}c=mi(a,e.mode,c),c.return=e,e=c}return o(e);case E:return a=wa(a),b(e,r,a,c)}if(k(a))return h(e,r,a,c);if(ae(a)){if(l=ae(a),typeof l!=`function`)throw Error(s(150));return a=l.call(a),g(e,r,a,c)}if(typeof a.then==`function`)return b(e,r,ka(a),c);if(a.$$typeof===C)return b(e,r,ea(e,a),c);ja(e,a)}return typeof a==`string`&&a!==``||typeof a==`number`||typeof a==`bigint`?(a=``+a,r!==null&&r.tag===6?(n(e,r.sibling),c=i(r,a),c.return=e,e=c):(n(e,r),c=fi(a,e.mode,c),c.return=e,e=c),o(e)):n(e,r)}return function(e,t,n,r){try{Oa=0;var i=b(e,t,n,r);return Da=null,i}catch(t){if(t===va||t===ba)throw t;var a=oi(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Na=Ma(!0),Pa=Ma(!1),Fa=!1;function Ia(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function La(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ra(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function za(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Y&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ri(e),ni(e,null,n),t}return $r(e,r,t,n),ri(e)}function Ba(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,tt(e,n)}}function Va(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ha=!1;function Ua(){if(Ha){var e=la;if(e!==null)throw e}}function Wa(e,t,n,r){Ha=!1;var i=e.updateQueue;Fa=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Z&f)===f:(r&f)===f){f!==0&&f===ca&&(Ha=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(m=g.payload,typeof m==`function`){d=m.call(_,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,f=typeof m==`function`?m.call(_,d,f):m,f==null)break a;d=h({},d,f);break a;case 2:Fa=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Ul|=o,e.lanes=o,e.memoizedState=d}}function Ga(e,t){if(typeof e!=`function`)throw Error(s(191,e));e.call(t)}function Ka(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=A.T,s={};A.T=s,js(e,!1,t,n);try{var c=i(),l=A.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?As(e,t,fa(c,r),du(e)):As(e,t,r,du(e))}catch(n){As(e,t,{then:function(){},status:`rejected`,reason:n},du())}finally{j.p=a,o!==null&&s.types!==null&&(o.types=s.types),A.T=o}}function bs(){}function xs(e,t,n,r){if(e.tag!==5)throw Error(s(476));var i=Ss(e).queue;ys(e,i,t,oe,n===null?bs:function(){return Cs(e),n(r)})}function Ss(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:oe,baseState:oe,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:No,lastRenderedState:oe},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:No,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Cs(e){var t=Ss(e);t.next===null&&(t=e.alternate.memoizedState),As(e,t.next.queue,{},du())}function ws(){return $i(Qf)}function Ts(){return Oo().memoizedState}function Es(){return Oo().memoizedState}function Ds(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=du();e=Ra(n);var r=za(t,e,n);r!==null&&(pu(r,t,n),Ba(r,t,n)),t={cache:aa()},e.payload=t;return}t=t.return}}function Os(e,t,n){var r=du();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Ms(e)?Ns(t,n):(n=ei(e,t,n,r),n!==null&&(pu(n,e,r),Ps(n,t,r)))}function ks(e,t,n){As(e,t,n,du())}function As(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ms(e))Ns(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,xr(s,o))return $r(e,t,i,0),Il===null&&Qr(),!1}catch{}if(n=ei(e,t,i,r),n!==null)return pu(n,e,r),Ps(n,t,r),!0}return!1}function js(e,t,n,r){if(r={lane:2,revertLane:ud(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Ms(e)){if(t)throw Error(s(479))}else t=ei(e,n,r,2),t!==null&&pu(t,e,2)}function Ms(e){var t=e.alternate;return e===G||t!==null&&t===G}function Ns(e,t){fo=uo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ps(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,tt(e,n)}}var Fs={readContext:$i,use:jo,useCallback:vo,useContext:vo,useEffect:vo,useImperativeHandle:vo,useLayoutEffect:vo,useInsertionEffect:vo,useMemo:vo,useReducer:vo,useRef:vo,useState:vo,useDebugValue:vo,useDeferredValue:vo,useTransition:vo,useSyncExternalStore:vo,useId:vo,useHostTransitionStatus:vo,useFormState:vo,useActionState:vo,useOptimistic:vo,useMemoCache:vo,useCacheRefresh:vo};Fs.useEffectEvent=vo;var Is={readContext:$i,use:jo,useCallback:function(e,t){return Do().memoizedState=[e,t===void 0?null:t],e},useContext:$i,useEffect:os,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),is(4194308,4,fs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return is(4194308,4,e,t)},useInsertionEffect:function(e,t){is(4,2,e,t)},useMemo:function(e,t){var n=Do();t=t===void 0?null:t;var r=e();if(po){Re(!0);try{e()}finally{Re(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Do();if(n!==void 0){var i=n(t);if(po){Re(!0);try{n(t)}finally{Re(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Os.bind(null,G,e),[r.memoizedState,e]},useRef:function(e){var t=Do();return e={current:e},t.memoizedState=e},useState:function(e){e=Uo(e);var t=e.queue,n=ks.bind(null,G,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:ms,useDeferredValue:function(e,t){return _s(Do(),e,t)},useTransition:function(){var e=Uo(!1);return e=ys.bind(null,G,e.queue,!0,!1),Do().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=G,i=Do();if(V){if(n===void 0)throw Error(s(407));n=n()}else{if(n=t(),Il===null)throw Error(s(349));Z&127||Ro(r,t,n)}i.memoizedState=n;var a={value:n,getSnapshot:t};return i.queue=a,os(Bo.bind(null,r,a,e),[e]),r.flags|=2048,ns(9,{destroy:void 0},zo.bind(null,r,a,n,t),null),n},useId:function(){var e=Do(),t=Il.identifierPrefix;if(V){var n=Ti,r=wi;n=(r&~(1<<32-ze(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=mo++,0<\/script>`,a=a.removeChild(a.firstChild);break;case`select`:a=typeof r.is==`string`?o.createElement(`select`,{is:r.is}):o.createElement(`select`),r.multiple?a.multiple=!0:r.size&&(a.size=r.size);break;default:a=typeof r.is==`string`?o.createElement(i,{is:r.is}):o.createElement(i)}}a[ct]=t,a[lt]=r;a:for(o=t.child;o!==null;){if(o.tag===5||o.tag===6)a.appendChild(o.stateNode);else if(o.tag!==4&&o.tag!==27&&o.child!==null){o.child.return=o,o=o.child;continue}if(o===t)break a;for(;o.sibling===null;){if(o.return===null||o.return===t)break a;o=o.return}o.sibling.return=o.return,o=o.sibling}t.stateNode=a;a:switch(Pd(a,i,r),i){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Oc(t)}}return Nc(t),kc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Oc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(s(166));if(e=de.current,zi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,i=ji,i!==null)switch(i.tag){case 27:case 5:r=i.memoizedProps}e[ct]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||jd(e.nodeValue,n)),e||Ii(t,!0)}else e=Bd(e).createTextNode(r),e[ct]=t,t.stateNode=e}return Nc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=zi(t),n!==null){if(e===null){if(!r)throw Error(s(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(s(557));e[ct]=t}else Bi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Nc(t),e=!1}else n=Vi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(io(t),t):(io(t),null);if(t.flags&128)throw Error(s(558))}return Nc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(i=zi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!i)throw Error(s(318));if(i=t.memoizedState,i=i===null?null:i.dehydrated,!i)throw Error(s(317));i[ct]=t}else Bi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Nc(t),i=!1}else i=Vi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=i),i=!0;if(!i)return t.flags&256?(io(t),t):(io(t),null)}return io(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,i=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(i=r.alternate.memoizedState.cachePool.pool),a=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(a=r.memoizedState.cachePool.pool),a!==i&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),jc(t,t.updateQueue),Nc(t),null);case 4:return me(),e===null&&xd(t.stateNode.containerInfo),Nc(t),null;case 10:return qi(t.type),Nc(t),null;case 19:if(ce(ao),r=t.memoizedState,r===null)return Nc(t),null;if(i=!!(t.flags&128),a=r.rendering,a===null){if(i)Mc(r,!1);else{if(Hl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(a=oo(e),a!==null){for(t.flags|=128,Mc(r,!1),e=a.updateQueue,t.updateQueue=e,jc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)li(n,e),n=n.sibling;return P(ao,ao.current&1|2),V&&Ei(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&De()>$l&&(t.flags|=128,i=!0,Mc(r,!1),t.lanes=4194304)}}else{if(!i){if(e=oo(a),e!==null){if(t.flags|=128,i=!0,e=e.updateQueue,t.updateQueue=e,jc(t,e),Mc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!a.alternate&&!V)return Nc(t),null}else 2*De()-r.renderingStartTime>$l&&n!==536870912&&(t.flags|=128,i=!0,Mc(r,!1),t.lanes=4194304)}r.isBackwards?(a.sibling=t.child,t.child=a):(e=r.last,e===null?t.child=a:e.sibling=a,r.last=a)}return r.tail===null?(Nc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=De(),e.sibling=null,n=ao.current,P(ao,i?n&1|2:n&1),V&&Ei(t,r.treeForkCount),e);case 22:case 23:return io(t),Za(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Nc(t),t.subtreeFlags&6&&(t.flags|=8192)):Nc(t),n=t.updateQueue,n!==null&&jc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&ce(ma),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),qi(H),Nc(t),null;case 25:return null;case 30:return null}throw Error(s(156,t.tag))}function Fc(e,t){switch(ki(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return qi(H),me(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return ge(t),null;case 31:if(t.memoizedState!==null){if(io(t),t.alternate===null)throw Error(s(340));Bi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(io(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(s(340));Bi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return ce(ao),null;case 4:return me(),null;case 10:return qi(t.type),null;case 22:case 23:return io(t),Za(),e!==null&&ce(ma),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return qi(H),null;case 25:return null;default:return null}}function Ic(e,t){switch(ki(t),t.tag){case 3:qi(H),me();break;case 26:case 27:case 5:ge(t);break;case 4:me();break;case 31:t.memoizedState!==null&&io(t);break;case 13:io(t);break;case 19:ce(ao);break;case 10:qi(t.type);break;case 22:case 23:io(t),Za(),e!==null&&ce(ma);break;case 24:qi(H)}}function Lc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Uu(t,t.return,e)}}function Rc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Uu(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Uu(t,t.return,e)}}function zc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Ka(t,n)}catch(t){Uu(e,e.return,t)}}}function Bc(e,t,n){n.props=Us(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Uu(e,t,n)}}function Vc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Uu(e,t,n)}}function Hc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null){if(typeof r==`function`)try{r()}catch(n){Uu(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Uu(e,t,n)}else n.current=null}}function Uc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Uu(e,e.return,t)}}function Wc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[lt]=t}catch(t){Uu(e,e.return,t)}}function Gc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Kc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Gc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Qt));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(qc(e,t,n),e=e.sibling;e!==null;)qc(e,t,n),e=e.sibling}function Jc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Jc(e,t,n),e=e.sibling;e!==null;)Jc(e,t,n),e=e.sibling}function Yc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[ct]=e,t[lt]=n}catch(t){Uu(e,e.return,t)}}var Xc=!1,Zc=!1,Qc=!1,$c=typeof WeakSet==`function`?WeakSet:Set,el=null;function tl(e,t){if(e=e.containerInfo,Rd=sp,e=Er(e),Dr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var i=r.anchorOffset,a=r.focusNode;r=r.focusOffset;try{n.nodeType,a.nodeType}catch{n=null;break a}var o=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||i!==0&&f.nodeType!==3||(c=o+i),f!==a||r!==0&&f.nodeType!==3||(l=o+r),f.nodeType===3&&(o+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===i&&(c=o),p===a&&++d===r&&(l=o),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,el=t;el!==null;)if(t=el,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,el=e;else for(;el!==null;){switch(t=el,a=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(a,r,n),a[ct]=e,yt(a),r=a;break a;case`link`:var o=Vf(`link`,`href`,i).get(r+(n.href||``));if(o){for(var c=0;cg&&(o=g,g=h,h=o);var _=wr(s,h),v=wr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,A.T=null,n=su,su=null;var a=ru,o=au;if(nu=0,iu=ru=null,au=0,Y&6)throw Error(s(331));var c=Y;if(Y|=4,jl(a.current),Cl(a,a.current,o,n),Y=c,rd(0,!1),Le&&typeof Le.onPostCommitFiberRoot==`function`)try{Le.onPostCommitFiberRoot(Ie,a)}catch{}return!0}finally{j.p=i,A.T=r,zu(e,t)}}function Hu(e,t,n){t=gi(n,t),t=Js(e.stateNode,t,2),e=za(e,t,2),e!==null&&(Qe(e,2),nd(e))}function Uu(e,t,n){if(e.tag===3)Hu(e,e,n);else for(;t!==null;){if(t.tag===3){Hu(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(tu===null||!tu.has(r))){e=gi(n,e),n=Ys(2),r=za(t,n,2),r!==null&&(Xs(n,r,t,e),Qe(r,2),nd(r));break}}t=t.return}}function Wu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Fl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Q=!0,i.add(n),e=Gu.bind(null,e,t,n),t.then(e,e))}function Gu(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Il===e&&(Z&n)===n&&(Hl===4||Hl===3&&(Z&62914560)===Z&&300>De()-Zl?!(Y&2)&&bu(e,0):Gl|=n,ql===Z&&(ql=0)),nd(e)}function Ku(e,t){t===0&&(t=Xe()),e=ti(e,t),e!==null&&(Qe(e,t),nd(e))}function qu(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Ku(e,n)}function Ju(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,i=e.memoizedState;i!==null&&(n=i.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(s(314))}r!==null&&r.delete(t),Ku(e,n)}function Yu(e,t){return Ce(e,t)}var Xu=null,Zu=null,Qu=!1,$u=!1,ed=!1,td=0;function nd(e){e!==Zu&&e.next===null&&(Zu===null?Xu=Zu=e:Zu=Zu.next=e),$u=!0,Qu||(Qu=!0,ld())}function rd(e,t){if(!ed&&$u){ed=!0;do for(var n=!1,r=Xu;r!==null;){if(!t){if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-ze(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,cd(r,a))}else a=Z,a=qe(r,r===Il?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Je(r,a)||(n=!0,cd(r,a))}r=r.next}while(n);ed=!1}}function id(){ad()}function ad(){$u=Qu=!1;var e=0;td!==0&&Gd()&&(e=td);for(var t=De(),n=null,r=Xu;r!==null;){var i=r.next,a=od(r,t);a===0?(r.next=null,n===null?Xu=i:n.next=i,i===null&&(Zu=n)):(n=r,(e!==0||a&3)&&($u=!0)),r=i}nu!==0&&nu!==5||rd(e,!1),td!==0&&(td=0)}function od(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Lt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),yt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Lt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Lt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Lt(n.imageSizes)+`"]`)):i+=`[href="`+Lt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=h({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),yt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Lt(r)+`"][href="`+Lt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=h({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),yt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=vt(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=h({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);yt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=vt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),yt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=vt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),yt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var i=(i=de.current)?gf(i):null;if(!i)throw Error(s(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=vt(i).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var a=vt(i).hoistableStyles,o=a.get(e);if(o||(i=i.ownerDocument||i,o={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},a.set(e,o),(a=i.querySelector(jf(e)))&&!a._p&&(o.instance=a,o.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),a||Nf(i,e,n,o.state))),t&&r===null)throw Error(s(528,``));return o}if(t&&r!==null)throw Error(s(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=vt(i).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(s(444,e))}}function Af(e){return`href="`+Lt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return h({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),yt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Lt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Lt(n.href)+`"]`);if(r)return t.instance=r,yt(r),r;var i=h({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),yt(r),Pd(r,`style`,i),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:i=Af(n.href);var a=e.querySelector(jf(i));if(a)return t.state.loading|=4,t.instance=a,yt(a),a;r=Mf(n),(i=mf.get(i))&&Rf(r,i),a=(e.ownerDocument||e).createElement(`link`),yt(a);var o=a;return o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),t.state.loading|=4,Lf(a,n.precedence,e),t.instance=a;case`script`:return a=Pf(n.src),(i=e.querySelector(Ff(a)))?(t.instance=i,yt(i),i):(r=n,(i=mf.get(a))&&(r=h({},n),zf(r,i)),e=e.ownerDocument||e,i=e.createElement(`script`),yt(i),Pd(i,`link`,r),e.head.appendChild(i),t.instance=i);case`void`:return null;default:throw Error(s(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,yt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),yt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=s()})),l=n(),u=c(),d=new class{state={conn:`connecting`,lastFrameAt:0,tick:0,alerts:[]};listeners=new Set;backoff=500;timer=null;started=!1;frameSubs=new Set;getState=()=>this.state;subscribe=e=>(this.listeners.add(e),this.start(),()=>{this.listeners.delete(e)});onFrame=e=>(this.frameSubs.add(e),()=>{this.frameSubs.delete(e)});set(e){this.state={...this.state,...e};for(let e of this.listeners)e()}start(){this.started||typeof WebSocket>`u`||(this.started=!0,this.connect())}connect(){let e=`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/v1/live`;this.set({conn:`connecting`});let t;try{t=new WebSocket(e)}catch{this.scheduleReconnect();return}t.onopen=()=>{this.backoff=500,this.set({conn:`open`})},t.onmessage=e=>{let t;try{t=JSON.parse(String(e.data))}catch{return}this.handle(t)},t.onclose=()=>{this.set({conn:`closed`}),this.scheduleReconnect()},t.onerror=()=>{t.close()}}scheduleReconnect(){this.timer===null&&(this.timer=window.setTimeout(()=>{this.timer=null,this.connect()},this.backoff),this.backoff=Math.min(this.backoff*2,1e4))}handle(e){let t=Date.now();for(let t of this.frameSubs)try{t(e)}catch(e){console.error(`[caprock] live frame subscriber failed`,e)}switch(e.type){case`alert`:this.set({lastFrameAt:t,alerts:[e.data,...this.state.alerts.filter(t=>t.session_id!==e.data.session_id)].slice(0,50),tick:this.state.tick+1});break;case`event`:this.set({lastFrameAt:t,lastEvent:e.data,tick:this.state.tick+1});break;case`session`:this.set({lastFrameAt:t,tick:this.state.tick+1});break;case`task`:this.set({lastFrameAt:t,tick:this.state.tick+1});break;default:this.set({lastFrameAt:t})}}dismissAlert(e){this.set({alerts:this.state.alerts.filter(t=>t.session_id!==e)})}};function f(){return(0,l.useSyncExternalStore)(d.subscribe,d.getState,d.getState)}function p(e=400){let{tick:t}=f(),[n,r]=m(t,e);return(0,l.useEffect)(()=>{r(t)},[t,r]),n}function m(e,t){let[n,r]=(0,l.useState)(e),i=(0,l.useRef)(null),a=(0,l.useRef)(e);return[n,(0,l.useCallback)(e=>{a.current=e,i.current===null&&(i.current=window.setTimeout(()=>{i.current=null,r(a.current)},t))},[t])]}function h(e){let[t,n]=e.replace(/^#\/?/,``).split(`?`),r=(t??``).split(`/`).filter(Boolean),i=new URLSearchParams(n??``),a=i.get(`tab`)??void 0,o=Number(i.get(`at`)),s=Number.isFinite(o)&&o>0?o:void 0;switch(r[0]){case void 0:case``:case`now`:return{name:`now`};case`session`:return r[1]?{name:`session`,id:decodeURIComponent(r[1]),tab:a,at:s}:{name:`now`};case`cost`:return{name:`cost`};case`history`:return{name:`history`};case`tasks`:return{name:`tasks`};case`graph`:return{name:`graph`};case`notes`:return{name:`notes`};case`settings`:return{name:`settings`};default:return{name:`now`}}}function g(e){switch(e.name){case`now`:return`#/`;case`session`:{let t=new URLSearchParams;e.tab&&t.set(`tab`,e.tab),e.at&&t.set(`at`,String(e.at));let n=t.toString();return`#/session/${encodeURIComponent(e.id)}${n?`?${n}`:``}`}case`cost`:return`#/cost`;case`history`:return`#/history`;case`tasks`:return`#/tasks`;case`graph`:return`#/graph`;case`notes`:return`#/notes`;case`settings`:return`#/settings`}}function _(){let[e,t]=(0,l.useState)(()=>h(location.hash));return(0,l.useEffect)(()=>{let e=()=>t(h(location.hash));return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),e}function v(e){location.hash=g(e)}var y=new Intl.NumberFormat(`en-US`,{style:`currency`,currency:`USD`,minimumFractionDigits:2,maximumFractionDigits:2}),b=new Intl.NumberFormat(`en-US`,{style:`currency`,currency:`USD`,minimumFractionDigits:4,maximumFractionDigits:4});function x(e){return typeof e==`number`&&Number.isFinite(e)?e:null}function S(e){return x(e)===null?`—`:(e=e,e!==0&&Math.abs(e)<.01?b.format(e):y.format(e))}function C(e){if(x(e)===null)return`—`;e=e;let t=Math.abs(e);return t>=1e9?`${(e/1e9).toFixed(2)}B`:t>=1e6?`${(e/1e6).toFixed(2)}M`:t>=1e4?`${(e/1e3).toFixed(1)}k`:new Intl.NumberFormat(`en-US`).format(e)}function w(e,t=0){if(x(e)===null)return`—`;let n=e;if(t===0){let e=Math.floor(n);return`${Number.isFinite(e)?e:0}%`}let r=Math.min(100,Math.max(0,Math.trunc(x(t)??0)));return`${e.toFixed(r)}%`}function ee(e,t=Date.now()){if(!e)return`—`;let n=typeof e==`number`?e:Date.parse(e);if(Number.isNaN(n))return`—`;let r=Math.max(0,Math.round((t-n)/1e3));if(r<5)return`now`;if(r<60)return`${r}s ago`;let i=Math.floor(r/60);if(i<60)return`${i}m ago`;let a=Math.floor(i/60);return a<48?`${a}h ago`:`${Math.floor(a/24)}d ago`}function te(e){if(x(e)===null)return`—`;if(e<1e3)return`${Math.round(e)}ms`;let t=Math.round(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m ${t%60}s`:`${Math.floor(n/60)}h ${n%60}m`}function T(e){return e.length>8?e.slice(0,8):e}function E(e){let t=e.replace(/[\\/]+$/,``),n=Math.max(t.lastIndexOf(`/`),t.lastIndexOf(`\\`));return n>=0?t.slice(n+1):t}function ne(e){let t=/^mcp__(.+?)__(.+)$/.exec(e);return t?`${t[1]}·${t[2]}`:e}function re(e){return e.replace(/-\d{6,}$/,`…`)}function ie(e){let[t,n]=(0,l.useState)(()=>Date.now());return(0,l.useEffect)(()=>{let t=window.setInterval(()=>n(Date.now()),e);return()=>window.clearInterval(t)},[e]),t}var ae=`caprock-theme`;function D(){let e=localStorage.getItem(ae);return e===`dark`||e===`light`?e:window.matchMedia?.(`(prefers-color-scheme: light)`).matches?`light`:`dark`}function O(e){document.documentElement.setAttribute(`data-theme`,e),document.documentElement.style.colorScheme=e}function k(){let[e,t]=(0,l.useState)(D);return(0,l.useEffect)(()=>{O(e),localStorage.setItem(ae,e)},[e]),[e,()=>t(e=>e===`dark`?`light`:`dark`)]}async function A(e,t,n=`POST`){let r=await fetch(e,{method:n,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!r.ok){let e;try{e=await r.json()}catch{}throw new j(r.status,`${r.status} ${r.statusText}`,e)}return r.status===204?void 0:await r.json()}var j=class extends Error{status;body;constructor(e,t,n){super(t),this.status=e,this.body=n}};function oe(e){if(e instanceof j){let t=e.body,n=t?.error??e.message;return t?.detail?`${n} — ${t.detail}`:n}return e instanceof Error?e.message:String(e)}async function M(e){let t=await fetch(e,{headers:{Accept:`application/json`}});if(!t.ok){let e;try{e=await t.json()}catch{}throw new j(t.status,`${t.status} ${t.statusText}`,e)}return await t.json()}var N={sessions:(e=!1)=>M(`/v1/sessions${e?`?active=true`:``}`),session:e=>M(`/v1/sessions/${encodeURIComponent(e)}`),events:(e,t=0,n=500)=>M(`/v1/sessions/${encodeURIComponent(e)}/events?after=${t}&limit=${n}`),eventsBefore:(e,t,n=200)=>M(`/v1/sessions/${encodeURIComponent(e)}/events?before=${t}&limit=${n}`),recentEvents:(e,t=2e3)=>M(`/v1/sessions/${encodeURIComponent(e)}/events?newest=1&limit=${t}`),diff:e=>M(`/v1/sessions/${encodeURIComponent(e)}/diff`),notes:(e,t=200)=>M(`/v1/sessions/${encodeURIComponent(e)}/notes?limit=${t}`),searchNotes:(e,t=100,n=0)=>M(`/v1/notes?q=${encodeURIComponent(e)}&limit=${t}${n?`&before=${n}`:``}`),settings:()=>M(`/v1/settings`),update:()=>M(`/v1/update`),checkUpdate:()=>A(`/v1/update/check`,{}),saveSettings:e=>A(`/v1/settings`,e,`PUT`),summary:(e=`today`,t)=>M(`/v1/stats/summary?range=${e}${t&&t!==`all`?`&agent=${t}`:``}`),daily:(e=30)=>M(`/v1/stats/daily?days=${e}`),premium:()=>M(`/v1/premium`),browse:(e=``)=>M(`/v1/browse${e?`?dir=${encodeURIComponent(e)}`:``}`),recentDirs:()=>M(`/v1/recent-dirs`),history:(e=`all`)=>M(`/v1/history?range=${e}`),enableHive:(e,t)=>A(`/v1/hive`,{hive:e??``,repo:t??``}),tasks:()=>M(`/v1/tasks`),task:e=>M(`/v1/tasks/${encodeURIComponent(e)}`),createTask:e=>A(`/v1/tasks`,e),approve:(e,t)=>A(`/v1/tasks/${encodeURIComponent(e)}/${t?`approve`:`reject`}`,{}),startOrchestrator:()=>A(`/v1/orchestrator/start`,{}),stopOrchestrator:()=>A(`/v1/orchestrator/stop`,{}),status:()=>M(`/v1/status`),spawn:e=>A(`/v1/agents`,e),signal:(e,t)=>A(`/v1/agents/${encodeURIComponent(e)}/signal`,{action:t}),paste:(e,t)=>A(`/v1/paste`,{type:e,data:t}),agentInput:(e,t)=>A(`/v1/agents/${encodeURIComponent(e)}/input`,{data:t})},se=[{id:`macos`,label:`macOS`},{id:`linux`,label:`Linux`},{id:`windows`,label:`Windows`}],ce={cmd:`caprock down && caprock up`,note:`The running daemon is the old binary until it restarts. Your database is untouched.`},P={cmd:`caprock status`,note:`Confirms the new version is the one running, and that hooks are still registered.`},le={label:`Homebrew`,steps:[{cmd:`brew update && brew upgrade caprock`,note:`The update is not optional: without it Homebrew reads a cached copy of the tap, refreshed at most once a day, and reports "already installed" for a release that is already out.`},ce,P]},ue={label:`Scoop`,steps:[{cmd:`scoop update caprock`,note:`Scoop refreshes its buckets as part of this, so no separate step.`},ce,P]},de={label:`go install`,steps:[{cmd:`go install github.com/dspv/caprock/cmd/caprock@latest`,note:`Also install the hook shim: same command with cmd/caprock-hook.`},ce,P]},fe={label:`Downloaded binary`,steps:[{cmd:``,note:`Download the archive for your platform from the release page, and replace the caprock and caprock-hook binaries with the ones inside it.`},ce,P]};function pe(e){switch(e){case`macos`:return[le,de,fe];case`linux`:return[le,de,fe];case`windows`:return[ue,de,fe]}}function me(e,t){let n=`${t??``} ${e}`.toLowerCase();return n.includes(`win`)?`windows`:n.includes(`mac`)||n.includes(`darwin`)||n.includes(`iphone`)||n.includes(`ipad`)?`macos`:`linux`}function he(e){if(e&&e.startsWith(`scoop`))return`windows`}function ge(e,t){return e?be(e,pe(t))===void 0:!1}var _e=`caprock-update-platform`;function ve(){try{let e=localStorage.getItem(_e);return se.some(t=>t.id===e)?e:void 0}catch{return}}function ye(e){try{localStorage.setItem(_e,e)}catch{}}function be(e,t){if(!e)return;let n=e.split(/\s+/)[0];if(n)return t.find(e=>e.steps.some(e=>e.cmd.startsWith(n)))}function F(e,t=[],n={}){let{live:r=!0,intervalMs:i=0}=n,a=p(400),[o,s]=(0,l.useState)({data:void 0,error:void 0,loading:!0,refresh:()=>{},loadedAt:0}),c=(0,l.useRef)(0),u=(0,l.useRef)(e);u.current=e;let d=(0,l.useCallback)(()=>{let e=++c.current;u.current().then(t=>{e===c.current&&s(e=>({...e,data:t,error:void 0,loading:!1,loadedAt:Date.now()}))},t=>{e===c.current&&s(e=>({...e,error:t,loading:!1}))})},[]);return(0,l.useEffect)(d,[d,...t]),(0,l.useEffect)(()=>{r&&a>0&&d()},[r,a,d]),(0,l.useEffect)(()=>{if(!i)return;let e=window.setInterval(d,i);return()=>window.clearInterval(e)},[i,d]),{...o,refresh:d}}var xe=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),I=e(((e,t)=>{t.exports=xe()}))(),Se=[{label:`Pro`,kind:`flat`,usd:20,note:`$20/mo`},{label:`Max 5×`,kind:`flat`,usd:100,note:`$100/mo`},{label:`Max 20×`,kind:`flat`,usd:200,note:`$200/mo`},{label:`Team seat`,kind:`flat`,usd:30,note:`$30/seat/mo`},{label:`API / Bedrock`,kind:`metered`,usd:0,note:`billed per token`}],Ce,we=null,Te=new Set;function Ee(){for(let e of Te)e()}function De(){let[,e]=(0,l.useState)(0);return(0,l.useEffect)(()=>{let t=()=>e(e=>e+1);return Te.add(t),!Ce&&!we&&(we=N.settings().then(e=>{Ce=e}).catch(()=>{Ce={update_checks:!1,plan_kind:``,plan_label:``,plan_usd_per_month:0}}).finally(()=>{we=null,Ee()})),()=>{Te.delete(t)}},[]),[Ce,e=>{Ce=e,Ee(),N.saveSettings(e).catch(()=>{})}]}function Oe({plan:e,onSave:t}){let[n,r]=(0,l.useState)(!1),i=(0,l.useRef)(null);(0,l.useEffect)(()=>{if(!n)return;let e=e=>{i.current&&!i.current.contains(e.target)&&r(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[n]);let a=e?.plan_kind?e.plan_kind===`metered`?e.plan_label||`API`:`${e.plan_label||`plan`} · ${S(e.plan_usd_per_month)}/mo`:`set plan`;return(0,I.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,I.jsx)(`button`,{onClick:()=>r(e=>!e),className:`mono text-[11px] px-1.5 py-0.5 rounded-sm border ${e?.plan_kind?`border-border text-fg-muted hover:text-fg`:`border-accent/50 text-accent`}`,title:`How you pay for Claude Code — Caprock cannot detect this, so you tell it`,children:a}),n&&(0,I.jsx)(ke,{plan:e,onSave:e=>{t(e),r(!1)}})]})}function ke({plan:e,onSave:t}){let[n,r]=(0,l.useState)(String(e?.plan_usd_per_month||``)),i=e??{update_checks:!1,plan_kind:``,plan_label:``,plan_usd_per_month:0};return(0,I.jsxs)(`div`,{className:`absolute right-0 top-7 z-20 w-[268px] border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg p-2`,children:[(0,I.jsx)(`div`,{className:`text-[11px] text-fg-muted px-1 pb-1.5`,children:`How do you pay for Claude Code? Caprock can't detect this and never guesses.`}),Se.map(n=>{let r=e?.plan_label===n.label;return(0,I.jsxs)(`button`,{onClick:()=>t({...i,plan_kind:n.kind,plan_label:n.label,plan_usd_per_month:n.usd}),className:`w-full flex items-baseline gap-2 px-1.5 py-1 rounded-sm text-left text-[12px] hover:bg-panel-2 ${r?`text-accent`:`text-fg`}`,children:[(0,I.jsx)(`span`,{children:n.label}),(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-faint ml-auto`,children:n.note})]},n.label)}),(0,I.jsxs)(`div`,{className:`border-t border-border mt-1.5 pt-1.5 px-1.5`,children:[(0,I.jsx)(`label`,{className:`text-[11px] text-fg-faint`,children:`Or a different monthly price`}),(0,I.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,I.jsx)(`span`,{className:`mono text-[12px] text-fg-faint`,children:`$`}),(0,I.jsx)(`input`,{className:`input`,inputMode:`decimal`,value:n,onChange:e=>r(e.target.value),placeholder:`e.g. 150`}),(0,I.jsx)(`button`,{className:`text-[11px] border border-border px-1.5 py-1 rounded-sm hover:border-border-strong`,onClick:()=>{let e=Number(n);!Number.isFinite(e)||e<0||t({...i,plan_kind:`flat`,plan_label:`plan`,plan_usd_per_month:e})},children:`set`})]})]})]})}var Ae=[{id:`bug`,label:`bug`,hint:`What did you see?`,gh:`bug`},{id:`feature`,label:`feature`,hint:`What would you want?`,gh:`enhancement`},{id:`unclear`,label:`unclear`,hint:`What did not make sense?`,gh:`question`},{id:`other`,label:`other`,hint:`Anything else — a sentence is enough.`,gh:`question`}],je=`dspv/caprock`;function Me(e,t){if(!e)return[`Screen: ${t}`];let n=e.hooks,r=n?(n.missing?.length??0)>0?`partly installed`:n.shim_exists?`installed`:`not installed`:`unknown`;return[`Caprock ${e.version}${e.platform?` (${e.platform})`:``}`,`Screen: ${t}`,`${e.events.toLocaleString(`en-US`)} events${e.owned_active?` · ${e.owned_active} owned session(s) running`:``}`,`Hooks: ${r} · Orchestration: ${e.orchestration?`on`:`off`}`]}function Ne(e,t,n){let r=n.trim().split(` +`).replace(kd,``)}function jd(e,t){return t=Ad(t),Ad(e)===t}function Md(e,t,n,r,i,a){switch(n){case`children`:typeof r==`string`?t===`body`||t===`textarea`&&r===``||Wt(e,r):(typeof r==`number`||typeof r==`bigint`)&&t!==`body`&&Wt(e,``+r);break;case`className`:Ot(e,`class`,r);break;case`tabIndex`:Ot(e,`tabindex`,r);break;case`dir`:case`role`:case`viewBox`:case`width`:case`height`:Ot(e,n,r);break;case`style`:qt(e,r,a);break;case`data`:if(t!==`object`){Ot(e,`data`,r);break}case`src`:case`href`:if(r===``&&(t!==`a`||n!==`href`)){e.removeAttribute(n);break}if(r==null||typeof r==`function`||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=Zt(``+r),e.setAttribute(n,r);break;case`action`:case`formAction`:if(typeof r==`function`){e.setAttribute(n,`javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')`);break}if(typeof a==`function`&&(n===`formAction`?(t!==`input`&&Md(e,t,`name`,i.name,i,null),Md(e,t,`formEncType`,i.formEncType,i,null),Md(e,t,`formMethod`,i.formMethod,i,null),Md(e,t,`formTarget`,i.formTarget,i,null)):(Md(e,t,`encType`,i.encType,i,null),Md(e,t,`method`,i.method,i,null),Md(e,t,`target`,i.target,i,null))),r==null||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=Zt(``+r),e.setAttribute(n,r);break;case`onClick`:r!=null&&(e.onclick=Qt);break;case`onScroll`:r!=null&&$(`scroll`,e);break;case`onScrollEnd`:r!=null&&$(`scrollend`,e);break;case`dangerouslySetInnerHTML`:if(r!=null){if(typeof r!=`object`||!(`__html`in r))throw Error(s(61));if(n=r.__html,n!=null){if(i.children!=null)throw Error(s(60));e.innerHTML=n}}break;case`multiple`:e.multiple=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`muted`:e.muted=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`suppressContentEditableWarning`:case`suppressHydrationWarning`:case`defaultValue`:case`defaultChecked`:case`innerHTML`:case`ref`:break;case`autoFocus`:break;case`xlinkHref`:if(r==null||typeof r==`function`||typeof r==`boolean`||typeof r==`symbol`){e.removeAttribute(`xlink:href`);break}n=Zt(``+r),e.setAttributeNS(`http://www.w3.org/1999/xlink`,`xlink:href`,n);break;case`contentEditable`:case`spellCheck`:case`draggable`:case`value`:case`autoReverse`:case`externalResourcesRequired`:case`focusable`:case`preserveAlpha`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``+r):e.removeAttribute(n);break;case`inert`:case`allowFullScreen`:case`async`:case`autoPlay`:case`controls`:case`default`:case`defer`:case`disabled`:case`disablePictureInPicture`:case`disableRemotePlayback`:case`formNoValidate`:case`hidden`:case`loop`:case`noModule`:case`noValidate`:case`open`:case`playsInline`:case`readOnly`:case`required`:case`reversed`:case`scoped`:case`seamless`:case`itemScope`:r&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``):e.removeAttribute(n);break;case`capture`:case`download`:!0===r?e.setAttribute(n,``):!1!==r&&r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,r):e.removeAttribute(n);break;case`cols`:case`rows`:case`size`:case`span`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`&&!isNaN(r)&&1<=r?e.setAttribute(n,r):e.removeAttribute(n);break;case`rowSpan`:case`start`:r==null||typeof r==`function`||typeof r==`symbol`||isNaN(r)?e.removeAttribute(n):e.setAttribute(n,r);break;case`popover`:$(`beforetoggle`,e),$(`toggle`,e),Dt(e,`popover`,r);break;case`xlinkActuate`:kt(e,`http://www.w3.org/1999/xlink`,`xlink:actuate`,r);break;case`xlinkArcrole`:kt(e,`http://www.w3.org/1999/xlink`,`xlink:arcrole`,r);break;case`xlinkRole`:kt(e,`http://www.w3.org/1999/xlink`,`xlink:role`,r);break;case`xlinkShow`:kt(e,`http://www.w3.org/1999/xlink`,`xlink:show`,r);break;case`xlinkTitle`:kt(e,`http://www.w3.org/1999/xlink`,`xlink:title`,r);break;case`xlinkType`:kt(e,`http://www.w3.org/1999/xlink`,`xlink:type`,r);break;case`xmlBase`:kt(e,`http://www.w3.org/XML/1998/namespace`,`xml:base`,r);break;case`xmlLang`:kt(e,`http://www.w3.org/XML/1998/namespace`,`xml:lang`,r);break;case`xmlSpace`:kt(e,`http://www.w3.org/XML/1998/namespace`,`xml:space`,r);break;case`is`:Dt(e,`is`,r);break;case`innerText`:case`textContent`:break;default:(!(2s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Lt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),yt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Lt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Lt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Lt(n.imageSizes)+`"]`)):i+=`[href="`+Lt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=h({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),yt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Lt(r)+`"][href="`+Lt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=h({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),yt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=vt(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=h({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);yt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=vt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),yt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=vt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),yt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var i=(i=de.current)?gf(i):null;if(!i)throw Error(s(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=vt(i).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var a=vt(i).hoistableStyles,o=a.get(e);if(o||(i=i.ownerDocument||i,o={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},a.set(e,o),(a=i.querySelector(jf(e)))&&!a._p&&(o.instance=a,o.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),a||Nf(i,e,n,o.state))),t&&r===null)throw Error(s(528,``));return o}if(t&&r!==null)throw Error(s(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=vt(i).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(s(444,e))}}function Af(e){return`href="`+Lt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return h({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),yt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Lt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Lt(n.href)+`"]`);if(r)return t.instance=r,yt(r),r;var i=h({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),yt(r),Pd(r,`style`,i),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:i=Af(n.href);var a=e.querySelector(jf(i));if(a)return t.state.loading|=4,t.instance=a,yt(a),a;r=Mf(n),(i=mf.get(i))&&Rf(r,i),a=(e.ownerDocument||e).createElement(`link`),yt(a);var o=a;return o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),t.state.loading|=4,Lf(a,n.precedence,e),t.instance=a;case`script`:return a=Pf(n.src),(i=e.querySelector(Ff(a)))?(t.instance=i,yt(i),i):(r=n,(i=mf.get(a))&&(r=h({},n),zf(r,i)),e=e.ownerDocument||e,i=e.createElement(`script`),yt(i),Pd(i,`link`,r),e.head.appendChild(i),t.instance=i);case`void`:return null;default:throw Error(s(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,yt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),yt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=s()})),l=n(),u=c(),d=new class{state={conn:`connecting`,lastFrameAt:0,tick:0,alerts:[]};listeners=new Set;backoff=500;timer=null;started=!1;frameSubs=new Set;getState=()=>this.state;subscribe=e=>(this.listeners.add(e),this.start(),()=>{this.listeners.delete(e)});onFrame=e=>(this.frameSubs.add(e),()=>{this.frameSubs.delete(e)});set(e){this.state={...this.state,...e};for(let e of this.listeners)e()}start(){this.started||typeof WebSocket>`u`||(this.started=!0,this.connect())}connect(){let e=`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/v1/live`;this.set({conn:`connecting`});let t;try{t=new WebSocket(e)}catch{this.scheduleReconnect();return}t.onopen=()=>{this.backoff=500,this.set({conn:`open`})},t.onmessage=e=>{let t;try{t=JSON.parse(String(e.data))}catch{return}this.handle(t)},t.onclose=()=>{this.set({conn:`closed`}),this.scheduleReconnect()},t.onerror=()=>{t.close()}}scheduleReconnect(){this.timer===null&&(this.timer=window.setTimeout(()=>{this.timer=null,this.connect()},this.backoff),this.backoff=Math.min(this.backoff*2,1e4))}handle(e){let t=Date.now();for(let t of this.frameSubs)try{t(e)}catch(e){console.error(`[caprock] live frame subscriber failed`,e)}switch(e.type){case`alert`:this.set({lastFrameAt:t,alerts:[e.data,...this.state.alerts.filter(t=>t.session_id!==e.data.session_id)].slice(0,50),tick:this.state.tick+1});break;case`event`:this.set({lastFrameAt:t,lastEvent:e.data,tick:this.state.tick+1});break;case`session`:this.set({lastFrameAt:t,tick:this.state.tick+1});break;case`task`:this.set({lastFrameAt:t,tick:this.state.tick+1});break;default:this.set({lastFrameAt:t})}}dismissAlert(e){this.set({alerts:this.state.alerts.filter(t=>t.session_id!==e)})}};function f(){return(0,l.useSyncExternalStore)(d.subscribe,d.getState,d.getState)}function p(e=400){let{tick:t}=f(),[n,r]=m(t,e);return(0,l.useEffect)(()=>{r(t)},[t,r]),n}function m(e,t){let[n,r]=(0,l.useState)(e),i=(0,l.useRef)(null),a=(0,l.useRef)(e);return[n,(0,l.useCallback)(e=>{a.current=e,i.current===null&&(i.current=window.setTimeout(()=>{i.current=null,r(a.current)},t))},[t])]}function h(e){let[t,n]=e.replace(/^#\/?/,``).split(`?`),r=(t??``).split(`/`).filter(Boolean),i=new URLSearchParams(n??``),a=i.get(`tab`)??void 0,o=Number(i.get(`at`)),s=Number.isFinite(o)&&o>0?o:void 0;switch(r[0]){case void 0:case``:case`now`:return{name:`now`};case`session`:return r[1]?{name:`session`,id:decodeURIComponent(r[1]),tab:a,at:s}:{name:`now`};case`cost`:return{name:`cost`};case`history`:return{name:`history`};case`tasks`:return{name:`tasks`};case`graph`:return{name:`graph`};case`notes`:return{name:`notes`};case`settings`:return{name:`settings`};default:return{name:`now`}}}function g(e){switch(e.name){case`now`:return`#/`;case`session`:{let t=new URLSearchParams;e.tab&&t.set(`tab`,e.tab),e.at&&t.set(`at`,String(e.at));let n=t.toString();return`#/session/${encodeURIComponent(e.id)}${n?`?${n}`:``}`}case`cost`:return`#/cost`;case`history`:return`#/history`;case`tasks`:return`#/tasks`;case`graph`:return`#/graph`;case`notes`:return`#/notes`;case`settings`:return`#/settings`}}function _(){let[e,t]=(0,l.useState)(()=>h(location.hash));return(0,l.useEffect)(()=>{let e=()=>t(h(location.hash));return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]),e}function v(e){location.hash=g(e)}var y=new Intl.NumberFormat(`en-US`,{style:`currency`,currency:`USD`,minimumFractionDigits:2,maximumFractionDigits:2}),b=new Intl.NumberFormat(`en-US`,{style:`currency`,currency:`USD`,minimumFractionDigits:4,maximumFractionDigits:4});function x(e){return typeof e==`number`&&Number.isFinite(e)?e:null}function S(e){return x(e)===null?`—`:(e=e,e!==0&&Math.abs(e)<.01?b.format(e):y.format(e))}function C(e){if(x(e)===null)return`—`;e=e;let t=Math.abs(e);return t>=1e9?`${(e/1e9).toFixed(2)}B`:t>=1e6?`${(e/1e6).toFixed(2)}M`:t>=1e4?`${(e/1e3).toFixed(1)}k`:new Intl.NumberFormat(`en-US`).format(e)}function w(e,t=0){if(x(e)===null)return`—`;let n=e;if(t===0){let e=Math.floor(n);return`${Number.isFinite(e)?e:0}%`}let r=Math.min(100,Math.max(0,Math.trunc(x(t)??0)));return`${e.toFixed(r)}%`}function ee(e,t=Date.now()){if(!e)return`—`;let n=typeof e==`number`?e:Date.parse(e);if(Number.isNaN(n))return`—`;let r=Math.max(0,Math.round((t-n)/1e3));if(r<5)return`now`;if(r<60)return`${r}s ago`;let i=Math.floor(r/60);if(i<60)return`${i}m ago`;let a=Math.floor(i/60);return a<48?`${a}h ago`:`${Math.floor(a/24)}d ago`}function te(e){if(x(e)===null)return`—`;if(e<1e3)return`${Math.round(e)}ms`;let t=Math.round(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m ${t%60}s`:`${Math.floor(n/60)}h ${n%60}m`}function T(e){return e.length>8?e.slice(0,8):e}function E(e){let t=e.replace(/[\\/]+$/,``),n=Math.max(t.lastIndexOf(`/`),t.lastIndexOf(`\\`));return n>=0?t.slice(n+1):t}function ne(e){let t=/^mcp__(.+?)__(.+)$/.exec(e);return t?`${t[1]}·${t[2]}`:e}function re(e){return e.replace(/-\d{6,}$/,`…`)}function ie(e){let[t,n]=(0,l.useState)(()=>Date.now());return(0,l.useEffect)(()=>{let t=window.setInterval(()=>n(Date.now()),e);return()=>window.clearInterval(t)},[e]),t}var ae=`caprock-theme`;function D(){let e=localStorage.getItem(ae);return e===`dark`||e===`light`?e:window.matchMedia?.(`(prefers-color-scheme: light)`).matches?`light`:`dark`}function O(e){document.documentElement.setAttribute(`data-theme`,e),document.documentElement.style.colorScheme=e}function k(){let[e,t]=(0,l.useState)(D);return(0,l.useEffect)(()=>{O(e),localStorage.setItem(ae,e)},[e]),[e,()=>t(e=>e===`dark`?`light`:`dark`)]}async function A(e,t,n=`POST`){let r=await fetch(e,{method:n,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!r.ok){let e;try{e=await r.json()}catch{}throw new j(r.status,`${r.status} ${r.statusText}`,e)}return r.status===204?void 0:await r.json()}var j=class extends Error{status;body;constructor(e,t,n){super(t),this.status=e,this.body=n}};function oe(e){if(e instanceof j){let t=e.body,n=t?.error??e.message;return t?.detail?`${n} — ${t.detail}`:n}return e instanceof Error?e.message:String(e)}async function M(e){let t=await fetch(e,{headers:{Accept:`application/json`}});if(!t.ok){let e;try{e=await t.json()}catch{}throw new j(t.status,`${t.status} ${t.statusText}`,e)}return await t.json()}var N={sessions:(e=!1)=>M(`/v1/sessions${e?`?active=true`:``}`),session:e=>M(`/v1/sessions/${encodeURIComponent(e)}`),events:(e,t=0,n=500)=>M(`/v1/sessions/${encodeURIComponent(e)}/events?after=${t}&limit=${n}`),eventsBefore:(e,t,n=200)=>M(`/v1/sessions/${encodeURIComponent(e)}/events?before=${t}&limit=${n}`),recentEvents:(e,t=2e3)=>M(`/v1/sessions/${encodeURIComponent(e)}/events?newest=1&limit=${t}`),diff:e=>M(`/v1/sessions/${encodeURIComponent(e)}/diff`),notes:(e,t=200)=>M(`/v1/sessions/${encodeURIComponent(e)}/notes?limit=${t}`),searchNotes:(e,t=100,n=0)=>M(`/v1/notes?q=${encodeURIComponent(e)}&limit=${t}${n?`&before=${n}`:``}`),settings:()=>M(`/v1/settings`),update:()=>M(`/v1/update`),checkUpdate:()=>A(`/v1/update/check`,{}),saveSettings:e=>A(`/v1/settings`,e,`PUT`),summary:(e=`today`,t)=>M(`/v1/stats/summary?range=${e}${t&&t!==`all`?`&agent=${t}`:``}`),daily:(e=30)=>M(`/v1/stats/daily?days=${e}`),premium:()=>M(`/v1/premium`),gemini:()=>M(`/v1/gemini`),askGemini:(e,t)=>A(`/v1/gemini/ask`,{prompt:e,model:t}),browse:(e=``)=>M(`/v1/browse${e?`?dir=${encodeURIComponent(e)}`:``}`),recentDirs:()=>M(`/v1/recent-dirs`),history:(e=`all`)=>M(`/v1/history?range=${e}`),enableHive:(e,t)=>A(`/v1/hive`,{hive:e??``,repo:t??``}),tasks:()=>M(`/v1/tasks`),task:e=>M(`/v1/tasks/${encodeURIComponent(e)}`),createTask:e=>A(`/v1/tasks`,e),approve:(e,t)=>A(`/v1/tasks/${encodeURIComponent(e)}/${t?`approve`:`reject`}`,{}),startOrchestrator:()=>A(`/v1/orchestrator/start`,{}),stopOrchestrator:()=>A(`/v1/orchestrator/stop`,{}),status:()=>M(`/v1/status`),spawn:e=>A(`/v1/agents`,e),signal:(e,t)=>A(`/v1/agents/${encodeURIComponent(e)}/signal`,{action:t}),paste:(e,t)=>A(`/v1/paste`,{type:e,data:t}),agentInput:(e,t)=>A(`/v1/agents/${encodeURIComponent(e)}/input`,{data:t})},se=[{id:`macos`,label:`macOS`},{id:`linux`,label:`Linux`},{id:`windows`,label:`Windows`}],ce={cmd:`caprock down && caprock up`,note:`The running daemon is the old binary until it restarts. Your database is untouched.`},P={cmd:`caprock status`,note:`Confirms the new version is the one running, and that hooks are still registered.`},le={label:`Homebrew`,steps:[{cmd:`brew update && brew upgrade caprock`,note:`The update is not optional: without it Homebrew reads a cached copy of the tap, refreshed at most once a day, and reports "already installed" for a release that is already out.`},ce,P]},ue={label:`Scoop`,steps:[{cmd:`scoop update caprock`,note:`Scoop refreshes its buckets as part of this, so no separate step.`},ce,P]},de={label:`go install`,steps:[{cmd:`go install github.com/dspv/caprock/cmd/caprock@latest`,note:`Also install the hook shim: same command with cmd/caprock-hook.`},ce,P]},fe={label:`Downloaded binary`,steps:[{cmd:``,note:`Download the archive for your platform from the release page, and replace the caprock and caprock-hook binaries with the ones inside it.`},ce,P]};function pe(e){switch(e){case`macos`:return[le,de,fe];case`linux`:return[le,de,fe];case`windows`:return[ue,de,fe]}}function me(e,t){let n=`${t??``} ${e}`.toLowerCase();return n.includes(`win`)?`windows`:n.includes(`mac`)||n.includes(`darwin`)||n.includes(`iphone`)||n.includes(`ipad`)?`macos`:`linux`}function he(e){if(e&&e.startsWith(`scoop`))return`windows`}function ge(e,t){return e?be(e,pe(t))===void 0:!1}var _e=`caprock-update-platform`;function ve(){try{let e=localStorage.getItem(_e);return se.some(t=>t.id===e)?e:void 0}catch{return}}function ye(e){try{localStorage.setItem(_e,e)}catch{}}function be(e,t){if(!e)return;let n=e.split(/\s+/)[0];if(n)return t.find(e=>e.steps.some(e=>e.cmd.startsWith(n)))}function F(e,t=[],n={}){let{live:r=!0,intervalMs:i=0}=n,a=p(400),[o,s]=(0,l.useState)({data:void 0,error:void 0,loading:!0,refresh:()=>{},loadedAt:0}),c=(0,l.useRef)(0),u=(0,l.useRef)(e);u.current=e;let d=(0,l.useCallback)(()=>{let e=++c.current;u.current().then(t=>{e===c.current&&s(e=>({...e,data:t,error:void 0,loading:!1,loadedAt:Date.now()}))},t=>{e===c.current&&s(e=>({...e,error:t,loading:!1}))})},[]);return(0,l.useEffect)(d,[d,...t]),(0,l.useEffect)(()=>{r&&a>0&&d()},[r,a,d]),(0,l.useEffect)(()=>{if(!i)return;let e=window.setInterval(d,i);return()=>window.clearInterval(e)},[i,d]),{...o,refresh:d}}var xe=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),I=e(((e,t)=>{t.exports=xe()}))(),Se=[{label:`Pro`,kind:`flat`,usd:20,note:`$20/mo`},{label:`Max 5×`,kind:`flat`,usd:100,note:`$100/mo`},{label:`Max 20×`,kind:`flat`,usd:200,note:`$200/mo`},{label:`Team seat`,kind:`flat`,usd:30,note:`$30/seat/mo`},{label:`API / Bedrock`,kind:`metered`,usd:0,note:`billed per token`}],Ce,we=null,Te=new Set;function Ee(){for(let e of Te)e()}function De(){let[,e]=(0,l.useState)(0);return(0,l.useEffect)(()=>{let t=()=>e(e=>e+1);return Te.add(t),!Ce&&!we&&(we=N.settings().then(e=>{Ce=e}).catch(()=>{Ce={update_checks:!1,plan_kind:``,plan_label:``,plan_usd_per_month:0}}).finally(()=>{we=null,Ee()})),()=>{Te.delete(t)}},[]),[Ce,e=>{Ce=e,Ee(),N.saveSettings(e).catch(()=>{})}]}function Oe({plan:e,onSave:t}){let[n,r]=(0,l.useState)(!1),i=(0,l.useRef)(null);(0,l.useEffect)(()=>{if(!n)return;let e=e=>{i.current&&!i.current.contains(e.target)&&r(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[n]);let a=e?.plan_kind?e.plan_kind===`metered`?e.plan_label||`API`:`${e.plan_label||`plan`} · ${S(e.plan_usd_per_month)}/mo`:`set plan`;return(0,I.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,I.jsx)(`button`,{onClick:()=>r(e=>!e),className:`mono text-[11px] px-1.5 py-0.5 rounded-sm border ${e?.plan_kind?`border-border text-fg-muted hover:text-fg`:`border-accent/50 text-accent`}`,title:`How you pay for Claude Code — Caprock cannot detect this, so you tell it`,children:a}),n&&(0,I.jsx)(ke,{plan:e,onSave:e=>{t(e),r(!1)}})]})}function ke({plan:e,onSave:t}){let[n,r]=(0,l.useState)(String(e?.plan_usd_per_month||``)),i=e??{update_checks:!1,plan_kind:``,plan_label:``,plan_usd_per_month:0};return(0,I.jsxs)(`div`,{className:`absolute right-0 top-7 z-20 w-[268px] border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg p-2`,children:[(0,I.jsx)(`div`,{className:`text-[11px] text-fg-muted px-1 pb-1.5`,children:`How do you pay for Claude Code? Caprock can't detect this and never guesses.`}),Se.map(n=>{let r=e?.plan_label===n.label;return(0,I.jsxs)(`button`,{onClick:()=>t({...i,plan_kind:n.kind,plan_label:n.label,plan_usd_per_month:n.usd}),className:`w-full flex items-baseline gap-2 px-1.5 py-1 rounded-sm text-left text-[12px] hover:bg-panel-2 ${r?`text-accent`:`text-fg`}`,children:[(0,I.jsx)(`span`,{children:n.label}),(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-faint ml-auto`,children:n.note})]},n.label)}),(0,I.jsxs)(`div`,{className:`border-t border-border mt-1.5 pt-1.5 px-1.5`,children:[(0,I.jsx)(`label`,{className:`text-[11px] text-fg-faint`,children:`Or a different monthly price`}),(0,I.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,I.jsx)(`span`,{className:`mono text-[12px] text-fg-faint`,children:`$`}),(0,I.jsx)(`input`,{className:`input`,inputMode:`decimal`,value:n,onChange:e=>r(e.target.value),placeholder:`e.g. 150`}),(0,I.jsx)(`button`,{className:`text-[11px] border border-border px-1.5 py-1 rounded-sm hover:border-border-strong`,onClick:()=>{let e=Number(n);!Number.isFinite(e)||e<0||t({...i,plan_kind:`flat`,plan_label:`plan`,plan_usd_per_month:e})},children:`set`})]})]})]})}var Ae=[{id:`bug`,label:`bug`,hint:`What did you see?`,gh:`bug`},{id:`feature`,label:`feature`,hint:`What would you want?`,gh:`enhancement`},{id:`unclear`,label:`unclear`,hint:`What did not make sense?`,gh:`question`},{id:`other`,label:`other`,hint:`Anything else — a sentence is enough.`,gh:`question`}],je=`dspv/caprock`;function Me(e,t){if(!e)return[`Screen: ${t}`];let n=e.hooks,r=n?(n.missing?.length??0)>0?`partly installed`:n.shim_exists?`installed`:`not installed`:`unknown`;return[`Caprock ${e.version}${e.platform?` (${e.platform})`:``}`,`Screen: ${t}`,`${e.events.toLocaleString(`en-US`)} events${e.owned_active?` · ${e.owned_active} owned session(s) running`:``}`,`Hooks: ${r} · Orchestration: ${e.orchestration?`on`:`off`}`]}function Ne(e,t,n){let r=n.trim().split(` `)[0]?.trim()??``;return`[${e}] ${t}: ${r.length>60?`${r.slice(0,57)}…`:r}`}function Pe(e,t,n){let r=e===`bug`?`What happened`:e===`feature`?`What is missing`:e===`unclear`?`What is unclear`:`Feedback`,i=t.trim(),a=i.length>6e3?`${i.slice(0,Ie)}\n\n_[…truncated — the rest did not fit in the link; paste it below]_`:i;return[`### ${r}`,``,a,``,`### Context`,``,...n.map(e=>`- ${e}`),``,`Filed from the Caprock dashboard. Nothing was sent automatically — this issue was opened in your browser for you to review.`].join(` -`)}function Fe(e,t,n,r){let i=Ae.find(t=>t.id===e)??Ae[0];return`https://github.com/${je}/issues/new?${new URLSearchParams({title:Ne(e,t,n),body:Pe(e,n,r),labels:i.gh}).toString()}`}var Ie=6e3;function Le(e){return e.trim().length>=8}function Re({screen:e}){let[t,n]=(0,l.useState)(!1);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{onClick:()=>n(!0),className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,title:`Report a bug, ask for something, or say what was unclear`,children:`feedback`}),t&&(0,I.jsx)(ze,{screen:e,onClose:()=>n(!1)})]})}function ze({screen:e,onClose:t}){let[n,r]=(0,l.useState)(`bug`),[i,a]=(0,l.useState)(``),o=Me(F(()=>N.status(),[],{live:!1,intervalMs:0}).data,e),s=Le(i),c=Ae.find(e=>e.id===n)??Ae[0],u=()=>{s&&(window.open(Fe(n,e,i,o),`_blank`,`noopener`),t())};return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 bg-black/50 flex items-start justify-center pt-[12vh] px-4`,onClick:t,children:(0,I.jsxs)(`div`,{className:`w-full max-w-[660px] border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`div`,{className:`px-4 pt-3 pb-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`span`,{className:`text-[15px] font-medium`,children:`Tell us what happened`}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-[16px] leading-none text-fg-faint hover:text-fg`,children:`×`})]}),(0,I.jsxs)(`div`,{className:`p-4 grid gap-3`,children:[(0,I.jsx)(`div`,{className:`flex gap-1.5`,children:Ae.map(e=>(0,I.jsx)(`button`,{onClick:()=>r(e.id),className:`text-[13px] px-3.5 py-1.5 rounded-sm border font-mono ${e.id===n?`border-accent/60 bg-accent/10 text-accent`:`border-border text-fg-muted hover:text-fg`}`,children:e.label},e.id))}),(0,I.jsx)(`textarea`,{autoFocus:!0,value:i,onChange:e=>a(e.target.value),placeholder:c.hint,rows:6,className:`input w-full resize-y text-[14px] leading-relaxed`,onKeyDown:e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&u()}}),(0,I.jsxs)(`div`,{className:`border border-border rounded-sm bg-panel-2/50 px-3 py-2`,children:[(0,I.jsx)(`div`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint mb-1`,children:`Attached`}),(0,I.jsx)(`ul`,{className:`text-[11px] text-fg-muted num grid gap-0.5`,children:o.map(e=>(0,I.jsx)(`li`,{children:e},e))})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(`button`,{onClick:u,disabled:!s,className:`text-[12px] px-3 py-1.5 rounded-sm border ${s?`border-accent/50 bg-accent/10 text-accent hover:bg-accent/20`:`border-border text-fg-faint cursor-not-allowed`}`,children:`Open a GitHub issue →`}),(0,I.jsx)(`span`,{className:`text-[12px] ${s?`text-fg-faint`:`text-fg-muted`}`,children:s?`⌘↵ to open`:`One sentence is enough.`})]}),(0,I.jsx)(`p`,{className:`text-[11px] text-fg-faint leading-relaxed`,children:`Nothing is sent from here — the issue opens prefilled in your browser for you to submit.`})]})]})})}var Be=1200,Ve=630;function He(e,t){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()||t}var Ue={command:`running commands`,edit:`writing code`,read:`reading code`,mcp:`MCP tools`,web:`web research`,other:`other tools`,none:`no tool call`};function We(e){return e.slice(e.lastIndexOf(`/`)+1).replace(/^claude-/,``).replace(/-\d{8}$/,``).slice(0,18)}function Ge(e){return e>=1e9?`${(e/1e9).toFixed(1)}B`:e>=1e6?`${Math.round(e/1e6)}M`:e>=1e3?`${Math.round(e/1e3)}k`:String(e)}function Ke(e,t){let n=He(`--color-bg`,`#141414`),r=He(`--color-panel`,`#1a1a19`),i=He(`--color-border`,`#2a2a28`),a=He(`--color-fg`,`#e8e6e2`),o=He(`--color-fg-muted`,`#a9a59e`),s=He(`--color-fg-faint`,`#6f6b64`),c=He(`--color-accent`,`#feb157`),l=He(`--color-ok`,`#7fc99a`),u=`"JetBrains Mono", ui-monospace, monospace`,d=`"Hanken Grotesk", ui-sans-serif, system-ui, sans-serif`;e.fillStyle=n,e.fillRect(0,0,Be,Ve);let f=(t,n,r,i,a=12)=>{e.beginPath(),e.moveTo(t+a,n),e.arcTo(t+r,n,t+r,n+i,a),e.arcTo(t+r,n+i,t,n+i,a),e.arcTo(t,n+i,t,n,a),e.arcTo(t,n,t+r,n,a),e.closePath()},p=(t,n,a,o)=>{f(t,n,a,o),e.fillStyle=r,e.fill(),e.strokeStyle=i,e.lineWidth=1,e.stroke()},m=(t,n,r,i,a,o=d,s=400,c=`left`)=>{e.fillStyle=a,e.font=`${s} ${i}px ${o}`,e.textAlign=c,e.fillText(r,t,n)};e.font=`600 32px ${d}`;let h=`My stats on`,g=e.measureText(` `).width,_=e.measureText(h).width;m(64,78,h,32,a,d,600);let v=64+_+g;m(v,78,`caprock.dev`,32,c,d,600);let y=e.measureText(`caprock.dev`).width,b=t.takenAt.toLocaleDateString(`en-GB`,{day:`numeric`,month:`short`,year:`numeric`});m(v+y+g*2,78,`– ${b}`,26,s,d,600),[[`TODAY`,S(t.today.cost),`${t.today.sessions} sessions`,c],[`THIS WEEK`,S(t.week.cost),`${t.week.sessions} sessions`,a],[`THIS MONTH`,S(t.month.cost),`${Ge(t.month.tokens)} tokens`,a],[`ALL TIME`,S(t.allTime.cost),`${t.allTime.days} active days`,c],[`A DAY`,S(t.allTime.cost/Math.max(1,t.allTime.days)),`on average`,a],[`TOKENS`,Ge(t.allTime.tokens),`all time`,a],[`PER 1M TOKENS`,S(t.allTime.cost/Math.max(1,t.allTime.tokens/1e6)),`what a million costs`,a],[`CACHE HIT`,`${Math.round(t.cacheHitPct)}%`,`input cost cut`,l]].forEach(([e,t,n,r],i)=>{let a=64+i%4*272,c=130+Math.floor(i/4)*114;p(a,c,256,98),m(a+20,c+30,e,13,s,u),m(a+20,c+56,t,28,r,d,600),m(a+20,c+81,n,14,o)});let x=(t,n,r,i)=>{let l=44+r.length*26+12;p(t,n,524,l),m(t+20,n+30,i,13,s,u);let d=Math.max(...r.map(e=>e.cost),1),h=r.reduce((e,t)=>e+t.cost,0),g=t+170;return r.forEach((r,i)=>{let l=n+62+i*26;m(t+20,l,r.label,14,o,u),e.fillStyle=c,e.globalAlpha=.85;let p=Math.max(2,164*(r.cost/d));f(g,l-10,p,10,Math.min(3,p/2)),e.fill(),e.globalAlpha=1,m(t+524-62,l,S(r.cost),14,a,u,400,`right`);let _=h>0?Math.max(1,Math.floor(100*r.cost/h)):0;m(t+524-20,l,`${_}%`,14,s,u,400,`right`)}),l},C=x(64,372,t.models,`WHERE THE MONEY WENT`);x(612,372,t.work,`WHAT IT WENT ON`);let w=372+C+34;m(64,w,`at API list prices — not a bill, and not money saved`,14,s),m(1136,w,`What's yours?`,15,c,d,600,`right`),e.textAlign=`left`}function qe(e=new Date){let t=e=>String(e).padStart(2,`0`);return`caprock-${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}.png`}async function Je(){let[e,t,n,r]=await Promise.all([N.summary(`today`),N.summary(`7d`),N.summary(`30d`),N.history(`all`)]),i=e=>e.tokens_in+e.tokens_out+e.cache_read+e.cache_write;return{takenAt:new Date,today:{cost:e.cost_usd,sessions:e.sessions},week:{cost:t.cost_usd,sessions:t.sessions},month:{cost:n.cost_usd,tokens:i(n)},allTime:{cost:r.totals.cost_usd,days:r.totals.days,tokens:i(r.summary)},cacheHitPct:(n.savings?.hit_rate??0)*100,models:(n.models??[]).slice(0,5).map(e=>({label:We(e.model),cost:e.cost_usd})),work:(n.work??[]).slice(0,5).map(e=>({label:Ue[e.kind]??e.kind,cost:e.cost_usd}))}}async function Ye(e){let t=document.createElement(`canvas`);t.width=Be,t.height=Ve;let n=null;try{n=t.getContext(`2d`)}catch{return null}return n?(Ke(n,e),await new Promise(e=>{if(typeof t.toBlob!=`function`){e(null);return}t.toBlob(t=>e(t),`image/png`)})):null}function Xe(e){let t=`over ${e.days} active days`;return`${S(e.cost_usd)} of Claude Code ${t}, across ${e.sessions.toLocaleString(`en-US`)} sessions — measured on my own machine with Caprock. https://caprock.dev`}function Ze(){let[e,t]=(0,l.useState)(!1);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{onClick:()=>t(!0),className:`rounded-md border border-accent/45 bg-accent/[0.08] px-2 py-0.5 text-accent hover:bg-accent/[0.16]`,title:`Draw a shareable image of your figures`,children:`Share`}),e&&(0,I.jsx)(Qe,{onClose:()=>t(!1)})]})}function Qe({onClose:e}){let[t,n]=(0,l.useState)(!1),[r,i]=(0,l.useState)(!1),[a,o]=(0,l.useState)(``),s=async()=>{let[e,t]=await Promise.all([Je(),N.history(`all`)]);return{blob:await Ye(e),text:Xe(t.totals)}},c=async()=>{if(!r){i(!0),n(!0),o(``);try{let{blob:t}=await s();if(!t){o(`Could not draw the card in this browser.`),i(!1);return}let r=new File([t],qe(),{type:`image/png`});n(!1),await navigator.share({files:[r]}),e()}catch(e){e?.name!==`AbortError`&&o(`Sharing was not available — the card was not sent.`),i(!1)}finally{n(!1)}}},u=async e=>{if(!r){i(!0),n(!0),o(``);try{let{blob:t,text:n}=await s();if(!t){o(`Could not draw the card in this browser.`);return}let r=URL.createObjectURL(t),i=document.createElement(`a`);if(i.href=r,i.download=qe(),i.click(),URL.revokeObjectURL(r),e===`download`){o(`Saved to your downloads.`);return}let a=e===`x`?`https://x.com/intent/tweet?text=${encodeURIComponent(n)}`:`https://www.linkedin.com/feed/?shareActive=true&text=${encodeURIComponent(n)}`;window.open(a,`_blank`,`noopener`),o(`Card saved and the post opened — drag the image in.`)}finally{n(!1),i(!1)}}},d=typeof navigator<`u`&&typeof navigator.canShare==`function`&&navigator.canShare({files:[new File([],`x.png`,{type:`image/png`})]});return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 flex items-start justify-center bg-black/50 px-4 pt-[14vh]`,onClick:e,role:`dialog`,"aria-modal":`true`,"aria-label":`Share your figures`,children:(0,I.jsxs)(`div`,{className:`w-[420px] max-w-full rounded-[var(--radius-panel)] border border-border-strong bg-panel`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`flex items-center border-b border-border px-4 py-3`,children:[(0,I.jsx)(`h2`,{className:`text-[13px] font-medium text-fg`,children:`Share your figures`}),(0,I.jsx)(`button`,{onClick:e,className:`ml-auto text-fg-muted hover:text-fg`,"aria-label":`Close`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`px-4 py-4`,children:[(0,I.jsxs)(`div`,{className:`grid gap-2.5`,children:[d&&(0,I.jsxs)(`button`,{onClick:c,disabled:r,className:`rounded-md border border-accent bg-accent/15 px-4 py-3 text-[14px] font-medium text-accent hover:bg-accent/25 disabled:opacity-50`,children:[t?`Drawing the card…`:`Send it somewhere`,(0,I.jsx)(`span`,{className:`mt-0.5 block text-[12px] font-normal text-fg-muted`,children:`Opens your share menu — Messages, Mail, anywhere`})]}),(0,I.jsxs)(`button`,{onClick:()=>u(`download`),disabled:r,className:`rounded-md border border-border bg-transparent px-4 py-3 text-[14px] text-fg transition-colors hover:border-border-strong hover:bg-panel-2 disabled:opacity-50`,children:[t&&!d?`Drawing the card…`:`Save the image`,(0,I.jsx)(`span`,{className:`mt-0.5 block text-[12px] text-fg-muted`,children:`A PNG in your downloads, to post wherever you like`})]})]}),(0,I.jsxs)(`ul`,{className:`mt-4 grid gap-1 text-[13px] text-fg-muted`,children:[(0,I.jsx)(`li`,{children:`Totals only — no names, no paths, nothing Claude wrote.`}),(0,I.jsx)(`li`,{children:`Drawn on your machine. Uploaded nowhere.`})]}),a&&(0,I.jsx)(`p`,{className:`mt-2 text-[12px] text-fg-muted`,children:a})]})]})})}function $e(){let e=F(()=>N.history(`all`),[],{intervalMs:6e4}),[t,n]=(0,l.useState)(!1),r=e.data?.totals;return!r||r.sessions===0?null:(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{onClick:()=>n(!0),className:`rounded-md border border-accent/45 bg-accent/[0.08] px-2.5 py-1 text-[12px] text-accent hover:bg-accent/[0.16]`,title:`Draw a shareable image of these figures`,children:`Share these numbers`}),t&&(0,I.jsx)(Qe,{onClose:()=>n(!1)})]})}var et={cap:{title:`A daily cap that pauses sessions`,body:`A number for the day. Cross it and Caprock stops its own sessions.`,points:[`A runaway loop stops at $40 instead of finishing at $400`,`It happens while you are asleep, not in tomorrow’s summary`,`Your own sessions are never touched — only the ones Caprock started`]},report:{title:`A weekly report, sent where you are`,body:`Monday morning, before you open a terminal.`,points:[`What moved: the repository that cost 3× its usual week`,`Last week against the one before it, per repository and model`,`Through your own Telegram bot — nothing passes our server`],setup:`Setup: one message to BotFather, about two minutes.`}};function tt({p:e,onClose:t}){return e?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,I.jsxs)(`a`,{href:e.yearly.url,target:`_blank`,rel:`noreferrer`,onClick:t,className:`rounded-sm bg-premium/75 px-3 py-2.5 text-center text-[14px] font-medium text-white no-underline hover:bg-premium`,children:[`$`,e.yearly.charged_usd,` / year`]}),(0,I.jsxs)(`a`,{href:e.lifetime?.url,target:`_blank`,rel:`noreferrer`,onClick:t,className:`rounded-sm bg-premium-strong px-3 py-2.5 text-center text-[14px] font-medium text-white no-underline hover:brightness-110`,children:[`$`,e.lifetime?.charged_usd,` once`]})]}),(0,I.jsxs)(`div`,{className:`mt-2 grid grid-cols-2 gap-2 text-center text-[11px] leading-snug text-fg-faint`,children:[(0,I.jsx)(`span`,{children:`Every Premium feature, renews yearly`}),(0,I.jsx)(`span`,{children:`Every Premium feature, now and future — no renewal`})]})]}):(0,I.jsx)(`div`,{className:`h-[92px] text-[13px] text-fg-faint`,children:`…`})}function nt({feature:e,onClose:t}){let n=F(()=>N.premium(),[]).data,r=et[e];return(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]),(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 flex items-start justify-center bg-black/50 px-4 pt-[12vh]`,onClick:t,role:`dialog`,"aria-modal":`true`,"aria-label":`Caprock Premium`,children:(0,I.jsxs)(`div`,{className:`w-[440px] max-w-full rounded-[var(--radius-panel)] border border-border-strong bg-panel`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`flex items-start gap-3 px-5 pt-4`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`p`,{className:`text-[11px] uppercase tracking-wide text-premium-strong`,children:`Caprock Premium`}),(0,I.jsx)(`h2`,{className:`mt-1 text-[16px] font-medium leading-snug text-fg`,children:r.title})]}),(0,I.jsx)(`button`,{onClick:t,className:`-mr-1 ml-auto text-fg-muted hover:text-fg`,"aria-label":`Close`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`px-5 pt-3`,children:[(0,I.jsx)(`p`,{className:`text-[13px] leading-relaxed text-fg-muted`,children:r.body}),(0,I.jsx)(`ul`,{className:`mt-3 space-y-1.5`,children:r.points.map(e=>(0,I.jsxs)(`li`,{className:`flex gap-2 text-[13px] leading-snug text-fg`,children:[(0,I.jsx)(`span`,{"aria-hidden":!0,className:`text-premium-strong`,children:`·`}),(0,I.jsx)(`span`,{children:e})]},e))}),r.setup&&(0,I.jsx)(`p`,{className:`mt-2.5 text-[12px] text-fg-faint`,children:r.setup})]}),(0,I.jsx)(`div`,{className:`mt-4 border-t border-border px-5 py-4`,children:(0,I.jsx)(tt,{p:n,onClose:t})}),(0,I.jsx)(`footer`,{className:`border-t border-border px-5 py-3 text-[12px]`,children:(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(`a`,{href:n?.info_url??`https://caprock.dev/premium/`,target:`_blank`,rel:`noreferrer`,className:`whitespace-nowrap text-fg-muted no-underline hover:text-fg`,children:`Read more`}),(0,I.jsx)(`span`,{className:`whitespace-nowrap text-fg-faint`,children:`opens a new tab`}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-fg-muted hover:text-fg`,children:`Close`})]})}),(0,I.jsx)(`p`,{className:`border-t border-border px-5 py-2.5 text-[11px] leading-relaxed text-fg-faint`,children:`Everything Caprock does now stays free and Apache-2.0 — Premium only ever adds.`})]})})}function rt(){let[e,t]=(0,l.useState)(!1),n=F(()=>N.premium(),[],{live:!1,intervalMs:3e5});if(!n.data?.yearly?.url)return null;if(n.data.license?.active)return(0,I.jsx)(`span`,{className:`text-premium-strong`,children:`premium`});let r=n.data;return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`span`,{className:`inline-flex items-center overflow-hidden rounded-sm border border-premium/60`,children:[(0,I.jsxs)(`a`,{href:r.yearly.url,target:`_blank`,rel:`noreferrer`,className:`bg-premium px-2 py-0.5 text-white no-underline hover:brightness-110`,children:[`premium $`,r.yearly.charged_usd,`/yr`]}),(0,I.jsx)(`button`,{onClick:()=>t(!0),"aria-label":`What Premium includes`,title:`What Premium includes`,className:`px-1.5 py-0.5 text-premium-strong hover:bg-premium/10`,children:`›`})]}),e&&(0,I.jsx)(nt,{feature:`cap`,onClose:()=>t(!1)})]})}var it=`https://github.com/dspv/caprock`,at=`https://caprock.dev/teams`,ot=`https://caprock.dev/premium`,st=`caprock.footer.starred`;function ct(){let[e,t]=(0,l.useState)(()=>localStorage.getItem(st)===`1`);return(0,I.jsx)(`footer`,{className:`mt-6 border-t border-border`,children:(0,I.jsxs)(`div`,{className:`max-w-[1600px] mx-auto px-3 py-4 flex flex-wrap items-center gap-x-6 gap-y-3 text-[11px] text-fg-faint`,children:[(0,I.jsxs)(`a`,{href:at,target:`_blank`,rel:`noreferrer`,className:`group inline-flex items-center gap-2 no-underline`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted group-hover:text-fg`,children:`Want this for your team?`}),(0,I.jsx)(`span`,{className:`text-accent group-hover:text-accent-strong`,children:`Caprock for Teams →`})]}),(0,I.jsxs)(`span`,{className:`ml-auto inline-flex items-center gap-4`,children:[(0,I.jsx)(`a`,{href:ot,target:`_blank`,rel:`noreferrer`,className:`text-fg-muted hover:text-fg no-underline`,title:`A daily spend cap — Caprock pauses its own sessions when the day passes a limit you set`,children:`premium`}),!e&&(0,I.jsx)(`a`,{href:it,target:`_blank`,rel:`noreferrer`,onClick:()=>{localStorage.setItem(st,`1`),t(!0)},className:`text-fg-faint hover:text-fg no-underline`,title:`Opens GitHub in a new tab`,children:`★ star on GitHub`}),(0,I.jsx)(`a`,{href:`https://caprock.dev/blog`,target:`_blank`,rel:`noreferrer`,className:`text-fg-faint hover:text-fg no-underline`,children:`blog`}),(0,I.jsx)(`a`,{href:`https://caprock.dev/docs`,target:`_blank`,rel:`noreferrer`,className:`text-fg-faint hover:text-fg no-underline`,children:`docs`})]})]})})}var lt=[{route:{name:`now`},label:`Now`},{route:{name:`cost`},label:`Cost`},{route:{name:`history`},label:`Lifetime`},{route:{name:`notes`},label:`Answers`},{route:{name:`tasks`},label:`Tasks`}];function ut(e){switch(e.name){case`now`:return`Now`;case`session`:return`Session detail`;case`cost`:return`Cost`;case`history`:return`Lifetime`;case`tasks`:return`Tasks`;case`graph`:return`Graph`;case`notes`:return`Answers`;case`settings`:return`Status`}}function dt({route:e,children:t}){let n=f(),[r,i]=De(),a=t=>t.name===e.name||t.name===`now`&&e.name===`session`;return(0,I.jsxs)(`div`,{className:`min-h-screen flex flex-col`,children:[(0,I.jsxs)(`header`,{className:`h-10 border-b border-border bg-panel flex items-center px-3 gap-4 sticky top-0 z-10`,children:[(0,I.jsxs)(`a`,{href:`#/`,className:`flex items-center gap-2 text-fg no-underline hover:no-underline`,children:[(0,I.jsxs)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 32 32`,"aria-hidden":!0,children:[(0,I.jsx)(`path`,{d:`M6 22 L16 8 L26 22 Z`,fill:`none`,stroke:`var(--color-accent)`,strokeWidth:`3`,strokeLinejoin:`round`}),(0,I.jsx)(`rect`,{x:`6`,y:`22`,width:`20`,height:`3`,fill:`var(--color-accent)`})]}),(0,I.jsx)(`span`,{className:`font-medium tracking-wide text-[13px]`,children:`caprock`}),(0,I.jsx)(`span`,{className:`text-fg-faint text-[11px] hidden sm:inline`,children:`mission control`})]}),(0,I.jsx)(`nav`,{className:`inline-flex items-center gap-0.5 ml-2 rounded-md bg-panel-2 p-0.5`,children:lt.map(e=>(0,I.jsxs)(`a`,{href:g(e.route),"aria-current":a(e.route)?`page`:void 0,className:`px-2.5 py-1 rounded-[5px] text-[12px] no-underline hover:no-underline transition-colors ${a(e.route)?`bg-accent text-panel font-medium`:`text-fg hover:text-accent`}`,children:[e.label,e.phase&&(0,I.jsx)(`span`,{className:`ml-1 text-[9px] uppercase tracking-wider text-fg-faint`,children:e.phase})]},e.label))}),(0,I.jsxs)(`div`,{className:`ml-auto flex items-center gap-3 text-[11px] text-fg-muted`,children:[(0,I.jsx)(Ze,{}),(0,I.jsx)(rt,{}),(0,I.jsx)(Re,{screen:ut(e)}),(0,I.jsx)(pt,{state:n.conn,lastFrameAt:n.lastFrameAt}),(0,I.jsx)(Oe,{plan:r,onSave:i}),(0,I.jsx)(ft,{}),(0,I.jsx)(mt,{}),(0,I.jsx)(`a`,{href:`#/settings`,className:`text-fg-muted hover:text-fg no-underline`,children:`status`})]})]}),(0,I.jsx)(`main`,{className:`flex-1 p-3 max-w-[1600px] w-full mx-auto`,children:t}),(0,I.jsx)(ct,{})]})}function ft(){let[e,t]=k(),n=e===`dark`;return(0,I.jsx)(`button`,{type:`button`,onClick:t,title:n?`Switch to light theme`:`Switch to dark theme`,"aria-label":n?`Switch to light theme`:`Switch to dark theme`,className:`text-fg-muted hover:text-fg inline-flex items-center`,children:n?(0,I.jsxs)(`svg`,{width:`15`,height:`15`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,"aria-hidden":!0,children:[(0,I.jsx)(`circle`,{cx:`12`,cy:`12`,r:`4`}),(0,I.jsx)(`path`,{d:`M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M19.1 4.9l-1.4 1.4M6.3 17.7l-1.4 1.4`})]}):(0,I.jsx)(`svg`,{width:`15`,height:`15`,viewBox:`0 0 24 24`,fill:`currentColor`,"aria-hidden":!0,children:(0,I.jsx)(`path`,{d:`M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z`})})})}function pt({state:e,lastFrameAt:t}){let n=ie(1e3),r=e===`open`?`bg-ok`:e===`connecting`?`bg-warn`:`bg-danger`,i=e===`open`?`live · ${t?ee(t,n):`connected`}`:e===`connecting`?`connecting…`:`disconnected — reconnecting`;return(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,title:e===`open`?`Connected to the daemon. The time is when it last sent anything — on an idle machine that keeps counting up, which is normal.`:`WebSocket /v1/live`,children:[(0,I.jsx)(`span`,{className:`inline-block w-1.5 h-1.5 rounded-full ${r}`}),(0,I.jsx)(`span`,{className:`num`,children:i})]})}function mt(){let e=F(()=>N.status(),[],{live:!1,intervalMs:6e4}),t=F(()=>N.update().catch(()=>void 0),[],{live:!1,intervalMs:6e4}),[n,r]=(0,l.useState)(!1),[i,a]=(0,l.useState)(!1),o=e.data?.version;if(!o)return null;let s=/^v?\d+\.\d+\.\d+$/.test(o),c=s&&t.data?.update_available?t.data.latest:void 0;return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{onClick:()=>r(!0),className:c?`mono text-[11px] text-accent hover:text-accent-strong`:`mono text-[11px] text-fg-faint hover:text-fg`,title:c?`${c} is available — you are on ${o}`:`version and updates`,children:c?`${o} → ${c}`:s?o:`dev build`}),t.data?.notes&&(0,I.jsx)(`button`,{onClick:()=>a(!0),className:`text-[11px] text-fg-faint hover:text-accent`,title:`what changed in ${t.data.notes_for??`the latest release`}`,children:`what's new`}),n&&(0,I.jsx)(gt,{onClose:()=>r(!1)}),i&&t.data&&(0,I.jsx)(ht,{u:t.data,onClose:()=>a(!1)})]})}function ht({u:e,onClose:t}){return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 bg-black/50 flex items-start justify-center pt-[10vh] px-4`,onClick:t,children:(0,I.jsxs)(`div`,{className:`w-full max-w-[620px] max-h-[76vh] flex flex-col border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg`,onClick:e=>e.stopPropagation(),role:`dialog`,"aria-label":`What's new`,children:[(0,I.jsxs)(`div`,{className:`px-4 pt-3 pb-2 border-b border-border flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[15px] font-medium`,children:`What's new`}),e.notes_for&&(0,I.jsx)(`span`,{className:`mono text-[12px] text-accent`,children:e.notes_for}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-[16px] leading-none text-fg-faint hover:text-fg`,children:`×`})]}),(0,I.jsx)(`div`,{className:`overflow-y-auto px-4 py-3`,children:(0,I.jsx)(`pre`,{className:`whitespace-pre-wrap break-words font-sans text-[13px] leading-relaxed text-fg-muted`,children:e.notes})}),(0,I.jsx)(`div`,{className:`border-t border-border px-4 py-2.5`,children:(0,I.jsx)(`a`,{href:e.url??`https://github.com/dspv/caprock/releases/latest`,target:`_blank`,rel:`noopener noreferrer`,className:`text-[12px] text-fg-faint no-underline hover:text-accent`,children:`the full release on GitHub →`})})]})})}function gt({onClose:e}){let t=F(()=>N.status(),[],{live:!1,intervalMs:0}),n=F(()=>N.update().catch(()=>void 0),[],{live:!1,intervalMs:0}),[r,i]=(0,l.useState)(!1),[a,o]=(0,l.useState)(void 0),[s,c]=(0,l.useState)(``),[u,d]=(0,l.useState)(()=>ve()??me(navigator.userAgent,navigator.userAgentData?.platform)),[f,p]=(0,l.useState)(!1),m=a??n.data,h=t.data?.version??``,g=/^v?\d+\.\d+\.\d+$/.test(h),_=!f&&ge(m?.command,u)?he(m?.command)??(u===`windows`?`macos`:u):u,v=pe(_),y=be(m?.command,v),[b,x]=(0,l.useState)(void 0),S=v.find(e=>e.label===b)??y??v[0],C=e=>{d(e),p(!0),ye(e),x(void 0)},w=async()=>{i(!0);try{o(await N.checkUpdate())}catch{}finally{i(!1)}},ee=e=>{navigator.clipboard.writeText(e),c(e),setTimeout(()=>c(``),1600)};return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 bg-black/50 flex items-start justify-center pt-[10vh] px-4`,onClick:e,children:(0,I.jsxs)(`div`,{className:`w-full max-w-[560px] max-h-[80vh] overflow-y-auto border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg`,onClick:e=>e.stopPropagation(),role:`dialog`,"aria-label":`Version and updates`,children:[(0,I.jsxs)(`div`,{className:`px-4 pt-3 pb-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`span`,{className:`text-[15px] font-medium`,children:`Version`}),(0,I.jsx)(`button`,{onClick:e,className:`ml-auto text-[16px] leading-none text-fg-faint hover:text-fg`,children:`×`})]}),(0,I.jsxs)(`div`,{className:`p-4 grid gap-3.5`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2 text-[13px]`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`running`}),(0,I.jsx)(`span`,{className:`mono text-fg`,children:g?h:`${h} (local build)`}),m?.update_available&&(0,I.jsxs)(`span`,{className:`mono text-accent`,children:[`→ `,m.latest,` is out`]})]}),m?.enabled===!1?(0,I.jsxs)(`div`,{className:`text-[13px] text-fg-muted`,children:[`Release checks are off, so this copy never asks GitHub what the latest version is. Turn them on in`,` `,(0,I.jsx)(`a`,{href:`#/status`,onClick:e,className:`text-accent no-underline hover:text-accent-strong`,children:`status`}),`.`]}):m?.update_available?null:(0,I.jsx)(`div`,{className:`text-[13px] text-fg-muted`,children:m?.latest?`Up to date — ${m.latest} is the latest release.`:`No newer release found.`}),(0,I.jsxs)(`div`,{className:`grid gap-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-1`,children:[se.map(e=>(0,I.jsx)(`button`,{onClick:()=>C(e.id),className:`rounded-sm px-2.5 py-1 text-[12px] transition-colors ${_===e.id?`bg-accent text-panel font-medium`:`text-fg-muted hover:text-fg`}`,children:e.label},e.id)),v.length>1&&(0,I.jsx)(`span`,{className:`ml-auto flex items-center gap-1`,children:v.map(e=>(0,I.jsxs)(`button`,{onClick:()=>x(e.label),className:`rounded-sm px-2 py-1 text-[11px] transition-colors ${S.label===e.label?`text-accent`:`text-fg-faint hover:text-fg-muted`}`,title:e.label===y?.label?`how this copy appears to be installed`:void 0,children:[e.label,e.label===y?.label?` ·`:``]},e.label))})]}),(0,I.jsx)(`ol`,{className:`grid gap-2.5`,children:S.steps.map((e,t)=>(0,I.jsxs)(`li`,{className:`grid gap-1`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-faint`,children:t+1}),e.cmd?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`code`,{className:`mono flex-1 truncate rounded-sm border border-border bg-bg px-2 py-1.5 text-[13px] text-fg`,children:e.cmd}),(0,I.jsx)(`button`,{onClick:()=>ee(e.cmd),className:`shrink-0 rounded-md border border-accent/45 bg-accent/[0.08] px-2.5 py-1.5 text-[12px] text-accent hover:bg-accent/[0.16]`,children:s===e.cmd?`copied`:`copy`})]}):(0,I.jsx)(`a`,{href:m?.url??`https://github.com/dspv/caprock/releases/latest`,target:`_blank`,rel:`noopener noreferrer`,className:`flex-1 rounded-sm border border-border bg-bg px-2 py-1.5 text-[13px] text-accent no-underline hover:text-accent-strong`,children:`Open the release page →`})]}),(0,I.jsx)(`p`,{className:`pl-5 text-[11px] leading-relaxed text-fg-faint`,children:e.note})]},t))})]}),(0,I.jsx)(`div`,{className:`text-[11px] leading-relaxed text-fg-faint border-t border-border pt-3`,children:`Caprock does not update itself: it would have to overwrite its own binary while running, and where a package manager owns that binary, replacing it behind their back breaks the next upgrade.`}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(`button`,{onClick:w,disabled:r,className:`rounded-md border border-border px-3 py-1.5 text-[13px] text-fg-muted hover:text-fg disabled:opacity-50`,children:r?`checking…`:`check now`}),(0,I.jsx)(`a`,{href:m?.url??`https://github.com/dspv/caprock/releases/latest`,target:`_blank`,rel:`noopener noreferrer`,className:`text-[12px] text-fg-faint no-underline hover:text-accent`,children:`release notes →`})]})]})]})})}var _t=class extends l.Component{state={error:null};static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error(`[caprock ui]`,e,t.componentStack)}render(){return this.state.error?(0,I.jsxs)(`div`,{className:`border border-danger/50 bg-danger/10 rounded-[var(--radius-panel)] px-3 py-2 text-[12px]`,children:[(0,I.jsxs)(`div`,{className:`text-danger font-medium`,children:[this.props.label??`This view`,` failed to render`]}),(0,I.jsx)(`div`,{className:`mono text-fg-muted mt-1`,children:this.state.error.message}),(0,I.jsx)(`button`,{className:`mt-2 border border-border px-2 py-0.5 rounded-sm text-fg-muted hover:text-fg`,onClick:()=>this.setState({error:null}),children:`retry`})]}):this.props.children}};function L({title:e,center:t,right:n,children:r,className:i=``,onMouseEnter:a,onMouseLeave:o}){return(0,I.jsxs)(`section`,{className:`border border-border bg-panel rounded-[var(--radius-panel)] shadow-[var(--shadow-panel)] min-w-0 ${i}`,onMouseEnter:a,onMouseLeave:o,children:[(e||t||n)&&(0,I.jsxs)(`header`,{className:`relative flex items-center justify-between px-3 py-2 border-b border-border bg-panel-2/60 rounded-t-[var(--radius-panel)]`,children:[(0,I.jsx)(`h2`,{className:`text-[11px] uppercase tracking-[0.12em] text-fg-muted font-medium`,children:e}),t?(0,I.jsx)(`div`,{className:`absolute left-1/2 -translate-x-1/2`,children:t}):null,(0,I.jsx)(`div`,{className:`text-[11px] text-fg-muted`,children:n})]}),(0,I.jsx)(`div`,{children:r})]})}function R({label:e,value:t,sub:n,tone:r,size:i=`default`}){return(0,I.jsxs)(`div`,{className:`flex h-full flex-col px-3 py-2.5 min-w-0`,children:[(0,I.jsx)(`div`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:e}),(0,I.jsx)(`div`,{className:`num font-semibold tracking-[-0.01em] ${i===`hero`?`text-[34px] leading-[1.05]`:i===`compact`?`text-[17px] leading-tight`:`text-[24px] leading-[1.1]`} ${r===`ok`?`text-ok`:r===`warn`?`text-warn`:r===`danger`?`text-danger`:r===`info`?`text-info`:`text-fg`}`,children:t}),n&&(0,I.jsx)(`div`,{className:`mt-auto pt-1 text-[11px] text-fg-muted num truncate`,children:n})]})}var vt={working:`working`,idle:`idle`,"waiting-on-you":`waiting on you`,looping:`looping?`,error:`error`,ended:`ended`};function yt(e){switch(e){case`working`:return`ok`;case`idle`:return`warn`;case`waiting-on-you`:return`warn`;case`looping`:return`danger`;case`error`:return`danger`;case`ended`:return`muted`}}function bt({health:e}){let t=yt(e);return(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 border rounded-sm px-1.5 py-[1px] text-[11px] leading-4 ${t===`ok`?`text-ok border-ok/40 bg-ok/10`:t===`warn`?`text-warn border-warn/40 bg-warn/10`:t===`danger`?`text-danger border-danger/40 bg-danger/10`:`text-fg-muted border-border bg-panel-2`}`,children:[(0,I.jsx)(`span`,{className:`inline-block w-1.5 h-1.5 rounded-full ${t===`ok`?`bg-ok`:t===`warn`?`bg-warn`:t===`danger`?`bg-danger`:`bg-fg-faint`} ${e===`working`?`animate-pulse`:``}`}),vt[e]]})}function xt({values:e,width:t=120,height:n=24,tone:r=`info`}){if(e.length<2)return(0,I.jsx)(`svg`,{width:t,height:n,"aria-hidden":!0});let i=Math.max(...e,1e-9),a=Math.min(...e,0),o=i-a||1,s=t/(e.length-1),c=e.map((e,t)=>`${(t*s).toFixed(1)},${(n-(e-a)/o*(n-2)-1).toFixed(1)}`).join(` `),l=r===`ok`?`var(--color-ok)`:r===`warn`?`var(--color-warn)`:r===`danger`?`var(--color-danger)`:r===`accent`?`var(--color-accent)`:`var(--color-info)`;return(0,I.jsx)(`svg`,{width:t,height:n,viewBox:`0 0 ${t} ${n}`,className:`block`,"aria-hidden":!0,children:(0,I.jsx)(`polyline`,{fill:`none`,stroke:l,strokeWidth:`1.25`,points:c,vectorEffect:`non-scaling-stroke`})})}function z({title:e,children:t}){return(0,I.jsxs)(`div`,{className:`px-4 py-10 text-center`,children:[(0,I.jsx)(`div`,{className:`text-fg-muted`,children:e}),t&&(0,I.jsx)(`div`,{className:`text-[12px] text-fg-faint mt-1`,children:t})]})}function St({rows:e=3,className:t=``}){return(0,I.jsx)(`div`,{className:`px-3 py-2 grid gap-2 ${t}`,"aria-hidden":!0,children:Array.from({length:e},(e,t)=>(0,I.jsx)(`div`,{className:`h-3 rounded-sm bg-panel-2 skeleton-pulse`,style:{width:`${[92,74,83,61,88][t%5]}%`}},t))})}function Ct({command:e,className:t=``}){let[n,r]=(0,l.useState)(!1);return(0,I.jsx)(`button`,{className:`mono text-[12px] bg-panel-2 border border-border px-2 py-0.5 rounded-sm hover:border-border-strong text-fg text-left ${t}`,onClick:()=>{navigator.clipboard?.writeText(e).then(()=>{r(!0),window.setTimeout(()=>r(!1),1500)})},title:`copy to clipboard — run it in your terminal`,children:n?`copied`:`$ ${e}`})}var wt={edit:{label:`writing code`,title:`Turns that wrote to a file — Edit, Write, NotebookEdit.`},command:{label:`running commands`,title:`Turns that ran a shell command — builds, tests, git, anything through Bash. The command itself is free; what costs is the turn that issued it and read its output.`},read:{label:`reading and searching`,title:`Turns that read or searched the codebase — Read, Grep, Glob. The file contents enter the prompt and are billed, which is why reading is not free.`},web:{label:`web research`,title:`Turns that fetched or searched the web — WebFetch, WebSearch.`},mcp:{label:`MCP tools`,title:`Turns that called one of your own MCP integrations.`},other:{label:`other tools`,title:`Turns that called a tool in none of the categories above — subagents, task and skill control, and any tool Caprock does not yet know by name.`},none:{label:`no tool call`,title:`Turns that called no tool at all. They may have been reasoning, planning, answering a question or writing prose — Caprock records which tools ran, not what a turn was thinking, so it does not claim to know which.`}},Tt=`Each turn counts toward one kind of work, decided by the tools it called: writing a file wins over running a command, which wins over reading or searching, then web, then an MCP tool, then anything else. A turn that called no tool is counted as exactly that. Each turn goes whole to one row, never split, so the rows add up to the total exactly.`;function Et({summary:e}){let t=e,n=t?.work??[],r=t?.work_unlinked_calls??0,i=t?.tool_calls??0,a=r>0&&i>0&&r/i>.01;return(0,I.jsxs)(L,{title:`What it went on`,right:(0,I.jsx)(`span`,{title:Tt,children:`by cost`}),children:[t?n.length===0&&(0,I.jsx)(z,{title:`No priced turns in range`}):(0,I.jsx)(St,{rows:4}),(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:n.map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1`,title:wt[e.kind]?.title,children:wt[e.kind]?.label??e.kind}),(0,I.jsxs)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:[e.turns,` turns`]}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:S(e.cost_usd)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-faint w-14`,children:w(e.cost_pct)})]},e.kind))})}),a&&(0,I.jsxs)(`div`,{className:`mx-3 mb-2.5 text-[11px] text-warn`,children:[r.toLocaleString(),` tool calls in this range could not be matched to the turn that paid for them, so their cost is counted under “no tool call” rather than the work they actually did. Every other row is understated by up to that much.`]})]})}function Dt({summary:e}){let t=e?.work??[],n=e?.work_unlinked_calls??0,r=e?.tool_calls??0;if(t.length===0||r===0||n/r>.2)return null;let i=t.filter(e=>e.cost_pct>=1).slice(0,5);return i.length===0?null:(0,I.jsxs)(`div`,{className:`border-t border-border px-3 py-2.5`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:`what it went on`}),(0,I.jsx)(`a`,{href:`#/cost`,className:`text-[10px] text-fg-faint hover:text-accent no-underline`,children:`details →`})]}),(0,I.jsx)(`div`,{className:`mt-2 flex h-1.5 w-full overflow-hidden rounded-full bg-panel-2`,title:Tt,children:i.map((e,t)=>(0,I.jsx)(`span`,{className:`h-full`,style:{width:`${e.cost_pct}%`,background:`var(--color-accent)`,opacity:1-t*.17}},e.kind))}),(0,I.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-x-4 gap-y-1`,children:i.map((e,t)=>(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-1.5 text-[11px]`,children:[(0,I.jsx)(`span`,{className:`inline-block h-2 w-2 rounded-[2px] translate-y-[1px]`,style:{background:`var(--color-accent)`,opacity:1-t*.17}}),(0,I.jsx)(`span`,{className:`text-fg-muted`,title:wt[e.kind]?.title,children:wt[e.kind]?.label??e.kind}),(0,I.jsx)(`span`,{className:`num text-fg-faint`,children:w(e.cost_pct)})]},e.kind))})]})}var Ot=.62;function kt(e,t){return e?t===`tokens`?e.tokens??[]:e.cost??[]:[]}function At(e,t,n){let r=kt(e,t);if(!e||r.length===0)return[];let i=n>0?n:0;return r.map((t,n)=>{let r=Number.isFinite(t)&&t>0?t:0,a=i>0&&r>0?Math.min(1,r/i)**+Ot:0;return{value:r,at:e.from_ms+n*e.width_ms,height:a,empty:r<=0}})}function jt(e,t){let n=0;for(let r of e)for(let e of kt(r,t))Number.isFinite(e)&&e>n&&(n=e);return n}function Mt(e,t){let n=new Date(e);return t<864e5?n.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):n.toLocaleDateString([],{month:`short`,day:`numeric`})}function Nt(e){return e.split(`/`).filter(Boolean)}function Pt(e,t=3){let n=[],r=new Map,i=[],a=(e,t)=>{let n=r.get(e);if(n)return n;let o=Nt(e),s={path:e,name:o.length===0?`/`:o[o.length-1],depth:t,tokens:0,cost:0,turns:0,tokensPct:0,costPct:0,ownTokens:0,ownCost:0,ownTurns:0,ownTokensPct:0,ownCostPct:0,children:[],rolledUp:0};if(r.set(e,s),t===0)i.push(s);else{let e=t===1?`/`:`/`+o.slice(0,t-1).join(`/`);a(e,t-1).children.push(s)}return s};for(let r of e){if(r.unattributed||r.outside){n.push(r);continue}let e=Nt(r.path),i=e.length,o=Math.min(i,t),s=a(o===0?`/`:`/`+e.slice(0,o).join(`/`),o);s.ownTokens+=r.tokens,s.ownCost+=r.cost_usd,s.ownTurns+=r.turns,s.ownTokensPct+=r.tokens_pct,s.ownCostPct+=r.cost_pct,i>o&&s.rolledUp++;for(let t=0;t<=o;t++){let n=a(t===0?`/`:`/`+e.slice(0,t).join(`/`),t);n.tokens+=r.tokens,n.cost+=r.cost_usd,n.tokensPct+=r.tokens_pct,n.costPct+=r.cost_pct,n.turns+=r.turns}}let o=i[0],s=i;o&&o.path===`/`&&(s=[...o.children],(o.ownTokens>0||o.ownCost>0||o.ownTurns>0||o.rolledUp>0)&&s.push({...o,depth:1,tokens:o.ownTokens,cost:o.ownCost,turns:o.ownTurns,tokensPct:o.ownTokensPct,costPct:o.ownCostPct,children:[],ownTokens:o.ownTokens,ownCost:o.ownCost,ownTurns:o.ownTurns}));let c=e=>{e.sort((e,t)=>t.cost-e.cost);for(let t of e)c(t.children)};return c(s),{roots:s,buckets:n}}function Ft(e){return e.map(e=>{let t=e;for(;t.children.length===1&&t.ownTokens===0&&t.ownCost===0&&t.ownTurns===0&&t.rolledUp===0;)t=t.children[0];return{...t,children:Ft(t.children)}})}var It=[{key:`all`,label:`all`},{key:`claude`,label:`claude`},{key:`opencode`,label:`opencode`}],Lt=[{key:`today`,label:`today`},{key:`7d`,label:`7d`},{key:`30d`,label:`30d`},{key:`all`,label:`all`}],Rt=`tokens`,zt=`A turn counts toward the directory of the most recent file it touched, and keeps counting there until it touches a file somewhere else — so the commands, tests and searches between two edits count toward the directory being worked on. Reading, editing or writing a file counts as touching it; running a command does not. Each turn goes whole to one row, never split between two, so the rows add up to the repository total exactly.`,Bt=`repository-wide work`,Vt=`Turns from the start of a session, before Claude had touched any file — so there is no directory yet for them to count toward. Their cost is counted here whole rather than guessed onto the directory the session reached later.`,Ht=`outside the repository`,Ut=`Turns whose most recent file touch was outside this repository — Claude’s notes on the project, agent scratchpads, test-output directories, or another checkout. This is real work and it counts toward the repository total, but it happened outside the tree, so it is not charged to any directory inside it.`;function Wt({sessions:e,agent:t}){let[n,r]=(0,l.useState)(`7d`),[i,a]=(0,l.useState)(!1),o=F(()=>N.summary(n),[n],{intervalMs:3e4}),s=o.data?.projects??[],c=(0,l.useMemo)(()=>t===`all`?s:s.filter(e=>!e.agent||e.agent===t),[s,t]),[u,d]=(0,l.useState)(null),f=(0,l.useMemo)(()=>{if(!u)return c;let e=new Map(u.map((e,t)=>[e,t]));return[...c].sort((t,n)=>(e.get(t.project)??1/0)-(e.get(n.project)??1/0))},[c,u]),p=i?f:f.slice(0,6),m=c.reduce((e,t)=>e+t.cost_usd,0),h=c.reduce((e,t)=>e+t.tokens,0),g=(0,l.useMemo)(()=>jt(p.map(e=>e.spark),Rt),[p]),_=(0,l.useMemo)(()=>p.reduce((e,t)=>Math.max(e,t.tokens),0),[p]);return(0,I.jsx)(L,{onMouseEnter:()=>d(c.map(e=>e.project)),onMouseLeave:()=>d(null),title:`Projects`,right:(0,I.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,I.jsxs)(`span`,{className:`num text-[13px]`,children:[(0,I.jsx)(`span`,{className:`text-fg`,children:C(h)}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[` · `,S(m),` total`]})]}),(0,I.jsx)(`span`,{className:`inline-flex border border-border rounded-sm overflow-hidden`,children:Lt.map(e=>(0,I.jsx)(`button`,{onClick:()=>r(e.key),className:`px-1.5 py-0.5 text-[11px] mono ${n===e.key?`bg-panel-2 text-fg`:`text-fg-faint hover:text-fg-muted`}`,children:e.label},e.key))})]}),children:o.data?c.length===0?(0,I.jsx)(`div`,{className:`px-3 py-4 text-[12px] text-fg-muted`,children:`No spend captured in this range yet.`}):(0,I.jsxs)(`div`,{className:`grid`,children:[p.map(t=>(0,I.jsx)(Kt,{p:t,max:_,ceiling:g,live:Gt(e).has(t.project)},t.project||`(unknown)`)),c.length>6&&(0,I.jsx)(`button`,{onClick:()=>a(e=>!e),className:`text-[11px] text-fg-faint hover:text-fg-muted px-3 py-1.5 text-left border-t border-border`,children:i?`show less`:`show all ${c.length} projects`}),(0,I.jsx)(Dt,{summary:o.data}),(0,I.jsx)(Zt,{count:c.length})]}):(0,I.jsx)(St,{rows:5})})}function Gt(e){return new Set(e.filter(e=>e.status!==`ended`).map(e=>e.project).filter(Boolean))}function Kt({p:e,max:t,ceiling:n,live:r}){let i=e.paths??[],a=i.length>1,[o,s]=(0,l.useState)(!1),c=e.project||`unknown project`,u=t>0?100*e.tokens/t:0,d=(0,l.useMemo)(()=>At(e.spark,Rt,n),[e.spark,n]),f=(0,l.useMemo)(()=>{let e=Pt(i);return{roots:Ft(e.roots),buckets:e.buckets}},[i]),p=(0,l.useMemo)(()=>Math.max(0,...f.roots.map(e=>e.tokens),...f.buckets.map(e=>e.tokens)),[f]),m=(0,I.jsxs)(`div`,{className:`grid grid-cols-[1fr_128px_auto] items-center gap-3 w-full text-left`,children:[(0,I.jsx)(`div`,{className:`min-w-0`,children:(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[r&&(0,I.jsx)(`span`,{className:`inline-block w-1.5 h-1.5 rounded-full bg-ok shrink-0`,title:`a session is live in this project`}),(0,I.jsx)(`span`,{className:`truncate text-[14px]`,children:c}),e.agent===`opencode`&&(0,I.jsx)(`span`,{className:`shrink-0 text-[9px] uppercase tracking-[0.08em] text-fg-faint border border-border px-1 rounded-sm`,children:`oc`}),(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-faint num shrink-0`,children:[e.sessions,` `,e.sessions===1?`session`:`sessions`]}),a&&(0,I.jsx)(`span`,{"aria-hidden":!0,className:`text-[9px] text-fg-faint shrink-0 transition-transform ${o?`rotate-90`:``}`,children:`▶`})]})}),d.length>0?(0,I.jsx)(Xt,{bars:d,widthMs:e.spark?.width_ms??0,label:c}):(0,I.jsx)(`div`,{className:`h-1 bg-panel-2 rounded-sm overflow-hidden`,title:`${c}: share of the largest project`,children:(0,I.jsx)(`div`,{className:`h-full bg-accent/70`,style:{width:`${u}%`}})}),(0,I.jsxs)(`div`,{className:`text-right shrink-0`,children:[(0,I.jsx)(`div`,{className:`num text-[17px] font-semibold leading-tight text-accent`,children:C(e.tokens)}),(0,I.jsx)(`div`,{className:`num text-[13px] leading-tight text-fg-muted`,children:S(e.cost_usd)})]})]});return(0,I.jsxs)(`div`,{className:`border-t border-border first:border-t-0`,children:[a?(0,I.jsx)(`button`,{type:`button`,onClick:()=>s(e=>!e),"aria-expanded":o,className:`w-full px-3 py-1.5 hover:bg-panel-2/50`,title:`${c}: show cost by directory`,children:m}):(0,I.jsx)(`div`,{className:`px-3 py-1.5`,children:m}),a&&o&&(0,I.jsxs)(`div`,{className:`pb-1.5 bg-panel-2/30`,children:[(0,I.jsx)(`div`,{className:`pl-7 pr-3 pt-1 pb-0.5 text-[10px] text-fg-faint`,title:zt,children:`by files touched · share of this repository's tokens`}),f.roots.map(e=>(0,I.jsx)(qt,{n:e,max:p},e.path)),f.buckets.length>0&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`div`,{className:`pl-7 pr-3 pt-2 pb-0.5 text-[10px] uppercase tracking-[0.08em] text-fg-faint`,children:`not a directory`}),f.buckets.map(e=>(0,I.jsx)(Jt,{q:e,max:p},e.path))]})]})]})}function qt({n:e,max:t}){let[n,r]=(0,l.useState)(!1),i=t>0?100*e.tokens/t:0,a=e.children.length>0,o=(0,l.useMemo)(()=>Math.max(0,...e.children.map(e=>e.tokens)),[e.children]),s=a&&e.ownCost>0,c=e.children.length,u=(0,I.jsxs)(`div`,{className:`grid grid-cols-[1fr_auto] items-center gap-3 w-full text-left`,children:[(0,I.jsxs)(`div`,{className:`min-w-0`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`truncate text-[12px] text-fg-muted mono`,children:e.path}),e.rolledUp>0&&(0,I.jsxs)(`span`,{className:`text-[10px] text-fg-faint shrink-0`,title:`${e.rolledUp} ${e.rolledUp===1?`directory`:`directories`} below this one ${e.rolledUp===1?`is`:`are`} counted here rather than shown: the breakdown stops at 3 levels.`,children:[`+`,e.rolledUp,` deeper`]}),(0,I.jsxs)(`span`,{className:`text-[10px] text-fg-faint num shrink-0`,children:[e.turns,` `,e.turns===1?`turn`:`turns`]}),a&&(0,I.jsx)(`span`,{"aria-hidden":!0,className:`text-[9px] text-fg-faint shrink-0 transition-transform ${n?`rotate-90`:``}`,children:`▶`})]}),s&&(0,I.jsxs)(`div`,{className:`text-[10px] text-fg-faint mt-0.5`,children:[S(e.ownCost),` here · `,S(e.cost-e.ownCost),` in `,c,` `,c===1?`subdirectory`:`subdirectories`]}),(0,I.jsx)(`div`,{className:`h-0.5 mt-1 bg-panel-2 rounded-sm overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full bg-accent/40`,style:{width:`${i}%`}})})]}),(0,I.jsxs)(`div`,{className:`text-right shrink-0 num text-[12px]`,title:`${Yt(e.costPct)} of this repository's cost`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:C(e.tokens)}),(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` `,Yt(e.tokensPct)]}),(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` · `,S(e.cost)]})]})]}),d={paddingLeft:`${28+(e.depth-1)*14}px`};return(0,I.jsxs)(`div`,{children:[a?(0,I.jsx)(`button`,{type:`button`,onClick:()=>r(e=>!e),"aria-expanded":n,className:`w-full pr-3 py-1 hover:bg-panel-2/50`,style:d,title:`${e.path}: show the directories inside it`,children:u}):(0,I.jsx)(`div`,{className:`pr-3 py-1`,style:d,children:u}),a&&n&&e.children.map(e=>(0,I.jsx)(qt,{n:e,max:o},e.path))]})}function Jt({q:e,max:t}){let n=t>0?100*e.tokens/t:0,r=e.unattributed===!0;return(0,I.jsxs)(`div`,{className:`grid grid-cols-[1fr_auto] items-center gap-3 pl-7 pr-3 py-1`,children:[(0,I.jsxs)(`div`,{className:`min-w-0`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`truncate text-[12px] text-fg-muted`,title:r?Vt:Ut,children:r?Bt:Ht}),(0,I.jsxs)(`span`,{className:`text-[10px] text-fg-faint num shrink-0`,children:[e.turns,` `,e.turns===1?`turn`:`turns`]})]}),(0,I.jsx)(`div`,{className:`h-0.5 mt-1 bg-panel-2 rounded-sm overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full bg-fg-faint/30`,style:{width:`${n}%`}})})]}),(0,I.jsxs)(`div`,{className:`text-right shrink-0 num text-[12px]`,title:`${Yt(e.cost_pct)} of this repository's cost`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:C(e.tokens)}),(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` `,Yt(e.tokens_pct)]}),(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` · `,S(e.cost_usd)]})]})]})}function Yt(e){return!Number.isFinite(e)||e<=0?`0%`:e<.1?`<0.1%`:w(e)}function Xt({bars:e,widthMs:t,label:n}){let r=(0,l.useRef)(null);(0,l.useEffect)(()=>{let t=r.current;if(!t)return;let n=()=>{let n=t.clientWidth,r=t.clientHeight;if(n===0||r===0)return;let i=window.devicePixelRatio||1;t.width=Math.round(n*i),t.height=Math.round(r*i);let a=t.getContext(`2d`);if(!a)return;a.setTransform(i,0,0,i,0,0),a.clearRect(0,0,n,r);let o=getComputedStyle(t),s=o.getPropertyValue(`--color-accent`).trim()||`#feb157`,c=o.getPropertyValue(`--color-fg-faint`).trim()||`#837f78`,l=n/e.length;for(let t=0;ti.disconnect()},[e]);let i=e.filter(e=>!e.empty),a=i[0],o=i[i.length-1],s=!a||!o?`no spend in this range`:a===o?`all of it on ${Mt(a.at,t)}`:`${Mt(a.at,t)} → ${Mt(o.at,t)}`;return(0,I.jsx)(`canvas`,{ref:r,className:`w-full h-[14px] block`,role:`img`,"aria-label":`${n}: ${Rt} over time, ${s}`,title:`${n}: when the spend happened — ${s}`})}function Zt({count:e}){return e<10?null:(0,I.jsxs)(`a`,{href:`https://caprock.dev/teams`,target:`_blank`,rel:`noreferrer`,className:`flex items-baseline gap-2 border-t border-border px-3 py-1.5 text-[11px] no-underline hover:no-underline`,children:[(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[e,` repositories on one machine.`]}),(0,I.jsx)(`span`,{className:`text-fg-faint hover:text-accent`,children:`See them across the team →`})]})}function Qt(e){return typeof e==`string`?e:``}function $t(e){let t=e.split(/[/\\]/).filter(Boolean);return t[t.length-1]??e}function en(e,t){let n=e.replace(/\s+/g,` `).trim(),r=[...n];return r.length>t?r.slice(0,t-1).join(``)+`…`:n}function tn(e){return e.replace(/(\/[\w.@%+-]+){3,}/g,e=>`…/`+e.split(`/`).filter(Boolean).slice(-2).join(`/`))}function nn(e,t){switch(e){case`Edit`:case`NotebookEdit`:return Qt(t.file_path)?{icon:`✎`,text:`editing`,detail:$t(Qt(t.file_path))}:null;case`Write`:return Qt(t.file_path)?{icon:`✎`,text:`writing`,detail:$t(Qt(t.file_path))}:null;case`Read`:return Qt(t.file_path)?{icon:`◇`,text:`reading`,detail:$t(Qt(t.file_path))}:null;case`Bash`:return Qt(t.command)?{icon:`$`,text:`running`,detail:en(tn(Qt(t.command)),46)}:null;case`Grep`:case`Glob`:return{icon:`⌕`,text:`searching`,detail:en(Qt(t.pattern)||Qt(t.query),40)||void 0};case`WebFetch`:case`WebSearch`:return{icon:`⇢`,text:`fetching`,detail:en(Qt(t.url)||Qt(t.query),44)||void 0};case`Agent`:return{icon:`⚑`,text:`spawned a subagent`,detail:Qt(t.subagent_type)||void 0};case`Skill`:return{icon:`⚑`,text:`invoked skill`,detail:Qt(t.skill)||void 0};case`TodoWrite`:return{icon:`☑`,text:`updated its plan`};default:return e?{icon:`·`,text:`used`,detail:e}:null}}function rn(e,t){let n=e.payload??{},r=Date.parse(e.ts),i={id:`${e.id}`,ts:Number.isNaN(r)?Date.now():r,sessionId:e.session_id,project:t};switch(e.kind){case`tool.pre`:{let t=nn(Qt(n.tool_name)||Qt(e.tool),n.tool_input??{});return t?{...i,...t,tone:`normal`}:null}case`tool.post`:return n.is_error?{...i,icon:`✕`,text:`a tool call failed`,tone:`danger`}:null;case`agent.spawn`:return{...i,icon:`▸`,text:`session started`,tone:`ok`};case`agent.stop`:return{...i,icon:`■`,text:`session ended`,tone:`normal`};case`context.compact`:return{...i,icon:`⇱`,text:`compacted its context`,tone:`warn`};case`throttle`:return{...i,icon:`⏳`,text:`rate-limited by the API`,tone:`warn`};case`task.created`:return{...i,icon:`+`,text:`task created`,tone:`normal`};case`task.done`:return{...i,icon:`✓`,text:`task verified — tests passed`,tone:`ok`};case`approval.requested`:return{...i,icon:`!`,text:`needs your approval`,tone:`warn`};default:return null}}function an(e,t,n=60){return e.some(e=>e.id===t.id)?e:[t,...e].slice(0,n)}function on({sessions:e,now:t,emptyHint:n}){let[r,i]=(0,l.useState)([]),[a,o]=(0,l.useState)(!1),s=(0,l.useRef)(new Map),c=(0,l.useRef)(a);c.current=a;for(let t of e)t.project&&s.current.set(t.session_id,t.project);(0,l.useEffect)(()=>{let t=!1;return(async()=>{let n=[...e].sort((e,t)=>t.last_event_at-e.last_event_at).slice(0,4),r=await Promise.all(n.map(e=>N.events(e.session_id,0,60).catch(()=>[])));if(t)return;let a=r.flat().map(e=>rn(e)).filter(e=>e!==null).sort((e,t)=>t.ts-e.ts).slice(0,40);i(e=>{let t=new Set(n.map(e=>e.session_id)),r=e.filter(e=>!e.sessionId||t.has(e.sessionId)),i=new Set(r.map(e=>e.id));return[...r,...a.filter(e=>!i.has(e.id))].sort((e,t)=>t.ts-e.ts).slice(0,60)})})(),()=>{t=!0}},[e.map(e=>e.session_id).join(`,`)]);let u=(0,l.useRef)(new Set);return u.current=new Set(e.map(e=>e.session_id)),(0,l.useEffect)(()=>d.onFrame(e=>{if(e.type!==`event`||c.current)return;let t=e.data?.session_id;if(t&&s.current.has(t)&&!u.current.has(t))return;let n=rn(e.data);n&&i(e=>an(e,n))}),[]),(0,I.jsx)(L,{title:`Live activity`,right:(0,I.jsx)(`button`,{onClick:()=>o(e=>!e),className:`text-[11px] mono text-fg-faint hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,children:a?`resume`:`pause`}),children:r.length===0?(0,I.jsx)(`div`,{className:`px-3 py-4 text-[12px] text-fg-muted`,children:n??(0,I.jsxs)(I.Fragment,{children:[`Nothing yet — start `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` in any terminal.`]})}):(0,I.jsxs)(`div`,{className:`relative`,children:[(0,I.jsx)(`div`,{className:`max-h-[420px] overflow-y-auto`,children:r.map(e=>(0,I.jsx)(cn,{it:e,now:t,project:s.current.get(e.sessionId)},e.id))}),(0,I.jsx)(`div`,{className:`pointer-events-none absolute inset-x-0 bottom-0 h-8 bg-gradient-to-t from-panel to-transparent`})]})})}function sn(e){switch(e){case`ok`:return`text-ok`;case`warn`:return`text-warn`;case`danger`:return`text-danger`;default:return`text-fg-faint`}}function cn({it:e,now:t,project:n}){return(0,I.jsxs)(`a`,{href:g({name:`session`,id:e.sessionId}),className:`grid grid-cols-[auto_auto_1fr_auto] items-baseline gap-2 px-3 py-1 border-t border-border first:border-t-0 hover:bg-panel-2 no-underline text-fg`,children:[(0,I.jsx)(`span`,{className:`mono text-[12px] w-3 text-center ${sn(e.tone)}`,children:e.icon}),(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-muted truncate max-w-[12ch]`,children:n??e.project??T(e.sessionId)}),(0,I.jsxs)(`span`,{className:`text-[12px] truncate`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:e.text}),e.detail&&(0,I.jsx)(`span`,{className:`mono text-fg ml-1.5`,children:e.detail})]}),(0,I.jsx)(`span`,{className:`num text-[11px] text-fg-faint`,children:ee(e.ts,t)})]})}function ln(e){return e?.plan_kind===`metered`?`at API list price · ≈ your bill`:e?.plan_kind===`flat`?`at API list price · not a bill`:`at API list price`}function un(e){return e?.plan_kind===`metered`?`Priced from your captured tokens at Anthropic list prices. You are billed per token, so this is approximately your actual cost.`:e?.plan_kind===`flat`?`Priced from your captured tokens at Anthropic list prices. You pay ${e.plan_label||`a flat plan`}, so this is what the same work would have cost through the API — not money out of pocket.`:`Priced from your captured tokens at Anthropic list prices. Whether that is your actual bill depends on how you pay — set your plan in the header.`}function dn({plan:e}){let t=F(()=>N.history(`all`),[],{intervalMs:6e4}).data?.totals;if(!t||t.sessions===0)return null;let n=t.days>0?t.sessions/t.days:0;return(0,I.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-6 gap-y-1 rounded-[var(--radius-panel)] border border-border bg-panel px-3 py-2.5`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:`all time`}),(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num font-semibold tracking-[-0.01em] text-[22px] leading-none text-info`,children:S(t.cost_usd)}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,title:un(e),children:ln(e)})]}),(0,I.jsx)(fn,{value:t.sessions.toLocaleString(`en-US`),label:`sessions`}),(0,I.jsx)(fn,{value:t.days.toLocaleString(`en-US`),label:`active days`}),(0,I.jsx)(fn,{value:t.turns.toLocaleString(`en-US`),label:`turns`}),n>=1&&(0,I.jsx)(fn,{value:n.toFixed(1),label:`sessions a day`}),(0,I.jsx)(`span`,{className:`ml-auto inline-flex items-baseline gap-4`,children:(0,I.jsx)(pn,{})})]})}function fn({value:e,label:t}){return(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-1.5`,children:[(0,I.jsx)(`span`,{className:`num text-[13px] text-fg`,children:e}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:t})]})}function pn(){let e=F(()=>N.daily(30),[],{intervalMs:3e5}),t=F(()=>N.summary(`today`),[],{intervalMs:3e4}),n=e.data??[];if(n.length===0)return null;let r=new Map;for(let e of n)r.set(e.day,(r.get(e.day)??0)+e.cost_usd);let i=[...r.values()].filter(e=>e>0).sort((e,t)=>e-t);if(i.length<7)return null;let a=i[Math.floor(i.length/2)]??0,o=t.data?.cost_usd??0;return a<=0||o=99?{label:`outstanding`,color:`text-ok`}:e>=95?{label:`good`,color:`text-ok`}:e>=85?{label:`ok`,color:``}:{label:`low`,color:`text-warn`}}function hn({hitRate:e,cutPct:t,measured:n,size:r=`compact`,label:i=`Cache hit`}){let a=n&&e!==void 0?e*100:void 0,o=mn(a);return(0,I.jsx)(R,{label:i,value:(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{children:a===void 0?`—`:w(a)}),o&&(0,I.jsx)(`span`,{className:`text-[11px] font-normal ${o.color||`text-fg-faint`}`,children:o.label})]}),sub:n&&t!==void 0?`${w(t)} input cost cut`:void 0,size:r})}function gn(e,t){let n=Math.round(e.used_percentage),r=(e.resets_at??0)*1e3,i=r>t&&r85?`text-danger`:n>=60?`text-warn`:`text-fg`,resetsAt:i?new Date(r).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):null,stale:e.resets_at?!i:!1}}function _n({label:e,w:t,now:n}){let{pct:r,color:i,resetsAt:a,stale:o}=gn(t,n);return(0,I.jsxs)(`div`,{className:`flex items-baseline justify-between gap-3 text-sm`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:e}),(0,I.jsxs)(`span`,{className:`flex items-baseline gap-3`,children:[(0,I.jsxs)(`span`,{className:`font-mono tabular-nums ${i}`,children:[r,`%`]}),a&&(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[`resets `,a]}),o&&(0,I.jsx)(`span`,{className:`text-fg-faint`,title:`Claude Code has not refreshed this window recently`,children:`reset time stale`}),t.forecast&&(0,I.jsx)(`span`,{className:`text-warn`,children:t.forecast})]})]})}function vn({limits:e,now:t}){let n=[];if(e?.five_hour&&n.push([`5h`,e.five_hour]),e?.seven_day&&n.push([`7d`,e.seven_day]),n.length===0)return null;let r=n.map(([e,n])=>({label:e,...gn(n,t)})),i=r.filter(e=>!e.stale),a=i.length===0,o=(i.length?i:r).reduce((e,t)=>t.pct>e.pct?t:e),s=r.find(e=>e.label!==o.label);return(0,I.jsx)(R,{label:`Plan limits`,value:(0,I.jsxs)(`span`,{className:a?`text-fg-faint`:o.color,children:[o.pct,`%`]}),sub:a?(0,I.jsx)(`span`,{title:`Claude Code writes these to its status line; they stop updating when no session is running`,children:`last reported a while ago`}):(0,I.jsxs)(`span`,{children:[o.label,` window`,o.resetsAt?` · resets ${o.resetsAt}`:``,s?` · ${s.label} ${s.pct}%`:``]}),tone:a?void 0:o.pct>85?`danger`:o.pct>=60?`warn`:void 0,size:`compact`})}var yn=`caprock-prompts`,bn={"share-week":6048e5,"share-month":2592e6,"premium-hint":2592e6,"premium-banner":2592e6};function xn(){try{let e=localStorage.getItem(yn);return e?JSON.parse(e):{}}catch{return{}}}function Sn(e){try{localStorage.setItem(yn,JSON.stringify(e))}catch{}}function Cn(e,t){let n=xn()[e];return!n||t-n>=bn[e]}function wn(e,t){let n={...xn(),[e]:t};e===`share-month`&&(n[`share-week`]=t),Sn(n)}var Tn=`premium-banner`;function En({costUSD:e,days:t,now:n}){let[r]=(0,l.useState)(()=>Cn(Tn,n)),[i,a]=(0,l.useState)(!1),[o,s]=(0,l.useState)(!1);if(!r||i||e<=0||t<=0)return null;let c=e/t;return(0,I.jsxs)(`div`,{className:`flex items-center gap-3 rounded-[var(--radius-panel)] border border-border bg-panel-2 px-3 py-2 text-[12px]`,children:[(0,I.jsxs)(`span`,{className:`text-fg`,children:[(0,I.jsx)(`span`,{className:`num`,children:S(c)}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[` a day, on average, across `,t,` active `,t===1?`day`:`days`,`.`]})]}),(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`Premium pauses sessions when the day crosses a limit you set.`}),(0,I.jsxs)(`span`,{className:`ml-auto flex shrink-0 items-center gap-2`,children:[(0,I.jsx)(`button`,{onClick:()=>s(!0),className:`rounded-sm border border-accent/50 bg-accent/10 px-2 py-0.5 text-accent hover:bg-accent/20`,children:`what it does`}),(0,I.jsx)(`button`,{onClick:()=>{wn(Tn,n),a(!0)},className:`rounded-sm border border-border px-1.5 py-0.5 text-[11px] text-fg-faint hover:text-fg-muted`,title:`hide this for a month`,children:`not now`})]}),o&&(0,I.jsx)(nt,{feature:`cap`,onClose:()=>s(!1)})]})}var Dn=[1e3,5e3,1e4,25e3,5e4,1e5],On=e=>e>=1e3?`$${Math.round(e).toLocaleString(`en-US`)}`:`$${e.toFixed(2)}`;function kn(e){let t=Dn.filter(t=>e>=t).pop();return t===void 0||e-t>t*.1?null:{kind:`milestone`,line:`You just passed ${On(t)} of Claude Code.`}}function An(e,t){return e<7||e>10?null:{kind:`first-week`,line:`A week of Claude Code: ${On(t)} measured.`}}function jn(e){if(e.length<3)return null;let[t,...n]=e;if(t===void 0)return null;let r=Math.max(...n);return r<=0||tt[0].localeCompare(e[0])),r=[];for(let e=0;ee+t[1],0));return r}function Nn(e,t,n){return e.sessions===0||e.cost_usd<=0?null:kn(e.cost_usd)??An(e.days,n.cost_usd)??jn(Mn(t))}var Pn=`share-week`;function Fn({now:e}){let[t]=(0,l.useState)(()=>Cn(Pn,e)),[n,r]=(0,l.useState)(!1),[i,a]=(0,l.useState)(!1),o=F(()=>N.history(`all`),[],{intervalMs:3e5}),s=F(()=>N.summary(`7d`),[],{intervalMs:3e5});if(!t||n||!o.data||!s.data)return null;let c=Nn(o.data.totals,o.data.daily??[],s.data);if(!c)return null;let u=()=>{wn(Pn,e),r(!0)};return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 rounded-lg border border-accent/35 bg-accent/[0.07] py-1.5 pl-3.5 pr-2 text-[13px]`,children:[(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[c.line,` Don’t be shy and share it off —`]}),(0,I.jsx)(`button`,{onClick:()=>{a(!0),u()},className:`rounded-[5px] bg-accent px-3 py-1 font-medium text-panel hover:bg-accent/90`,children:`Share`}),(0,I.jsx)(`button`,{onClick:u,title:`hide this for a week`,className:`px-1 text-fg-faint hover:text-fg-muted`,children:`✕`})]}),i&&(0,I.jsx)(Qe,{onClose:()=>a(!1)})]})}function In(){let e=F(()=>N.history(`all`),[],{intervalMs:6e4}),t=(e.data?.tools??[]).slice(0,6),n=(e.data?.summary?.models??[]).slice(0,5);if(t.length===0&&n.length===0)return null;let r=t[0]?.count??0,i=n[0]?.cost_usd??0,a=(e.data?.tools??[]).reduce((e,t)=>e+t.count,0),o=(e.data?.summary?.models??[]).reduce((e,t)=>e+t.cost_usd,0),s=e.data?.summary,c=s&&(s.tokens_in||s.tokens_out||s.cache_read||s.cache_write)?{in:s.tokens_in,out:s.tokens_out,cacheRead:s.cache_read,cacheWrite:s.cache_write}:null;return(0,I.jsxs)(L,{title:`All time`,right:(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-3`,children:[(0,I.jsx)(Fn,{now:Date.now()}),(0,I.jsx)($e,{}),(0,I.jsx)(`a`,{href:`#/history`,className:`text-fg-faint hover:text-accent no-underline`,children:`every tool, model and project →`})]}),children:[(0,I.jsxs)(`div`,{className:`grid gap-x-8 gap-y-5 px-3 py-3 md:grid-cols-2`,children:[(0,I.jsx)(Ln,{title:`Most-used tools`,note:`by calls`,rows:t.map(e=>({key:e.tool,label:ne(e.tool),value:e.count.toLocaleString(`en-US`),share:a>0?100*e.count/a:null,frac:r>0?e.count/r:0}))}),(0,I.jsx)(Ln,{title:`Where the money went`,note:`by cost`,rows:n.map(e=>({key:e.model,label:e.model||`unknown`,value:S(e.cost_usd),sub:C(e.tokens),share:o>0?100*e.cost_usd/o:null,frac:i>0?e.cost_usd/i:0}))})]}),c&&(0,I.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-6 gap-y-1 border-t border-border px-3 py-2 text-[11px]`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:`Tokens`}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`input `,(0,I.jsx)(`span`,{className:`num text-fg`,children:C(c.in)})]}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`output `,(0,I.jsx)(`span`,{className:`num text-fg`,children:C(c.out)})]}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`cache read `,(0,I.jsx)(`span`,{className:`num text-fg`,children:C(c.cacheRead)})]}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`cache write `,(0,I.jsx)(`span`,{className:`num text-fg`,children:C(c.cacheWrite)})]}),(0,I.jsx)(`span`,{className:`ml-auto text-fg-faint`,children:`fresh input is billed at full price`})]})]})}function Ln({title:e,note:t,rows:n}){return n.length===0?null:(0,I.jsxs)(`div`,{children:[(0,I.jsxs)(`div`,{className:`mb-2 flex items-baseline justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:e}),(0,I.jsx)(`span`,{className:`text-[10px] text-fg-faint`,children:t})]}),(0,I.jsx)(`div`,{className:`grid gap-1.5`,children:n.map(e=>(0,I.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px]`,children:[(0,I.jsx)(`span`,{className:`mono w-36 shrink-0 truncate text-fg-muted`,title:e.label,children:e.label}),(0,I.jsx)(`span`,{className:`h-1.5 flex-1 rounded-full bg-panel-2`,children:(0,I.jsx)(`span`,{className:`block h-full rounded-full bg-accent/70`,style:{width:`${Math.max(2,Math.round(e.frac*100))}%`}})}),(0,I.jsx)(`span`,{className:`num w-20 shrink-0 text-right text-fg`,children:e.value}),(0,I.jsx)(`span`,{className:`num w-16 shrink-0 text-right text-fg-faint`,children:e.sub??``}),(0,I.jsx)(`span`,{className:`num w-9 shrink-0 text-right text-fg-faint`,children:e.share===null?``:e.share<1?`<1%`:`${Math.floor(e.share)}%`})]},e.key))})]})}function Rn(e){return e.bars.reduce((e,t)=>e+t.n,0)}function zn(e){return e.bars.reduce((e,t)=>e+t.cost,0)}var Bn=6,Vn=new Set([`description`,`timeout`,`run_in_background`]),Hn=new Set([`true`,`:`,`echo`,`pwd`,`clear`]);function Un(e){if(typeof e==`string`)return e;if(e==null)return``;try{return JSON.stringify(e)}catch{return``}}function Wn(e){if(e.kind!==`tool.pre`)return null;let t=typeof e.tool==`string`?e.tool:``;if(!t)return null;let n=e.payload,r=n&&typeof n==`object`?n.tool_input:void 0,i=r&&typeof r==`object`?r:{},a=Un(i.command).trim();if(t===`Bash`&&Hn.has(a))return null;let o=[t],s=t;for(let e of Object.keys(i).sort()){if(Vn.has(e))continue;let n=Un(i[e]);(e===`content`||e===`new_string`||e===`old_string`)&&(n=n.slice(0,200)),o.push(`${e}=${n}`),s===t&&(e===`command`||e===`file_path`||e===`pattern`)&&(s=`${t} ${n.slice(0,48)}`)}return{sig:o.join(`|`),label:s}}function Gn(e){let t=Date.parse(e.ts);return Number.isFinite(t)?t:0}function Kn(e,t,n=60){let r=Array.from({length:n},()=>({n:0,turns:0,tools:0,cost:0})),i=t-n*6e4,a=[...e].sort((e,t)=>Gn(e)-Gn(t)),o=[],s=new Map,c=0,l=``;for(let e of a){let a=Gn(e);if(a<=0)continue;if(a>=i&&a<=t){let t=r[Math.min(n-1,Math.floor((a-i)/6e4))];if(t){t.n++,e.kind===`turn.assistant`?t.turns++:(e.kind===`tool.pre`||e.kind===`tool.post`)&&t.tools++;let n=typeof e.cost_usd==`number`&&Number.isFinite(e.cost_usd)?e.cost_usd:0;t.cost+=n}}let u=Wn(e);if(!u)continue;for(o.push({at:a,sig:u.sig,label:u.label});o.length>0;){let e=o[0];if(!e||a-e.at<=Bn*6e4)break;o.shift();let t=(s.get(e.sig)??1)-1;t<=0?s.delete(e.sig):s.set(e.sig,t)}let d=(s.get(u.sig)??0)+1;s.set(u.sig,d),d>c&&(c=d,l=u.label)}return{bars:r,repeats:c,repeatSample:l}}function qn(e,t){if(e.repeats>=8)return{kind:`repeat`,label:`×${e.repeats} same call`};switch(t){case`waiting-on-you`:return{kind:`waiting`,label:`waiting on you`};case`error`:return{kind:`error`,label:`error`};case`looping`:return{kind:`repeat`,label:`looping`};case`ended`:return{kind:`quiet`,label:`ended`};case`idle`:return{kind:`quiet`,label:`idle`};case`working`:return{kind:`working`,label:`working`}}return e.bars.filter(e=>e.n>0).length===0?{kind:`quiet`,label:`quiet`}:{kind:`working`,label:`working`}}function Jn(e,t){return t<=0?`mid`:e>=t*1.8?`high`:e<=t*.5?`low`:`mid`}function Yn(e){let t=e.filter(e=>e.cost>0).map(e=>e.cost).sort((e,t)=>e-t);return t.length===0?0:t[Math.floor(t.length/2)]??0}var Xn=6,Zn=2e3;function Qn({sessions:e,now:t}){let n=(0,l.useMemo)(()=>[...e].filter(e=>e.status!==`ended`).sort((e,t)=>t.last_event_at-e.last_event_at).slice(0,Xn),[e]),r=n.map(e=>e.session_id).join(`,`),[i,a]=(0,l.useState)(new Map);(0,l.useEffect)(()=>{let e=!1;return(async()=>{let t=r?r.split(`,`):[],n=await Promise.all(t.map(e=>N.recentEvents(e,Zn).catch(()=>[])));e||a(new Map(t.map((e,t)=>[e,n[t]??[]])))})(),()=>{e=!0}},[r]),(0,l.useEffect)(()=>d.onFrame(e=>{if(e.type!==`event`)return;let t=e.data;a(e=>{if(!e.has(t.session_id))return e;let n=new Map(e),r=n.get(t.session_id)??[];return n.set(t.session_id,[...r,t].slice(-4e3)),n})}),[]);let o=Math.floor(t/6e4),s=(0,l.useMemo)(()=>n.map(e=>({s:e,pulse:Kn(i.get(e.session_id)??[],o*6e4)})).filter(e=>Rn(e.pulse)>0),[n,i,o]);return n.length===0?null:(0,I.jsxs)(L,{title:`Live pulse`,right:(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-faint`,children:[`last `,60,` minutes · one bar per minute`]}),children:[(0,I.jsx)(`div`,{children:s.length===0?(0,I.jsxs)(`div`,{className:`px-3 py-6 text-[12px] text-fg-faint text-center`,children:[`Nothing ran in the last `,60,` minutes.`]}):s.map(({s:e,pulse:t})=>(0,I.jsx)(er,{s:e,pulse:t,minute:o,showId:s.length>1},e.session_id))}),(0,I.jsxs)(`div`,{className:`px-3 py-2 flex items-center gap-4 flex-wrap text-[11px] text-fg-faint border-t border-border`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,title:`They are independent: one call carrying a large context is a short bright bar, twenty greps are a tall dark one.`,children:`bar height = turns and tools · colour = what the minute cost`}),(0,I.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)($n,{tier:nr,className:`h-[2px]`}),`idle`]}),(0,I.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)($n,{tier:tr.low}),`below this session's median`]}),(0,I.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)($n,{tier:tr.mid}),`around it`]}),(0,I.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)($n,{tier:tr.high}),`well above it`]}),(0,I.jsxs)(`span`,{className:`ml-auto`,children:[(0,I.jsx)(`span`,{className:`text-warn`,children:`×N same call`}),` = most-repeated identical tool call in six minutes`]})]})]})}function $n({tier:e,className:t=``}){return(0,I.jsx)(`span`,{"data-token":e.token,className:`inline-block w-3 h-3 rounded-[2px] ${t}`,style:{background:`var(${e.token}, ${e.fallback})`,opacity:e.alpha}})}function er({s:e,pulse:t,minute:n,showId:r}){let i=qn(t,e.activity?.health),a=i.kind===`repeat`||i.kind===`waiting`?`text-warn`:i.kind===`error`?`text-danger`:i.kind===`quiet`?`text-fg-faint`:`text-ok`;return(0,I.jsxs)(`a`,{href:g({name:`session`,id:e.session_id}),className:`grid grid-cols-[132px_1fr_92px_104px] items-center gap-3 px-3 py-2 border-t border-border first:border-t-0 hover:bg-panel-2 no-underline text-fg`,children:[(0,I.jsxs)(`div`,{className:`min-w-0`,children:[(0,I.jsxs)(`div`,{className:`text-[13px] font-medium flex items-baseline gap-1.5 min-w-0`,children:[(0,I.jsx)(`span`,{className:`shrink-0`,children:e.project||`unknown project`}),e.git_branch&&(0,I.jsx)(`span`,{className:`min-w-0 truncate text-[10px] text-fg-faint mono`,title:e.git_branch,children:e.git_branch}),e.agent===`opencode`&&(0,I.jsx)(`span`,{className:`shrink-0 text-[9px] uppercase tracking-[0.08em] text-fg-faint border border-border px-1 rounded-sm`,children:`oc`})]}),(0,I.jsxs)(`div`,{className:`text-[10px] text-fg-faint mono truncate`,children:[r&&(0,I.jsxs)(`span`,{title:`session ${e.session_id} · started ${ee(e.started_at)} ago`,children:[T(e.session_id),` · `]}),e.activity?.phrase??``]})]}),(0,I.jsx)(ir,{pulse:t,now:n*6e4,sessionID:e.session_id}),(0,I.jsx)(`div`,{className:`num text-[13px] font-semibold text-right`,title:`${S(e.stats?.cost_usd)} for the whole session`,children:S(zn(t))}),(0,I.jsx)(`div`,{className:`text-[11px] text-right ${a}`,title:t.repeatSample,children:i.label})]})}var tr={low:{token:`--color-ok`,fallback:`#4fbf6b`,alpha:.55},mid:{token:`--color-accent`,fallback:`#feb157`,alpha:.85},high:{token:`--color-accent-strong`,fallback:`#ffcb85`,alpha:1}},nr={token:`--color-fg-faint`,fallback:`#837f78`,alpha:.3};function rr(e,t,n){return e.getPropertyValue(t).trim()||n}function ir({pulse:e,now:t,sessionID:n}){let r=(0,l.useRef)(null),[i,a]=(0,l.useState)(null);(0,l.useEffect)(()=>{let t=r.current;if(!t)return;let n=()=>{let n=t.clientWidth,r=t.clientHeight;if(n===0||r===0)return;let i=window.devicePixelRatio||1;t.width=Math.round(n*i),t.height=Math.round(r*i);let a=t.getContext(`2d`);if(!a)return;a.setTransform(i,0,0,i,0,0),a.clearRect(0,0,n,r);let o=getComputedStyle(t),s=rr(o,nr.token,nr.fallback),c=e.bars,l=Math.max(...c.map(e=>e.n),1),u=Yn(c),d=n/c.length;for(let e=0;e{i.disconnect(),a.disconnect()}},[e]);let o=t=>{let n=t.currentTarget.getBoundingClientRect();if(n.width===0)return;let r=Math.floor((t.clientX-n.left)/n.width*e.bars.length);a(r>=0&&ra(null),onClick:e=>{i===null||!s||s.n===0||(e.preventDefault(),e.stopPropagation(),v({name:`session`,id:n,at:u}))},"aria-hidden":!0}),s&&(0,I.jsx)(`div`,{className:`absolute -top-1 left-0 right-0 pointer-events-none flex justify-center`,children:(0,I.jsxs)(`span`,{className:`num text-[10px] bg-panel-2 border border-border-strong rounded-sm px-1.5 py-0.5 text-fg-muted whitespace-nowrap`,children:[new Date(u).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}),s.n===0?` · nothing happened`:(0,I.jsxs)(I.Fragment,{children:[` · ${s.n} event${s.n===1?``:`s`}`,s.turns>0&&` · ${s.turns} turn${s.turns===1?``:`s`}`,s.cost>0&&` · ${S(s.cost)}`,s.cost>0&&c>0&&(0,I.jsx)(`span`,{className:`text-fg-faint`,children:` (median ${S(c)})`}),(0,I.jsx)(`span`,{className:`text-fg-faint`,children:` · click to open`})]})]})})]})}function ar({session:e,now:t,onClose:n}){let[r,i]=(0,l.useState)(null),[a,o]=(0,l.useState)();(0,l.useEffect)(()=>{let t=!1;return(async()=>{try{let n=await N.notes(e.session_id,12);t||i(n)}catch(e){t||o(e instanceof Error?e.message:`could not load`)}})(),()=>{t=!0}},[e.session_id]);let s=r?.find(e=>!e.fragment),c=r?.[0],u=s??c;return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 bg-black/50 flex items-start justify-center pt-[10vh] px-4`,onClick:n,children:(0,I.jsxs)(`div`,{className:`w-full max-w-[720px] max-h-[76vh] flex flex-col border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`div`,{className:`px-4 pt-3 pb-2 border-b border-border flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[13px] font-medium truncate`,children:e.project||`unknown project`}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted truncate`,children:e.activity?.phrase}),(0,I.jsx)(`button`,{onClick:n,className:`ml-auto text-[16px] leading-none text-fg-faint hover:text-fg`,children:`×`})]}),(0,I.jsxs)(`div`,{className:`overflow-y-auto px-4 py-3 grid gap-3`,children:[!r&&!a&&(0,I.jsx)(`div`,{className:`text-[12px] text-fg-muted`,children:`loading…`}),a&&(0,I.jsx)(`div`,{className:`text-[12px] text-danger`,children:a}),r&&!u&&(0,I.jsx)(`div`,{className:`text-[12px] text-fg-muted`,children:`This session has not said anything yet — it may be running without hooks, or still on its first turn.`}),u&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:[`Last thing Claude said · `,ee(u.ts,t),s&&c&&s.event_id!==c.event_id&&(0,I.jsx)(`span`,{className:`ml-2 normal-case tracking-normal text-fg-muted`,children:`(the newest line was mid-thought; this is the last complete one)`})]}),(0,I.jsx)(`div`,{className:`text-[13px] leading-relaxed whitespace-pre-wrap text-fg`,children:u.text})]}),e.activity?.plan&&e.activity.plan.total>0&&(0,I.jsxs)(`div`,{className:`border-t border-border pt-3`,children:[(0,I.jsxs)(`div`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint mb-1`,children:[`Plan · `,e.activity.plan.done,`/`,e.activity.plan.total]}),e.activity.plan.next&&(0,I.jsxs)(`div`,{className:`text-[12px] text-fg-muted`,children:[`→ `,e.activity.plan.next]})]})]}),(0,I.jsxs)(`div`,{className:`px-4 py-2 border-t border-border flex items-center gap-3 text-[11px]`,children:[(0,I.jsx)(`a`,{href:g({name:`session`,id:e.session_id}),className:`link text-fg-muted hover:text-fg`,children:`open the session →`}),(0,I.jsx)(`span`,{className:`ml-auto text-fg-faint`,children:e.owned?`answer in its terminal tab`:`reply in the terminal you started it in`})]})]})})}var or=`premium-hint`;function sr({reason:e,now:t}){let[n]=(0,l.useState)(()=>Cn(or,t)),[r,i]=(0,l.useState)(!1),[a,o]=(0,l.useState)(!1);return!n||r?null:(0,I.jsxs)(`span`,{className:`flex shrink-0 items-center gap-2 text-[11px]`,children:[(0,I.jsx)(`span`,{className:`text-fg-faint`,children:e}),(0,I.jsx)(`button`,{onClick:()=>o(!0),className:`rounded-sm border border-border px-1.5 py-0.5 text-fg-muted hover:border-border-strong hover:text-fg`,children:`a cap that stops this`}),(0,I.jsx)(`button`,{title:`hide this for a month`,onClick:()=>{wn(or,t),i(!0)},className:`text-fg-faint hover:text-fg-muted`,children:`✕`}),a&&(0,I.jsx)(nt,{feature:`cap`,onClose:()=>o(!1)})]})}function cr({items:e,now:t,onDismiss:n,sessions:r}){return e.length===0?null:(0,I.jsx)(`div`,{className:`grid gap-1.5`,children:e.map(e=>(0,I.jsx)(lr,{it:e,now:t,onDismiss:n,session:r?.find(t=>t.session_id===e.sessionId)},e.id))})}function lr({it:e,now:t,onDismiss:n,session:r}){let[i,a]=(0,l.useState)(!1),o=e.severity===`high`;return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`border rounded-[var(--radius-panel)] px-3 py-2 flex items-center gap-3 ${o?`border-danger/50 bg-danger/10`:`border-warn/50 bg-warn/10`}`,children:[(0,I.jsx)(`span`,{className:`font-medium text-[13px] shrink-0 ${o?`text-danger`:`text-warn`}`,children:e.title}),(0,I.jsxs)(`span`,{className:`text-[12px] text-fg-muted truncate`,children:[e.sessionId&&(0,I.jsx)(`a`,{href:g({name:`session`,id:e.sessionId}),className:`link mono text-fg`,children:e.project||T(e.sessionId)}),(0,I.jsx)(`span`,{className:e.sessionId?`ml-2`:``,children:e.detail})]}),(0,I.jsxs)(`span`,{className:`ml-auto flex items-center gap-3 shrink-0`,children:[e.costUSD!==void 0&&e.costUSD>0&&(0,I.jsx)(`span`,{className:`num text-[13px] text-fg`,title:`spent by this session so far`,children:S(e.costUSD)}),e.since!==void 0&&(0,I.jsx)(`span`,{className:`num text-[11px] text-fg-faint`,children:ee(e.since,t)}),r&&e.id.startsWith(`waiting-`)&&(0,I.jsx)(`button`,{className:`text-[11px] border border-border px-1.5 py-0.5 rounded-sm hover:border-border-strong text-fg-muted hover:text-fg`,onClick:()=>a(!0),children:`what did it ask?`}),(0,I.jsx)(`a`,{href:e.sessionId?g({name:`session`,id:e.sessionId,tab:`timeline`,at:e.at}):`#/cost`,className:`text-[11px] border border-border px-1.5 py-0.5 rounded-sm hover:border-border-strong no-underline text-fg-muted hover:text-fg`,children:e.sessionId?`open`:`details`}),(e.id.startsWith(`loop-`)||e.id.startsWith(`spent-`))&&(0,I.jsx)(sr,{reason:`this is what a cap stops`,now:t}),n&&e.id.startsWith(`loop-`)&&(0,I.jsx)(`button`,{className:`text-[11px] text-fg-faint hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,onClick:()=>n(e.sessionId),children:`dismiss`})]})]}),i&&r&&(0,I.jsx)(ar,{session:r,now:t,onClose:()=>a(!1)})]})}var ur=9e5,dr=25,fr=300,pr=2,mr=864e5,hr=90,gr=6912e5;function _r(e){return typeof e==`number`?e:e&&Date.parse(e)||0}function vr({sessions:e,alerts:t,now:n,limits:r,waitingMs:i=ur}){let a=[],o=Array.isArray(e)?e.filter(Boolean):[],s=Array.isArray(t)?t.filter(Boolean):[],c=new Map(o.map(e=>[e.session_id,e]));for(let e of s){let t=c.get(e.session_id);a.push({id:`loop-${e.session_id}`,sessionId:e.session_id,project:t?.project??``,severity:`high`,title:`Stuck in a loop`,detail:[`ran ${e.sample||e.tool||`the same call`}`,Number.isFinite(e.count)?`${e.count}×`:`repeatedly`,Number.isFinite(e.window_min)?`in ${e.window_min} min`:``].filter(Boolean).join(` `),costUSD:t?.stats?.cost_usd,since:_r(e.ts)||void 0,at:_r(e.first_ts)||_r(e.ts)||void 0})}for(let e of o)if(e.status!==`ended`&&e.activity){if(e.activity.health===`error`){a.push({id:`error-${e.session_id}`,sessionId:e.session_id,project:e.project,severity:`high`,title:`Session hit an error`,detail:e.activity.phrase,costUSD:e.stats?.cost_usd,since:_r(e.activity.at)||e.last_event_at});continue}if(e.activity.health===`waiting-on-you`){let t=_r(e.activity.at)||e.last_event_at;t>0&&n-t>=i&&a.push({id:`waiting-${e.session_id}`,sessionId:e.session_id,project:e.project,severity:`medium`,title:`Waiting on you`,detail:e.activity.phrase,since:t})}}for(let e of o){if(!e.stats||!e.activity)continue;let{cost_usd:t,turns:r,files_touched:i}=e.stats;if(tpr)continue;let o=_r(e.activity.at)||e.last_event_at;o>0&&n-o>mr||a.push({id:`spent-${e.session_id}`,sessionId:e.session_id,project:e.project,severity:`medium`,title:`Lots of turns, few files`,detail:`${r.toLocaleString()} turns, ${i===0?`no files`:i===1?`1 file`:`${i} files`} touched`,costUSD:t,since:_r(e.activity.at)||e.last_event_at})}let l={high:0,medium:1};for(let[e,t]of[[`5-hour`,r?.five_hour],[`7-day`,r?.seven_day]]){if(!t||t.used_percentagen&&r=95?`high`:`medium`,title:`${e} plan window ${i}% used`,detail:`resets at ${o}${t.forecast?` — ${t.forecast}`:``}`})}return a.sort((e,t)=>l[e.severity]-l[t.severity]||(e.since??0)-(t.since??0))}var yr=`caprock.update.dismissed`;function br({plan:e,onSave:t,now:n,owned:r=0}){let[i,a]=(0,l.useState)(),[o,s]=(0,l.useState)(()=>localStorage.getItem(yr)??``);return(0,l.useEffect)(()=>{if(!e?.update_checks){a(void 0);return}let t=!0,n=()=>{N.update().then(e=>{t&&a(e)}).catch(()=>{})};n();let r=window.setInterval(n,6e4);return()=>{t=!1,window.clearInterval(r)}},[e?.update_checks]),e&&!e.update_checks?o===`offer`?null:(0,I.jsxs)(xr,{tone:`muted`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`Caprock can check GitHub for new releases. It's the only outbound call it makes, so it's off unless you turn it on — no usage data is sent, and you can turn it off again any time.`}),(0,I.jsxs)(`span`,{className:`ml-auto flex items-center gap-2 shrink-0`,children:[(0,I.jsx)(`button`,{className:`text-[11px] border border-accent/50 text-accent bg-accent/10 px-2 py-0.5 rounded-sm hover:bg-accent/20`,onClick:()=>t({...e,update_checks:!0}),children:`check for updates`}),(0,I.jsx)(`button`,{className:`text-[11px] text-fg-faint hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,onClick:()=>{localStorage.setItem(yr,`offer`),s(`offer`)},children:`no thanks`})]})]}):!i?.update_available||!i.latest||o===i.latest?null:(0,I.jsxs)(xr,{tone:`accent`,children:[(0,I.jsxs)(`span`,{className:`text-fg`,children:[(0,I.jsxs)(`span`,{className:`font-medium`,children:[`Caprock `,i.latest]}),` is available — you're on `,(0,I.jsx)(`span`,{className:`mono`,children:i.current}),`.`]}),r>0&&(0,I.jsx)(`span`,{className:`text-[12px] text-warn shrink-0`,children:r===1?`1 session Caprock started will close`:`${r} sessions Caprock started will close`}),i.command?(0,I.jsx)(Ct,{command:i.command}):(0,I.jsx)(`a`,{className:`link text-[12px]`,href:i.url,target:`_blank`,rel:`noreferrer`,children:`download it`}),(0,I.jsxs)(`span`,{className:`ml-auto flex items-center gap-2 shrink-0`,children:[i.checked_at?(0,I.jsxs)(`span`,{className:`num text-[11px] text-fg-faint`,children:[`checked `,ee(i.checked_at,n)]}):null,(0,I.jsx)(`a`,{className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-0.5 rounded-sm no-underline`,href:i.url,target:`_blank`,rel:`noreferrer`,children:`what's new`}),(0,I.jsx)(`button`,{className:`text-[11px] text-fg-faint hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,onClick:()=>{localStorage.setItem(yr,i.latest),s(i.latest)},children:`not now`})]})]})}function xr({tone:e,children:t}){return(0,I.jsx)(`div`,{className:`border rounded-[var(--radius-panel)] px-3 py-2 flex items-center gap-3 text-[12px] ${e===`accent`?`border-accent/40 bg-accent/5`:`border-border bg-panel`}`,children:t})}function Sr({u:e,className:t=``}){return!e||e.turns===0?null:(0,I.jsxs)(`div`,{className:`border border-warn/50 bg-warn/10 px-3 py-2 text-[12px] rounded-[var(--radius-panel)] ${t}`,children:[(0,I.jsx)(`span`,{className:`text-warn font-medium`,children:`Cost is incomplete`}),` `,(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[C(e.tokens),` tokens over `,e.turns,` turn`,e.turns===1?``:`s`,` could not be priced, so they are missing from the total above — not free. `,e.models.length===1?`Model`:`Models`,` with no entry in the pricing table:`,` `,e.models.map((e,t)=>(0,I.jsxs)(`span`,{children:[t>0&&`, `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:e||`unknown`})]},e)),`. This happens when a model ships newer than the pricing table, or when a gateway reports ids that do not normalise.`]})]})}function Cr({value:e,onPick:t}){let[n,r]=(0,l.useState)(`recent`),[i,a]=(0,l.useState)(``),o=F(()=>N.recentDirs(),[],{live:!1}),s=F(()=>N.browse(i),[i],{live:!1});return(0,l.useEffect)(()=>{o.data&&o.data.length===0&&r(`browse`)},[o.data]),(0,I.jsxs)(`div`,{className:`rounded-[3px] border border-border-strong bg-panel-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-1 border-b border-border-strong px-2 py-1.5 text-[12px]`,children:[(0,I.jsx)(wr,{on:n===`recent`,onClick:()=>r(`recent`),children:`Recent`}),(0,I.jsx)(wr,{on:n===`browse`,onClick:()=>r(`browse`),children:`Browse`}),n===`browse`&&s.data&&(0,I.jsx)(`span`,{className:`mono ml-auto min-w-0 truncate pl-2 text-[11px] text-fg-faint`,title:s.data.dir,children:kr(s.data.dir,s.data.root)})]}),(0,I.jsx)(`div`,{className:`h-[168px] overflow-y-auto overflow-x-hidden`,children:n===`recent`?(0,I.jsx)(Tr,{rows:o.data,value:e,onPick:t}):(0,I.jsx)(Er,{data:s.data,value:e,onOpen:a,onPick:t,error:s.error?.message})})]})}function wr({on:e,onClick:t,children:n}){return(0,I.jsx)(`button`,{type:`button`,onClick:t,className:`rounded-sm px-2 py-0.5 ${e?`bg-accent/15 text-accent`:`text-fg-muted hover:text-fg`}`,children:n})}function Tr({rows:e,value:t,onPick:n}){return e?e.length===0?(0,I.jsx)(Or,{children:`No sessions yet — use Browse, or type a path.`}):(0,I.jsx)(`ul`,{children:e.map(e=>(0,I.jsxs)(Dr,{selected:t===e.dir,onClick:()=>n(e.dir),children:[(0,I.jsx)(`span`,{className:`shrink-0 text-fg`,children:e.name}),(0,I.jsx)(`span`,{className:`mono ml-2 min-w-0 flex-1 truncate text-[11px] text-fg-faint`,title:e.dir,children:e.dir}),(0,I.jsx)(`span`,{className:`shrink-0 pl-2 text-[11px] text-fg-faint`,children:ee(e.last_event_at)})]},e.dir))}):(0,I.jsx)(Or,{children:`…`})}function Er({data:e,value:t,onOpen:n,onPick:r,error:i}){return i?(0,I.jsx)(Or,{children:i}):e?(0,I.jsxs)(`ul`,{children:[e.parent&&(0,I.jsx)(Dr,{selected:!1,onClick:()=>n(e.parent),children:(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`↑ up`})}),e.entries.length===0&&(0,I.jsx)(Or,{children:`Nothing here.`}),e.entries.map(e=>(0,I.jsxs)(Dr,{selected:t===e.path,onClick:()=>e.repo?r(e.path):n(e.path),children:[(0,I.jsx)(`span`,{className:`min-w-0 truncate ${e.repo?`text-fg`:`text-fg-muted`}`,children:e.name}),e.repo&&(0,I.jsx)(`span`,{className:`ml-2 shrink-0 text-[10px] uppercase tracking-wide text-accent`,children:`repo`}),(0,I.jsx)(`span`,{className:`flex-1`}),(0,I.jsx)(`button`,{type:`button`,onClick:t=>{t.stopPropagation(),e.repo?n(e.path):r(e.path)},className:`shrink-0 px-1 text-[11px] text-fg-faint hover:text-fg`,title:e.repo?`Open this folder`:`Use this folder`,children:e.repo?`›`:`use`})]},e.path))]}):(0,I.jsx)(Or,{children:`…`})}function Dr({selected:e,onClick:t,children:n}){return(0,I.jsx)(`li`,{children:(0,I.jsx)(`button`,{type:`button`,onClick:t,className:`flex w-full min-w-0 items-center px-2.5 py-1 text-left text-[12px] hover:bg-panel ${e?`bg-accent/10`:``}`,children:n})})}function Or({children:e}){return(0,I.jsx)(`p`,{className:`px-2.5 py-3 text-[12px] text-fg-faint`,children:e})}function kr(e,t){return e===t?`~`:e.startsWith(t+`/`)?`~`+e.slice(t.length):e}var Ar=`claude-opus-5`,jr=`acceptEdits`,Mr=[[`claude-opus-5`,`Opus 5 · most capable`],[`claude-sonnet-5`,`Sonnet 5 · faster, cheaper`],[`claude-haiku-4-5`,`Haiku 4.5 · cheapest`]],Nr=[[`acceptEdits`,`Accept edits · asks before commands`],[`plan`,`Plan · reads and plans, changes nothing`],[`bypassPermissions`,`Bypass · never asks`]];function Pr({available:e,onClose:t,initialCwd:n=``}){let[r,i]=(0,l.useState)(n),[a,o]=(0,l.useState)(Ar),[s,c]=(0,l.useState)(jr),[u,d]=(0,l.useState)(``),[f,p]=(0,l.useState)(!1),[m,h]=(0,l.useState)(!1),[g,_]=(0,l.useState)(``),y=async()=>{if(!r.trim()){_(`Working directory is required.`);return}h(!0),_(``);try{let e={cwd:r.trim()};a&&(e.model=a),s&&(e.permission_mode=s),u.trim()&&(e.worktree=u.trim()),f&&(e.create=!0);let{session_id:n}=await N.spawn(e);t(),v({name:`session`,id:n,tab:`terminal`})}catch(e){_(oe(e))}finally{h(!1)}};return(0,I.jsx)(`div`,{className:`fixed inset-0 z-20 bg-black/50 flex items-start justify-center pt-24`,onClick:t,children:(0,I.jsxs)(`div`,{className:`border border-border-strong bg-panel rounded-[var(--radius-panel)] w-[520px] max-w-[92vw]`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`px-3 py-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`h2`,{className:`text-[12px] uppercase tracking-[0.08em] text-fg-muted`,children:`New session`}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-fg-muted hover:text-fg`,children:`✕`})]}),e?(0,I.jsxs)(`div`,{className:`px-4 py-3 grid min-w-0 gap-3 text-[13px]`,children:[(0,I.jsxs)(Fr,{label:`Working directory`,hint:`pick one, or type a path`,children:[(0,I.jsx)(`input`,{autoFocus:!0,className:`input`,placeholder:`/Users/you/dev/project`,value:r,onChange:e=>i(e.target.value),onKeyDown:e=>e.key===`Enter`&&y()}),(0,I.jsx)(`div`,{className:`mt-1.5 min-w-0 max-w-full`,children:(0,I.jsx)(Cr,{value:r,onPick:i})})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,I.jsx)(Fr,{label:`Model`,children:(0,I.jsx)(`select`,{className:`input`,value:a,onChange:e=>o(e.target.value),children:Mr.map(([e,t])=>(0,I.jsx)(`option`,{value:e,children:t},e))})}),(0,I.jsx)(Fr,{label:`Permissions`,children:(0,I.jsx)(`select`,{className:`input`,value:s,onChange:e=>c(e.target.value),children:Nr.map(([e,t])=>(0,I.jsx)(`option`,{value:e,children:t},e))})})]}),(0,I.jsxs)(`details`,{className:`text-[12px] group`,children:[(0,I.jsxs)(`summary`,{className:`cursor-pointer select-none text-fg-muted hover:text-fg list-none marker:content-none`,children:[(0,I.jsx)(`span`,{className:`inline-block transition-transform group-open:rotate-90 text-fg-faint`,children:`▶`}),` Advanced`]}),(0,I.jsxs)(`div`,{className:`grid gap-2 pt-2`,children:[(0,I.jsxs)(`label`,{className:`inline-flex items-center gap-1.5 cursor-pointer select-none text-fg-muted`,children:[(0,I.jsx)(`input`,{type:`checkbox`,className:`accent-[var(--color-accent)]`,checked:f,onChange:e=>p(e.target.checked)}),`create the directory if it does not exist`]}),(0,I.jsx)(Fr,{label:`Git worktree`,hint:`creates .caprock-worktrees/ on a new branch`,children:(0,I.jsx)(`input`,{className:`input`,placeholder:`feature-x`,value:u,onChange:e=>d(e.target.value)})})]})]}),g&&(0,I.jsx)(`div`,{className:`text-danger text-[12px]`,children:g})]}):(0,I.jsxs)(`div`,{className:`px-4 py-6 text-[13px] text-fg-muted`,children:[`The `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` binary was not found on this machine, so Caprock cannot spawn sessions. It still observes every session you start yourself.`]}),e&&(0,I.jsxs)(`footer`,{className:`px-4 py-2 border-t border-border flex gap-2 justify-end`,children:[(0,I.jsx)(`button`,{onClick:t,className:`border border-border px-3 py-1 rounded-sm text-fg-muted hover:text-fg`,children:`Cancel`}),(0,I.jsx)(`button`,{onClick:y,disabled:m,className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm hover:bg-accent/25 disabled:opacity-50`,children:m?`starting…`:`Start session`})]})]})})}function Fr({label:e,hint:t,children:n}){return(0,I.jsxs)(`label`,{className:`grid min-w-0 gap-1`,children:[(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[e,t&&(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` · `,t]})]}),n]})}function Ir(){let[e,t]=(0,l.useState)(!1),[n,r]=(0,l.useState)(`all`),[i,a]=(0,l.useState)(!1),o=F(()=>N.sessions(!e),[e],{intervalMs:5e3}),s=F(()=>N.status(),[],{live:!1,intervalMs:3e4}),c=F(()=>N.summary(`today`,n),[n],{intervalMs:5e3}),u=F(()=>N.history(`all`),[],{intervalMs:6e4}),{alerts:p}=f(),m=ie(1e3),h=o.data??[],g=n===`all`?h:h.filter(e=>(e.agent??`claude`)===n),_=!!s.data?.opencode,v=g.filter(e=>e.activity.health===`working`||e.activity.health===`looping`||e.activity.health===`error`||e.activity.health===`waiting-on-you`),y=g.filter(e=>!v.includes(e)&&e.status!==`ended`),b=g.filter(e=>e.status===`ended`),[x,w]=De(),te=vr({sessions:g,alerts:p,now:m,limits:c.data?.rate_limits}),T=s.data?.hooks&&(s.data.hooks.missing??[]).length>0,E=!!c.data&&c.data.turns>0,ne=s.data?.ingest_error;return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[ne&&(0,I.jsxs)(`div`,{className:`border border-danger/50 bg-danger/10 px-3 py-2 text-[12px] rounded-[var(--radius-panel)] flex items-center gap-3`,children:[(0,I.jsx)(`span`,{className:`text-danger font-medium`,children:`Ingest stopped`}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`No new sessions are being captured. `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:ne}),` — check that`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` ~/.claude`}),` is readable, then restart with`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` caprock down && caprock up`}),`.`]})]}),T&&(0,I.jsxs)(`div`,{className:`border border-warn/50 bg-warn/10 px-3 py-2 text-[12px] rounded-[var(--radius-panel)] flex items-center gap-3`,children:[(0,I.jsx)(`span`,{className:`text-warn font-medium`,children:`Hooks not installed`}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`Activity is coming from transcripts only (a few seconds late, no tool-level detail for running commands). Run `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:`caprock hooks install`}),` for real-time narration.`]}),(0,I.jsx)(`a`,{href:`#/settings`,className:`link ml-auto text-[11px]`,children:`details`})]}),(0,I.jsx)(br,{plan:x,onSave:w,now:m,owned:g.filter(e=>e.owned&&e.status!==`ended`).length}),(0,I.jsx)(cr,{items:te,now:m,onDismiss:e=>d.dismissAlert(e),sessions:g}),(0,I.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,I.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,I.jsx)(dn,{plan:x})}),(0,I.jsx)(Lr,{available:s.data?.claude_available}),(0,I.jsx)(Rr,{available:s.data?.claude_available,onClick:()=>a(!0)})]}),E&&u.data?.totals&&(0,I.jsx)(En,{costUSD:u.data.totals.cost_usd,days:u.data.totals.days,now:m}),(0,I.jsxs)(L,{title:`Today`,center:_?(0,I.jsx)(`span`,{className:`inline-flex items-center gap-0.5 rounded-md bg-panel-2 p-0.5`,children:It.map(e=>(0,I.jsx)(`button`,{onClick:()=>r(e.key),title:e.key===`all`?`Every agent`:`Only ${e.label}`,className:`px-2.5 py-1 text-[12px] mono rounded-[5px] transition-colors ${n===e.key?`bg-accent text-panel font-medium`:`text-fg-muted hover:text-fg`}`,children:e.label},e.key))}):null,right:c.data?(0,I.jsxs)(`span`,{className:`num`,children:[`pricing `,c.data.pricing_version,` · at API list price`]}):null,children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 lg:grid-cols-[1.4fr_1fr_1fr_1fr_1fr_1fr] divide-x divide-border`,children:[(0,I.jsx)(R,{label:`Cost today`,value:E?S(c.data?.cost_usd):`—`,sub:(0,I.jsx)(`span`,{title:un(x),children:E?ln(x):`nothing measured yet`}),tone:`info`,size:`hero`}),(0,I.jsx)(R,{label:`Burn now`,value:E?`${S(c.data.burn.usd_per_hour)}/h`:`—`,sub:E?`${C(Math.round(c.data.burn.tokens_per_min))} tok/min · last ${c.data.burn.window_min}m`:void 0}),(0,I.jsx)(R,{label:`Sessions`,value:E?c.data.sessions:`—`,sub:E?`${c.data.active_sessions} active`:void 0,size:`compact`}),(0,I.jsx)(R,{label:`Turns`,value:E?c.data.turns:`—`,sub:E?`${c.data.tool_calls} tool calls`:void 0,size:`compact`}),(0,I.jsx)(vn,{limits:c.data?.rate_limits,now:m}),(0,I.jsx)(hn,{hitRate:c.data?.savings.hit_rate,cutPct:c.data?.savings.cut_pct,measured:E})]}),(0,I.jsx)(Sr,{u:c.data?.unpriced,className:`mx-3 mb-2.5`})]}),(0,I.jsx)(Qn,{sessions:g,now:m}),(0,I.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-2`,children:[(0,I.jsx)(on,{sessions:g,now:m,emptyHint:n===`all`?void 0:(0,I.jsxs)(I.Fragment,{children:[`Nothing from `,n===`opencode`?`OpenCode`:`Claude Code`,` yet.`]})}),(0,I.jsx)(Wt,{sessions:g,agent:n})]}),(0,I.jsx)(In,{}),o.error&&!o.data&&(0,I.jsxs)(z,{title:`Cannot reach the daemon`,children:[o.error.message,` — is `,(0,I.jsx)(`span`,{className:`mono`,children:`caprock up`}),` running?`]}),!o.data&&!o.error&&(0,I.jsx)(St,{rows:4,className:`border border-border rounded-[var(--radius-panel)] bg-panel`}),o.data&&g.length===0&&(n===`all`?(0,I.jsxs)(z,{title:`No sessions yet`,children:[`Start `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` in any terminal — it will show up here within seconds.`]}):(0,I.jsxs)(z,{title:`No ${n===`opencode`?`OpenCode`:`Claude Code`} sessions here`,children:[`Nothing from this agent in the current view. Switch to`,` `,(0,I.jsx)(`button`,{className:`link underline`,onClick:()=>r(`all`),children:`all`}),` `,`to see everything.`]})),(0,I.jsx)(zr,{groups:[{label:`Active`,items:v},{label:`Idle`,items:y,dim:!0},...e?[{label:`Ended`,items:b,dim:!0}]:[]],now:m}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3 text-[11px] text-fg-faint px-0.5`,children:[(0,I.jsxs)(`label`,{className:`inline-flex items-center gap-1.5 cursor-pointer select-none`,children:[(0,I.jsx)(`input`,{type:`checkbox`,className:`accent-[var(--color-accent)]`,checked:e,onChange:e=>t(e.target.checked)}),`show ended sessions`]}),o.loadedAt>0&&(0,I.jsxs)(`span`,{className:`num ml-auto`,children:[`refreshed `,ee(o.loadedAt,m)]})]}),i&&(0,I.jsx)(Pr,{available:s.data?.claude_available??!1,onClose:()=>{a(!1),o.refresh()}})]})}function Lr({available:e}){let[t,n]=(0,l.useState)(!1),[r,i]=(0,l.useState)(``);return e===!1?null:(0,I.jsx)(I.Fragment,{children:(0,I.jsxs)(`button`,{onClick:async()=>{n(!0),i(``);try{let{session_id:e}=await N.spawn({chat:!0});v({name:`session`,id:e,tab:`terminal`})}catch(e){i(oe(e))}finally{n(!1)}},disabled:t,title:`start a session without picking a folder`,className:`relative shrink-0 rounded-[var(--radius-panel)] border border-border-strong px-3 py-2 text-[13px] leading-5 text-fg-muted hover:text-fg hover:border-accent/50 disabled:opacity-50`,children:[t?`starting…`:`Quick chat`,r&&(0,I.jsx)(`span`,{className:`absolute right-0 top-full mt-1 block max-w-[220px] text-right text-[11px] text-danger`,children:r})]})})}function Rr({available:e,onClick:t}){let n=e===!1;return(0,I.jsxs)(`button`,{onClick:t,title:n?`claude was not found on this machine — click for details`:`start a session Caprock owns`,className:`shrink-0 rounded-[var(--radius-panel)] border px-3 py-2 text-[13px] leading-5 font-medium transition-colors ${n?`border-border text-fg-faint hover:text-fg-muted`:`border-accent/60 bg-accent/15 text-accent hover:bg-accent/25`}`,children:[`+ New session`,n?` (claude not found)`:``]})}function zr({groups:e,now:t}){let n=e.flatMap(e=>e.items.map((t,n)=>({s:t,dim:e.dim,label:n===0?`${e.label} · ${e.items.length}`:null})));return n.length===0?null:(0,I.jsx)(`div`,{"data-testid":`session-grid`,className:`mt-3 grid gap-2 gap-y-6`,children:n.map(({s:e,dim:n,label:r})=>(0,I.jsxs)(`div`,{className:`relative ${n?`opacity-80`:``}`,children:[r&&(0,I.jsx)(`div`,{className:`absolute -top-4 left-0.5 text-[11px] uppercase tracking-[0.08em] text-fg-faint`,children:r}),(0,I.jsx)(Br,{s:e,now:t})]},e.session_id))})}function Br({s:e,now:t}){let n=e.context,r=n?n.pct>=85?`danger`:n.pct>=60?`warn`:void 0:void 0,[i,a]=(0,l.useState)(!1),o=e.activity?.health===`waiting-on-you`;return(0,I.jsxs)(`a`,{href:g({name:`session`,id:e.session_id}),className:`block border border-border bg-panel rounded-[var(--radius-panel)] hover:border-border-strong no-underline hover:no-underline text-fg`,children:[(0,I.jsxs)(`div`,{className:`px-3 pt-2 pb-1 flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`font-medium truncate text-[15px]`,children:e.project||`unknown project`}),(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-faint`,children:T(e.session_id)}),e.agent===`opencode`&&(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.08em] text-fg-muted border border-border px-1 py-px rounded-sm`,children:`opencode`}),e.git_branch&&(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-muted truncate`,children:e.git_branch}),(0,I.jsxs)(`span`,{className:`ml-auto flex items-center gap-2`,children:[o&&(0,I.jsx)(`button`,{className:`text-[11px] border border-warn/50 text-warn bg-warn/10 px-1.5 py-0.5 rounded-sm hover:bg-warn/20`,onClick:e=>{e.preventDefault(),a(!0)},children:`what did it ask?`}),(0,I.jsx)(bt,{health:e.activity.health})]})]}),i&&(0,I.jsx)(ar,{session:e,now:t,onClose:()=>a(!1)}),(0,I.jsxs)(`div`,{className:`px-3 pb-2 text-[13px] truncate`,title:e.activity.phrase,children:[(0,I.jsx)(`span`,{className:e.activity.health===`working`?`text-fg`:`text-fg-muted`,children:e.activity.phrase}),(0,I.jsx)(`span`,{className:`text-fg-faint num text-[11px] ml-2`,children:ee(e.activity.at||e.last_event_at,t)})]}),e.activity.plan&&e.activity.plan.total>0&&(0,I.jsxs)(`div`,{className:`px-3 pb-2 flex items-center gap-2 text-[11px] text-fg-muted`,children:[(0,I.jsx)(`div`,{className:`h-1 flex-1 bg-panel-2 rounded-sm overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full bg-accent`,style:{width:`${Math.min(100,Math.max(0,100*e.activity.plan.done/e.activity.plan.total))}%`}})}),(0,I.jsxs)(`span`,{className:`num`,children:[e.activity.plan.done,`/`,e.activity.plan.total]}),e.activity.plan.next&&(0,I.jsxs)(`span`,{className:`truncate max-w-[50%]`,children:[`→ `,e.activity.plan.next]})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-2 sm:grid-cols-4 divide-x divide-border border-t border-border`,children:[(0,I.jsx)(R,{label:`Cost`,value:S(e.stats.cost_usd),sub:e.model||`—`,tone:`info`}),(0,I.jsx)(R,{label:`Tokens`,value:C(e.stats.tokens_in+e.stats.tokens_out+e.stats.cache_read+e.stats.cache_write),sub:`${w(e.savings.hit_rate*100)} cache hit`}),(0,I.jsx)(R,{label:`Context`,value:n?w(n.pct):`—`,sub:n?`${C(n.tokens)} / ${C(n.window)}`:`unknown model`,tone:r}),(0,I.jsx)(R,{label:`Activity`,value:e.stats.tool_calls,sub:`${e.stats.turns} turns · ${e.stats.files_touched} files`})]})]})}function Vr({id:e,now:t}){let n=F(()=>N.notes(e),[e],{intervalMs:1e4}),r=n.data??[],[i,a]=(0,l.useState)(!1),o=r.filter(e=>!e.fragment),s=i?r:o;return n.error&&!n.data?(0,I.jsx)(z,{title:`Cannot load notes`,children:n.error.message}):n.data?r.length===0?(0,I.jsx)(z,{title:`Nothing said yet`,children:`Claude's written answers appear here — the reasoning and the “what changed, what I still need from you” that otherwise lives only in your terminal scrollback.`}):(0,I.jsxs)(`div`,{className:`grid gap-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-3 text-[11px] text-fg-faint px-0.5`,children:[(0,I.jsxs)(`span`,{children:[o.length,` `,o.length===1?`answer`:`answers`,r.length>o.length&&` · ${r.length-o.length} short remarks`]}),r.length>o.length&&(0,I.jsx)(`button`,{className:`text-fg-muted hover:text-fg border border-border px-1.5 rounded-sm`,onClick:()=>a(e=>!e),children:i?`hide short remarks`:`show everything`}),(0,I.jsx)(`span`,{className:`ml-auto`,children:`subagent chatter excluded · newest first`})]}),s.map(e=>(0,I.jsx)(Ur,{note:e,now:t},e.event_id))]}):(0,I.jsx)(St,{rows:4})}var Hr=600;function Ur({note:e,now:t,showSession:n=!1}){let[r,i]=(0,l.useState)(!1),a=typeof e.text==`string`?e.text:``,o=[...a],s=o.length>Hr,c=r||!s?a:o.slice(0,Hr).join(``)+`…`;return(0,I.jsxs)(`div`,{className:`border border-border bg-panel rounded-[var(--radius-panel)]`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2 px-3 pt-2 text-[11px] text-fg-faint`,children:[n&&(0,I.jsx)(`a`,{href:g({name:`session`,id:e.session_id,at:e.ts}),className:`link`,title:`Open the session at this moment`,children:(0,I.jsx)(`span`,{className:`text-fg-muted`,children:e.project||T(e.session_id)})}),(0,I.jsx)(`span`,{className:`mono`,children:e.model||`assistant`}),e.fragment&&(0,I.jsx)(`span`,{className:`text-fg-faint`,children:`· mid-thought`}),(0,I.jsx)(`span`,{className:`num ml-auto`,children:ee(e.ts,t)})]}),(0,I.jsx)(`div`,{className:`px-3 py-2 text-[13px] leading-[1.55] whitespace-pre-wrap break-words`,children:c}),s&&(0,I.jsx)(`button`,{className:`text-[11px] text-fg-muted hover:text-fg px-3 pb-2`,onClick:()=>i(e=>!e),children:r?`show less`:`show all ${o.length.toLocaleString()} characters`})]})}var Wr=Object.defineProperty,Gr=Object.getOwnPropertyDescriptor,Kr=(e,t)=>{for(var n in t)Wr(e,n,{get:t[n],enumerable:!0})},qr=(e,t,n,r)=>{for(var i=r>1?void 0:r?Gr(t,n):t,a=e.length-1,o;a>=0;a--)(o=e[a])&&(i=(r?o(t,n,i):o(i))||i);return r&&i&&Wr(t,n,i),i},B=(e,t)=>(n,r)=>t(n,r,e),Jr=`Terminal input`,Yr={get:()=>Jr,set:e=>Jr=e},Xr=`Too much output to announce, navigate to rows manually to read`,Zr={get:()=>Xr,set:e=>Xr=e};function Qr(e){return e.replace(/\r?\n/g,`\r`)}function $r(e,t){return t?`\x1B[200~`+e+`\x1B[201~`:e}function ei(e,t){e.clipboardData&&e.clipboardData.setData(`text/plain`,t.selectionText),e.preventDefault()}function ti(e,t,n,r){e.stopPropagation(),e.clipboardData&&ni(e.clipboardData.getData(`text/plain`),t,n,r)}function ni(e,t,n,r){e=Qr(e),e=$r(e,n.decPrivateModes.bracketedPasteMode&&r.rawOptions.ignoreBracketedPasteMode!==!0),n.triggerDataEvent(e,!0),t.value=``}function ri(e,t,n){let r=n.getBoundingClientRect(),i=e.clientX-r.left-10,a=e.clientY-r.top-10;t.style.width=`20px`,t.style.height=`20px`,t.style.left=`${i}px`,t.style.top=`${a}px`,t.style.zIndex=`1000`,t.focus()}function ii(e,t,n,r,i){ri(e,t,n),i&&r.rightClickSelect(e),t.value=r.selectionText,t.select()}function ai(e){return e>65535?(e-=65536,String.fromCharCode((e>>10)+55296)+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)}function oi(e,t=0,n=e.length){let r=``;for(let i=t;i65535?(t-=65536,r+=String.fromCharCode((t>>10)+55296)+String.fromCharCode(t%1024+56320)):r+=String.fromCharCode(t)}return r}var si=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i=0;if(this._interim){let n=e.charCodeAt(i++);56320<=n&&n<=57343?t[r++]=(this._interim-55296)*1024+n-56320+65536:(t[r++]=this._interim,t[r++]=n),this._interim=0}for(let a=i;a=n)return this._interim=i,r;let o=e.charCodeAt(a);56320<=o&&o<=57343?t[r++]=(i-55296)*1024+o-56320+65536:(t[r++]=i,t[r++]=o);continue}i!==65279&&(t[r++]=i)}return r}},ci=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i,a,o,s,c=0,l=0;if(this.interim[0]){let i=!1,a=this.interim[0];a&=(a&224)==192?31:(a&240)==224?15:7;let o=0,s;for(;(s=this.interim[++o]&63)&&o<4;)a<<=6,a|=s;let c=(this.interim[0]&224)==192?2:(this.interim[0]&240)==224?3:4,u=c-o;for(;l=n)return 0;if(s=e[l++],(s&192)!=128){l--,i=!0;break}this.interim[o++]=s,a<<=6,a|=s&63}i||(c===2?a<128?l--:t[r++]=a:c===3?a<2048||a>=55296&&a<=57343||a===65279||(t[r++]=a):a<65536||a>1114111||(t[r++]=a)),this.interim.fill(0)}let u=n-4,d=l;for(;d=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(c=(i&31)<<6|a&63,c<128){d--;continue}t[r++]=c}else if((i&240)==224){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(c=(i&15)<<12|(a&63)<<6|o&63,c<2048||c>=55296&&c<=57343||c===65279)continue;t[r++]=c}else if((i&248)==240){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,this.interim[2]=o,r;if(s=e[d++],(s&192)!=128){d--;continue}if(c=(i&7)<<18|(a&63)<<12|(o&63)<<6|s&63,c<65536||c>1114111)continue;t[r++]=c}}return r}},li=``,ui=` `,di=class e{constructor(){this.fg=0,this.bg=0,this.extended=new fi}static toColorRGB(e){return[e>>>16&255,e>>>8&255,e&255]}static fromColorRGB(e){return(e[0]&255)<<16|(e[1]&255)<<8|e[2]&255}clone(){let t=new e;return t.fg=this.fg,t.bg=this.bg,t.extended=this.extended.clone(),t}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)==50331648}isBgRGB(){return(this.bg&50331648)==50331648}isFgPalette(){return(this.fg&50331648)==16777216||(this.fg&50331648)==33554432}isBgPalette(){return(this.bg&50331648)==16777216||(this.bg&50331648)==33554432}isFgDefault(){return!(this.fg&50331648)}isBgDefault(){return!(this.bg&50331648)}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==16777216||(this.extended.underlineColor&50331648)==33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?!(this.extended.underlineColor&50331648):this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},fi=class e{constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(e){this._ext&=-67108864,this._ext|=e&67108863}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){let e=(this._ext&3758096384)>>29;return e<0?e^4294967288:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}clone(){return new e(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}},pi=class e extends di{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new fi,this.combinedData=``}static fromCharData(t){let n=new e;return n.setFromCharData(t),n}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?ai(this.content&2097151):``}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(e){this.fg=e[0],this.bg=0;let t=!1;if(e[1].length>2)t=!0;else if(e[1].length===2){let n=e[1].charCodeAt(0);if(55296<=n&&n<=56319){let r=e[1].charCodeAt(1);56320<=r&&r<=57343?this.content=(n-55296)*1024+r-56320+65536|e[2]<<22:t=!0}else t=!0}else this.content=e[1].charCodeAt(0)|e[2]<<22;t&&(this.combinedData=e[1],this.content=2097152|e[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}},mi=`di$target`,hi=`di$dependencies`,gi=new Map;function _i(e){return e[hi]||[]}function vi(e){if(gi.has(e))return gi.get(e);let t=function(e,n,r){if(arguments.length!==3)throw Error(`@IServiceName-decorator can only be used to decorate a parameter`);yi(t,e,r)};return t._id=e,gi.set(e,t),t}function yi(e,t,n){t[mi]===t?t[hi].push({id:e,index:n}):(t[hi]=[{id:e,index:n}],t[mi]=t)}var bi=vi(`BufferService`),xi=vi(`CoreMouseService`),Si=vi(`CoreService`),Ci=vi(`CharsetService`),wi=vi(`InstantiationService`),Ti=vi(`LogService`),Ei=vi(`OptionsService`),Di=vi(`OscLinkService`),Oi=vi(`UnicodeService`),ki=vi(`DecorationService`),Ai=class{constructor(e,t,n){this._bufferService=e,this._optionsService=t,this._oscLinkService=n}provideLinks(e,t){let n=this._bufferService.buffer.lines.get(e-1);if(!n){t(void 0);return}let r=[],i=this._optionsService.rawOptions.linkHandler,a=new pi,o=n.getTrimmedLength(),s=-1,c=-1,l=!1;for(let t=0;ti?i.activate(e,t,a):ji(e,t),hover:(e,t)=>i?.hover?.(e,t,a),leave:(e,t)=>i?.leave?.(e,t,a)})}l=!1,a.hasExtendedAttrs()&&a.extended.urlId?(c=t,s=a.extended.urlId):(c=-1,s=-1)}}t(r)}};Ai=qr([B(0,bi),B(1,Ei),B(2,Di)],Ai);function ji(e,t){if(confirm(`Do you want to navigate to ${t}? +`)}function Fe(e,t,n,r){let i=Ae.find(t=>t.id===e)??Ae[0];return`https://github.com/${je}/issues/new?${new URLSearchParams({title:Ne(e,t,n),body:Pe(e,n,r),labels:i.gh}).toString()}`}var Ie=6e3;function Le(e){return e.trim().length>=8}function Re({screen:e}){let[t,n]=(0,l.useState)(!1);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{onClick:()=>n(!0),className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,title:`Report a bug, ask for something, or say what was unclear`,children:`feedback`}),t&&(0,I.jsx)(ze,{screen:e,onClose:()=>n(!1)})]})}function ze({screen:e,onClose:t}){let[n,r]=(0,l.useState)(`bug`),[i,a]=(0,l.useState)(``),o=Me(F(()=>N.status(),[],{live:!1,intervalMs:0}).data,e),s=Le(i),c=Ae.find(e=>e.id===n)??Ae[0],u=()=>{s&&(window.open(Fe(n,e,i,o),`_blank`,`noopener`),t())};return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 bg-black/50 flex items-start justify-center pt-[12vh] px-4`,onClick:t,children:(0,I.jsxs)(`div`,{className:`w-full max-w-[660px] border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`div`,{className:`px-4 pt-3 pb-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`span`,{className:`text-[15px] font-medium`,children:`Tell us what happened`}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-[16px] leading-none text-fg-faint hover:text-fg`,children:`×`})]}),(0,I.jsxs)(`div`,{className:`p-4 grid gap-3`,children:[(0,I.jsx)(`div`,{className:`flex gap-1.5`,children:Ae.map(e=>(0,I.jsx)(`button`,{onClick:()=>r(e.id),className:`text-[13px] px-3.5 py-1.5 rounded-sm border font-mono ${e.id===n?`border-accent/60 bg-accent/10 text-accent`:`border-border text-fg-muted hover:text-fg`}`,children:e.label},e.id))}),(0,I.jsx)(`textarea`,{autoFocus:!0,value:i,onChange:e=>a(e.target.value),placeholder:c.hint,rows:6,className:`input w-full resize-y text-[14px] leading-relaxed`,onKeyDown:e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&u()}}),(0,I.jsxs)(`div`,{className:`border border-border rounded-sm bg-panel-2/50 px-3 py-2`,children:[(0,I.jsx)(`div`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint mb-1`,children:`Attached`}),(0,I.jsx)(`ul`,{className:`text-[11px] text-fg-muted num grid gap-0.5`,children:o.map(e=>(0,I.jsx)(`li`,{children:e},e))})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(`button`,{onClick:u,disabled:!s,className:`text-[12px] px-3 py-1.5 rounded-sm border ${s?`border-accent/50 bg-accent/10 text-accent hover:bg-accent/20`:`border-border text-fg-faint cursor-not-allowed`}`,children:`Open a GitHub issue →`}),(0,I.jsx)(`span`,{className:`text-[12px] ${s?`text-fg-faint`:`text-fg-muted`}`,children:s?`⌘↵ to open`:`One sentence is enough.`})]}),(0,I.jsx)(`p`,{className:`text-[11px] text-fg-faint leading-relaxed`,children:`Nothing is sent from here — the issue opens prefilled in your browser for you to submit.`})]})]})})}var Be=1200,Ve=630;function He(e,t){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()||t}var Ue={command:`running commands`,edit:`writing code`,read:`reading code`,mcp:`MCP tools`,web:`web research`,other:`other tools`,none:`no tool call`};function We(e){return e.slice(e.lastIndexOf(`/`)+1).replace(/^claude-/,``).replace(/-\d{8}$/,``).slice(0,18)}function Ge(e){return e>=1e9?`${(e/1e9).toFixed(1)}B`:e>=1e6?`${Math.round(e/1e6)}M`:e>=1e3?`${Math.round(e/1e3)}k`:String(e)}function Ke(e,t){let n=He(`--color-bg`,`#141414`),r=He(`--color-panel`,`#1a1a19`),i=He(`--color-border`,`#2a2a28`),a=He(`--color-fg`,`#e8e6e2`),o=He(`--color-fg-muted`,`#a9a59e`),s=He(`--color-fg-faint`,`#6f6b64`),c=He(`--color-accent`,`#feb157`),l=He(`--color-ok`,`#7fc99a`),u=`"JetBrains Mono", ui-monospace, monospace`,d=`"Hanken Grotesk", ui-sans-serif, system-ui, sans-serif`;e.fillStyle=n,e.fillRect(0,0,Be,Ve);let f=(t,n,r,i,a=12)=>{e.beginPath(),e.moveTo(t+a,n),e.arcTo(t+r,n,t+r,n+i,a),e.arcTo(t+r,n+i,t,n+i,a),e.arcTo(t,n+i,t,n,a),e.arcTo(t,n,t+r,n,a),e.closePath()},p=(t,n,a,o)=>{f(t,n,a,o),e.fillStyle=r,e.fill(),e.strokeStyle=i,e.lineWidth=1,e.stroke()},m=(t,n,r,i,a,o=d,s=400,c=`left`)=>{e.fillStyle=a,e.font=`${s} ${i}px ${o}`,e.textAlign=c,e.fillText(r,t,n)};e.font=`600 32px ${d}`;let h=`My stats on`,g=e.measureText(` `).width,_=e.measureText(h).width;m(64,78,h,32,a,d,600);let v=64+_+g;m(v,78,`caprock.dev`,32,c,d,600);let y=e.measureText(`caprock.dev`).width,b=t.takenAt.toLocaleDateString(`en-GB`,{day:`numeric`,month:`short`,year:`numeric`});m(v+y+g*2,78,`– ${b}`,26,s,d,600),[[`TODAY`,S(t.today.cost),`${t.today.sessions} sessions`,c],[`THIS WEEK`,S(t.week.cost),`${t.week.sessions} sessions`,a],[`THIS MONTH`,S(t.month.cost),`${Ge(t.month.tokens)} tokens`,a],[`ALL TIME`,S(t.allTime.cost),`${t.allTime.days} active days`,c],[`A DAY`,S(t.allTime.cost/Math.max(1,t.allTime.days)),`on average`,a],[`TOKENS`,Ge(t.allTime.tokens),`all time`,a],[`PER 1M TOKENS`,S(t.allTime.cost/Math.max(1,t.allTime.tokens/1e6)),`what a million costs`,a],[`CACHE HIT`,`${Math.round(t.cacheHitPct)}%`,`input cost cut`,l]].forEach(([e,t,n,r],i)=>{let a=64+i%4*272,c=130+Math.floor(i/4)*114;p(a,c,256,98),m(a+20,c+30,e,13,s,u),m(a+20,c+56,t,28,r,d,600),m(a+20,c+81,n,14,o)});let x=(t,n,r,i)=>{let l=44+r.length*26+12;p(t,n,524,l),m(t+20,n+30,i,13,s,u);let d=Math.max(...r.map(e=>e.cost),1),h=r.reduce((e,t)=>e+t.cost,0),g=t+170;return r.forEach((r,i)=>{let l=n+62+i*26;m(t+20,l,r.label,14,o,u),e.fillStyle=c,e.globalAlpha=.85;let p=Math.max(2,164*(r.cost/d));f(g,l-10,p,10,Math.min(3,p/2)),e.fill(),e.globalAlpha=1,m(t+524-62,l,S(r.cost),14,a,u,400,`right`);let _=h>0?Math.max(1,Math.floor(100*r.cost/h)):0;m(t+524-20,l,`${_}%`,14,s,u,400,`right`)}),l},C=x(64,372,t.models,`WHERE THE MONEY WENT`);x(612,372,t.work,`WHAT IT WENT ON`);let w=372+C+34;m(64,w,`at API list prices — not a bill, and not money saved`,14,s),m(1136,w,`What's yours?`,15,c,d,600,`right`),e.textAlign=`left`}function qe(e=new Date){let t=e=>String(e).padStart(2,`0`);return`caprock-${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}.png`}async function Je(){let[e,t,n,r]=await Promise.all([N.summary(`today`),N.summary(`7d`),N.summary(`30d`),N.history(`all`)]),i=e=>e.tokens_in+e.tokens_out+e.cache_read+e.cache_write;return{takenAt:new Date,today:{cost:e.cost_usd,sessions:e.sessions},week:{cost:t.cost_usd,sessions:t.sessions},month:{cost:n.cost_usd,tokens:i(n)},allTime:{cost:r.totals.cost_usd,days:r.totals.days,tokens:i(r.summary)},cacheHitPct:(n.savings?.hit_rate??0)*100,models:(n.models??[]).slice(0,5).map(e=>({label:We(e.model),cost:e.cost_usd})),work:(n.work??[]).slice(0,5).map(e=>({label:Ue[e.kind]??e.kind,cost:e.cost_usd}))}}async function Ye(e){let t=document.createElement(`canvas`);t.width=Be,t.height=Ve;let n=null;try{n=t.getContext(`2d`)}catch{return null}return n?(Ke(n,e),await new Promise(e=>{if(typeof t.toBlob!=`function`){e(null);return}t.toBlob(t=>e(t),`image/png`)})):null}function Xe(e){let t=`over ${e.days} active days`;return`${S(e.cost_usd)} of Claude Code ${t}, across ${e.sessions.toLocaleString(`en-US`)} sessions — measured on my own machine with Caprock. https://caprock.dev`}function Ze(){let[e,t]=(0,l.useState)(!1);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{onClick:()=>t(!0),className:`rounded-md border border-accent/45 bg-accent/[0.08] px-2 py-0.5 text-accent hover:bg-accent/[0.16]`,title:`Draw a shareable image of your figures`,children:`Share`}),e&&(0,I.jsx)(Qe,{onClose:()=>t(!1)})]})}function Qe({onClose:e}){let[t,n]=(0,l.useState)(!1),[r,i]=(0,l.useState)(!1),[a,o]=(0,l.useState)(``),s=async()=>{let[e,t]=await Promise.all([Je(),N.history(`all`)]);return{blob:await Ye(e),text:Xe(t.totals)}},c=async()=>{if(!r){i(!0),n(!0),o(``);try{let{blob:t}=await s();if(!t){o(`Could not draw the card in this browser.`),i(!1);return}let r=new File([t],qe(),{type:`image/png`});n(!1),await navigator.share({files:[r]}),e()}catch(e){e?.name!==`AbortError`&&o(`Sharing was not available — the card was not sent.`),i(!1)}finally{n(!1)}}},u=async e=>{if(!r){i(!0),n(!0),o(``);try{let{blob:t,text:n}=await s();if(!t){o(`Could not draw the card in this browser.`);return}let r=URL.createObjectURL(t),i=document.createElement(`a`);if(i.href=r,i.download=qe(),i.click(),URL.revokeObjectURL(r),e===`download`){o(`Saved to your downloads.`);return}let a=e===`x`?`https://x.com/intent/tweet?text=${encodeURIComponent(n)}`:`https://www.linkedin.com/feed/?shareActive=true&text=${encodeURIComponent(n)}`;window.open(a,`_blank`,`noopener`),o(`Card saved and the post opened — drag the image in.`)}finally{n(!1),i(!1)}}},d=typeof navigator<`u`&&typeof navigator.canShare==`function`&&navigator.canShare({files:[new File([],`x.png`,{type:`image/png`})]});return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 flex items-start justify-center bg-black/50 px-4 pt-[14vh]`,onClick:e,role:`dialog`,"aria-modal":`true`,"aria-label":`Share your figures`,children:(0,I.jsxs)(`div`,{className:`w-[420px] max-w-full rounded-[var(--radius-panel)] border border-border-strong bg-panel`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`flex items-center border-b border-border px-4 py-3`,children:[(0,I.jsx)(`h2`,{className:`text-[13px] font-medium text-fg`,children:`Share your figures`}),(0,I.jsx)(`button`,{onClick:e,className:`ml-auto text-fg-muted hover:text-fg`,"aria-label":`Close`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`px-4 py-4`,children:[(0,I.jsxs)(`div`,{className:`grid gap-2.5`,children:[d&&(0,I.jsxs)(`button`,{onClick:c,disabled:r,className:`rounded-md border border-accent bg-accent/15 px-4 py-3 text-[14px] font-medium text-accent hover:bg-accent/25 disabled:opacity-50`,children:[t?`Drawing the card…`:`Send it somewhere`,(0,I.jsx)(`span`,{className:`mt-0.5 block text-[12px] font-normal text-fg-muted`,children:`Opens your share menu — Messages, Mail, anywhere`})]}),(0,I.jsxs)(`button`,{onClick:()=>u(`download`),disabled:r,className:`rounded-md border border-border bg-transparent px-4 py-3 text-[14px] text-fg transition-colors hover:border-border-strong hover:bg-panel-2 disabled:opacity-50`,children:[t&&!d?`Drawing the card…`:`Save the image`,(0,I.jsx)(`span`,{className:`mt-0.5 block text-[12px] text-fg-muted`,children:`A PNG in your downloads, to post wherever you like`})]})]}),(0,I.jsxs)(`ul`,{className:`mt-4 grid gap-1 text-[13px] text-fg-muted`,children:[(0,I.jsx)(`li`,{children:`Totals only — no names, no paths, nothing Claude wrote.`}),(0,I.jsx)(`li`,{children:`Drawn on your machine. Uploaded nowhere.`})]}),a&&(0,I.jsx)(`p`,{className:`mt-2 text-[12px] text-fg-muted`,children:a})]})]})})}function $e(){let e=F(()=>N.history(`all`),[],{intervalMs:6e4}),[t,n]=(0,l.useState)(!1),r=e.data?.totals;return!r||r.sessions===0?null:(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{onClick:()=>n(!0),className:`rounded-md border border-accent/45 bg-accent/[0.08] px-2.5 py-1 text-[12px] text-accent hover:bg-accent/[0.16]`,title:`Draw a shareable image of these figures`,children:`Share these numbers`}),t&&(0,I.jsx)(Qe,{onClose:()=>n(!1)})]})}var et={cap:{title:`A daily cap that pauses sessions`,body:`A number for the day. Cross it and Caprock stops its own sessions.`,points:[`A runaway loop stops at $40 instead of finishing at $400`,`It happens while you are asleep, not in tomorrow’s summary`,`Your own sessions are never touched — only the ones Caprock started`]},gemini:{title:`Ask Gemini, on your own key`,body:`A second model inside Caprock, paid for by you, at Google’s prices.`,points:[`Ask about your own sessions without leaving the dashboard`,`What it costs is counted and shown beside your Claude spend`,`Caprock never stores the key — it reads it from your environment`],setup:`Set GEMINI_API_KEY in the daemon’s environment and restart it. Google bills you directly.`},report:{title:`A weekly report, sent where you are`,body:`Monday morning, before you open a terminal.`,points:[`What moved: the repository that cost 3× its usual week`,`Last week against the one before it, per repository and model`,`Through your own Telegram bot — nothing passes our server`],setup:`Setup: one message to BotFather, about two minutes.`}};function tt({p:e,onClose:t}){return e?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,I.jsxs)(`a`,{href:e.yearly.url,target:`_blank`,rel:`noreferrer`,onClick:t,className:`rounded-sm bg-premium/75 px-3 py-2.5 text-center text-[14px] font-medium text-white no-underline hover:bg-premium`,children:[`$`,e.yearly.charged_usd,` / year`]}),(0,I.jsxs)(`a`,{href:e.lifetime?.url,target:`_blank`,rel:`noreferrer`,onClick:t,className:`rounded-sm bg-premium-strong px-3 py-2.5 text-center text-[14px] font-medium text-white no-underline hover:brightness-110`,children:[`$`,e.lifetime?.charged_usd,` once`]})]}),(0,I.jsxs)(`div`,{className:`mt-2 grid grid-cols-2 gap-2 text-center text-[11px] leading-snug text-fg-faint`,children:[(0,I.jsx)(`span`,{children:`Every Premium feature, renews yearly`}),(0,I.jsx)(`span`,{children:`Every Premium feature, now and future — no renewal`})]})]}):(0,I.jsx)(`div`,{className:`h-[92px] text-[13px] text-fg-faint`,children:`…`})}function nt({feature:e,onClose:t}){let n=F(()=>N.premium(),[]).data,r=et[e];return(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]),(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 flex items-start justify-center bg-black/50 px-4 pt-[12vh]`,onClick:t,role:`dialog`,"aria-modal":`true`,"aria-label":`Caprock Premium`,children:(0,I.jsxs)(`div`,{className:`w-[440px] max-w-full rounded-[var(--radius-panel)] border border-border-strong bg-panel`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`flex items-start gap-3 px-5 pt-4`,children:[(0,I.jsxs)(`div`,{children:[(0,I.jsx)(`p`,{className:`text-[11px] uppercase tracking-wide text-premium-strong`,children:`Caprock Premium`}),(0,I.jsx)(`h2`,{className:`mt-1 text-[16px] font-medium leading-snug text-fg`,children:r.title})]}),(0,I.jsx)(`button`,{onClick:t,className:`-mr-1 ml-auto text-fg-muted hover:text-fg`,"aria-label":`Close`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`px-5 pt-3`,children:[(0,I.jsx)(`p`,{className:`text-[13px] leading-relaxed text-fg-muted`,children:r.body}),(0,I.jsx)(`ul`,{className:`mt-3 space-y-1.5`,children:r.points.map(e=>(0,I.jsxs)(`li`,{className:`flex gap-2 text-[13px] leading-snug text-fg`,children:[(0,I.jsx)(`span`,{"aria-hidden":!0,className:`text-premium-strong`,children:`·`}),(0,I.jsx)(`span`,{children:e})]},e))}),r.setup&&(0,I.jsx)(`p`,{className:`mt-2.5 text-[12px] text-fg-faint`,children:r.setup})]}),(0,I.jsx)(`div`,{className:`mt-4 border-t border-border px-5 py-4`,children:(0,I.jsx)(tt,{p:n,onClose:t})}),(0,I.jsx)(`footer`,{className:`border-t border-border px-5 py-3 text-[12px]`,children:(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(`a`,{href:n?.info_url??`https://caprock.dev/premium/`,target:`_blank`,rel:`noreferrer`,className:`whitespace-nowrap text-fg-muted no-underline hover:text-fg`,children:`Read more`}),(0,I.jsx)(`span`,{className:`whitespace-nowrap text-fg-faint`,children:`opens a new tab`}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-fg-muted hover:text-fg`,children:`Close`})]})}),(0,I.jsx)(`p`,{className:`border-t border-border px-5 py-2.5 text-[11px] leading-relaxed text-fg-faint`,children:`Everything Caprock does now stays free and Apache-2.0 — Premium only ever adds.`})]})})}function rt(){let[e,t]=(0,l.useState)(!1),n=F(()=>N.premium(),[],{live:!1,intervalMs:3e5});if(!n.data?.yearly?.url)return null;if(n.data.license?.active)return(0,I.jsx)(`span`,{className:`text-premium-strong`,children:`premium`});let r=n.data;return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`span`,{className:`inline-flex items-center overflow-hidden rounded-sm border border-premium/60`,children:[(0,I.jsxs)(`a`,{href:r.yearly.url,target:`_blank`,rel:`noreferrer`,className:`bg-premium px-2 py-0.5 text-white no-underline hover:brightness-110`,children:[`premium $`,r.yearly.charged_usd,`/yr`]}),(0,I.jsx)(`button`,{onClick:()=>t(!0),"aria-label":`What Premium includes`,title:`What Premium includes`,className:`px-1.5 py-0.5 text-premium-strong hover:bg-premium/10`,children:`›`})]}),e&&(0,I.jsx)(nt,{feature:`cap`,onClose:()=>t(!1)})]})}var it=`https://github.com/dspv/caprock`,at=`https://caprock.dev/teams`,ot=`https://caprock.dev/premium`,st=`caprock.footer.starred`;function ct(){let[e,t]=(0,l.useState)(()=>localStorage.getItem(st)===`1`);return(0,I.jsx)(`footer`,{className:`mt-6 border-t border-border`,children:(0,I.jsxs)(`div`,{className:`max-w-[1600px] mx-auto px-3 py-4 flex flex-wrap items-center gap-x-6 gap-y-3 text-[11px] text-fg-faint`,children:[(0,I.jsxs)(`a`,{href:at,target:`_blank`,rel:`noreferrer`,className:`group inline-flex items-center gap-2 no-underline`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted group-hover:text-fg`,children:`Want this for your team?`}),(0,I.jsx)(`span`,{className:`text-accent group-hover:text-accent-strong`,children:`Caprock for Teams →`})]}),(0,I.jsxs)(`span`,{className:`ml-auto inline-flex items-center gap-4`,children:[(0,I.jsx)(`a`,{href:ot,target:`_blank`,rel:`noreferrer`,className:`text-fg-muted hover:text-fg no-underline`,title:`A daily spend cap — Caprock pauses its own sessions when the day passes a limit you set`,children:`premium`}),!e&&(0,I.jsx)(`a`,{href:it,target:`_blank`,rel:`noreferrer`,onClick:()=>{localStorage.setItem(st,`1`),t(!0)},className:`text-fg-faint hover:text-fg no-underline`,title:`Opens GitHub in a new tab`,children:`★ star on GitHub`}),(0,I.jsx)(`a`,{href:`https://caprock.dev/blog`,target:`_blank`,rel:`noreferrer`,className:`text-fg-faint hover:text-fg no-underline`,children:`blog`}),(0,I.jsx)(`a`,{href:`https://caprock.dev/docs`,target:`_blank`,rel:`noreferrer`,className:`text-fg-faint hover:text-fg no-underline`,children:`docs`})]})]})})}var lt=[{route:{name:`now`},label:`Now`},{route:{name:`cost`},label:`Cost`},{route:{name:`history`},label:`Lifetime`},{route:{name:`notes`},label:`Answers`},{route:{name:`tasks`},label:`Tasks`}];function ut(e){switch(e.name){case`now`:return`Now`;case`session`:return`Session detail`;case`cost`:return`Cost`;case`history`:return`Lifetime`;case`tasks`:return`Tasks`;case`graph`:return`Graph`;case`notes`:return`Answers`;case`settings`:return`Status`}}function dt({route:e,children:t}){let n=f(),[r,i]=De(),a=t=>t.name===e.name||t.name===`now`&&e.name===`session`;return(0,I.jsxs)(`div`,{className:`min-h-screen flex flex-col`,children:[(0,I.jsxs)(`header`,{className:`h-10 border-b border-border bg-panel flex items-center px-3 gap-4 sticky top-0 z-10`,children:[(0,I.jsxs)(`a`,{href:`#/`,className:`flex items-center gap-2 text-fg no-underline hover:no-underline`,children:[(0,I.jsxs)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 32 32`,"aria-hidden":!0,children:[(0,I.jsx)(`path`,{d:`M6 22 L16 8 L26 22 Z`,fill:`none`,stroke:`var(--color-accent)`,strokeWidth:`3`,strokeLinejoin:`round`}),(0,I.jsx)(`rect`,{x:`6`,y:`22`,width:`20`,height:`3`,fill:`var(--color-accent)`})]}),(0,I.jsx)(`span`,{className:`font-medium tracking-wide text-[13px]`,children:`caprock`}),(0,I.jsx)(`span`,{className:`text-fg-faint text-[11px] hidden sm:inline`,children:`mission control`})]}),(0,I.jsx)(`nav`,{className:`inline-flex items-center gap-0.5 ml-2 rounded-md bg-panel-2 p-0.5`,children:lt.map(e=>(0,I.jsxs)(`a`,{href:g(e.route),"aria-current":a(e.route)?`page`:void 0,className:`px-2.5 py-1 rounded-[5px] text-[12px] no-underline hover:no-underline transition-colors ${a(e.route)?`bg-accent text-panel font-medium`:`text-fg hover:text-accent`}`,children:[e.label,e.phase&&(0,I.jsx)(`span`,{className:`ml-1 text-[9px] uppercase tracking-wider text-fg-faint`,children:e.phase})]},e.label))}),(0,I.jsxs)(`div`,{className:`ml-auto flex items-center gap-3 text-[11px] text-fg-muted`,children:[(0,I.jsx)(Ze,{}),(0,I.jsx)(rt,{}),(0,I.jsx)(Re,{screen:ut(e)}),(0,I.jsx)(pt,{state:n.conn,lastFrameAt:n.lastFrameAt}),(0,I.jsx)(Oe,{plan:r,onSave:i}),(0,I.jsx)(ft,{}),(0,I.jsx)(mt,{}),(0,I.jsx)(`a`,{href:`#/settings`,className:`text-fg-muted hover:text-fg no-underline`,children:`status`})]})]}),(0,I.jsx)(`main`,{className:`flex-1 p-3 max-w-[1600px] w-full mx-auto`,children:t}),(0,I.jsx)(ct,{})]})}function ft(){let[e,t]=k(),n=e===`dark`;return(0,I.jsx)(`button`,{type:`button`,onClick:t,title:n?`Switch to light theme`:`Switch to dark theme`,"aria-label":n?`Switch to light theme`:`Switch to dark theme`,className:`text-fg-muted hover:text-fg inline-flex items-center`,children:n?(0,I.jsxs)(`svg`,{width:`15`,height:`15`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,"aria-hidden":!0,children:[(0,I.jsx)(`circle`,{cx:`12`,cy:`12`,r:`4`}),(0,I.jsx)(`path`,{d:`M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M19.1 4.9l-1.4 1.4M6.3 17.7l-1.4 1.4`})]}):(0,I.jsx)(`svg`,{width:`15`,height:`15`,viewBox:`0 0 24 24`,fill:`currentColor`,"aria-hidden":!0,children:(0,I.jsx)(`path`,{d:`M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z`})})})}function pt({state:e,lastFrameAt:t}){let n=ie(1e3),r=e===`open`?`bg-ok`:e===`connecting`?`bg-warn`:`bg-danger`,i=e===`open`?`live · ${t?ee(t,n):`connected`}`:e===`connecting`?`connecting…`:`disconnected — reconnecting`;return(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,title:e===`open`?`Connected to the daemon. The time is when it last sent anything — on an idle machine that keeps counting up, which is normal.`:`WebSocket /v1/live`,children:[(0,I.jsx)(`span`,{className:`inline-block w-1.5 h-1.5 rounded-full ${r}`}),(0,I.jsx)(`span`,{className:`num`,children:i})]})}function mt(){let e=F(()=>N.status(),[],{live:!1,intervalMs:6e4}),t=F(()=>N.update().catch(()=>void 0),[],{live:!1,intervalMs:6e4}),[n,r]=(0,l.useState)(!1),[i,a]=(0,l.useState)(!1),o=e.data?.version;if(!o)return null;let s=/^v?\d+\.\d+\.\d+$/.test(o),c=s&&t.data?.update_available?t.data.latest:void 0;return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`button`,{onClick:()=>r(!0),className:c?`mono text-[11px] text-accent hover:text-accent-strong`:`mono text-[11px] text-fg-faint hover:text-fg`,title:c?`${c} is available — you are on ${o}`:`version and updates`,children:c?`${o} → ${c}`:s?o:`dev build`}),t.data?.notes&&(0,I.jsx)(`button`,{onClick:()=>a(!0),className:`text-[11px] text-fg-faint hover:text-accent`,title:`what changed in ${t.data.notes_for??`the latest release`}`,children:`what's new`}),n&&(0,I.jsx)(gt,{onClose:()=>r(!1)}),i&&t.data&&(0,I.jsx)(ht,{u:t.data,onClose:()=>a(!1)})]})}function ht({u:e,onClose:t}){return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 bg-black/50 flex items-start justify-center pt-[10vh] px-4`,onClick:t,children:(0,I.jsxs)(`div`,{className:`w-full max-w-[620px] max-h-[76vh] flex flex-col border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg`,onClick:e=>e.stopPropagation(),role:`dialog`,"aria-label":`What's new`,children:[(0,I.jsxs)(`div`,{className:`px-4 pt-3 pb-2 border-b border-border flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[15px] font-medium`,children:`What's new`}),e.notes_for&&(0,I.jsx)(`span`,{className:`mono text-[12px] text-accent`,children:e.notes_for}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-[16px] leading-none text-fg-faint hover:text-fg`,children:`×`})]}),(0,I.jsx)(`div`,{className:`overflow-y-auto px-4 py-3`,children:(0,I.jsx)(`pre`,{className:`whitespace-pre-wrap break-words font-sans text-[13px] leading-relaxed text-fg-muted`,children:e.notes})}),(0,I.jsx)(`div`,{className:`border-t border-border px-4 py-2.5`,children:(0,I.jsx)(`a`,{href:e.url??`https://github.com/dspv/caprock/releases/latest`,target:`_blank`,rel:`noopener noreferrer`,className:`text-[12px] text-fg-faint no-underline hover:text-accent`,children:`the full release on GitHub →`})})]})})}function gt({onClose:e}){let t=F(()=>N.status(),[],{live:!1,intervalMs:0}),n=F(()=>N.update().catch(()=>void 0),[],{live:!1,intervalMs:0}),[r,i]=(0,l.useState)(!1),[a,o]=(0,l.useState)(void 0),[s,c]=(0,l.useState)(``),[u,d]=(0,l.useState)(()=>ve()??me(navigator.userAgent,navigator.userAgentData?.platform)),[f,p]=(0,l.useState)(!1),m=a??n.data,h=t.data?.version??``,g=/^v?\d+\.\d+\.\d+$/.test(h),_=!f&&ge(m?.command,u)?he(m?.command)??(u===`windows`?`macos`:u):u,v=pe(_),y=be(m?.command,v),[b,x]=(0,l.useState)(void 0),S=v.find(e=>e.label===b)??y??v[0],C=e=>{d(e),p(!0),ye(e),x(void 0)},w=async()=>{i(!0);try{o(await N.checkUpdate())}catch{}finally{i(!1)}},ee=e=>{navigator.clipboard.writeText(e),c(e),setTimeout(()=>c(``),1600)};return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 bg-black/50 flex items-start justify-center pt-[10vh] px-4`,onClick:e,children:(0,I.jsxs)(`div`,{className:`w-full max-w-[560px] max-h-[80vh] overflow-y-auto border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg`,onClick:e=>e.stopPropagation(),role:`dialog`,"aria-label":`Version and updates`,children:[(0,I.jsxs)(`div`,{className:`px-4 pt-3 pb-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`span`,{className:`text-[15px] font-medium`,children:`Version`}),(0,I.jsx)(`button`,{onClick:e,className:`ml-auto text-[16px] leading-none text-fg-faint hover:text-fg`,children:`×`})]}),(0,I.jsxs)(`div`,{className:`p-4 grid gap-3.5`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2 text-[13px]`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`running`}),(0,I.jsx)(`span`,{className:`mono text-fg`,children:g?h:`${h} (local build)`}),m?.update_available&&(0,I.jsxs)(`span`,{className:`mono text-accent`,children:[`→ `,m.latest,` is out`]})]}),m?.enabled===!1?(0,I.jsxs)(`div`,{className:`text-[13px] text-fg-muted`,children:[`Release checks are off, so this copy never asks GitHub what the latest version is. Turn them on in`,` `,(0,I.jsx)(`a`,{href:`#/status`,onClick:e,className:`text-accent no-underline hover:text-accent-strong`,children:`status`}),`.`]}):m?.update_available?null:(0,I.jsx)(`div`,{className:`text-[13px] text-fg-muted`,children:m?.latest?`Up to date — ${m.latest} is the latest release.`:`No newer release found.`}),(0,I.jsxs)(`div`,{className:`grid gap-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-1`,children:[se.map(e=>(0,I.jsx)(`button`,{onClick:()=>C(e.id),className:`rounded-sm px-2.5 py-1 text-[12px] transition-colors ${_===e.id?`bg-accent text-panel font-medium`:`text-fg-muted hover:text-fg`}`,children:e.label},e.id)),v.length>1&&(0,I.jsx)(`span`,{className:`ml-auto flex items-center gap-1`,children:v.map(e=>(0,I.jsxs)(`button`,{onClick:()=>x(e.label),className:`rounded-sm px-2 py-1 text-[11px] transition-colors ${S.label===e.label?`text-accent`:`text-fg-faint hover:text-fg-muted`}`,title:e.label===y?.label?`how this copy appears to be installed`:void 0,children:[e.label,e.label===y?.label?` ·`:``]},e.label))})]}),(0,I.jsx)(`ol`,{className:`grid gap-2.5`,children:S.steps.map((e,t)=>(0,I.jsxs)(`li`,{className:`grid gap-1`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-faint`,children:t+1}),e.cmd?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`code`,{className:`mono flex-1 truncate rounded-sm border border-border bg-bg px-2 py-1.5 text-[13px] text-fg`,children:e.cmd}),(0,I.jsx)(`button`,{onClick:()=>ee(e.cmd),className:`shrink-0 rounded-md border border-accent/45 bg-accent/[0.08] px-2.5 py-1.5 text-[12px] text-accent hover:bg-accent/[0.16]`,children:s===e.cmd?`copied`:`copy`})]}):(0,I.jsx)(`a`,{href:m?.url??`https://github.com/dspv/caprock/releases/latest`,target:`_blank`,rel:`noopener noreferrer`,className:`flex-1 rounded-sm border border-border bg-bg px-2 py-1.5 text-[13px] text-accent no-underline hover:text-accent-strong`,children:`Open the release page →`})]}),(0,I.jsx)(`p`,{className:`pl-5 text-[11px] leading-relaxed text-fg-faint`,children:e.note})]},t))})]}),(0,I.jsx)(`div`,{className:`text-[11px] leading-relaxed text-fg-faint border-t border-border pt-3`,children:`Caprock does not update itself: it would have to overwrite its own binary while running, and where a package manager owns that binary, replacing it behind their back breaks the next upgrade.`}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(`button`,{onClick:w,disabled:r,className:`rounded-md border border-border px-3 py-1.5 text-[13px] text-fg-muted hover:text-fg disabled:opacity-50`,children:r?`checking…`:`check now`}),(0,I.jsx)(`a`,{href:m?.url??`https://github.com/dspv/caprock/releases/latest`,target:`_blank`,rel:`noopener noreferrer`,className:`text-[12px] text-fg-faint no-underline hover:text-accent`,children:`release notes →`})]})]})]})})}var _t=class extends l.Component{state={error:null};static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error(`[caprock ui]`,e,t.componentStack)}render(){return this.state.error?(0,I.jsxs)(`div`,{className:`border border-danger/50 bg-danger/10 rounded-[var(--radius-panel)] px-3 py-2 text-[12px]`,children:[(0,I.jsxs)(`div`,{className:`text-danger font-medium`,children:[this.props.label??`This view`,` failed to render`]}),(0,I.jsx)(`div`,{className:`mono text-fg-muted mt-1`,children:this.state.error.message}),(0,I.jsx)(`button`,{className:`mt-2 border border-border px-2 py-0.5 rounded-sm text-fg-muted hover:text-fg`,onClick:()=>this.setState({error:null}),children:`retry`})]}):this.props.children}};function L({title:e,center:t,right:n,children:r,className:i=``,onMouseEnter:a,onMouseLeave:o}){return(0,I.jsxs)(`section`,{className:`border border-border bg-panel rounded-[var(--radius-panel)] shadow-[var(--shadow-panel)] min-w-0 ${i}`,onMouseEnter:a,onMouseLeave:o,children:[(e||t||n)&&(0,I.jsxs)(`header`,{className:`relative flex items-center justify-between px-3 py-2 border-b border-border bg-panel-2/60 rounded-t-[var(--radius-panel)]`,children:[(0,I.jsx)(`h2`,{className:`text-[11px] uppercase tracking-[0.12em] text-fg-muted font-medium`,children:e}),t?(0,I.jsx)(`div`,{className:`absolute left-1/2 -translate-x-1/2`,children:t}):null,(0,I.jsx)(`div`,{className:`text-[11px] text-fg-muted`,children:n})]}),(0,I.jsx)(`div`,{children:r})]})}function R({label:e,value:t,sub:n,tone:r,size:i=`default`}){return(0,I.jsxs)(`div`,{className:`flex h-full flex-col px-3 py-2.5 min-w-0`,children:[(0,I.jsx)(`div`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:e}),(0,I.jsx)(`div`,{className:`num font-semibold tracking-[-0.01em] ${i===`hero`?`text-[34px] leading-[1.05]`:i===`compact`?`text-[17px] leading-tight`:`text-[24px] leading-[1.1]`} ${r===`ok`?`text-ok`:r===`warn`?`text-warn`:r===`danger`?`text-danger`:r===`info`?`text-info`:`text-fg`}`,children:t}),n&&(0,I.jsx)(`div`,{className:`mt-auto pt-1 text-[11px] text-fg-muted num truncate`,children:n})]})}var vt={working:`working`,idle:`idle`,"waiting-on-you":`waiting on you`,looping:`looping?`,error:`error`,ended:`ended`};function yt(e){switch(e){case`working`:return`ok`;case`idle`:return`warn`;case`waiting-on-you`:return`warn`;case`looping`:return`danger`;case`error`:return`danger`;case`ended`:return`muted`}}function bt({health:e}){let t=yt(e);return(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 border rounded-sm px-1.5 py-[1px] text-[11px] leading-4 ${t===`ok`?`text-ok border-ok/40 bg-ok/10`:t===`warn`?`text-warn border-warn/40 bg-warn/10`:t===`danger`?`text-danger border-danger/40 bg-danger/10`:`text-fg-muted border-border bg-panel-2`}`,children:[(0,I.jsx)(`span`,{className:`inline-block w-1.5 h-1.5 rounded-full ${t===`ok`?`bg-ok`:t===`warn`?`bg-warn`:t===`danger`?`bg-danger`:`bg-fg-faint`} ${e===`working`?`animate-pulse`:``}`}),vt[e]]})}function xt({values:e,width:t=120,height:n=24,tone:r=`info`}){if(e.length<2)return(0,I.jsx)(`svg`,{width:t,height:n,"aria-hidden":!0});let i=Math.max(...e,1e-9),a=Math.min(...e,0),o=i-a||1,s=t/(e.length-1),c=e.map((e,t)=>`${(t*s).toFixed(1)},${(n-(e-a)/o*(n-2)-1).toFixed(1)}`).join(` `),l=r===`ok`?`var(--color-ok)`:r===`warn`?`var(--color-warn)`:r===`danger`?`var(--color-danger)`:r===`accent`?`var(--color-accent)`:`var(--color-info)`;return(0,I.jsx)(`svg`,{width:t,height:n,viewBox:`0 0 ${t} ${n}`,className:`block`,"aria-hidden":!0,children:(0,I.jsx)(`polyline`,{fill:`none`,stroke:l,strokeWidth:`1.25`,points:c,vectorEffect:`non-scaling-stroke`})})}function z({title:e,children:t}){return(0,I.jsxs)(`div`,{className:`px-4 py-10 text-center`,children:[(0,I.jsx)(`div`,{className:`text-fg-muted`,children:e}),t&&(0,I.jsx)(`div`,{className:`text-[12px] text-fg-faint mt-1`,children:t})]})}function St({rows:e=3,className:t=``}){return(0,I.jsx)(`div`,{className:`px-3 py-2 grid gap-2 ${t}`,"aria-hidden":!0,children:Array.from({length:e},(e,t)=>(0,I.jsx)(`div`,{className:`h-3 rounded-sm bg-panel-2 skeleton-pulse`,style:{width:`${[92,74,83,61,88][t%5]}%`}},t))})}function Ct({command:e,className:t=``}){let[n,r]=(0,l.useState)(!1);return(0,I.jsx)(`button`,{className:`mono text-[12px] bg-panel-2 border border-border px-2 py-0.5 rounded-sm hover:border-border-strong text-fg text-left ${t}`,onClick:()=>{navigator.clipboard?.writeText(e).then(()=>{r(!0),window.setTimeout(()=>r(!1),1500)})},title:`copy to clipboard — run it in your terminal`,children:n?`copied`:`$ ${e}`})}var wt={edit:{label:`writing code`,title:`Turns that wrote to a file — Edit, Write, NotebookEdit.`},command:{label:`running commands`,title:`Turns that ran a shell command — builds, tests, git, anything through Bash. The command itself is free; what costs is the turn that issued it and read its output.`},read:{label:`reading and searching`,title:`Turns that read or searched the codebase — Read, Grep, Glob. The file contents enter the prompt and are billed, which is why reading is not free.`},web:{label:`web research`,title:`Turns that fetched or searched the web — WebFetch, WebSearch.`},mcp:{label:`MCP tools`,title:`Turns that called one of your own MCP integrations.`},other:{label:`other tools`,title:`Turns that called a tool in none of the categories above — subagents, task and skill control, and any tool Caprock does not yet know by name.`},none:{label:`no tool call`,title:`Turns that called no tool at all. They may have been reasoning, planning, answering a question or writing prose — Caprock records which tools ran, not what a turn was thinking, so it does not claim to know which.`}},Tt=`Each turn counts toward one kind of work, decided by the tools it called: writing a file wins over running a command, which wins over reading or searching, then web, then an MCP tool, then anything else. A turn that called no tool is counted as exactly that. Each turn goes whole to one row, never split, so the rows add up to the total exactly.`;function Et({summary:e}){let t=e,n=t?.work??[],r=t?.work_unlinked_calls??0,i=t?.tool_calls??0,a=r>0&&i>0&&r/i>.01;return(0,I.jsxs)(L,{title:`What it went on`,right:(0,I.jsx)(`span`,{title:Tt,children:`by cost`}),children:[t?n.length===0&&(0,I.jsx)(z,{title:`No priced turns in range`}):(0,I.jsx)(St,{rows:4}),(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:n.map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1`,title:wt[e.kind]?.title,children:wt[e.kind]?.label??e.kind}),(0,I.jsxs)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:[e.turns,` turns`]}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:S(e.cost_usd)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-faint w-14`,children:w(e.cost_pct)})]},e.kind))})}),a&&(0,I.jsxs)(`div`,{className:`mx-3 mb-2.5 text-[11px] text-warn`,children:[r.toLocaleString(),` tool calls in this range could not be matched to the turn that paid for them, so their cost is counted under “no tool call” rather than the work they actually did. Every other row is understated by up to that much.`]})]})}function Dt({summary:e}){let t=e?.work??[],n=e?.work_unlinked_calls??0,r=e?.tool_calls??0;if(t.length===0||r===0||n/r>.2)return null;let i=t.filter(e=>e.cost_pct>=1).slice(0,5);return i.length===0?null:(0,I.jsxs)(`div`,{className:`border-t border-border px-3 py-2.5`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:`what it went on`}),(0,I.jsx)(`a`,{href:`#/cost`,className:`text-[10px] text-fg-faint hover:text-accent no-underline`,children:`details →`})]}),(0,I.jsx)(`div`,{className:`mt-2 flex h-1.5 w-full overflow-hidden rounded-full bg-panel-2`,title:Tt,children:i.map((e,t)=>(0,I.jsx)(`span`,{className:`h-full`,style:{width:`${e.cost_pct}%`,background:`var(--color-accent)`,opacity:1-t*.17}},e.kind))}),(0,I.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-x-4 gap-y-1`,children:i.map((e,t)=>(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-1.5 text-[11px]`,children:[(0,I.jsx)(`span`,{className:`inline-block h-2 w-2 rounded-[2px] translate-y-[1px]`,style:{background:`var(--color-accent)`,opacity:1-t*.17}}),(0,I.jsx)(`span`,{className:`text-fg-muted`,title:wt[e.kind]?.title,children:wt[e.kind]?.label??e.kind}),(0,I.jsx)(`span`,{className:`num text-fg-faint`,children:w(e.cost_pct)})]},e.kind))})]})}var Ot=.62;function kt(e,t){return e?t===`tokens`?e.tokens??[]:e.cost??[]:[]}function At(e,t,n){let r=kt(e,t);if(!e||r.length===0)return[];let i=n>0?n:0;return r.map((t,n)=>{let r=Number.isFinite(t)&&t>0?t:0,a=i>0&&r>0?Math.min(1,r/i)**+Ot:0;return{value:r,at:e.from_ms+n*e.width_ms,height:a,empty:r<=0}})}function jt(e,t){let n=0;for(let r of e)for(let e of kt(r,t))Number.isFinite(e)&&e>n&&(n=e);return n}function Mt(e,t){let n=new Date(e);return t<864e5?n.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):n.toLocaleDateString([],{month:`short`,day:`numeric`})}function Nt(e){return e.split(`/`).filter(Boolean)}function Pt(e,t=3){let n=[],r=new Map,i=[],a=(e,t)=>{let n=r.get(e);if(n)return n;let o=Nt(e),s={path:e,name:o.length===0?`/`:o[o.length-1],depth:t,tokens:0,cost:0,turns:0,tokensPct:0,costPct:0,ownTokens:0,ownCost:0,ownTurns:0,ownTokensPct:0,ownCostPct:0,children:[],rolledUp:0};if(r.set(e,s),t===0)i.push(s);else{let e=t===1?`/`:`/`+o.slice(0,t-1).join(`/`);a(e,t-1).children.push(s)}return s};for(let r of e){if(r.unattributed||r.outside){n.push(r);continue}let e=Nt(r.path),i=e.length,o=Math.min(i,t),s=a(o===0?`/`:`/`+e.slice(0,o).join(`/`),o);s.ownTokens+=r.tokens,s.ownCost+=r.cost_usd,s.ownTurns+=r.turns,s.ownTokensPct+=r.tokens_pct,s.ownCostPct+=r.cost_pct,i>o&&s.rolledUp++;for(let t=0;t<=o;t++){let n=a(t===0?`/`:`/`+e.slice(0,t).join(`/`),t);n.tokens+=r.tokens,n.cost+=r.cost_usd,n.tokensPct+=r.tokens_pct,n.costPct+=r.cost_pct,n.turns+=r.turns}}let o=i[0],s=i;o&&o.path===`/`&&(s=[...o.children],(o.ownTokens>0||o.ownCost>0||o.ownTurns>0||o.rolledUp>0)&&s.push({...o,depth:1,tokens:o.ownTokens,cost:o.ownCost,turns:o.ownTurns,tokensPct:o.ownTokensPct,costPct:o.ownCostPct,children:[],ownTokens:o.ownTokens,ownCost:o.ownCost,ownTurns:o.ownTurns}));let c=e=>{e.sort((e,t)=>t.cost-e.cost);for(let t of e)c(t.children)};return c(s),{roots:s,buckets:n}}function Ft(e){return e.map(e=>{let t=e;for(;t.children.length===1&&t.ownTokens===0&&t.ownCost===0&&t.ownTurns===0&&t.rolledUp===0;)t=t.children[0];return{...t,children:Ft(t.children)}})}var It=[{key:`all`,label:`all`},{key:`claude`,label:`claude`},{key:`opencode`,label:`opencode`}],Lt=[{key:`today`,label:`today`},{key:`7d`,label:`7d`},{key:`30d`,label:`30d`},{key:`all`,label:`all`}],Rt=`tokens`,zt=`A turn counts toward the directory of the most recent file it touched, and keeps counting there until it touches a file somewhere else — so the commands, tests and searches between two edits count toward the directory being worked on. Reading, editing or writing a file counts as touching it; running a command does not. Each turn goes whole to one row, never split between two, so the rows add up to the repository total exactly.`,Bt=`repository-wide work`,Vt=`Turns from the start of a session, before Claude had touched any file — so there is no directory yet for them to count toward. Their cost is counted here whole rather than guessed onto the directory the session reached later.`,Ht=`outside the repository`,Ut=`Turns whose most recent file touch was outside this repository — Claude’s notes on the project, agent scratchpads, test-output directories, or another checkout. This is real work and it counts toward the repository total, but it happened outside the tree, so it is not charged to any directory inside it.`;function Wt({sessions:e,agent:t}){let[n,r]=(0,l.useState)(`7d`),[i,a]=(0,l.useState)(!1),o=F(()=>N.summary(n),[n],{intervalMs:3e4}),s=o.data?.projects??[],c=(0,l.useMemo)(()=>t===`all`?s:s.filter(e=>!e.agent||e.agent===t),[s,t]),[u,d]=(0,l.useState)(null),f=(0,l.useMemo)(()=>{if(!u)return c;let e=new Map(u.map((e,t)=>[e,t]));return[...c].sort((t,n)=>(e.get(t.project)??1/0)-(e.get(n.project)??1/0))},[c,u]),p=i?f:f.slice(0,6),m=c.reduce((e,t)=>e+t.cost_usd,0),h=c.reduce((e,t)=>e+t.tokens,0),g=(0,l.useMemo)(()=>jt(p.map(e=>e.spark),Rt),[p]),_=(0,l.useMemo)(()=>p.reduce((e,t)=>Math.max(e,t.tokens),0),[p]);return(0,I.jsx)(L,{onMouseEnter:()=>d(c.map(e=>e.project)),onMouseLeave:()=>d(null),title:`Projects`,right:(0,I.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,I.jsxs)(`span`,{className:`num text-[13px]`,children:[(0,I.jsx)(`span`,{className:`text-fg`,children:C(h)}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[` · `,S(m),` total`]})]}),(0,I.jsx)(`span`,{className:`inline-flex border border-border rounded-sm overflow-hidden`,children:Lt.map(e=>(0,I.jsx)(`button`,{onClick:()=>r(e.key),className:`px-1.5 py-0.5 text-[11px] mono ${n===e.key?`bg-panel-2 text-fg`:`text-fg-faint hover:text-fg-muted`}`,children:e.label},e.key))})]}),children:o.data?c.length===0?(0,I.jsx)(`div`,{className:`px-3 py-4 text-[12px] text-fg-muted`,children:`No spend captured in this range yet.`}):(0,I.jsxs)(`div`,{className:`grid`,children:[p.map(t=>(0,I.jsx)(Kt,{p:t,max:_,ceiling:g,live:Gt(e).has(t.project)},t.project||`(unknown)`)),c.length>6&&(0,I.jsx)(`button`,{onClick:()=>a(e=>!e),className:`text-[11px] text-fg-faint hover:text-fg-muted px-3 py-1.5 text-left border-t border-border`,children:i?`show less`:`show all ${c.length} projects`}),(0,I.jsx)(Dt,{summary:o.data}),(0,I.jsx)(Zt,{count:c.length})]}):(0,I.jsx)(St,{rows:5})})}function Gt(e){return new Set(e.filter(e=>e.status!==`ended`).map(e=>e.project).filter(Boolean))}function Kt({p:e,max:t,ceiling:n,live:r}){let i=e.paths??[],a=i.length>1,[o,s]=(0,l.useState)(!1),c=e.project||`unknown project`,u=t>0?100*e.tokens/t:0,d=(0,l.useMemo)(()=>At(e.spark,Rt,n),[e.spark,n]),f=(0,l.useMemo)(()=>{let e=Pt(i);return{roots:Ft(e.roots),buckets:e.buckets}},[i]),p=(0,l.useMemo)(()=>Math.max(0,...f.roots.map(e=>e.tokens),...f.buckets.map(e=>e.tokens)),[f]),m=(0,I.jsxs)(`div`,{className:`grid grid-cols-[1fr_128px_auto] items-center gap-3 w-full text-left`,children:[(0,I.jsx)(`div`,{className:`min-w-0`,children:(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[r&&(0,I.jsx)(`span`,{className:`inline-block w-1.5 h-1.5 rounded-full bg-ok shrink-0`,title:`a session is live in this project`}),(0,I.jsx)(`span`,{className:`truncate text-[14px]`,children:c}),e.agent===`opencode`&&(0,I.jsx)(`span`,{className:`shrink-0 text-[9px] uppercase tracking-[0.08em] text-fg-faint border border-border px-1 rounded-sm`,children:`oc`}),(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-faint num shrink-0`,children:[e.sessions,` `,e.sessions===1?`session`:`sessions`]}),a&&(0,I.jsx)(`span`,{"aria-hidden":!0,className:`text-[9px] text-fg-faint shrink-0 transition-transform ${o?`rotate-90`:``}`,children:`▶`})]})}),d.length>0?(0,I.jsx)(Xt,{bars:d,widthMs:e.spark?.width_ms??0,label:c}):(0,I.jsx)(`div`,{className:`h-1 bg-panel-2 rounded-sm overflow-hidden`,title:`${c}: share of the largest project`,children:(0,I.jsx)(`div`,{className:`h-full bg-accent/70`,style:{width:`${u}%`}})}),(0,I.jsxs)(`div`,{className:`text-right shrink-0`,children:[(0,I.jsx)(`div`,{className:`num text-[17px] font-semibold leading-tight text-accent`,children:C(e.tokens)}),(0,I.jsx)(`div`,{className:`num text-[13px] leading-tight text-fg-muted`,children:S(e.cost_usd)})]})]});return(0,I.jsxs)(`div`,{className:`border-t border-border first:border-t-0`,children:[a?(0,I.jsx)(`button`,{type:`button`,onClick:()=>s(e=>!e),"aria-expanded":o,className:`w-full px-3 py-1.5 hover:bg-panel-2/50`,title:`${c}: show cost by directory`,children:m}):(0,I.jsx)(`div`,{className:`px-3 py-1.5`,children:m}),a&&o&&(0,I.jsxs)(`div`,{className:`pb-1.5 bg-panel-2/30`,children:[(0,I.jsx)(`div`,{className:`pl-7 pr-3 pt-1 pb-0.5 text-[10px] text-fg-faint`,title:zt,children:`by files touched · share of this repository's tokens`}),f.roots.map(e=>(0,I.jsx)(qt,{n:e,max:p},e.path)),f.buckets.length>0&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`div`,{className:`pl-7 pr-3 pt-2 pb-0.5 text-[10px] uppercase tracking-[0.08em] text-fg-faint`,children:`not a directory`}),f.buckets.map(e=>(0,I.jsx)(Jt,{q:e,max:p},e.path))]})]})]})}function qt({n:e,max:t}){let[n,r]=(0,l.useState)(!1),i=t>0?100*e.tokens/t:0,a=e.children.length>0,o=(0,l.useMemo)(()=>Math.max(0,...e.children.map(e=>e.tokens)),[e.children]),s=a&&e.ownCost>0,c=e.children.length,u=(0,I.jsxs)(`div`,{className:`grid grid-cols-[1fr_auto] items-center gap-3 w-full text-left`,children:[(0,I.jsxs)(`div`,{className:`min-w-0`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`truncate text-[12px] text-fg-muted mono`,children:e.path}),e.rolledUp>0&&(0,I.jsxs)(`span`,{className:`text-[10px] text-fg-faint shrink-0`,title:`${e.rolledUp} ${e.rolledUp===1?`directory`:`directories`} below this one ${e.rolledUp===1?`is`:`are`} counted here rather than shown: the breakdown stops at 3 levels.`,children:[`+`,e.rolledUp,` deeper`]}),(0,I.jsxs)(`span`,{className:`text-[10px] text-fg-faint num shrink-0`,children:[e.turns,` `,e.turns===1?`turn`:`turns`]}),a&&(0,I.jsx)(`span`,{"aria-hidden":!0,className:`text-[9px] text-fg-faint shrink-0 transition-transform ${n?`rotate-90`:``}`,children:`▶`})]}),s&&(0,I.jsxs)(`div`,{className:`text-[10px] text-fg-faint mt-0.5`,children:[S(e.ownCost),` here · `,S(e.cost-e.ownCost),` in `,c,` `,c===1?`subdirectory`:`subdirectories`]}),(0,I.jsx)(`div`,{className:`h-0.5 mt-1 bg-panel-2 rounded-sm overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full bg-accent/40`,style:{width:`${i}%`}})})]}),(0,I.jsxs)(`div`,{className:`text-right shrink-0 num text-[12px]`,title:`${Yt(e.costPct)} of this repository's cost`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:C(e.tokens)}),(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` `,Yt(e.tokensPct)]}),(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` · `,S(e.cost)]})]})]}),d={paddingLeft:`${28+(e.depth-1)*14}px`};return(0,I.jsxs)(`div`,{children:[a?(0,I.jsx)(`button`,{type:`button`,onClick:()=>r(e=>!e),"aria-expanded":n,className:`w-full pr-3 py-1 hover:bg-panel-2/50`,style:d,title:`${e.path}: show the directories inside it`,children:u}):(0,I.jsx)(`div`,{className:`pr-3 py-1`,style:d,children:u}),a&&n&&e.children.map(e=>(0,I.jsx)(qt,{n:e,max:o},e.path))]})}function Jt({q:e,max:t}){let n=t>0?100*e.tokens/t:0,r=e.unattributed===!0;return(0,I.jsxs)(`div`,{className:`grid grid-cols-[1fr_auto] items-center gap-3 pl-7 pr-3 py-1`,children:[(0,I.jsxs)(`div`,{className:`min-w-0`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`truncate text-[12px] text-fg-muted`,title:r?Vt:Ut,children:r?Bt:Ht}),(0,I.jsxs)(`span`,{className:`text-[10px] text-fg-faint num shrink-0`,children:[e.turns,` `,e.turns===1?`turn`:`turns`]})]}),(0,I.jsx)(`div`,{className:`h-0.5 mt-1 bg-panel-2 rounded-sm overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full bg-fg-faint/30`,style:{width:`${n}%`}})})]}),(0,I.jsxs)(`div`,{className:`text-right shrink-0 num text-[12px]`,title:`${Yt(e.cost_pct)} of this repository's cost`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:C(e.tokens)}),(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` `,Yt(e.tokens_pct)]}),(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` · `,S(e.cost_usd)]})]})]})}function Yt(e){return!Number.isFinite(e)||e<=0?`0%`:e<.1?`<0.1%`:w(e)}function Xt({bars:e,widthMs:t,label:n}){let r=(0,l.useRef)(null);(0,l.useEffect)(()=>{let t=r.current;if(!t)return;let n=()=>{let n=t.clientWidth,r=t.clientHeight;if(n===0||r===0)return;let i=window.devicePixelRatio||1;t.width=Math.round(n*i),t.height=Math.round(r*i);let a=t.getContext(`2d`);if(!a)return;a.setTransform(i,0,0,i,0,0),a.clearRect(0,0,n,r);let o=getComputedStyle(t),s=o.getPropertyValue(`--color-accent`).trim()||`#feb157`,c=o.getPropertyValue(`--color-fg-faint`).trim()||`#837f78`,l=n/e.length;for(let t=0;ti.disconnect()},[e]);let i=e.filter(e=>!e.empty),a=i[0],o=i[i.length-1],s=!a||!o?`no spend in this range`:a===o?`all of it on ${Mt(a.at,t)}`:`${Mt(a.at,t)} → ${Mt(o.at,t)}`;return(0,I.jsx)(`canvas`,{ref:r,className:`w-full h-[14px] block`,role:`img`,"aria-label":`${n}: ${Rt} over time, ${s}`,title:`${n}: when the spend happened — ${s}`})}function Zt({count:e}){return e<10?null:(0,I.jsxs)(`a`,{href:`https://caprock.dev/teams`,target:`_blank`,rel:`noreferrer`,className:`flex items-baseline gap-2 border-t border-border px-3 py-1.5 text-[11px] no-underline hover:no-underline`,children:[(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[e,` repositories on one machine.`]}),(0,I.jsx)(`span`,{className:`text-fg-faint hover:text-accent`,children:`See them across the team →`})]})}function Qt(e){return typeof e==`string`?e:``}function $t(e){let t=e.split(/[/\\]/).filter(Boolean);return t[t.length-1]??e}function en(e,t){let n=e.replace(/\s+/g,` `).trim(),r=[...n];return r.length>t?r.slice(0,t-1).join(``)+`…`:n}function tn(e){return e.replace(/(\/[\w.@%+-]+){3,}/g,e=>`…/`+e.split(`/`).filter(Boolean).slice(-2).join(`/`))}function nn(e,t){switch(e){case`Edit`:case`NotebookEdit`:return Qt(t.file_path)?{icon:`✎`,text:`editing`,detail:$t(Qt(t.file_path))}:null;case`Write`:return Qt(t.file_path)?{icon:`✎`,text:`writing`,detail:$t(Qt(t.file_path))}:null;case`Read`:return Qt(t.file_path)?{icon:`◇`,text:`reading`,detail:$t(Qt(t.file_path))}:null;case`Bash`:return Qt(t.command)?{icon:`$`,text:`running`,detail:en(tn(Qt(t.command)),46)}:null;case`Grep`:case`Glob`:return{icon:`⌕`,text:`searching`,detail:en(Qt(t.pattern)||Qt(t.query),40)||void 0};case`WebFetch`:case`WebSearch`:return{icon:`⇢`,text:`fetching`,detail:en(Qt(t.url)||Qt(t.query),44)||void 0};case`Agent`:return{icon:`⚑`,text:`spawned a subagent`,detail:Qt(t.subagent_type)||void 0};case`Skill`:return{icon:`⚑`,text:`invoked skill`,detail:Qt(t.skill)||void 0};case`TodoWrite`:return{icon:`☑`,text:`updated its plan`};default:return e?{icon:`·`,text:`used`,detail:e}:null}}function rn(e,t){let n=e.payload??{},r=Date.parse(e.ts),i={id:`${e.id}`,ts:Number.isNaN(r)?Date.now():r,sessionId:e.session_id,project:t};switch(e.kind){case`tool.pre`:{let t=nn(Qt(n.tool_name)||Qt(e.tool),n.tool_input??{});return t?{...i,...t,tone:`normal`}:null}case`tool.post`:return n.is_error?{...i,icon:`✕`,text:`a tool call failed`,tone:`danger`}:null;case`agent.spawn`:return{...i,icon:`▸`,text:`session started`,tone:`ok`};case`agent.stop`:return{...i,icon:`■`,text:`session ended`,tone:`normal`};case`context.compact`:return{...i,icon:`⇱`,text:`compacted its context`,tone:`warn`};case`throttle`:return{...i,icon:`⏳`,text:`rate-limited by the API`,tone:`warn`};case`task.created`:return{...i,icon:`+`,text:`task created`,tone:`normal`};case`task.done`:return{...i,icon:`✓`,text:`task verified — tests passed`,tone:`ok`};case`approval.requested`:return{...i,icon:`!`,text:`needs your approval`,tone:`warn`};default:return null}}function an(e,t,n=60){return e.some(e=>e.id===t.id)?e:[t,...e].slice(0,n)}function on({sessions:e,now:t,emptyHint:n}){let[r,i]=(0,l.useState)([]),[a,o]=(0,l.useState)(!1),s=(0,l.useRef)(new Map),c=(0,l.useRef)(a);c.current=a;for(let t of e)t.project&&s.current.set(t.session_id,t.project);(0,l.useEffect)(()=>{let t=!1;return(async()=>{let n=[...e].sort((e,t)=>t.last_event_at-e.last_event_at).slice(0,4),r=await Promise.all(n.map(e=>N.events(e.session_id,0,60).catch(()=>[])));if(t)return;let a=r.flat().map(e=>rn(e)).filter(e=>e!==null).sort((e,t)=>t.ts-e.ts).slice(0,40);i(e=>{let t=new Set(n.map(e=>e.session_id)),r=e.filter(e=>!e.sessionId||t.has(e.sessionId)),i=new Set(r.map(e=>e.id));return[...r,...a.filter(e=>!i.has(e.id))].sort((e,t)=>t.ts-e.ts).slice(0,60)})})(),()=>{t=!0}},[e.map(e=>e.session_id).join(`,`)]);let u=(0,l.useRef)(new Set);return u.current=new Set(e.map(e=>e.session_id)),(0,l.useEffect)(()=>d.onFrame(e=>{if(e.type!==`event`||c.current)return;let t=e.data?.session_id;if(t&&s.current.has(t)&&!u.current.has(t))return;let n=rn(e.data);n&&i(e=>an(e,n))}),[]),(0,I.jsx)(L,{title:`Live activity`,right:(0,I.jsx)(`button`,{onClick:()=>o(e=>!e),className:`text-[11px] mono text-fg-faint hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,children:a?`resume`:`pause`}),children:r.length===0?(0,I.jsx)(`div`,{className:`px-3 py-4 text-[12px] text-fg-muted`,children:n??(0,I.jsxs)(I.Fragment,{children:[`Nothing yet — start `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` in any terminal.`]})}):(0,I.jsxs)(`div`,{className:`relative`,children:[(0,I.jsx)(`div`,{className:`max-h-[420px] overflow-y-auto`,children:r.map(e=>(0,I.jsx)(cn,{it:e,now:t,project:s.current.get(e.sessionId)},e.id))}),(0,I.jsx)(`div`,{className:`pointer-events-none absolute inset-x-0 bottom-0 h-8 bg-gradient-to-t from-panel to-transparent`})]})})}function sn(e){switch(e){case`ok`:return`text-ok`;case`warn`:return`text-warn`;case`danger`:return`text-danger`;default:return`text-fg-faint`}}function cn({it:e,now:t,project:n}){return(0,I.jsxs)(`a`,{href:g({name:`session`,id:e.sessionId}),className:`grid grid-cols-[auto_auto_1fr_auto] items-baseline gap-2 px-3 py-1 border-t border-border first:border-t-0 hover:bg-panel-2 no-underline text-fg`,children:[(0,I.jsx)(`span`,{className:`mono text-[12px] w-3 text-center ${sn(e.tone)}`,children:e.icon}),(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-muted truncate max-w-[12ch]`,children:n??e.project??T(e.sessionId)}),(0,I.jsxs)(`span`,{className:`text-[12px] truncate`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:e.text}),e.detail&&(0,I.jsx)(`span`,{className:`mono text-fg ml-1.5`,children:e.detail})]}),(0,I.jsx)(`span`,{className:`num text-[11px] text-fg-faint`,children:ee(e.ts,t)})]})}function ln(e){return e?.plan_kind===`metered`?`at API list price · ≈ your bill`:e?.plan_kind===`flat`?`at API list price · not a bill`:`at API list price`}function un(e){return e?.plan_kind===`metered`?`Priced from your captured tokens at Anthropic list prices. You are billed per token, so this is approximately your actual cost.`:e?.plan_kind===`flat`?`Priced from your captured tokens at Anthropic list prices. You pay ${e.plan_label||`a flat plan`}, so this is what the same work would have cost through the API — not money out of pocket.`:`Priced from your captured tokens at Anthropic list prices. Whether that is your actual bill depends on how you pay — set your plan in the header.`}function dn({plan:e}){let t=F(()=>N.history(`all`),[],{intervalMs:6e4}).data?.totals;if(!t||t.sessions===0)return null;let n=t.days>0?t.sessions/t.days:0;return(0,I.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-6 gap-y-1 rounded-[var(--radius-panel)] border border-border bg-panel px-3 py-2.5`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:`all time`}),(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num font-semibold tracking-[-0.01em] text-[22px] leading-none text-info`,children:S(t.cost_usd)}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,title:un(e),children:ln(e)})]}),(0,I.jsx)(fn,{value:t.sessions.toLocaleString(`en-US`),label:`sessions`}),(0,I.jsx)(fn,{value:t.days.toLocaleString(`en-US`),label:`active days`}),(0,I.jsx)(fn,{value:t.turns.toLocaleString(`en-US`),label:`turns`}),n>=1&&(0,I.jsx)(fn,{value:n.toFixed(1),label:`sessions a day`}),(0,I.jsx)(`span`,{className:`ml-auto inline-flex items-baseline gap-4`,children:(0,I.jsx)(pn,{})})]})}function fn({value:e,label:t}){return(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-1.5`,children:[(0,I.jsx)(`span`,{className:`num text-[13px] text-fg`,children:e}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:t})]})}function pn(){let e=F(()=>N.daily(30),[],{intervalMs:3e5}),t=F(()=>N.summary(`today`),[],{intervalMs:3e4}),n=e.data??[];if(n.length===0)return null;let r=new Map;for(let e of n)r.set(e.day,(r.get(e.day)??0)+e.cost_usd);let i=[...r.values()].filter(e=>e>0).sort((e,t)=>e-t);if(i.length<7)return null;let a=i[Math.floor(i.length/2)]??0,o=t.data?.cost_usd??0;return a<=0||o=99?{label:`outstanding`,color:`text-ok`}:e>=95?{label:`good`,color:`text-ok`}:e>=85?{label:`ok`,color:``}:{label:`low`,color:`text-warn`}}function hn({hitRate:e,cutPct:t,measured:n,size:r=`compact`,label:i=`Cache hit`}){let a=n&&e!==void 0?e*100:void 0,o=mn(a);return(0,I.jsx)(R,{label:i,value:(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{children:a===void 0?`—`:w(a)}),o&&(0,I.jsx)(`span`,{className:`text-[11px] font-normal ${o.color||`text-fg-faint`}`,children:o.label})]}),sub:n&&t!==void 0?`${w(t)} input cost cut`:void 0,size:r})}function gn(e,t){let n=Math.round(e.used_percentage),r=(e.resets_at??0)*1e3,i=r>t&&r85?`text-danger`:n>=60?`text-warn`:`text-fg`,resetsAt:i?new Date(r).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):null,stale:e.resets_at?!i:!1}}function _n({label:e,w:t,now:n}){let{pct:r,color:i,resetsAt:a,stale:o}=gn(t,n);return(0,I.jsxs)(`div`,{className:`flex items-baseline justify-between gap-3 text-sm`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:e}),(0,I.jsxs)(`span`,{className:`flex items-baseline gap-3`,children:[(0,I.jsxs)(`span`,{className:`font-mono tabular-nums ${i}`,children:[r,`%`]}),a&&(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[`resets `,a]}),o&&(0,I.jsx)(`span`,{className:`text-fg-faint`,title:`Claude Code has not refreshed this window recently`,children:`reset time stale`}),t.forecast&&(0,I.jsx)(`span`,{className:`text-warn`,children:t.forecast})]})]})}function vn({limits:e,now:t}){let n=[];if(e?.five_hour&&n.push([`5h`,e.five_hour]),e?.seven_day&&n.push([`7d`,e.seven_day]),n.length===0)return null;let r=n.map(([e,n])=>({label:e,...gn(n,t)})),i=r.filter(e=>!e.stale),a=i.length===0,o=(i.length?i:r).reduce((e,t)=>t.pct>e.pct?t:e),s=r.find(e=>e.label!==o.label);return(0,I.jsx)(R,{label:`Plan limits`,value:(0,I.jsxs)(`span`,{className:a?`text-fg-faint`:o.color,children:[o.pct,`%`]}),sub:a?(0,I.jsx)(`span`,{title:`Claude Code writes these to its status line; they stop updating when no session is running`,children:`last reported a while ago`}):(0,I.jsxs)(`span`,{children:[o.label,` window`,o.resetsAt?` · resets ${o.resetsAt}`:``,s?` · ${s.label} ${s.pct}%`:``]}),tone:a?void 0:o.pct>85?`danger`:o.pct>=60?`warn`:void 0,size:`compact`})}var yn=`caprock-prompts`,bn={"share-week":6048e5,"share-month":2592e6,"premium-hint":2592e6,"premium-banner":2592e6};function xn(){try{let e=localStorage.getItem(yn);return e?JSON.parse(e):{}}catch{return{}}}function Sn(e){try{localStorage.setItem(yn,JSON.stringify(e))}catch{}}function Cn(e,t){let n=xn()[e];return!n||t-n>=bn[e]}function wn(e,t){let n={...xn(),[e]:t};e===`share-month`&&(n[`share-week`]=t),Sn(n)}var Tn=`premium-banner`;function En({costUSD:e,days:t,now:n}){let[r]=(0,l.useState)(()=>Cn(Tn,n)),[i,a]=(0,l.useState)(!1),[o,s]=(0,l.useState)(!1);if(!r||i||e<=0||t<=0)return null;let c=e/t;return(0,I.jsxs)(`div`,{className:`flex items-center gap-3 rounded-[var(--radius-panel)] border border-border bg-panel-2 px-3 py-2 text-[12px]`,children:[(0,I.jsxs)(`span`,{className:`text-fg`,children:[(0,I.jsx)(`span`,{className:`num`,children:S(c)}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[` a day, on average, across `,t,` active `,t===1?`day`:`days`,`.`]})]}),(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`Premium pauses sessions when the day crosses a limit you set.`}),(0,I.jsxs)(`span`,{className:`ml-auto flex shrink-0 items-center gap-2`,children:[(0,I.jsx)(`button`,{onClick:()=>s(!0),className:`rounded-sm border border-accent/50 bg-accent/10 px-2 py-0.5 text-accent hover:bg-accent/20`,children:`what it does`}),(0,I.jsx)(`button`,{onClick:()=>{wn(Tn,n),a(!0)},className:`rounded-sm border border-border px-1.5 py-0.5 text-[11px] text-fg-faint hover:text-fg-muted`,title:`hide this for a month`,children:`not now`})]}),o&&(0,I.jsx)(nt,{feature:`cap`,onClose:()=>s(!1)})]})}var Dn=[1e3,5e3,1e4,25e3,5e4,1e5],On=e=>e>=1e3?`$${Math.round(e).toLocaleString(`en-US`)}`:`$${e.toFixed(2)}`;function kn(e){let t=Dn.filter(t=>e>=t).pop();return t===void 0||e-t>t*.1?null:{kind:`milestone`,line:`You just passed ${On(t)} of Claude Code.`}}function An(e,t){return e<7||e>10?null:{kind:`first-week`,line:`A week of Claude Code: ${On(t)} measured.`}}function jn(e){if(e.length<3)return null;let[t,...n]=e;if(t===void 0)return null;let r=Math.max(...n);return r<=0||tt[0].localeCompare(e[0])),r=[];for(let e=0;ee+t[1],0));return r}function Nn(e,t,n){return e.sessions===0||e.cost_usd<=0?null:kn(e.cost_usd)??An(e.days,n.cost_usd)??jn(Mn(t))}var Pn=`share-week`;function Fn({now:e}){let[t]=(0,l.useState)(()=>Cn(Pn,e)),[n,r]=(0,l.useState)(!1),[i,a]=(0,l.useState)(!1),o=F(()=>N.history(`all`),[],{intervalMs:3e5}),s=F(()=>N.summary(`7d`),[],{intervalMs:3e5});if(!t||n||!o.data||!s.data)return null;let c=Nn(o.data.totals,o.data.daily??[],s.data);if(!c)return null;let u=()=>{wn(Pn,e),r(!0)};return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 rounded-lg border border-accent/35 bg-accent/[0.07] py-1.5 pl-3.5 pr-2 text-[13px]`,children:[(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[c.line,` Don’t be shy and share it off —`]}),(0,I.jsx)(`button`,{onClick:()=>{a(!0),u()},className:`rounded-[5px] bg-accent px-3 py-1 font-medium text-panel hover:bg-accent/90`,children:`Share`}),(0,I.jsx)(`button`,{onClick:u,title:`hide this for a week`,className:`px-1 text-fg-faint hover:text-fg-muted`,children:`✕`})]}),i&&(0,I.jsx)(Qe,{onClose:()=>a(!1)})]})}function In(){let e=F(()=>N.history(`all`),[],{intervalMs:6e4}),t=(e.data?.tools??[]).slice(0,6),n=(e.data?.summary?.models??[]).slice(0,5);if(t.length===0&&n.length===0)return null;let r=t[0]?.count??0,i=n[0]?.cost_usd??0,a=(e.data?.tools??[]).reduce((e,t)=>e+t.count,0),o=(e.data?.summary?.models??[]).reduce((e,t)=>e+t.cost_usd,0),s=e.data?.summary,c=s&&(s.tokens_in||s.tokens_out||s.cache_read||s.cache_write)?{in:s.tokens_in,out:s.tokens_out,cacheRead:s.cache_read,cacheWrite:s.cache_write}:null;return(0,I.jsxs)(L,{title:`All time`,right:(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-3`,children:[(0,I.jsx)(Fn,{now:Date.now()}),(0,I.jsx)($e,{}),(0,I.jsx)(`a`,{href:`#/history`,className:`text-fg-faint hover:text-accent no-underline`,children:`every tool, model and project →`})]}),children:[(0,I.jsxs)(`div`,{className:`grid gap-x-8 gap-y-5 px-3 py-3 md:grid-cols-2`,children:[(0,I.jsx)(Ln,{title:`Most-used tools`,note:`by calls`,rows:t.map(e=>({key:e.tool,label:ne(e.tool),value:e.count.toLocaleString(`en-US`),share:a>0?100*e.count/a:null,frac:r>0?e.count/r:0}))}),(0,I.jsx)(Ln,{title:`Where the money went`,note:`by cost`,rows:n.map(e=>({key:e.model,label:e.model||`unknown`,value:S(e.cost_usd),sub:C(e.tokens),share:o>0?100*e.cost_usd/o:null,frac:i>0?e.cost_usd/i:0}))})]}),c&&(0,I.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-6 gap-y-1 border-t border-border px-3 py-2 text-[11px]`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:`Tokens`}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`input `,(0,I.jsx)(`span`,{className:`num text-fg`,children:C(c.in)})]}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`output `,(0,I.jsx)(`span`,{className:`num text-fg`,children:C(c.out)})]}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`cache read `,(0,I.jsx)(`span`,{className:`num text-fg`,children:C(c.cacheRead)})]}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`cache write `,(0,I.jsx)(`span`,{className:`num text-fg`,children:C(c.cacheWrite)})]}),(0,I.jsx)(`span`,{className:`ml-auto text-fg-faint`,children:`fresh input is billed at full price`})]})]})}function Ln({title:e,note:t,rows:n}){return n.length===0?null:(0,I.jsxs)(`div`,{children:[(0,I.jsxs)(`div`,{className:`mb-2 flex items-baseline justify-between`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:e}),(0,I.jsx)(`span`,{className:`text-[10px] text-fg-faint`,children:t})]}),(0,I.jsx)(`div`,{className:`grid gap-1.5`,children:n.map(e=>(0,I.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px]`,children:[(0,I.jsx)(`span`,{className:`mono w-36 shrink-0 truncate text-fg-muted`,title:e.label,children:e.label}),(0,I.jsx)(`span`,{className:`h-1.5 flex-1 rounded-full bg-panel-2`,children:(0,I.jsx)(`span`,{className:`block h-full rounded-full bg-accent/70`,style:{width:`${Math.max(2,Math.round(e.frac*100))}%`}})}),(0,I.jsx)(`span`,{className:`num w-20 shrink-0 text-right text-fg`,children:e.value}),(0,I.jsx)(`span`,{className:`num w-16 shrink-0 text-right text-fg-faint`,children:e.sub??``}),(0,I.jsx)(`span`,{className:`num w-9 shrink-0 text-right text-fg-faint`,children:e.share===null?``:e.share<1?`<1%`:`${Math.floor(e.share)}%`})]},e.key))})]})}function Rn(e){return e.bars.reduce((e,t)=>e+t.n,0)}function zn(e){return e.bars.reduce((e,t)=>e+t.cost,0)}var Bn=6,Vn=new Set([`description`,`timeout`,`run_in_background`]),Hn=new Set([`true`,`:`,`echo`,`pwd`,`clear`]);function Un(e){if(typeof e==`string`)return e;if(e==null)return``;try{return JSON.stringify(e)}catch{return``}}function Wn(e){if(e.kind!==`tool.pre`)return null;let t=typeof e.tool==`string`?e.tool:``;if(!t)return null;let n=e.payload,r=n&&typeof n==`object`?n.tool_input:void 0,i=r&&typeof r==`object`?r:{},a=Un(i.command).trim();if(t===`Bash`&&Hn.has(a))return null;let o=[t],s=t;for(let e of Object.keys(i).sort()){if(Vn.has(e))continue;let n=Un(i[e]);(e===`content`||e===`new_string`||e===`old_string`)&&(n=n.slice(0,200)),o.push(`${e}=${n}`),s===t&&(e===`command`||e===`file_path`||e===`pattern`)&&(s=`${t} ${n.slice(0,48)}`)}return{sig:o.join(`|`),label:s}}function Gn(e){let t=Date.parse(e.ts);return Number.isFinite(t)?t:0}function Kn(e,t,n=60){let r=Array.from({length:n},()=>({n:0,turns:0,tools:0,cost:0})),i=t-n*6e4,a=[...e].sort((e,t)=>Gn(e)-Gn(t)),o=[],s=new Map,c=0,l=``;for(let e of a){let a=Gn(e);if(a<=0)continue;if(a>=i&&a<=t){let t=r[Math.min(n-1,Math.floor((a-i)/6e4))];if(t){t.n++,e.kind===`turn.assistant`?t.turns++:(e.kind===`tool.pre`||e.kind===`tool.post`)&&t.tools++;let n=typeof e.cost_usd==`number`&&Number.isFinite(e.cost_usd)?e.cost_usd:0;t.cost+=n}}let u=Wn(e);if(!u)continue;for(o.push({at:a,sig:u.sig,label:u.label});o.length>0;){let e=o[0];if(!e||a-e.at<=Bn*6e4)break;o.shift();let t=(s.get(e.sig)??1)-1;t<=0?s.delete(e.sig):s.set(e.sig,t)}let d=(s.get(u.sig)??0)+1;s.set(u.sig,d),d>c&&(c=d,l=u.label)}return{bars:r,repeats:c,repeatSample:l}}function qn(e,t){if(e.repeats>=8)return{kind:`repeat`,label:`×${e.repeats} same call`};switch(t){case`waiting-on-you`:return{kind:`waiting`,label:`waiting on you`};case`error`:return{kind:`error`,label:`error`};case`looping`:return{kind:`repeat`,label:`looping`};case`ended`:return{kind:`quiet`,label:`ended`};case`idle`:return{kind:`quiet`,label:`idle`};case`working`:return{kind:`working`,label:`working`}}return e.bars.filter(e=>e.n>0).length===0?{kind:`quiet`,label:`quiet`}:{kind:`working`,label:`working`}}function Jn(e,t){return t<=0?`mid`:e>=t*1.8?`high`:e<=t*.5?`low`:`mid`}function Yn(e){let t=e.filter(e=>e.cost>0).map(e=>e.cost).sort((e,t)=>e-t);return t.length===0?0:t[Math.floor(t.length/2)]??0}var Xn=6,Zn=2e3;function Qn({sessions:e,now:t}){let n=(0,l.useMemo)(()=>[...e].filter(e=>e.status!==`ended`).sort((e,t)=>t.last_event_at-e.last_event_at).slice(0,Xn),[e]),r=n.map(e=>e.session_id).join(`,`),[i,a]=(0,l.useState)(new Map);(0,l.useEffect)(()=>{let e=!1;return(async()=>{let t=r?r.split(`,`):[],n=await Promise.all(t.map(e=>N.recentEvents(e,Zn).catch(()=>[])));e||a(new Map(t.map((e,t)=>[e,n[t]??[]])))})(),()=>{e=!0}},[r]),(0,l.useEffect)(()=>d.onFrame(e=>{if(e.type!==`event`)return;let t=e.data;a(e=>{if(!e.has(t.session_id))return e;let n=new Map(e),r=n.get(t.session_id)??[];return n.set(t.session_id,[...r,t].slice(-4e3)),n})}),[]);let o=Math.floor(t/6e4),s=(0,l.useMemo)(()=>n.map(e=>({s:e,pulse:Kn(i.get(e.session_id)??[],o*6e4)})).filter(e=>Rn(e.pulse)>0),[n,i,o]);return n.length===0?null:(0,I.jsxs)(L,{title:`Live pulse`,right:(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-faint`,children:[`last `,60,` minutes · one bar per minute`]}),children:[(0,I.jsx)(`div`,{children:s.length===0?(0,I.jsxs)(`div`,{className:`px-3 py-6 text-[12px] text-fg-faint text-center`,children:[`Nothing ran in the last `,60,` minutes.`]}):s.map(({s:e,pulse:t})=>(0,I.jsx)(er,{s:e,pulse:t,minute:o,showId:s.length>1},e.session_id))}),(0,I.jsxs)(`div`,{className:`px-3 py-2 flex items-center gap-4 flex-wrap text-[11px] text-fg-faint border-t border-border`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,title:`They are independent: one call carrying a large context is a short bright bar, twenty greps are a tall dark one.`,children:`bar height = turns and tools · colour = what the minute cost`}),(0,I.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)($n,{tier:nr,className:`h-[2px]`}),`idle`]}),(0,I.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)($n,{tier:tr.low}),`below this session's median`]}),(0,I.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)($n,{tier:tr.mid}),`around it`]}),(0,I.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,I.jsx)($n,{tier:tr.high}),`well above it`]}),(0,I.jsxs)(`span`,{className:`ml-auto`,children:[(0,I.jsx)(`span`,{className:`text-warn`,children:`×N same call`}),` = most-repeated identical tool call in six minutes`]})]})]})}function $n({tier:e,className:t=``}){return(0,I.jsx)(`span`,{"data-token":e.token,className:`inline-block w-3 h-3 rounded-[2px] ${t}`,style:{background:`var(${e.token}, ${e.fallback})`,opacity:e.alpha}})}function er({s:e,pulse:t,minute:n,showId:r}){let i=qn(t,e.activity?.health),a=i.kind===`repeat`||i.kind===`waiting`?`text-warn`:i.kind===`error`?`text-danger`:i.kind===`quiet`?`text-fg-faint`:`text-ok`;return(0,I.jsxs)(`a`,{href:g({name:`session`,id:e.session_id}),className:`grid grid-cols-[132px_1fr_92px_104px] items-center gap-3 px-3 py-2 border-t border-border first:border-t-0 hover:bg-panel-2 no-underline text-fg`,children:[(0,I.jsxs)(`div`,{className:`min-w-0`,children:[(0,I.jsxs)(`div`,{className:`text-[13px] font-medium flex items-baseline gap-1.5 min-w-0`,children:[(0,I.jsx)(`span`,{className:`shrink-0`,children:e.project||`unknown project`}),e.git_branch&&(0,I.jsx)(`span`,{className:`min-w-0 truncate text-[10px] text-fg-faint mono`,title:e.git_branch,children:e.git_branch}),e.agent===`opencode`&&(0,I.jsx)(`span`,{className:`shrink-0 text-[9px] uppercase tracking-[0.08em] text-fg-faint border border-border px-1 rounded-sm`,children:`oc`})]}),(0,I.jsxs)(`div`,{className:`text-[10px] text-fg-faint mono truncate`,children:[r&&(0,I.jsxs)(`span`,{title:`session ${e.session_id} · started ${ee(e.started_at)} ago`,children:[T(e.session_id),` · `]}),e.activity?.phrase??``]})]}),(0,I.jsx)(ir,{pulse:t,now:n*6e4,sessionID:e.session_id}),(0,I.jsx)(`div`,{className:`num text-[13px] font-semibold text-right`,title:`${S(e.stats?.cost_usd)} for the whole session`,children:S(zn(t))}),(0,I.jsx)(`div`,{className:`text-[11px] text-right ${a}`,title:t.repeatSample,children:i.label})]})}var tr={low:{token:`--color-ok`,fallback:`#4fbf6b`,alpha:.55},mid:{token:`--color-accent`,fallback:`#feb157`,alpha:.85},high:{token:`--color-accent-strong`,fallback:`#ffcb85`,alpha:1}},nr={token:`--color-fg-faint`,fallback:`#837f78`,alpha:.3};function rr(e,t,n){return e.getPropertyValue(t).trim()||n}function ir({pulse:e,now:t,sessionID:n}){let r=(0,l.useRef)(null),[i,a]=(0,l.useState)(null);(0,l.useEffect)(()=>{let t=r.current;if(!t)return;let n=()=>{let n=t.clientWidth,r=t.clientHeight;if(n===0||r===0)return;let i=window.devicePixelRatio||1;t.width=Math.round(n*i),t.height=Math.round(r*i);let a=t.getContext(`2d`);if(!a)return;a.setTransform(i,0,0,i,0,0),a.clearRect(0,0,n,r);let o=getComputedStyle(t),s=rr(o,nr.token,nr.fallback),c=e.bars,l=Math.max(...c.map(e=>e.n),1),u=Yn(c),d=n/c.length;for(let e=0;e{i.disconnect(),a.disconnect()}},[e]);let o=t=>{let n=t.currentTarget.getBoundingClientRect();if(n.width===0)return;let r=Math.floor((t.clientX-n.left)/n.width*e.bars.length);a(r>=0&&ra(null),onClick:e=>{i===null||!s||s.n===0||(e.preventDefault(),e.stopPropagation(),v({name:`session`,id:n,at:u}))},"aria-hidden":!0}),s&&(0,I.jsx)(`div`,{className:`absolute -top-1 left-0 right-0 pointer-events-none flex justify-center`,children:(0,I.jsxs)(`span`,{className:`num text-[10px] bg-panel-2 border border-border-strong rounded-sm px-1.5 py-0.5 text-fg-muted whitespace-nowrap`,children:[new Date(u).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}),s.n===0?` · nothing happened`:(0,I.jsxs)(I.Fragment,{children:[` · ${s.n} event${s.n===1?``:`s`}`,s.turns>0&&` · ${s.turns} turn${s.turns===1?``:`s`}`,s.cost>0&&` · ${S(s.cost)}`,s.cost>0&&c>0&&(0,I.jsx)(`span`,{className:`text-fg-faint`,children:` (median ${S(c)})`}),(0,I.jsx)(`span`,{className:`text-fg-faint`,children:` · click to open`})]})]})})]})}function ar({session:e,now:t,onClose:n}){let[r,i]=(0,l.useState)(null),[a,o]=(0,l.useState)();(0,l.useEffect)(()=>{let t=!1;return(async()=>{try{let n=await N.notes(e.session_id,12);t||i(n)}catch(e){t||o(e instanceof Error?e.message:`could not load`)}})(),()=>{t=!0}},[e.session_id]);let s=r?.find(e=>!e.fragment),c=r?.[0],u=s??c;return(0,I.jsx)(`div`,{className:`fixed inset-0 z-30 bg-black/50 flex items-start justify-center pt-[10vh] px-4`,onClick:n,children:(0,I.jsxs)(`div`,{className:`w-full max-w-[720px] max-h-[76vh] flex flex-col border border-border-strong bg-panel rounded-[var(--radius-panel)] shadow-lg`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`div`,{className:`px-4 pt-3 pb-2 border-b border-border flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`text-[13px] font-medium truncate`,children:e.project||`unknown project`}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted truncate`,children:e.activity?.phrase}),(0,I.jsx)(`button`,{onClick:n,className:`ml-auto text-[16px] leading-none text-fg-faint hover:text-fg`,children:`×`})]}),(0,I.jsxs)(`div`,{className:`overflow-y-auto px-4 py-3 grid gap-3`,children:[!r&&!a&&(0,I.jsx)(`div`,{className:`text-[12px] text-fg-muted`,children:`loading…`}),a&&(0,I.jsx)(`div`,{className:`text-[12px] text-danger`,children:a}),r&&!u&&(0,I.jsx)(`div`,{className:`text-[12px] text-fg-muted`,children:`This session has not said anything yet — it may be running without hooks, or still on its first turn.`}),u&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint`,children:[`Last thing Claude said · `,ee(u.ts,t),s&&c&&s.event_id!==c.event_id&&(0,I.jsx)(`span`,{className:`ml-2 normal-case tracking-normal text-fg-muted`,children:`(the newest line was mid-thought; this is the last complete one)`})]}),(0,I.jsx)(`div`,{className:`text-[13px] leading-relaxed whitespace-pre-wrap text-fg`,children:u.text})]}),e.activity?.plan&&e.activity.plan.total>0&&(0,I.jsxs)(`div`,{className:`border-t border-border pt-3`,children:[(0,I.jsxs)(`div`,{className:`text-[10px] uppercase tracking-[0.12em] text-fg-faint mb-1`,children:[`Plan · `,e.activity.plan.done,`/`,e.activity.plan.total]}),e.activity.plan.next&&(0,I.jsxs)(`div`,{className:`text-[12px] text-fg-muted`,children:[`→ `,e.activity.plan.next]})]})]}),(0,I.jsxs)(`div`,{className:`px-4 py-2 border-t border-border flex items-center gap-3 text-[11px]`,children:[(0,I.jsx)(`a`,{href:g({name:`session`,id:e.session_id}),className:`link text-fg-muted hover:text-fg`,children:`open the session →`}),(0,I.jsx)(`span`,{className:`ml-auto text-fg-faint`,children:e.owned?`answer in its terminal tab`:`reply in the terminal you started it in`})]})]})})}var or=`premium-hint`;function sr({reason:e,now:t}){let[n]=(0,l.useState)(()=>Cn(or,t)),[r,i]=(0,l.useState)(!1),[a,o]=(0,l.useState)(!1);return!n||r?null:(0,I.jsxs)(`span`,{className:`flex shrink-0 items-center gap-2 text-[11px]`,children:[(0,I.jsx)(`span`,{className:`text-fg-faint`,children:e}),(0,I.jsx)(`button`,{onClick:()=>o(!0),className:`rounded-sm border border-border px-1.5 py-0.5 text-fg-muted hover:border-border-strong hover:text-fg`,children:`a cap that stops this`}),(0,I.jsx)(`button`,{title:`hide this for a month`,onClick:()=>{wn(or,t),i(!0)},className:`text-fg-faint hover:text-fg-muted`,children:`✕`}),a&&(0,I.jsx)(nt,{feature:`cap`,onClose:()=>o(!1)})]})}function cr({items:e,now:t,onDismiss:n,sessions:r}){return e.length===0?null:(0,I.jsx)(`div`,{className:`grid gap-1.5`,children:e.map(e=>(0,I.jsx)(lr,{it:e,now:t,onDismiss:n,session:r?.find(t=>t.session_id===e.sessionId)},e.id))})}function lr({it:e,now:t,onDismiss:n,session:r}){let[i,a]=(0,l.useState)(!1),o=e.severity===`high`;return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`border rounded-[var(--radius-panel)] px-3 py-2 flex items-center gap-3 ${o?`border-danger/50 bg-danger/10`:`border-warn/50 bg-warn/10`}`,children:[(0,I.jsx)(`span`,{className:`font-medium text-[13px] shrink-0 ${o?`text-danger`:`text-warn`}`,children:e.title}),(0,I.jsxs)(`span`,{className:`text-[12px] text-fg-muted truncate`,children:[e.sessionId&&(0,I.jsx)(`a`,{href:g({name:`session`,id:e.sessionId}),className:`link mono text-fg`,children:e.project||T(e.sessionId)}),(0,I.jsx)(`span`,{className:e.sessionId?`ml-2`:``,children:e.detail})]}),(0,I.jsxs)(`span`,{className:`ml-auto flex items-center gap-3 shrink-0`,children:[e.costUSD!==void 0&&e.costUSD>0&&(0,I.jsx)(`span`,{className:`num text-[13px] text-fg`,title:`spent by this session so far`,children:S(e.costUSD)}),e.since!==void 0&&(0,I.jsx)(`span`,{className:`num text-[11px] text-fg-faint`,children:ee(e.since,t)}),r&&e.id.startsWith(`waiting-`)&&(0,I.jsx)(`button`,{className:`text-[11px] border border-border px-1.5 py-0.5 rounded-sm hover:border-border-strong text-fg-muted hover:text-fg`,onClick:()=>a(!0),children:`what did it ask?`}),(0,I.jsx)(`a`,{href:e.sessionId?g({name:`session`,id:e.sessionId,tab:`timeline`,at:e.at}):`#/cost`,className:`text-[11px] border border-border px-1.5 py-0.5 rounded-sm hover:border-border-strong no-underline text-fg-muted hover:text-fg`,children:e.sessionId?`open`:`details`}),(e.id.startsWith(`loop-`)||e.id.startsWith(`spent-`))&&(0,I.jsx)(sr,{reason:`this is what a cap stops`,now:t}),n&&e.id.startsWith(`loop-`)&&(0,I.jsx)(`button`,{className:`text-[11px] text-fg-faint hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,onClick:()=>n(e.sessionId),children:`dismiss`})]})]}),i&&r&&(0,I.jsx)(ar,{session:r,now:t,onClose:()=>a(!1)})]})}var ur=9e5,dr=25,fr=300,pr=2,mr=864e5,hr=90,gr=6912e5;function _r(e){return typeof e==`number`?e:e&&Date.parse(e)||0}function vr({sessions:e,alerts:t,now:n,limits:r,waitingMs:i=ur}){let a=[],o=Array.isArray(e)?e.filter(Boolean):[],s=Array.isArray(t)?t.filter(Boolean):[],c=new Map(o.map(e=>[e.session_id,e]));for(let e of s){let t=c.get(e.session_id);a.push({id:`loop-${e.session_id}`,sessionId:e.session_id,project:t?.project??``,severity:`high`,title:`Stuck in a loop`,detail:[`ran ${e.sample||e.tool||`the same call`}`,Number.isFinite(e.count)?`${e.count}×`:`repeatedly`,Number.isFinite(e.window_min)?`in ${e.window_min} min`:``].filter(Boolean).join(` `),costUSD:t?.stats?.cost_usd,since:_r(e.ts)||void 0,at:_r(e.first_ts)||_r(e.ts)||void 0})}for(let e of o)if(e.status!==`ended`&&e.activity){if(e.activity.health===`error`){a.push({id:`error-${e.session_id}`,sessionId:e.session_id,project:e.project,severity:`high`,title:`Session hit an error`,detail:e.activity.phrase,costUSD:e.stats?.cost_usd,since:_r(e.activity.at)||e.last_event_at});continue}if(e.activity.health===`waiting-on-you`){let t=_r(e.activity.at)||e.last_event_at;t>0&&n-t>=i&&a.push({id:`waiting-${e.session_id}`,sessionId:e.session_id,project:e.project,severity:`medium`,title:`Waiting on you`,detail:e.activity.phrase,since:t})}}for(let e of o){if(!e.stats||!e.activity)continue;let{cost_usd:t,turns:r,files_touched:i}=e.stats;if(tpr)continue;let o=_r(e.activity.at)||e.last_event_at;o>0&&n-o>mr||a.push({id:`spent-${e.session_id}`,sessionId:e.session_id,project:e.project,severity:`medium`,title:`Lots of turns, few files`,detail:`${r.toLocaleString()} turns, ${i===0?`no files`:i===1?`1 file`:`${i} files`} touched`,costUSD:t,since:_r(e.activity.at)||e.last_event_at})}let l={high:0,medium:1};for(let[e,t]of[[`5-hour`,r?.five_hour],[`7-day`,r?.seven_day]]){if(!t||t.used_percentagen&&r=95?`high`:`medium`,title:`${e} plan window ${i}% used`,detail:`resets at ${o}${t.forecast?` — ${t.forecast}`:``}`})}return a.sort((e,t)=>l[e.severity]-l[t.severity]||(e.since??0)-(t.since??0))}var yr=`caprock.update.dismissed`;function br({plan:e,onSave:t,now:n,owned:r=0}){let[i,a]=(0,l.useState)(),[o,s]=(0,l.useState)(()=>localStorage.getItem(yr)??``);return(0,l.useEffect)(()=>{if(!e?.update_checks){a(void 0);return}let t=!0,n=()=>{N.update().then(e=>{t&&a(e)}).catch(()=>{})};n();let r=window.setInterval(n,6e4);return()=>{t=!1,window.clearInterval(r)}},[e?.update_checks]),e&&!e.update_checks?o===`offer`?null:(0,I.jsxs)(xr,{tone:`muted`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`Caprock can check GitHub for new releases. It's the only outbound call it makes, so it's off unless you turn it on — no usage data is sent, and you can turn it off again any time.`}),(0,I.jsxs)(`span`,{className:`ml-auto flex items-center gap-2 shrink-0`,children:[(0,I.jsx)(`button`,{className:`text-[11px] border border-accent/50 text-accent bg-accent/10 px-2 py-0.5 rounded-sm hover:bg-accent/20`,onClick:()=>t({...e,update_checks:!0}),children:`check for updates`}),(0,I.jsx)(`button`,{className:`text-[11px] text-fg-faint hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,onClick:()=>{localStorage.setItem(yr,`offer`),s(`offer`)},children:`no thanks`})]})]}):!i?.update_available||!i.latest||o===i.latest?null:(0,I.jsxs)(xr,{tone:`accent`,children:[(0,I.jsxs)(`span`,{className:`text-fg`,children:[(0,I.jsxs)(`span`,{className:`font-medium`,children:[`Caprock `,i.latest]}),` is available — you're on `,(0,I.jsx)(`span`,{className:`mono`,children:i.current}),`.`]}),r>0&&(0,I.jsx)(`span`,{className:`text-[12px] text-warn shrink-0`,children:r===1?`1 session Caprock started will close`:`${r} sessions Caprock started will close`}),i.command?(0,I.jsx)(Ct,{command:i.command}):(0,I.jsx)(`a`,{className:`link text-[12px]`,href:i.url,target:`_blank`,rel:`noreferrer`,children:`download it`}),(0,I.jsxs)(`span`,{className:`ml-auto flex items-center gap-2 shrink-0`,children:[i.checked_at?(0,I.jsxs)(`span`,{className:`num text-[11px] text-fg-faint`,children:[`checked `,ee(i.checked_at,n)]}):null,(0,I.jsx)(`a`,{className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-0.5 rounded-sm no-underline`,href:i.url,target:`_blank`,rel:`noreferrer`,children:`what's new`}),(0,I.jsx)(`button`,{className:`text-[11px] text-fg-faint hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,onClick:()=>{localStorage.setItem(yr,i.latest),s(i.latest)},children:`not now`})]})]})}function xr({tone:e,children:t}){return(0,I.jsx)(`div`,{className:`border rounded-[var(--radius-panel)] px-3 py-2 flex items-center gap-3 text-[12px] ${e===`accent`?`border-accent/40 bg-accent/5`:`border-border bg-panel`}`,children:t})}function Sr({u:e,className:t=``}){return!e||e.turns===0?null:(0,I.jsxs)(`div`,{className:`border border-warn/50 bg-warn/10 px-3 py-2 text-[12px] rounded-[var(--radius-panel)] ${t}`,children:[(0,I.jsx)(`span`,{className:`text-warn font-medium`,children:`Cost is incomplete`}),` `,(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[C(e.tokens),` tokens over `,e.turns,` turn`,e.turns===1?``:`s`,` could not be priced, so they are missing from the total above — not free. `,e.models.length===1?`Model`:`Models`,` with no entry in the pricing table:`,` `,e.models.map((e,t)=>(0,I.jsxs)(`span`,{children:[t>0&&`, `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:e||`unknown`})]},e)),`. This happens when a model ships newer than the pricing table, or when a gateway reports ids that do not normalise.`]})]})}function Cr({value:e,onPick:t}){let[n,r]=(0,l.useState)(`recent`),[i,a]=(0,l.useState)(``),o=F(()=>N.recentDirs(),[],{live:!1}),s=F(()=>N.browse(i),[i],{live:!1});return(0,l.useEffect)(()=>{o.data&&o.data.length===0&&r(`browse`)},[o.data]),(0,I.jsxs)(`div`,{className:`rounded-[3px] border border-border-strong bg-panel-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-1 border-b border-border-strong px-2 py-1.5 text-[12px]`,children:[(0,I.jsx)(wr,{on:n===`recent`,onClick:()=>r(`recent`),children:`Recent`}),(0,I.jsx)(wr,{on:n===`browse`,onClick:()=>r(`browse`),children:`Browse`}),n===`browse`&&s.data&&(0,I.jsx)(`span`,{className:`mono ml-auto min-w-0 truncate pl-2 text-[11px] text-fg-faint`,title:s.data.dir,children:kr(s.data.dir,s.data.root)})]}),(0,I.jsx)(`div`,{className:`h-[168px] overflow-y-auto overflow-x-hidden`,children:n===`recent`?(0,I.jsx)(Tr,{rows:o.data,value:e,onPick:t}):(0,I.jsx)(Er,{data:s.data,value:e,onOpen:a,onPick:t,error:s.error?.message})})]})}function wr({on:e,onClick:t,children:n}){return(0,I.jsx)(`button`,{type:`button`,onClick:t,className:`rounded-sm px-2 py-0.5 ${e?`bg-accent/15 text-accent`:`text-fg-muted hover:text-fg`}`,children:n})}function Tr({rows:e,value:t,onPick:n}){return e?e.length===0?(0,I.jsx)(Or,{children:`No sessions yet — use Browse, or type a path.`}):(0,I.jsx)(`ul`,{children:e.map(e=>(0,I.jsxs)(Dr,{selected:t===e.dir,onClick:()=>n(e.dir),children:[(0,I.jsx)(`span`,{className:`shrink-0 text-fg`,children:e.name}),(0,I.jsx)(`span`,{className:`mono ml-2 min-w-0 flex-1 truncate text-[11px] text-fg-faint`,title:e.dir,children:e.dir}),(0,I.jsx)(`span`,{className:`shrink-0 pl-2 text-[11px] text-fg-faint`,children:ee(e.last_event_at)})]},e.dir))}):(0,I.jsx)(Or,{children:`…`})}function Er({data:e,value:t,onOpen:n,onPick:r,error:i}){return i?(0,I.jsx)(Or,{children:i}):e?(0,I.jsxs)(`ul`,{children:[e.parent&&(0,I.jsx)(Dr,{selected:!1,onClick:()=>n(e.parent),children:(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`↑ up`})}),e.entries.length===0&&(0,I.jsx)(Or,{children:`Nothing here.`}),e.entries.map(e=>(0,I.jsxs)(Dr,{selected:t===e.path,onClick:()=>e.repo?r(e.path):n(e.path),children:[(0,I.jsx)(`span`,{className:`min-w-0 truncate ${e.repo?`text-fg`:`text-fg-muted`}`,children:e.name}),e.repo&&(0,I.jsx)(`span`,{className:`ml-2 shrink-0 text-[10px] uppercase tracking-wide text-accent`,children:`repo`}),(0,I.jsx)(`span`,{className:`flex-1`}),(0,I.jsx)(`button`,{type:`button`,onClick:t=>{t.stopPropagation(),e.repo?n(e.path):r(e.path)},className:`shrink-0 px-1 text-[11px] text-fg-faint hover:text-fg`,title:e.repo?`Open this folder`:`Use this folder`,children:e.repo?`›`:`use`})]},e.path))]}):(0,I.jsx)(Or,{children:`…`})}function Dr({selected:e,onClick:t,children:n}){return(0,I.jsx)(`li`,{children:(0,I.jsx)(`button`,{type:`button`,onClick:t,className:`flex w-full min-w-0 items-center px-2.5 py-1 text-left text-[12px] hover:bg-panel ${e?`bg-accent/10`:``}`,children:n})})}function Or({children:e}){return(0,I.jsx)(`p`,{className:`px-2.5 py-3 text-[12px] text-fg-faint`,children:e})}function kr(e,t){return e===t?`~`:e.startsWith(t+`/`)?`~`+e.slice(t.length):e}var Ar=`claude-opus-5`,jr=`acceptEdits`,Mr=[[`claude-opus-5`,`Opus 5 · most capable`],[`claude-sonnet-5`,`Sonnet 5 · faster, cheaper`],[`claude-haiku-4-5`,`Haiku 4.5 · cheapest`]],Nr=[[`acceptEdits`,`Accept edits · asks before commands`],[`plan`,`Plan · reads and plans, changes nothing`],[`bypassPermissions`,`Bypass · never asks`]];function Pr({available:e,onClose:t,initialCwd:n=``}){let[r,i]=(0,l.useState)(n),[a,o]=(0,l.useState)(Ar),[s,c]=(0,l.useState)(jr),[u,d]=(0,l.useState)(``),[f,p]=(0,l.useState)(!1),[m,h]=(0,l.useState)(!1),[g,_]=(0,l.useState)(``),y=async()=>{if(!r.trim()){_(`Working directory is required.`);return}h(!0),_(``);try{let e={cwd:r.trim()};a&&(e.model=a),s&&(e.permission_mode=s),u.trim()&&(e.worktree=u.trim()),f&&(e.create=!0);let{session_id:n}=await N.spawn(e);t(),v({name:`session`,id:n,tab:`terminal`})}catch(e){_(oe(e))}finally{h(!1)}};return(0,I.jsx)(`div`,{className:`fixed inset-0 z-20 bg-black/50 flex items-start justify-center pt-24`,onClick:t,children:(0,I.jsxs)(`div`,{className:`border border-border-strong bg-panel rounded-[var(--radius-panel)] w-[520px] max-w-[92vw]`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`px-3 py-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`h2`,{className:`text-[12px] uppercase tracking-[0.08em] text-fg-muted`,children:`New session`}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-fg-muted hover:text-fg`,children:`✕`})]}),e?(0,I.jsxs)(`div`,{className:`px-4 py-3 grid min-w-0 gap-3 text-[13px]`,children:[(0,I.jsxs)(Fr,{label:`Working directory`,hint:`pick one, or type a path`,children:[(0,I.jsx)(`input`,{autoFocus:!0,className:`input`,placeholder:`/Users/you/dev/project`,value:r,onChange:e=>i(e.target.value),onKeyDown:e=>e.key===`Enter`&&y()}),(0,I.jsx)(`div`,{className:`mt-1.5 min-w-0 max-w-full`,children:(0,I.jsx)(Cr,{value:r,onPick:i})})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,I.jsx)(Fr,{label:`Model`,children:(0,I.jsx)(`select`,{className:`input`,value:a,onChange:e=>o(e.target.value),children:Mr.map(([e,t])=>(0,I.jsx)(`option`,{value:e,children:t},e))})}),(0,I.jsx)(Fr,{label:`Permissions`,children:(0,I.jsx)(`select`,{className:`input`,value:s,onChange:e=>c(e.target.value),children:Nr.map(([e,t])=>(0,I.jsx)(`option`,{value:e,children:t},e))})})]}),(0,I.jsxs)(`details`,{className:`text-[12px] group`,children:[(0,I.jsxs)(`summary`,{className:`cursor-pointer select-none text-fg-muted hover:text-fg list-none marker:content-none`,children:[(0,I.jsx)(`span`,{className:`inline-block transition-transform group-open:rotate-90 text-fg-faint`,children:`▶`}),` Advanced`]}),(0,I.jsxs)(`div`,{className:`grid gap-2 pt-2`,children:[(0,I.jsxs)(`label`,{className:`inline-flex items-center gap-1.5 cursor-pointer select-none text-fg-muted`,children:[(0,I.jsx)(`input`,{type:`checkbox`,className:`accent-[var(--color-accent)]`,checked:f,onChange:e=>p(e.target.checked)}),`create the directory if it does not exist`]}),(0,I.jsx)(Fr,{label:`Git worktree`,hint:`creates .caprock-worktrees/ on a new branch`,children:(0,I.jsx)(`input`,{className:`input`,placeholder:`feature-x`,value:u,onChange:e=>d(e.target.value)})})]})]}),g&&(0,I.jsx)(`div`,{className:`text-danger text-[12px]`,children:g})]}):(0,I.jsxs)(`div`,{className:`px-4 py-6 text-[13px] text-fg-muted`,children:[`The `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` binary was not found on this machine, so Caprock cannot spawn sessions. It still observes every session you start yourself.`]}),e&&(0,I.jsxs)(`footer`,{className:`px-4 py-2 border-t border-border flex gap-2 justify-end`,children:[(0,I.jsx)(`button`,{onClick:t,className:`border border-border px-3 py-1 rounded-sm text-fg-muted hover:text-fg`,children:`Cancel`}),(0,I.jsx)(`button`,{onClick:y,disabled:m,className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm hover:bg-accent/25 disabled:opacity-50`,children:m?`starting…`:`Start session`})]})]})})}function Fr({label:e,hint:t,children:n}){return(0,I.jsxs)(`label`,{className:`grid min-w-0 gap-1`,children:[(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[e,t&&(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[` · `,t]})]}),n]})}function Ir(){let[e,t]=(0,l.useState)(!1),[n,r]=(0,l.useState)(`all`),[i,a]=(0,l.useState)(!1),o=F(()=>N.sessions(!e),[e],{intervalMs:5e3}),s=F(()=>N.status(),[],{live:!1,intervalMs:3e4}),c=F(()=>N.summary(`today`,n),[n],{intervalMs:5e3}),u=F(()=>N.history(`all`),[],{intervalMs:6e4}),{alerts:p}=f(),m=ie(1e3),h=o.data??[],g=n===`all`?h:h.filter(e=>(e.agent??`claude`)===n),_=!!s.data?.opencode,v=g.filter(e=>e.activity.health===`working`||e.activity.health===`looping`||e.activity.health===`error`||e.activity.health===`waiting-on-you`),y=g.filter(e=>!v.includes(e)&&e.status!==`ended`),b=g.filter(e=>e.status===`ended`),[x,w]=De(),te=vr({sessions:g,alerts:p,now:m,limits:c.data?.rate_limits}),T=s.data?.hooks&&(s.data.hooks.missing??[]).length>0,E=!!c.data&&c.data.turns>0,ne=s.data?.ingest_error;return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[ne&&(0,I.jsxs)(`div`,{className:`border border-danger/50 bg-danger/10 px-3 py-2 text-[12px] rounded-[var(--radius-panel)] flex items-center gap-3`,children:[(0,I.jsx)(`span`,{className:`text-danger font-medium`,children:`Ingest stopped`}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`No new sessions are being captured. `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:ne}),` — check that`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` ~/.claude`}),` is readable, then restart with`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` caprock down && caprock up`}),`.`]})]}),T&&(0,I.jsxs)(`div`,{className:`border border-warn/50 bg-warn/10 px-3 py-2 text-[12px] rounded-[var(--radius-panel)] flex items-center gap-3`,children:[(0,I.jsx)(`span`,{className:`text-warn font-medium`,children:`Hooks not installed`}),(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[`Activity is coming from transcripts only (a few seconds late, no tool-level detail for running commands). Run `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:`caprock hooks install`}),` for real-time narration.`]}),(0,I.jsx)(`a`,{href:`#/settings`,className:`link ml-auto text-[11px]`,children:`details`})]}),(0,I.jsx)(br,{plan:x,onSave:w,now:m,owned:g.filter(e=>e.owned&&e.status!==`ended`).length}),(0,I.jsx)(cr,{items:te,now:m,onDismiss:e=>d.dismissAlert(e),sessions:g}),(0,I.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,I.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,I.jsx)(dn,{plan:x})}),(0,I.jsx)(Lr,{available:s.data?.claude_available}),(0,I.jsx)(Rr,{available:s.data?.claude_available,onClick:()=>a(!0)})]}),E&&u.data?.totals&&(0,I.jsx)(En,{costUSD:u.data.totals.cost_usd,days:u.data.totals.days,now:m}),(0,I.jsxs)(L,{title:`Today`,center:_?(0,I.jsx)(`span`,{className:`inline-flex items-center gap-0.5 rounded-md bg-panel-2 p-0.5`,children:It.map(e=>(0,I.jsx)(`button`,{onClick:()=>r(e.key),title:e.key===`all`?`Every agent`:`Only ${e.label}`,className:`px-2.5 py-1 text-[12px] mono rounded-[5px] transition-colors ${n===e.key?`bg-accent text-panel font-medium`:`text-fg-muted hover:text-fg`}`,children:e.label},e.key))}):null,right:c.data?(0,I.jsxs)(`span`,{className:`num`,children:[`pricing `,c.data.pricing_version,` · at API list price`]}):null,children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 lg:grid-cols-[1.4fr_1fr_1fr_1fr_1fr_1fr] divide-x divide-border`,children:[(0,I.jsx)(R,{label:`Cost today`,value:E?S(c.data?.cost_usd):`—`,sub:(0,I.jsx)(`span`,{title:un(x),children:E?ln(x):`nothing measured yet`}),tone:`info`,size:`hero`}),(0,I.jsx)(R,{label:`Burn now`,value:E?`${S(c.data.burn.usd_per_hour)}/h`:`—`,sub:E?`${C(Math.round(c.data.burn.tokens_per_min))} tok/min · last ${c.data.burn.window_min}m`:void 0}),(0,I.jsx)(R,{label:`Sessions`,value:E?c.data.sessions:`—`,sub:E?`${c.data.active_sessions} active`:void 0,size:`compact`}),(0,I.jsx)(R,{label:`Turns`,value:E?c.data.turns:`—`,sub:E?`${c.data.tool_calls} tool calls`:void 0,size:`compact`}),(0,I.jsx)(vn,{limits:c.data?.rate_limits,now:m}),(0,I.jsx)(hn,{hitRate:c.data?.savings.hit_rate,cutPct:c.data?.savings.cut_pct,measured:E})]}),(0,I.jsx)(Sr,{u:c.data?.unpriced,className:`mx-3 mb-2.5`})]}),(0,I.jsx)(Qn,{sessions:g,now:m}),(0,I.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-2`,children:[(0,I.jsx)(on,{sessions:g,now:m,emptyHint:n===`all`?void 0:(0,I.jsxs)(I.Fragment,{children:[`Nothing from `,n===`opencode`?`OpenCode`:`Claude Code`,` yet.`]})}),(0,I.jsx)(Wt,{sessions:g,agent:n})]}),(0,I.jsx)(In,{}),o.error&&!o.data&&(0,I.jsxs)(z,{title:`Cannot reach the daemon`,children:[o.error.message,` — is `,(0,I.jsx)(`span`,{className:`mono`,children:`caprock up`}),` running?`]}),!o.data&&!o.error&&(0,I.jsx)(St,{rows:4,className:`border border-border rounded-[var(--radius-panel)] bg-panel`}),o.data&&g.length===0&&(n===`all`?(0,I.jsxs)(z,{title:`No sessions yet`,children:[`Start `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` in any terminal — it will show up here within seconds.`]}):(0,I.jsxs)(z,{title:`No ${n===`opencode`?`OpenCode`:`Claude Code`} sessions here`,children:[`Nothing from this agent in the current view. Switch to`,` `,(0,I.jsx)(`button`,{className:`link underline`,onClick:()=>r(`all`),children:`all`}),` `,`to see everything.`]})),(0,I.jsx)(zr,{groups:[{label:`Active`,items:v},{label:`Idle`,items:y,dim:!0},...e?[{label:`Ended`,items:b,dim:!0}]:[]],now:m}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3 text-[11px] text-fg-faint px-0.5`,children:[(0,I.jsxs)(`label`,{className:`inline-flex items-center gap-1.5 cursor-pointer select-none`,children:[(0,I.jsx)(`input`,{type:`checkbox`,className:`accent-[var(--color-accent)]`,checked:e,onChange:e=>t(e.target.checked)}),`show ended sessions`]}),o.loadedAt>0&&(0,I.jsxs)(`span`,{className:`num ml-auto`,children:[`refreshed `,ee(o.loadedAt,m)]})]}),i&&(0,I.jsx)(Pr,{available:s.data?.claude_available??!1,onClose:()=>{a(!1),o.refresh()}})]})}function Lr({available:e}){let[t,n]=(0,l.useState)(!1),[r,i]=(0,l.useState)(``);return e===!1?null:(0,I.jsx)(I.Fragment,{children:(0,I.jsxs)(`button`,{onClick:async()=>{n(!0),i(``);try{let{session_id:e}=await N.spawn({chat:!0});v({name:`session`,id:e,tab:`terminal`})}catch(e){i(oe(e))}finally{n(!1)}},disabled:t,title:`start a session without picking a folder`,className:`relative shrink-0 rounded-[var(--radius-panel)] border border-border-strong px-3 py-2 text-[13px] leading-5 text-fg-muted hover:text-fg hover:border-accent/50 disabled:opacity-50`,children:[t?`starting…`:`Quick chat`,r&&(0,I.jsx)(`span`,{className:`absolute right-0 top-full mt-1 block max-w-[220px] text-right text-[11px] text-danger`,children:r})]})})}function Rr({available:e,onClick:t}){let n=e===!1;return(0,I.jsxs)(`button`,{onClick:t,title:n?`claude was not found on this machine — click for details`:`start a session Caprock owns`,className:`shrink-0 rounded-[var(--radius-panel)] border px-3 py-2 text-[13px] leading-5 font-medium transition-colors ${n?`border-border text-fg-faint hover:text-fg-muted`:`border-accent/60 bg-accent/15 text-accent hover:bg-accent/25`}`,children:[`+ New session`,n?` (claude not found)`:``]})}function zr({groups:e,now:t}){let n=e.flatMap(e=>e.items.map((t,n)=>({s:t,dim:e.dim,label:n===0?`${e.label} · ${e.items.length}`:null})));return n.length===0?null:(0,I.jsx)(`div`,{"data-testid":`session-grid`,className:`mt-3 grid gap-2 gap-y-6`,children:n.map(({s:e,dim:n,label:r})=>(0,I.jsxs)(`div`,{className:`relative ${n?`opacity-80`:``}`,children:[r&&(0,I.jsx)(`div`,{className:`absolute -top-4 left-0.5 text-[11px] uppercase tracking-[0.08em] text-fg-faint`,children:r}),(0,I.jsx)(Br,{s:e,now:t})]},e.session_id))})}function Br({s:e,now:t}){let n=e.context,r=n?n.pct>=85?`danger`:n.pct>=60?`warn`:void 0:void 0,[i,a]=(0,l.useState)(!1),o=e.activity?.health===`waiting-on-you`;return(0,I.jsxs)(`a`,{href:g({name:`session`,id:e.session_id}),className:`block border border-border bg-panel rounded-[var(--radius-panel)] hover:border-border-strong no-underline hover:no-underline text-fg`,children:[(0,I.jsxs)(`div`,{className:`px-3 pt-2 pb-1 flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`font-medium truncate text-[15px]`,children:e.project||`unknown project`}),(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-faint`,children:T(e.session_id)}),e.agent===`opencode`&&(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.08em] text-fg-muted border border-border px-1 py-px rounded-sm`,children:`opencode`}),e.git_branch&&(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-muted truncate`,children:e.git_branch}),(0,I.jsxs)(`span`,{className:`ml-auto flex items-center gap-2`,children:[o&&(0,I.jsx)(`button`,{className:`text-[11px] border border-warn/50 text-warn bg-warn/10 px-1.5 py-0.5 rounded-sm hover:bg-warn/20`,onClick:e=>{e.preventDefault(),a(!0)},children:`what did it ask?`}),(0,I.jsx)(bt,{health:e.activity.health})]})]}),i&&(0,I.jsx)(ar,{session:e,now:t,onClose:()=>a(!1)}),(0,I.jsxs)(`div`,{className:`px-3 pb-2 text-[13px] truncate`,title:e.activity.phrase,children:[(0,I.jsx)(`span`,{className:e.activity.health===`working`?`text-fg`:`text-fg-muted`,children:e.activity.phrase}),(0,I.jsx)(`span`,{className:`text-fg-faint num text-[11px] ml-2`,children:ee(e.activity.at||e.last_event_at,t)})]}),e.activity.plan&&e.activity.plan.total>0&&(0,I.jsxs)(`div`,{className:`px-3 pb-2 flex items-center gap-2 text-[11px] text-fg-muted`,children:[(0,I.jsx)(`div`,{className:`h-1 flex-1 bg-panel-2 rounded-sm overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full bg-accent`,style:{width:`${Math.min(100,Math.max(0,100*e.activity.plan.done/e.activity.plan.total))}%`}})}),(0,I.jsxs)(`span`,{className:`num`,children:[e.activity.plan.done,`/`,e.activity.plan.total]}),e.activity.plan.next&&(0,I.jsxs)(`span`,{className:`truncate max-w-[50%]`,children:[`→ `,e.activity.plan.next]})]}),(0,I.jsxs)(`div`,{className:`grid grid-cols-2 sm:grid-cols-4 divide-x divide-border border-t border-border`,children:[(0,I.jsx)(R,{label:`Cost`,value:S(e.stats.cost_usd),sub:e.model||`—`,tone:`info`}),(0,I.jsx)(R,{label:`Tokens`,value:C(e.stats.tokens_in+e.stats.tokens_out+e.stats.cache_read+e.stats.cache_write),sub:`${w(e.savings.hit_rate*100)} cache hit`}),(0,I.jsx)(R,{label:`Context`,value:n?w(n.pct):`—`,sub:n?`${C(n.tokens)} / ${C(n.window)}`:`unknown model`,tone:r}),(0,I.jsx)(R,{label:`Activity`,value:e.stats.tool_calls,sub:`${e.stats.turns} turns · ${e.stats.files_touched} files`})]})]})}function Vr({id:e,now:t}){let n=F(()=>N.notes(e),[e],{intervalMs:1e4}),r=n.data??[],[i,a]=(0,l.useState)(!1),o=r.filter(e=>!e.fragment),s=i?r:o;return n.error&&!n.data?(0,I.jsx)(z,{title:`Cannot load notes`,children:n.error.message}):n.data?r.length===0?(0,I.jsx)(z,{title:`Nothing said yet`,children:`Claude's written answers appear here — the reasoning and the “what changed, what I still need from you” that otherwise lives only in your terminal scrollback.`}):(0,I.jsxs)(`div`,{className:`grid gap-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-3 text-[11px] text-fg-faint px-0.5`,children:[(0,I.jsxs)(`span`,{children:[o.length,` `,o.length===1?`answer`:`answers`,r.length>o.length&&` · ${r.length-o.length} short remarks`]}),r.length>o.length&&(0,I.jsx)(`button`,{className:`text-fg-muted hover:text-fg border border-border px-1.5 rounded-sm`,onClick:()=>a(e=>!e),children:i?`hide short remarks`:`show everything`}),(0,I.jsx)(`span`,{className:`ml-auto`,children:`subagent chatter excluded · newest first`})]}),s.map(e=>(0,I.jsx)(Ur,{note:e,now:t},e.event_id))]}):(0,I.jsx)(St,{rows:4})}var Hr=600;function Ur({note:e,now:t,showSession:n=!1}){let[r,i]=(0,l.useState)(!1),a=typeof e.text==`string`?e.text:``,o=[...a],s=o.length>Hr,c=r||!s?a:o.slice(0,Hr).join(``)+`…`;return(0,I.jsxs)(`div`,{className:`border border-border bg-panel rounded-[var(--radius-panel)]`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2 px-3 pt-2 text-[11px] text-fg-faint`,children:[n&&(0,I.jsx)(`a`,{href:g({name:`session`,id:e.session_id,at:e.ts}),className:`link`,title:`Open the session at this moment`,children:(0,I.jsx)(`span`,{className:`text-fg-muted`,children:e.project||T(e.session_id)})}),(0,I.jsx)(`span`,{className:`mono`,children:e.model||`assistant`}),e.fragment&&(0,I.jsx)(`span`,{className:`text-fg-faint`,children:`· mid-thought`}),(0,I.jsx)(`span`,{className:`num ml-auto`,children:ee(e.ts,t)})]}),(0,I.jsx)(`div`,{className:`px-3 py-2 text-[13px] leading-[1.55] whitespace-pre-wrap break-words`,children:c}),s&&(0,I.jsx)(`button`,{className:`text-[11px] text-fg-muted hover:text-fg px-3 pb-2`,onClick:()=>i(e=>!e),children:r?`show less`:`show all ${o.length.toLocaleString()} characters`})]})}var Wr=Object.defineProperty,Gr=Object.getOwnPropertyDescriptor,Kr=(e,t)=>{for(var n in t)Wr(e,n,{get:t[n],enumerable:!0})},qr=(e,t,n,r)=>{for(var i=r>1?void 0:r?Gr(t,n):t,a=e.length-1,o;a>=0;a--)(o=e[a])&&(i=(r?o(t,n,i):o(i))||i);return r&&i&&Wr(t,n,i),i},B=(e,t)=>(n,r)=>t(n,r,e),Jr=`Terminal input`,Yr={get:()=>Jr,set:e=>Jr=e},Xr=`Too much output to announce, navigate to rows manually to read`,Zr={get:()=>Xr,set:e=>Xr=e};function Qr(e){return e.replace(/\r?\n/g,`\r`)}function $r(e,t){return t?`\x1B[200~`+e+`\x1B[201~`:e}function ei(e,t){e.clipboardData&&e.clipboardData.setData(`text/plain`,t.selectionText),e.preventDefault()}function ti(e,t,n,r){e.stopPropagation(),e.clipboardData&&ni(e.clipboardData.getData(`text/plain`),t,n,r)}function ni(e,t,n,r){e=Qr(e),e=$r(e,n.decPrivateModes.bracketedPasteMode&&r.rawOptions.ignoreBracketedPasteMode!==!0),n.triggerDataEvent(e,!0),t.value=``}function ri(e,t,n){let r=n.getBoundingClientRect(),i=e.clientX-r.left-10,a=e.clientY-r.top-10;t.style.width=`20px`,t.style.height=`20px`,t.style.left=`${i}px`,t.style.top=`${a}px`,t.style.zIndex=`1000`,t.focus()}function ii(e,t,n,r,i){ri(e,t,n),i&&r.rightClickSelect(e),t.value=r.selectionText,t.select()}function ai(e){return e>65535?(e-=65536,String.fromCharCode((e>>10)+55296)+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)}function oi(e,t=0,n=e.length){let r=``;for(let i=t;i65535?(t-=65536,r+=String.fromCharCode((t>>10)+55296)+String.fromCharCode(t%1024+56320)):r+=String.fromCharCode(t)}return r}var si=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i=0;if(this._interim){let n=e.charCodeAt(i++);56320<=n&&n<=57343?t[r++]=(this._interim-55296)*1024+n-56320+65536:(t[r++]=this._interim,t[r++]=n),this._interim=0}for(let a=i;a=n)return this._interim=i,r;let o=e.charCodeAt(a);56320<=o&&o<=57343?t[r++]=(i-55296)*1024+o-56320+65536:(t[r++]=i,t[r++]=o);continue}i!==65279&&(t[r++]=i)}return r}},ci=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i,a,o,s,c=0,l=0;if(this.interim[0]){let i=!1,a=this.interim[0];a&=(a&224)==192?31:(a&240)==224?15:7;let o=0,s;for(;(s=this.interim[++o]&63)&&o<4;)a<<=6,a|=s;let c=(this.interim[0]&224)==192?2:(this.interim[0]&240)==224?3:4,u=c-o;for(;l=n)return 0;if(s=e[l++],(s&192)!=128){l--,i=!0;break}this.interim[o++]=s,a<<=6,a|=s&63}i||(c===2?a<128?l--:t[r++]=a:c===3?a<2048||a>=55296&&a<=57343||a===65279||(t[r++]=a):a<65536||a>1114111||(t[r++]=a)),this.interim.fill(0)}let u=n-4,d=l;for(;d=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(c=(i&31)<<6|a&63,c<128){d--;continue}t[r++]=c}else if((i&240)==224){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(c=(i&15)<<12|(a&63)<<6|o&63,c<2048||c>=55296&&c<=57343||c===65279)continue;t[r++]=c}else if((i&248)==240){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,this.interim[2]=o,r;if(s=e[d++],(s&192)!=128){d--;continue}if(c=(i&7)<<18|(a&63)<<12|(o&63)<<6|s&63,c<65536||c>1114111)continue;t[r++]=c}}return r}},li=``,ui=` `,di=class e{constructor(){this.fg=0,this.bg=0,this.extended=new fi}static toColorRGB(e){return[e>>>16&255,e>>>8&255,e&255]}static fromColorRGB(e){return(e[0]&255)<<16|(e[1]&255)<<8|e[2]&255}clone(){let t=new e;return t.fg=this.fg,t.bg=this.bg,t.extended=this.extended.clone(),t}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)==50331648}isBgRGB(){return(this.bg&50331648)==50331648}isFgPalette(){return(this.fg&50331648)==16777216||(this.fg&50331648)==33554432}isBgPalette(){return(this.bg&50331648)==16777216||(this.bg&50331648)==33554432}isFgDefault(){return!(this.fg&50331648)}isBgDefault(){return!(this.bg&50331648)}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==16777216||(this.extended.underlineColor&50331648)==33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?!(this.extended.underlineColor&50331648):this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},fi=class e{constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(e){this._ext&=-67108864,this._ext|=e&67108863}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){let e=(this._ext&3758096384)>>29;return e<0?e^4294967288:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}clone(){return new e(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}},pi=class e extends di{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new fi,this.combinedData=``}static fromCharData(t){let n=new e;return n.setFromCharData(t),n}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?ai(this.content&2097151):``}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(e){this.fg=e[0],this.bg=0;let t=!1;if(e[1].length>2)t=!0;else if(e[1].length===2){let n=e[1].charCodeAt(0);if(55296<=n&&n<=56319){let r=e[1].charCodeAt(1);56320<=r&&r<=57343?this.content=(n-55296)*1024+r-56320+65536|e[2]<<22:t=!0}else t=!0}else this.content=e[1].charCodeAt(0)|e[2]<<22;t&&(this.combinedData=e[1],this.content=2097152|e[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}},mi=`di$target`,hi=`di$dependencies`,gi=new Map;function _i(e){return e[hi]||[]}function vi(e){if(gi.has(e))return gi.get(e);let t=function(e,n,r){if(arguments.length!==3)throw Error(`@IServiceName-decorator can only be used to decorate a parameter`);yi(t,e,r)};return t._id=e,gi.set(e,t),t}function yi(e,t,n){t[mi]===t?t[hi].push({id:e,index:n}):(t[hi]=[{id:e,index:n}],t[mi]=t)}var bi=vi(`BufferService`),xi=vi(`CoreMouseService`),Si=vi(`CoreService`),Ci=vi(`CharsetService`),wi=vi(`InstantiationService`),Ti=vi(`LogService`),Ei=vi(`OptionsService`),Di=vi(`OscLinkService`),Oi=vi(`UnicodeService`),ki=vi(`DecorationService`),Ai=class{constructor(e,t,n){this._bufferService=e,this._optionsService=t,this._oscLinkService=n}provideLinks(e,t){let n=this._bufferService.buffer.lines.get(e-1);if(!n){t(void 0);return}let r=[],i=this._optionsService.rawOptions.linkHandler,a=new pi,o=n.getTrimmedLength(),s=-1,c=-1,l=!1;for(let t=0;ti?i.activate(e,t,a):ji(e,t),hover:(e,t)=>i?.hover?.(e,t,a),leave:(e,t)=>i?.leave?.(e,t,a)})}l=!1,a.hasExtendedAttrs()&&a.extended.urlId?(c=t,s=a.extended.urlId):(c=-1,s=-1)}}t(r)}};Ai=qr([B(0,bi),B(1,Ei),B(2,Di)],Ai);function ji(e,t){if(confirm(`Do you want to navigate to ${t}? WARNING: This link could potentially be dangerous`)){let e=window.open();if(e){try{e.opener=null}catch{}e.location.href=t}else console.warn(`Opening link blocked as opener could not be cleared`)}}var Mi=vi(`CharSizeService`),V=vi(`CoreBrowserService`),Ni=vi(`MouseService`),Pi=vi(`RenderService`),Fi=vi(`SelectionService`),Ii=vi(`CharacterJoinerService`),Li=vi(`ThemeService`),Ri=vi(`LinkProviderService`),zi=new class{constructor(){this.listeners=[],this.unexpectedErrorHandler=function(e){setTimeout(()=>{throw e.stack?Gi.isErrorNoTelemetry(e)?new Gi(e.message+` @@ -94,7 +94,7 @@ void main() { \x1B[2m[session ended]\x1B[0m\r `);let l=new TextEncoder,u=e=>{c.readyState===WebSocket.OPEN&&c.send(l.encode(e))},d=i.onData(u),f=(e,t)=>{c.readyState!==WebSocket.OPEN||e<=0||t<=0||c.send(JSON.stringify({resize:{cols:e,rows:t}}))},p=i.onResize(({cols:e,rows:t})=>f(e,t));c.onopen=()=>{try{o.fit()}catch{}f(i.cols,i.rows)};let m=e=>{e.preventDefault(),e.stopPropagation(),u(`\x1B\r`)};i.attachCustomKeyEventHandler(e=>{if(e.type!==`keydown`)return!0;if(h&&e.metaKey&&!e.ctrlKey&&!e.altKey){if(e.key===`c`)return!g();if(e.key===`v`)return _(),!1}if(!h&&e.ctrlKey&&e.shiftKey&&!e.altKey&&!e.metaKey){if(e.key===`C`||e.key===`c`)return g(),!1;if(e.key===`V`||e.key===`v`)return _(),!1}return!h&&e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey&&(e.key===`c`||e.key===`C`)?!g()||(i.clearSelection(),!1):e.ctrlKey&&!e.altKey&&!e.metaKey&&(e.key===`j`||e.key===`J`)?(m(e),!1):e.key!==`Enter`||[e.shiftKey,e.altKey,e.ctrlKey,e.metaKey].filter(Boolean).length!==1||e.metaKey?!0:(m(e),!1)});let h=/Mac|iP(hone|ad)/.test(navigator.platform||navigator.userAgent),g=()=>{let e=i.getSelection();return e?(navigator.clipboard?.writeText(e),!0):!1},_=()=>{navigator.clipboard?.readText().then(e=>{e&&i.paste(e)}).catch(()=>{})},v=async e=>{let t=e.type||`application/octet-stream`,n=new Uint8Array(await e.arrayBuffer()),r=``;for(let e=0;e{let t=[...e.clipboardData?.items??[]].find(e=>e.kind===`file`)?.getAsFile();t&&(e.preventDefault(),v(t))},b=e=>{let t=e.dataTransfer?.files?.[0];t&&(e.preventDefault(),v(t))},x=e=>{e.preventDefault()},S=a.current;S.addEventListener(`paste`,y),S.addEventListener(`drop`,b),S.addEventListener(`dragover`,x);let C=new ResizeObserver(()=>{try{o.fit()}catch{}});return C.observe(a.current),()=>{S.removeEventListener(`paste`,y),S.removeEventListener(`drop`,b),S.removeEventListener(`dragover`,x),C.disconnect(),d.dispose(),p.dispose(),c.close(),i.dispose()}},[e,t]),t?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`div`,{ref:a,className:`h-[70vh] bg-bg`}),(0,I.jsxs)(`div`,{className:`border-t border-border px-3 py-1.5 text-[11px] text-fg-faint`,children:[(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:`Shift`}),`+`,(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:`Enter`}),` for a new line —`,` `,(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:`Option`}),`+`,(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:`Enter`}),` and`,` `,(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:`Ctrl`}),`+`,(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:`J`}),` do the same.`]})]}):(0,I.jsxs)(`div`,{className:`flex flex-col items-center gap-3 px-4 py-10 text-center`,children:[(0,I.jsx)(`p`,{className:`text-[14px] text-fg`,children:`You started this session yourself, so it has no terminal here.`}),(0,I.jsx)(`button`,{onClick:()=>i(!0),className:`rounded-sm bg-accent px-3.5 py-2 text-[13px] font-medium text-bg hover:brightness-110`,children:`Launch a new Claude Code session here →`}),(0,I.jsxs)(`p`,{className:`max-w-[52ch] text-[12px] leading-relaxed text-fg-faint`,children:[`Runs a second `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` in`,` `,n?(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:n}):`this repository`,` and gives it a terminal you can type in. This session keeps running, untouched.`]}),r&&(0,I.jsx)(Pr,{available:!0,onClose:()=>i(!1),initialCwd:n??``}),(0,I.jsx)(`p`,{className:`mt-1 max-w-[52ch] text-[12px] leading-relaxed text-fg-faint`,children:`Caprock never types into a process it did not start — including this one, which stays visible here and keeps being measured.`})]})}function eg({id:e,tab:t,at:n}){let r=F(()=>N.session(e),[e],{intervalMs:5e3}),i=t===`changes`||t===`diff`||t===`files`?`changes`:t===`terminal`||t===`notes`?t:`timeline`,a=ie(1e3),[o]=De(),s=r.data;if(r.error&&!s)return(0,I.jsx)(z,{title:r.error instanceof j&&r.error.status===404?`Session not found`:`Cannot load session`,children:r.error.message});if(!s)return(0,I.jsx)(`div`,{className:`text-fg-muted px-1`,children:`loading…`});let c=t=>v({name:`session`,id:e,tab:t}),l=s.stats.tokens_in+s.stats.tokens_out+s.stats.cache_read+s.stats.cache_write;return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-3 flex-wrap`,children:[(0,I.jsx)(`a`,{href:g({name:`now`}),className:`link text-fg-muted text-[12px]`,children:`← Now`}),(0,I.jsx)(`h1`,{className:`text-[15px] font-medium`,children:s.project||`unknown project`}),(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-faint`,children:s.session_id}),s.git_branch&&(0,I.jsx)(`span`,{className:`mono text-[11px] text-fg-muted`,children:s.git_branch}),(0,I.jsx)(bt,{health:s.activity.health}),s.owned&&s.status!==`ended`&&(0,I.jsx)(lg,{id:e}),(0,I.jsx)(`span`,{className:`text-[12px] text-fg-muted ml-auto num`,children:s.cwd})]}),(0,I.jsxs)(`div`,{className:`text-[13px]`,children:[(0,I.jsx)(`span`,{className:`text-fg`,children:s.activity.phrase}),(0,I.jsx)(`span`,{className:`text-fg-faint num text-[11px] ml-2`,children:ee(s.activity.at||s.last_event_at,a)}),s.loop&&(0,I.jsxs)(`span`,{className:`ml-3 text-danger text-[12px]`,children:[`loop: `,s.loop.sample,` ×`,s.loop.count,` in `,s.loop.window_min,`m`]})]}),(0,I.jsx)(L,{children:(0,I.jsxs)(`div`,{className:`grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 divide-x divide-border`,children:[(0,I.jsx)(R,{label:`Cost`,value:S(s.stats.cost_usd),sub:(0,I.jsx)(`span`,{title:un(o),children:s.model||`unknown model`})}),(0,I.jsx)(R,{label:`Tokens`,value:C(l),sub:`in ${C(s.stats.tokens_in)} · out ${C(s.stats.tokens_out)} · cache ${C(s.stats.cache_read+s.stats.cache_write)}`}),(0,I.jsx)(R,{label:`Cache`,value:w(s.savings.hit_rate*100),sub:`read ${C(s.stats.cache_read)} · write ${C(s.stats.cache_write)}`,tone:s.savings.hit_rate>.5?`ok`:void 0}),(0,I.jsx)(R,{label:`Context`,value:s.context?w(s.context.pct):`—`,sub:s.context?`${C(s.context.tokens)} / ${C(s.context.window)}`:`unknown model`,tone:s.context&&s.context.pct>=85?`danger`:s.context&&s.context.pct>=60?`warn`:void 0}),(0,I.jsx)(R,{label:`Turns`,value:s.stats.turns,sub:`${s.stats.tool_calls} tool calls`}),(0,I.jsx)(R,{label:`Files`,value:s.stats.files_touched,sub:`${s.has_hooks?`hooks`:`no hooks`} · ${s.has_transcript?`transcript`:`no transcript`}`})]})}),(0,I.jsxs)(`div`,{className:`flex items-center gap-1 border-b border-border`,children:[[`timeline`,`notes`,`changes`,`terminal`].map(e=>(0,I.jsx)(`button`,{onClick:()=>c(e),className:`px-3 py-1.5 text-[12px] border-b-2 -mb-px ${i===e?`border-accent text-fg`:`border-transparent text-fg-muted hover:text-fg`}`,children:e===`timeline`?`Timeline`:e===`notes`?`Answers`:e===`changes`?`Changes`:`Terminal`},e)),!s.owned&&(0,I.jsx)(`span`,{className:`ml-auto text-[11px] text-fg-faint pr-1`,children:`observe-only — terminal is read/write for spawned sessions only`})]}),i===`timeline`&&(0,I.jsx)(ng,{id:e,initial:s.events,now:a,at:n}),i===`notes`&&(0,I.jsx)(Vr,{id:e,now:a}),i===`changes`&&(0,I.jsx)(og,{id:e,s}),i===`terminal`&&(0,I.jsx)(L,{className:`overflow-hidden`,children:(0,I.jsx)($h,{sessionId:e,owned:s.owned&&s.status!==`ended`,cwd:s.cwd})})]})}var tg=200;function ng({id:e,initial:t,now:n,at:r}){let[i,a]=(0,l.useState)(t),[o,s]=(0,l.useState)(`all`),c=(0,l.useRef)(t.length?t[t.length-1].id:0),u=(0,l.useRef)(null),[f,p]=(0,l.useState)(!1),[m,h]=(0,l.useState)(!1),g=async()=>{let t=i[0]?.id;if(!(t===void 0||f)){p(!0);try{let n=await N.eventsBefore(e,t,tg);n.length===0?h(!0):a(e=>[...n,...e])}catch{h(!0)}finally{p(!1)}}};(0,l.useEffect)(()=>{a(t),h(!1),c.current=t.length?t[t.length-1].id:0},[t]),(0,l.useEffect)(()=>d.onFrame(t=>{t.type!==`event`||t.data.session_id!==e||t.data.id<=c.current||(c.current=t.data.id,a(e=>[...e,t.data].slice(-5e3)))}),[e]);let _=(0,l.useMemo)(()=>{let e=0;return i.filter(e=>e.kind===`turn.assistant`).map(t=>e+=t.cost_usd??0)},[i]),v=(0,l.useMemo)(()=>{let e=new Map;for(let t of i)if(t.kind===`tool.pre`&&t.tool){let n=t.payload;n?.tool_use_id&&e.set(n.tool_use_id,t.tool)}return e},[i]),y=i.filter(e=>o===`all`||(o===`tools`?e.kind.startsWith(`tool.`):e.kind.startsWith(`turn.`)||e.kind===`agent.stop`)).slice().reverse();return(0,I.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-[minmax(0,1fr)_260px]`,children:[(0,I.jsx)(L,{title:`Events · ${i.length} shown`,className:`min-w-0 overflow-hidden`,right:(0,I.jsx)(`span`,{className:`inline-flex items-center gap-2`,children:[`all`,`tools`,`turns`].map(e=>(0,I.jsx)(`button`,{onClick:()=>s(e),className:`px-1.5 rounded-sm ${o===e?`bg-panel-2 text-fg`:`hover:text-fg`}`,children:e},e))}),children:(0,I.jsxs)(`ol`,{ref:u,className:`max-h-[70vh] overflow-auto`,children:[y.length===0&&(0,I.jsx)(z,{title:`No events yet`}),y.map(e=>(0,I.jsx)(ig,{e,now:n,toolByUse:v,inMinute:r!==void 0&&rg(e.ts,r)},e.id)),!m&&i.length>0&&(0,I.jsx)(`li`,{className:`px-3 py-1.5 border-t border-border/60`,children:(0,I.jsx)(`button`,{className:`text-[11px] text-fg-muted hover:text-fg border border-border px-2 py-0.5 rounded-sm`,onClick:()=>void g(),disabled:f,children:f?`loading…`:`load earlier events`})}),m&&(0,I.jsx)(`li`,{className:`px-3 py-1 text-[11px] text-fg-faint`,children:`start of session`})]})}),(0,I.jsxs)(`div`,{className:`grid gap-3 content-start`,children:[(0,I.jsxs)(L,{title:`Cost, cumulative`,children:[(0,I.jsx)(`div`,{className:`px-3 py-2`,children:(0,I.jsx)(xt,{values:_.length?_:[0,0],width:230,height:40,tone:`accent`})}),(0,I.jsxs)(`div`,{className:`px-3 pb-2 text-[11px] text-fg-muted num`,children:[_.length,` priced turns · `,S(_[_.length-1]??0)]})]}),(0,I.jsxs)(L,{title:`Tokens per turn`,children:[(0,I.jsx)(`div`,{className:`px-3 py-2`,children:(0,I.jsx)(xt,{values:i.filter(e=>e.tokens).map(e=>e.tokens.in+e.tokens.cache_read+e.tokens.cache_write),width:230,height:40})}),(0,I.jsx)(`div`,{className:`px-3 pb-2 text-[11px] text-fg-muted`,children:`prompt size (input + cache) per assistant turn`})]})]})]})}function rg(e,t){let n=Date.parse(e);return Number.isFinite(n)&&Math.floor(n/6e4)===Math.floor(t/6e4)}function ig({e,now:t,toolByUse:n,inMinute:r}){let[i,a]=(0,l.useState)(!1),o=(0,l.useRef)(null);(0,l.useEffect)(()=>{r&&o.current?.scrollIntoView({block:`center`})},[r]);let s=e.payload??{},c=e.tool||(e.kind===`tool.post`?n.get(String(s.tool_use_id??``)):void 0),u=ag({...e,tool:c},s),d=e.kind===`turn.assistant`?String(s.text??``):e.kind===`turn.user`?String(s.prompt??``):e.kind===`tool.post`&&typeof s.tool_response==`string`?s.tool_response:``,f=e.kind===`turn.user`?`text-info`:e.kind===`turn.assistant`?`text-fg`:e.kind===`agent.stop`||e.kind===`context.compact`?`text-warn`:`text-fg-muted`;return(0,I.jsxs)(`li`,{ref:o,className:`border-b border-border/60 last:border-0 hover:bg-panel-2 animate-flash ${r?`bg-accent/10 border-l-2 border-l-accent`:``}`,children:[(0,I.jsxs)(`button`,{className:`w-full text-left flex items-baseline gap-2 px-3 py-[3px]`,onClick:()=>a(!i),children:[(0,I.jsx)(`span`,{className:`num text-[10px] text-fg-faint w-14 shrink-0`,children:ee(e.ts,t)}),(0,I.jsx)(`span`,{className:`mono text-[10px] w-24 shrink-0 ${f}`,children:e.kind}),(0,I.jsx)(`span`,{className:`truncate text-[12px] min-w-0`,title:u,children:u}),e.tokens&&(0,I.jsxs)(`span`,{className:`ml-auto num text-[10px] text-fg-faint shrink-0`,children:[C(e.tokens.in+e.tokens.cache_read+e.tokens.cache_write),`→`,C(e.tokens.out),e.cost_usd===void 0?``:` · ${S(e.cost_usd)}`]})]}),i&&(0,I.jsxs)(`div`,{className:`px-3 pb-2`,children:[d?(0,I.jsx)(`div`,{className:`text-[12px] leading-[1.55] whitespace-pre-wrap break-words max-h-96 overflow-auto border-l-2 border-border-strong pl-3 mb-2`,children:d}):null,(0,I.jsxs)(`details`,{children:[(0,I.jsx)(`summary`,{className:`text-[10px] text-fg-faint cursor-pointer select-none`,children:`raw event`}),(0,I.jsx)(`pre`,{className:`mono text-[10px] leading-[1.4] text-fg-muted pt-1 max-h-64 overflow-auto whitespace-pre-wrap break-all`,children:JSON.stringify({id:e.id,ts:e.ts,source:e.source,key:e.key,agent_id:e.agent_id,model:e.model,tokens:e.tokens,cost_usd:e.cost_usd,payload:e.payload},null,2)})]})]})]})}function ag(e,t){let n=t.tool_input??{};switch(e.kind){case`tool.pre`:{let r=e.tool??String(t.tool_name??`tool`),i=n.command??n.file_path??n.pattern??n.query??n.url??n.prompt??``;return i?`${r} ${String(i).split(` `)[0]}`:r}case`tool.post`:{let n=e.tool??String(t.tool_name??`tool`),r=t.tool_response,i=t.is_error===!0,a=typeof r==`string`?r:r?JSON.stringify(r):``;return`${n} ${i?`failed`:`done`}${a?` ${a.slice(0,160)}`:``}`}case`turn.user`:return`you: ${String(t.prompt??``).slice(0,200)}`;case`turn.assistant`:{let n=String(t.text??``),r=Array.isArray(t.tools)?t.tools:[];return n?n.slice(0,200):r.length?`→ ${r.join(`, `)}`:`${e.model??`assistant`} turn`}case`agent.stop`:return e.agent_id?`subagent ${e.agent_id} stopped`:`turn ended (${String(t.stop_reason??`stop`)})`;case`agent.spawn`:return`session started (${String(t.source??`startup`)})`;case`context.compact`:return`context compaction (${String(t.trigger??`auto`)})`;default:return e.kind}}function og({id:e,s:t}){let n=F(()=>N.diff(e),[e,t.last_event_at],{live:!1,intervalMs:8e3}),[r,i]=(0,l.useState)(new Set),a=e=>i(t=>{let n=new Set(t);return n.delete(e)||n.add(e),n});if(n.error&&!n.data){let e=n.error;if(e instanceof j&&e.status===409){let n=e.body;return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(z,{title:`No git repository`,children:[n?.cwd?(0,I.jsx)(`span`,{className:`mono`,children:n.cwd}):null,` `,n?.error]}),(0,I.jsx)(cg,{s:t})]})}return(0,I.jsx)(z,{title:`Cannot load diff`,children:e.message})}let o=n.data;if(!o)return(0,I.jsx)(`div`,{className:`text-fg-muted px-1`,children:`loading…`});let s=new Set(o.files.map(e=>e.path)),c=t.files.filter(e=>!s.has(e)&&!s.has(e.replace(/^.*?\//,``))),u=o.files.length>0&&o.files.every(e=>r.has(e.path));return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(L,{title:`Changes · ${o.branch||`detached`}`,right:(0,I.jsxs)(`span`,{className:`flex items-center gap-2`,children:[o.base&&(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:o.base}),o.files.length>0&&(0,I.jsx)(`button`,{className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-0.5 rounded-sm`,onClick:()=>i(u?new Set:new Set(o.files.map(e=>e.path))),children:u?`collapse all`:`expand all`}),(0,I.jsxs)(`span`,{className:`num`,children:[o.files.length,` files`]})]}),children:[o.files.length===0&&(0,I.jsx)(z,{title:`Clean working tree`}),(0,I.jsx)(`ul`,{children:o.files.map(e=>{let t=r.has(e.path);return(0,I.jsxs)(`li`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsxs)(`button`,{className:`w-full text-left px-3 py-1.5 flex items-center gap-3 hover:bg-panel-2`,onClick:()=>a(e.path),"aria-expanded":t,children:[(0,I.jsx)(`span`,{className:`text-fg-faint text-[10px] shrink-0 transition-transform ${t?`rotate-90`:``}`,children:`▶`}),(0,I.jsx)(`span`,{className:`mono text-[10px] w-16 shrink-0 ${e.status===`added`||e.status===`untracked`?`text-ok`:e.status===`deleted`?`text-danger`:`text-fg-muted`}`,children:e.status}),(0,I.jsx)(`span`,{className:`mono text-[12px] truncate`,children:e.path}),(0,I.jsxs)(`span`,{className:`ml-auto num text-[11px] shrink-0`,children:[(0,I.jsxs)(`span`,{className:`text-ok`,children:[`+`,e.additions]}),` `,(0,I.jsxs)(`span`,{className:`text-danger`,children:[`−`,e.deletions]})]})]}),t&&e.patch&&(0,I.jsx)(sg,{patch:e.patch}),t&&!e.patch&&(0,I.jsx)(`div`,{className:`px-3 pb-2 text-[11px] text-fg-faint`,children:e.binary?`binary file`:`no patch`})]},e.path)})})]}),c.length>0&&(0,I.jsx)(cg,{s:t,only:c})]})}function sg({patch:e}){return(0,I.jsx)(`pre`,{className:`mono text-[11px] leading-[1.35] px-3 pb-2 overflow-auto max-h-[50vh]`,children:e.split(` -`).map((e,t)=>{let n=e.startsWith(`+`)&&!e.startsWith(`+++`)?`text-ok`:e.startsWith(`-`)&&!e.startsWith(`---`)?`text-danger`:e.startsWith(`@@`)?`text-info`:`text-fg-muted`;return(0,I.jsx)(`div`,{className:n,children:e||` `},t)})})}function cg({s:e,only:t}){let n=t??e.files,r=e.files.length(0,I.jsxs)(`li`,{className:`px-3 py-1 border-b border-border/60 last:border-0 flex gap-2 items-baseline`,children:[(0,I.jsx)(`span`,{className:`mono text-[12px]`,children:E(e)}),(0,I.jsx)(`span`,{className:`mono text-[10px] text-fg-faint truncate`,children:e})]},e))})]})}function lg({id:e}){let[t,n]=(0,l.useState)(``),r=async t=>{n(t);try{await N.signal(e,t)}catch{}finally{n(``)}};return(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-wider text-ok border border-ok/40 rounded-sm px-1`,children:`owned`}),(0,I.jsx)(`button`,{disabled:!!t,onClick:()=>r(`pause`),className:`text-[11px] border border-border px-1.5 rounded-sm text-fg-muted hover:text-fg`,children:`pause`}),(0,I.jsx)(`button`,{disabled:!!t,onClick:()=>r(`resume`),className:`text-[11px] border border-border px-1.5 rounded-sm text-fg-muted hover:text-fg`,children:`resume`}),(0,I.jsx)(`button`,{disabled:!!t,onClick:()=>r(`kill`),className:`text-[11px] border border-danger/40 text-danger px-1.5 rounded-sm hover:bg-danger/10`,children:`kill`})]})}function ug(e){if(!Number.isFinite(e)||e<=0)return[];let t=e/3,n=10**Math.floor(Math.log10(t)),r=[1,2,5,10].map(e=>e*n).find(e=>e>=t)??n*10,i=[];for(let t=r;t<=e*1.0001;t+=r)i.push(t);return i}function dg({bars:e,active:t,onActive:n,height:r=112,showDayLabels:i=!0}){let a=e=>typeof e==`number`&&Number.isFinite(e)?e:0,o=Math.max(...e.map(e=>a(e.cost)),1e-9),s=r-16,c=ug(o);return(0,I.jsxs)(`div`,{className:`relative px-3 py-3 flex items-end gap-[3px]`,style:{height:r},onMouseLeave:()=>n(null),children:[c.map(e=>(0,I.jsx)(`div`,{className:`pointer-events-none absolute left-3 right-3 border-t border-border/60`,style:{bottom:16+Math.round(s*e/o)},"aria-hidden":!0,children:(0,I.jsx)(`span`,{className:`num absolute -top-[7px] right-0 bg-panel pl-1 text-[9px] text-fg-faint`,children:S(e)})},e)),e.map(e=>{let r=t===e.day;return(0,I.jsxs)(`button`,{type:`button`,className:`flex-1 flex flex-col items-center justify-end gap-1 min-w-0 h-full cursor-default focus:outline-none`,onMouseEnter:()=>n(e.day),onFocus:()=>n(e.day),onBlur:()=>n(null),"aria-label":`${e.day}: ${S(a(e.cost))}`,children:[(0,I.jsx)(`div`,{className:`w-full rounded-t-sm transition-colors ${r?`bg-accent`:`bg-accent/70`}`,style:{height:Math.max(2,Math.round(s*a(e.cost)/o))}}),i&&(0,I.jsx)(`div`,{className:`num text-[9px] ${r?`text-fg`:`text-fg-faint`}`,children:e.day.slice(8)})]},e.day)})]})}function fg({bars:e,active:t,total:n}){let r=t?e.find(e=>e.day===t):void 0;return r?(0,I.jsxs)(`span`,{className:`num flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:r.day}),(0,I.jsx)(`span`,{className:`text-fg`,children:S(r.cost)}),(0,I.jsx)(`span`,{className:`text-fg-faint`,children:C(r.tokens)}),r.sessions!==void 0&&r.sessions>0&&(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[r.sessions,` `,r.sessions===1?`session`:`sessions`]})]}):(0,I.jsx)(`span`,{className:`num`,children:S(n)})}var pg=[`M`,`T`,`W`,`T`,`F`,`S`,`S`];function mg(e){return(new Date(`${e}T00:00:00Z`).getUTCDay()+6)%7}function hg(e,t){if(!(e>0))return`bg-border/60`;let n=Math.sqrt(e/Math.max(t,1e-9));return n>.75?`bg-accent`:n>.5?`bg-accent/75`:n>.25?`bg-accent/50`:`bg-accent/25`}function gg({bars:e,active:t,onActive:n,maxCell:r=44}){let i=e=>typeof e==`number`&&Number.isFinite(e)?e:0,a=Math.max(...e.map(e=>i(e.cost)),1e-9),o=e[0],s=o?mg(o.day):0;return(0,I.jsxs)(`div`,{className:`px-3 py-3`,onMouseLeave:()=>n(null),children:[(0,I.jsxs)(`div`,{className:`grid gap-1`,style:{gridTemplateColumns:`repeat(7, minmax(0, 1fr))`,maxWidth:r*7+24},children:[pg.map((e,t)=>(0,I.jsx)(`div`,{className:`text-center text-[9px] text-fg-faint`,"aria-hidden":!0,children:e},t)),Array.from({length:s},(e,t)=>(0,I.jsx)(`div`,{"aria-hidden":!0},`lead-${t}`)),e.map(e=>{let r=i(e.cost),o=t===e.day;return(0,I.jsx)(`button`,{type:`button`,className:`flex aspect-square items-center justify-center focus:outline-none cursor-default`,onMouseEnter:()=>n(e.day),onFocus:()=>n(e.day),onBlur:()=>n(null),"aria-label":`${e.day}: ${S(r)}`,children:(0,I.jsx)(`span`,{className:`h-full w-full rounded-[3px] transition-colors ${hg(r,a)} ${o?`ring-1 ring-accent ring-offset-1 ring-offset-panel`:``}`})},e.day)})]}),(0,I.jsxs)(`div`,{className:`mt-3 flex items-center gap-1.5 text-[9px] text-fg-faint`,children:[(0,I.jsx)(`span`,{children:`$0`}),[`bg-border/60`,`bg-accent/25`,`bg-accent/50`,`bg-accent/75`,`bg-accent`].map(e=>(0,I.jsx)(`span`,{className:`h-2 w-2 rounded-[2px] ${e}`,"aria-hidden":!0},e)),(0,I.jsx)(`span`,{className:`num`,children:S(a)})]})]})}var _g=e=>e===1?`day`:`days`;function vg({summary:e,plan:t,days:n}){if(!e)return null;let r=e.cost_usd;if(!t?.plan_kind)return(0,I.jsx)(L,{title:`Plan value`,children:(0,I.jsx)(`div`,{className:`px-3 py-3 text-[12px] text-fg-muted`,children:`Set your plan in the header and Caprock will show what this usage is worth against what you actually pay. It can't detect your plan, so it won't guess.`})});if(t.plan_kind===`metered`)return(0,I.jsx)(L,{title:`Spend`,right:(0,I.jsxs)(`span`,{className:`num text-[12px] text-fg-muted`,children:[t.plan_label||`API`,` · billed per token`]}),children:(0,I.jsxs)(`div`,{className:`px-3 py-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num text-3xl text-fg`,children:S(r)}),(0,I.jsxs)(`span`,{className:`text-[12px] text-fg-muted`,children:[`over the last `,n,` `,_g(n)]})]}),(0,I.jsxs)(`p`,{className:`text-[11px] text-fg-faint mt-2 max-w-[60ch]`,children:[`You are billed per token, so this is approximately your actual cost — at Anthropic list prices (`,e.pricing_version,`). Not a saving.`]})]})});let i=t.plan_usd_per_month*n/30,a=i>0?r/i:0;return(0,I.jsxs)(L,{title:`Plan value`,right:(0,I.jsxs)(`span`,{className:`num text-[12px] text-fg-muted`,children:[t.plan_label,` · `,S(t.plan_usd_per_month),`/mo`]}),children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-3 divide-y sm:divide-y-0 sm:divide-x divide-border`,children:[(0,I.jsx)(R,{label:`you pay · ${n}d`,value:S(i),sub:t.plan_label}),(0,I.jsx)(R,{label:`same usage at API list`,value:S(r),sub:`at list prices ${e.pricing_version}`,tone:`ok`}),(0,I.jsx)(R,{label:`which is`,value:a>0?`${a.toFixed(1)}×`:`—`,sub:a>0?`what ${n} ${_g(n)} would cost through the API`:`not enough measured usage yet`,tone:a>0?`ok`:void 0,size:`hero`})]}),(0,I.jsx)(`p`,{className:`border-t border-border px-3 py-2 text-[11px] text-fg-faint leading-relaxed`,children:`Not a discount you received, and not money back — without the plan you would not have run this much.`})]})}function yg({feature:e,title:t,children:n}){let[r,i]=(0,l.useState)(!1);return F(()=>N.premium(),[]).data?.license?.active?(0,I.jsx)(I.Fragment,{children:n}):(0,I.jsxs)(`div`,{className:`relative overflow-hidden rounded-[var(--radius-panel)] border border-border`,children:[(0,I.jsx)(`div`,{"aria-hidden":!0,className:`pointer-events-none select-none opacity-90`,children:n}),(0,I.jsxs)(`div`,{className:`absolute inset-0 flex flex-col items-center justify-center gap-2.5 px-4 text-center`,children:[(0,I.jsx)(`span`,{className:`rounded-sm bg-panel/95 px-3 py-1 text-[15px] font-medium text-fg shadow-[0_2px_12px_var(--color-bg)]`,children:t}),(0,I.jsx)(`button`,{onClick:()=>i(!0),className:`rounded-sm bg-premium px-3.5 py-1.5 text-[13px] font-medium text-white shadow-[0_2px_12px_var(--color-bg)] hover:brightness-110`,children:`Unlock with Premium`})]}),r&&(0,I.jsx)(nt,{feature:e,onClose:()=>i(!1)})]})}function bg({suggestion:e}){let t=F(()=>N.settings(),[],{live:!1}),[n,r]=(0,l.useState)(``),[i,a]=(0,l.useState)(!1),[o,s]=(0,l.useState)(``),[c,u]=(0,l.useState)(!1),[d,f]=(0,l.useState)(!1),p=t.data?.cap_usd_per_day;(0,l.useEffect)(()=>{d||p===void 0||(r(p?String(p):``),f(!0))},[p,d]);let m=t.data?.cap_usd_per_day??0,h=m>0,g=async e=>{a(!0),s(``),u(!1);try{await N.saveSettings({cap_usd_per_day:e}),r(e?String(e):``),u(!0),t.refresh()}catch(e){s(e instanceof Error?e.message:String(e))}finally{a(!1)}},_=()=>{let e=n.trim().replace(/^\$/,``).replace(/,/g,``),t=Number(e);if(e===``||!Number.isFinite(t)||t<0){s(`A daily cap has to be a positive number of dollars.`);return}g(t)};return(0,I.jsx)(L,{title:`Daily spend cap`,right:(0,I.jsx)(`span`,{className:h?`text-premium-strong`:`text-fg-faint`,children:h?`on`:`off`}),children:(0,I.jsxs)(`div`,{className:`grid gap-2.5 px-3 py-3 text-[13px]`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`Stop the day at`}),(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`$`}),(0,I.jsx)(`input`,{className:`input w-28`,inputMode:`decimal`,placeholder:`0`,value:n,onChange:e=>{r(e.target.value),u(!1)},onKeyDown:e=>e.key===`Enter`&&_(),"aria-label":`Daily spend cap in dollars`}),(0,I.jsx)(`button`,{onClick:_,disabled:i,className:`rounded-sm bg-premium px-3 py-1 text-[12px] font-medium text-white hover:brightness-110 disabled:opacity-50`,children:i?`Saving…`:`Save`}),h&&(0,I.jsx)(`button`,{onClick:()=>void g(0),disabled:i,className:`text-[12px] text-fg-faint hover:text-fg`,children:`turn off`}),c&&!o&&(0,I.jsx)(`span`,{className:`text-[12px] text-fg-faint`,children:`saved`})]}),!h&&e?(0,I.jsxs)(`p`,{className:`text-[12px] text-fg-faint`,children:[`Your days run about `,S(e/2),`.`,` `,(0,I.jsxs)(`button`,{onClick:()=>void g(e),className:`text-premium-strong hover:underline`,children:[`Use `,S(e)]}),` `,`— twice that, so an ordinary day never trips it.`]}):null,o&&(0,I.jsx)(`p`,{className:`text-[12px] text-danger`,children:o}),(0,I.jsx)(`p`,{className:`border-t border-border pt-2 text-[12px] leading-relaxed text-fg-faint`,children:h?(0,I.jsxs)(I.Fragment,{children:[`When today crosses `,S(m),`, Caprock pauses the sessions it started — paused, not killed, so resuming keeps the conversation. Sessions you started yourself are never touched.`]}):(0,I.jsx)(I.Fragment,{children:`Off. Nothing is paused, whatever the day costs. Sessions you started yourself are never touched either way.`})})]})})}function xg(){let[e,t]=(0,l.useState)(`30d`),n=Date.now(),r=F(()=>N.summary(e),[e],{intervalMs:5e3}),i=F(()=>N.daily(30),[],{intervalMs:3e4}),[a]=De(),[o,s]=(0,l.useState)(null),[c,u]=(0,l.useState)(`calendar`),d=r.data,f=!!d&&d.turns>0,p=Sg(i.data??[]),m=wg(p.map(e=>e.cost));return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-1`,children:[[`today`,`7d`,`30d`,`all`].map(n=>(0,I.jsx)(`button`,{onClick:()=>t(n),className:`px-2 py-1 text-[12px] rounded-sm ${e===n?`bg-panel-2 text-fg`:`text-fg-muted hover:text-fg`}`,children:n},n)),(0,I.jsxs)(`span`,{className:`ml-auto text-[11px] text-fg-faint`,children:[un(a),d?` (table ${d.pricing_version})`:``]})]}),r.error&&!d&&(0,I.jsx)(z,{title:`Cannot reach the daemon`,children:r.error.message}),e!==`today`&&d&&(0,I.jsx)(En,{costUSD:p.reduce((e,t)=>e+t.cost,0),days:p.filter(e=>e.cost>0).length,now:n}),(0,I.jsx)(vg,{summary:d,plan:a,days:Cg(e,d?.from_ms)}),(0,I.jsxs)(L,{title:`Totals · ${e}`,children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 divide-x divide-border`,children:[(0,I.jsx)(R,{label:`Cost`,value:f?S(d.cost_usd):`—`,sub:(0,I.jsx)(`span`,{title:un(a),children:f?ln(a):`nothing measured in this range`}),tone:`info`,size:`hero`}),(0,I.jsx)(R,{label:`Burn now`,value:f?`${S(d.burn.usd_per_hour)}/h`:`—`,sub:f?`${C(Math.round(d.burn.tokens_per_min))} tok/min · ${d.sessions} sessions`:void 0}),(0,I.jsx)(R,{label:`Input`,value:f?C(d.tokens_in):`—`,sub:`fresh, full price`}),(0,I.jsx)(R,{label:`Output`,value:f?C(d.tokens_out):`—`,sub:f?`${d.turns} turns`:void 0}),(0,I.jsx)(R,{label:`Cache read`,value:f?C(d.cache_read):`—`,sub:f?(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-1.5`,children:[(0,I.jsxs)(`span`,{children:[w(d.savings.hit_rate*100),` hit rate`]}),(()=>{let e=mn(d.savings.hit_rate*100);return e?(0,I.jsx)(`span`,{className:e.color||`text-fg-faint`,children:e.label}):null})()]}):void 0}),(0,I.jsx)(R,{label:`Cache write`,value:f?C(d.cache_write):`—`,sub:f?`${w(d.savings.cut_pct)} input cost cut by cache`:void 0})]}),(0,I.jsx)(Sr,{u:d?.unpriced,className:`mx-3 mb-2.5`})]}),(0,I.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-2 xl:grid-cols-3`,children:[(0,I.jsxs)(L,{title:`Model mix`,right:(0,I.jsx)(`span`,{children:`by cost`}),children:[d?d.models.length===0&&(0,I.jsx)(z,{title:`No priced turns in range`}):(0,I.jsx)(St,{rows:4}),(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:(d?.models??[]).map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 mono`,title:e.model||void 0,children:e.model?re(e.model):`unknown`}),(0,I.jsxs)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:[e.turns,` turns`]}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:(d?.unpriced?.models??[]).includes(e.model)?(0,I.jsx)(`span`,{className:`text-warn`,title:`this model is not in the pricing table, so its cost is unknown`,children:`unpriced`}):S(e.cost_usd)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-faint w-14`,children:d&&d.cost_usd>0&&!(d.unpriced?.models??[]).includes(e.model)?w(100*e.cost_usd/d.cost_usd):`—`})]},e.model))})})]}),(0,I.jsx)(Et,{summary:d}),(0,I.jsxs)(L,{title:`Per project`,right:(0,I.jsx)(`span`,{children:`by cost`}),children:[d?d.projects.length===0&&(0,I.jsx)(z,{title:`No priced turns in range`}):(0,I.jsx)(St,{rows:4}),(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:(d?.projects??[]).map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1`,children:e.project||`unknown`}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:S(e.cost_usd)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-faint w-14`,children:d&&d.cost_usd>0?w(100*e.cost_usd/d.cost_usd):`—`})]},e.project))})})]})]}),(0,I.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-3`,children:[(0,I.jsxs)(L,{className:`lg:col-span-2`,title:`Last 30 days`,right:(0,I.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(fg,{bars:p,active:o,total:p.reduce((e,t)=>e+t.cost,0)}),(0,I.jsx)(`span`,{className:`flex items-center gap-1`,children:[`calendar`,`bars`].map(e=>(0,I.jsx)(`button`,{onClick:()=>u(e),className:`px-1.5 py-0.5 rounded-sm text-[11px] ${c===e?`bg-panel-2 text-fg`:`text-fg-faint hover:text-fg`}`,children:e},e))})]}),children:[i.data?p.length===0&&(0,I.jsx)(z,{title:`No history yet`}):(0,I.jsx)(St,{rows:2}),p.length>0&&(c===`calendar`?(0,I.jsx)(gg,{bars:p,active:o,onActive:s}):(0,I.jsx)(dg,{bars:p,active:o,onActive:s}))]}),(0,I.jsx)(yg,{feature:`cap`,title:`Stop the day at a number you choose`,children:(0,I.jsx)(bg,{suggestion:m})}),d&&(0,I.jsxs)(L,{title:`Plan limits`,children:[d.rate_limits?(0,I.jsxs)(`div`,{className:`flex flex-col gap-2 px-3 pt-1`,children:[d.rate_limits.five_hour&&(0,I.jsx)(_n,{label:`5-hour window`,w:d.rate_limits.five_hour,now:n}),d.rate_limits.seven_day&&(0,I.jsx)(_n,{label:`7-day window`,w:d.rate_limits.seven_day,now:n})]}):(0,I.jsxs)(`div`,{className:`px-3 pt-1 text-sm text-fg-muted`,children:[`No window state yet. Caprock reads this from Claude Code's status line, so it appears once a Pro or Max session has run with `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:`caprock statusline`}),` registered —`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` caprock up`}),` offers to do that. API-billed usage has no windows to report.`]}),(0,I.jsx)(`div`,{className:`mt-2 px-3 pb-3 text-[11px] text-fg-faint leading-relaxed`,children:`Live from Claude Code's status line (Pro/Max). The percentage is your usage of the window; a forecast is shown only when your measured pace would reach the limit before the window resets.`})]})]}),(0,I.jsxs)(`div`,{className:`text-[11px] text-fg-faint`,children:[d&&d.throttles>0?`${d.throttles} rate-limit / overloaded event${d.throttles===1?``:`s`} observed in this range (from Claude Code's StopFailure hook).`:`No rate-limit events observed in this range.`,` `,`Everything here is measured — no invented numbers.`]})]})}function Sg(e){let t=new Map;for(let n of e){let e=t.get(n.day)??{day:n.day,cost:0,tokens:0,sessions:0};e.cost+=n.cost_usd,e.tokens+=n.tokens_total,e.sessions+=n.sessions,t.set(n.day,e)}return[...t.values()].sort((e,t)=>e.day.localeCompare(t.day))}function Cg(e,t){switch(e){case`today`:return 1;case`7d`:return 7;case`30d`:return 30;default:return t?Math.max(1,Math.ceil((Date.now()-t)/864e5)):30}}function wg(e){let t=e.filter(e=>e>0).sort((e,t)=>e-t);if(t.length<3)return 0;let n=t[Math.floor(t.length/2)]*2,r=n<10?1:n<100?5:10;return Math.round(n/r)*r}function Tg({plan:e,save:t}){let[n,r]=(0,l.useState)(e.license_key??``),i=F(()=>N.premium(),[e.license_key]).data?.license;(0,l.useEffect)(()=>{r(e.license_key??``)},[e.license_key]);let a=n.trim()!==(e.license_key??``).trim();return(0,I.jsxs)(`div`,{className:`border-t border-border pt-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`w-28 shrink-0 text-fg-muted`,children:`Licence`}),(0,I.jsx)(`input`,{className:`input flex-1 min-w-0`,placeholder:`CR-…`,spellCheck:!1,value:n,onChange:e=>r(e.target.value),onKeyDown:r=>{r.key===`Enter`&&a&&t({...e,license_key:n.trim()})}}),(0,I.jsx)(`button`,{disabled:!a,onClick:()=>t({...e,license_key:n.trim()}),className:`rounded-sm border border-border px-2 py-0.5 text-fg-muted hover:border-border-strong hover:text-fg disabled:opacity-40`,children:`save`})]}),(0,I.jsxs)(`p`,{className:`mt-1.5 pl-[7.5rem] text-[11px] leading-relaxed`,children:[i?.active&&!i.in_grace&&(0,I.jsxs)(`span`,{className:`text-ok`,children:[`Premium is on`,i.expires_at?` — renews ${i.expires_at.slice(0,10)}`:``,`.`]}),i?.active&&i.in_grace&&(0,I.jsxs)(`span`,{className:`text-warn`,children:[i.reason,`. Update your key or payment method.`]}),i&&!i.active&&(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[e.license_key?i.reason:`No key — the free product is unaffected.`,` `,(0,I.jsx)(`a`,{href:`https://caprock.dev/premium/`,target:`_blank`,rel:`noreferrer`,className:`link`,children:`what Premium does`})]}),(0,I.jsx)(`span`,{className:`block text-fg-faint`,children:`Checked on this machine against the date inside the key. Caprock makes no call to us to verify it.`})]})]})}function Eg(){let e=F(()=>N.status(),[],{live:!1,intervalMs:5e3}),t=e.data;if(e.error&&!t)return(0,I.jsx)(z,{title:`Cannot reach the daemon`,children:e.error.message});if(!t)return(0,I.jsx)(`div`,{className:`text-fg-muted`,children:`loading…`});let n=[[`version`,t.version],[`url`,t.url],[`pid`,String(t.pid)],[`uptime`,te(t.uptime_s*1e3)],[`data dir`,t.data_dir],[`pricing`,`${t.pricing.version} · ${t.pricing.models} models · fetched ${t.pricing.fetched_at}${t.pricing.user_override?` · user override`:``}`],[`pricing source`,t.pricing.source],[`loop rule`,`≥ ${t.loop_k} same-tool calls in ${t.loop_t_minutes} min · ${t.active_loops} active`],[`events stored`,`${t.events.toLocaleString()}${t.retention_days>0?` · pruned after ${t.retention_days}d`:` · kept forever (set retention_days to cap DB growth)`}`],[`orchestration`,t.orchestration?`on (--hive)`:`off`],[`claude`,t.claude_available?`found on PATH — Caprock can start sessions for you`:`not found on PATH — Caprock cannot start sessions, but still observes every session you start yourself`],[`dashboard`,t.ui_built?`embedded build`:`dev server / placeholder`]];if(t.hooks&&n.push([`hooks`,`${(t.hooks.installed??[]).length}/${(t.hooks.installed??[]).length+(t.hooks.missing??[]).length} events registered in ${t.hooks.settings_path}${t.hooks.shim_exists?``:` (shim missing)`}`]),t.desktop){let e=t.desktop;n.push([`claude desktop`,`${e.five_hour_pct}% of the 5-hour window · ${e.seven_day_pct}% of the 7-day${e.stale?` · last seen `+new Date(e.at).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})+`, app closed since`:` · now`}`])}return t.ingest_error&&n.push([`ingest error`,`STOPPED: ${t.ingest_error} — nothing is being captured`]),t.ingest&&n.push([`ingest`,`${t.ingest.files_known} transcripts · ${t.ingest.events_stored} events stored · ${t.ingest.events_deduped} deduped · ${t.ingest.lines_malformed} malformed lines · backfill ${t.ingest.backfill_done?`done`:`running`}`]),(0,I.jsxs)(`div`,{className:`grid gap-3 max-w-3xl`,children:[(0,I.jsx)(Dg,{}),(0,I.jsx)(L,{title:`Daemon`,children:(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:n.map(([e,t])=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 text-fg-muted w-32`,children:e}),(0,I.jsx)(`td`,{className:`px-3 py-1 mono break-all`,children:t})]},e))})})}),t.ingest_error&&(0,I.jsx)(L,{title:`Ingest stopped`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-muted`,children:[`No new sessions are being captured: `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:t.ingest_error}),`. Check that`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` ~/.claude`}),` is readable, then restart with`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` caprock down && caprock up`}),`.`]})}),!t.claude_available&&(0,I.jsx)(L,{title:`claude not found`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-muted`,children:[`The `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` binary was not found on this machine, so Caprock cannot spawn sessions. It still observes every session you start yourself. Install Claude Code, or make sure`,(0,I.jsx)(`span`,{className:`mono`,children:` claude`}),` is on the PATH the daemon was started with.`]})}),t.hooks&&(t.hooks.missing??[]).length>0&&(0,I.jsx)(L,{title:`Hooks not fully installed`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-muted`,children:[`Missing: `,(0,I.jsx)(`span`,{className:`mono`,children:(t.hooks.missing??[]).join(`, `)}),`. Run `,(0,I.jsx)(`span`,{className:`mono`,children:`caprock hooks install`}),` for real-time activity; transcript tailing keeps working with a few seconds of delay.`]})})]})}function Dg(){let[e,t]=De();return e?(0,I.jsx)(L,{title:`Settings`,children:(0,I.jsxs)(`div`,{className:`grid gap-2 px-3 py-2.5 text-[12px]`,children:[(0,I.jsxs)(`label`,{className:`flex items-start gap-2 cursor-pointer`,children:[(0,I.jsx)(`input`,{type:`checkbox`,className:`accent-[var(--color-accent)] mt-0.5`,checked:e.update_checks,onChange:n=>t({...e,update_checks:n.target.checked})}),(0,I.jsxs)(`span`,{children:[(0,I.jsx)(`span`,{className:`text-fg`,children:`Check GitHub for new releases`}),(0,I.jsx)(`span`,{className:`block text-[11px] text-fg-muted`,children:`The only outbound call Caprock makes. No usage data is sent, and it is checked at most once a day.`})]})]}),(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2 border-t border-border pt-2`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted w-28 shrink-0`,children:`Your plan`}),(0,I.jsx)(`span`,{className:`mono text-fg`,children:e.plan_kind===`metered`?`${e.plan_label||`API`} · billed per token`:e.plan_kind===`flat`?`${e.plan_label||`plan`} · ${S(e.plan_usd_per_month)}/mo`:`not set`}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint ml-auto`,children:`change it in the header`})]}),(0,I.jsx)(Tg,{plan:e,save:t})]})}):null}var Og=[`your-api`,`your-web`];function kg(){let[e,t]=(0,l.useState)(`all`),[n,r]=(0,l.useState)(null),i=F(()=>N.history(e),[e],{intervalMs:15e3}),[a]=De(),o=i.data,s=!!o&&o.totals.turns>0,c=Sg(o?.daily??[]),u=(F(()=>N.summary(`7d`),[],{intervalMs:6e4}).data?.projects??[]).slice(0,4).map(e=>e.project),d=Math.max(...(o?.tools??[]).map(e=>e.count),1);return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-1`,children:[[`today`,`7d`,`30d`,`all`].map(n=>(0,I.jsx)(`button`,{onClick:()=>t(n),className:`px-2 py-1 text-[12px] rounded-sm ${e===n?`bg-panel-2 text-fg`:`text-fg-muted hover:text-fg`}`,children:n},n)),(0,I.jsx)(`span`,{className:`ml-auto text-[11px] text-fg-faint`,children:`Everything you ever ran through Caprock. Measured, not estimated.`})]}),s&&o&&(0,I.jsx)(En,{costUSD:o.totals.cost_usd,days:o.totals.days,now:Date.now()}),i.error&&!o&&(0,I.jsx)(z,{title:`Cannot reach the daemon`,children:i.error.message}),(0,I.jsxs)(L,{title:`Lifetime · ${e}`,children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-7 divide-x divide-border`,children:[(0,I.jsx)(R,{size:`compact`,label:`Sessions`,value:s?o.totals.sessions:`—`,sub:s?`${o.totals.owned_sessions} spawned by caprock`:void 0}),(0,I.jsx)(R,{size:`compact`,label:`Active days`,value:s?o.totals.days:`—`}),(0,I.jsx)(R,{size:`compact`,label:`Turns`,value:s?C(o.totals.turns):`—`,sub:s?`${C(o.totals.tool_calls)} tool calls`:void 0}),(0,I.jsx)(R,{size:`compact`,label:`Files touched`,value:s?C(o.totals.files_touched):`—`,sub:`summed per session`}),(0,I.jsx)(R,{size:`compact`,label:`Avg session span`,value:s?te(Math.round(o.totals.avg_session_sec*1e3)):`—`,sub:`first to last event`}),(0,I.jsx)(hn,{hitRate:o?.savings.hit_rate,cutPct:o?.savings.cut_pct,measured:s}),(0,I.jsx)(R,{label:`Cost`,value:s?S(o.totals.cost_usd):`—`,sub:(0,I.jsx)(`span`,{title:un(a),children:s?ln(a):`nothing measured yet`}),tone:`info`,size:`hero`})]}),(0,I.jsx)(Sr,{u:o?.totals.unpriced,className:`mx-3 mb-2.5`})]}),(0,I.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-2`,children:[(0,I.jsxs)(L,{title:`Tool usage`,right:(0,I.jsx)(`span`,{children:`by calls`}),children:[o?o.tools.length===0&&(0,I.jsx)(z,{title:`No tool calls yet`}):(0,I.jsx)(St,{rows:5}),(0,I.jsx)(`ul`,{className:`py-1`,children:(o?.tools??[]).slice(0,18).map(e=>(0,I.jsxs)(`li`,{className:`flex items-center gap-2 px-3 py-[3px]`,children:[(0,I.jsx)(`span`,{className:`mono text-[12px] w-44 shrink-0 truncate`,title:e.tool,children:ne(e.tool)}),(0,I.jsx)(`div`,{className:`flex-1 h-2 bg-panel-2 rounded-sm overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full bg-accent/70`,style:{width:`${100*e.count/d}%`}})}),(0,I.jsx)(`span`,{className:`num text-[11px] text-fg-muted w-12 text-right`,children:C(e.count)})]},e.tool))})]}),(0,I.jsxs)(`div`,{className:`grid gap-3 content-start`,children:[(0,I.jsxs)(L,{title:`Model mix`,right:(0,I.jsx)(`span`,{children:`by cost`}),children:[o?o.summary.models.length===0&&(0,I.jsx)(z,{title:`No priced turns`}):(0,I.jsx)(St,{rows:3}),(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:(o?.summary.models??[]).map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 mono`,children:e.model||`unknown`}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:S(e.cost_usd)})]},e.model))})})]}),(0,I.jsx)(yg,{feature:`report`,title:`Get this every Monday, without opening the dashboard`,children:(0,I.jsx)(L,{title:`Weekly report`,right:(0,I.jsx)(`span`,{children:`Mondays, 09:00`}),children:(0,I.jsxs)(`div`,{className:`px-3 py-3 text-[13px]`,children:[(0,I.jsxs)(`p`,{className:`text-fg-muted`,children:[(0,I.jsx)(`span`,{className:`text-fg-faint`,children:`To:`}),` your Telegram bot or webhook`]}),(0,I.jsx)(`p`,{className:`mt-2 text-fg`,children:`Last week, by repository:`}),(0,I.jsx)(`div`,{className:`mt-1.5 grid gap-1`,children:(u.length?u:Og).map(e=>(0,I.jsxs)(`div`,{className:`flex items-baseline justify-between gap-3`,children:[(0,I.jsx)(`span`,{className:`truncate text-fg-muted`,children:e||`unknown`}),(0,I.jsx)(`span`,{"aria-hidden":!0,className:`h-1.5 w-24 shrink-0 rounded-full bg-fg-faint/25`})]},e))}),(0,I.jsx)(`p`,{className:`mt-2.5 border-t border-border pt-2 text-[12px] text-fg-faint`,children:`…and the same by model, in your inbox before you open a terminal.`})]})})}),(0,I.jsx)(L,{title:`Top projects`,right:(0,I.jsx)(`span`,{children:`by cost`}),children:(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:(o?.summary.projects??[]).slice(0,8).map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1`,children:e.project||`unknown`}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:S(e.cost_usd)})]},e.project))})})})]})]}),(0,I.jsxs)(L,{title:`Daily cost`,right:(0,I.jsx)(fg,{bars:c,active:n,total:c.reduce((e,t)=>e+t.cost,0)}),children:[i.data?c.length===0&&(0,I.jsx)(z,{title:`No history yet`}):(0,I.jsx)(St,{rows:2}),c.length>0&&(0,I.jsx)(dg,{bars:c,active:n,onActive:r,height:96,showDayLabels:!1})]})]})}var Ag=[{key:`inbox`,label:`Inbox`},{key:`assigned`,label:`Assigned`},{key:`in_progress`,label:`In progress`},{key:`verifying`,label:`Verifying`},{key:`needs_you`,label:`Needs you`},{key:`done`,label:`Done`}];function jg(){let e=F(()=>N.status(),[],{live:!1,intervalMs:3e4}),t=F(()=>N.tasks(),[],{intervalMs:4e3}),[n,r]=(0,l.useState)(!1),[i,a]=(0,l.useState)(null);if(e.data&&e.data.orchestration===!1)return(0,I.jsx)(Mg,{status:e.data,onEnabled:()=>{e.refresh(),t.refresh()}});let o=e=>(t.data??[]).filter(t=>t.status===e||e===`done`&&t.status===`failed`);return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`button`,{onClick:()=>r(!0),className:`border border-accent/50 text-accent bg-accent/10 px-2 py-1 rounded-sm text-[12px] hover:bg-accent/20`,children:`+ New task`}),(0,I.jsx)(Fg,{available:e.data?.claude_available??!1}),(t.data??[]).some(e=>e.assignee!==``&&e.status!==`done`&&e.status!==`failed`)&&(0,I.jsx)(`a`,{href:`#/graph`,className:`link text-[12px] border border-border px-2 py-1 rounded-sm hover:border-border-strong`,children:`view graph`}),(0,I.jsxs)(`span`,{className:`ml-auto text-[11px] text-fg-faint`,children:[`Tasks are files on disk (`,(0,I.jsx)(`span`,{className:`mono`,children:`tasks/.md`}),`); the orchestrator moves them. Nothing reaches Done until its `,(0,I.jsx)(`span`,{className:`mono`,children:`done_criteria`}),` pass.`]})]}),t.error&&!t.data&&(0,I.jsx)(z,{title:`Cannot reach the daemon`,children:t.error.message}),t.data&&t.data.length===0&&(0,I.jsxs)(`div`,{className:`border border-border bg-panel-2/60 rounded-sm px-3 py-2 text-[12px] text-fg-muted`,children:[`Start here: `,(0,I.jsx)(`span`,{className:`text-fg`,children:`+ New task`}),` — a title and the commands that have to pass. Then `,(0,I.jsx)(`span`,{className:`text-fg`,children:`▶ Start orchestrator`}),`, which assigns it to a worker and keeps going until the checks are green.`]}),(0,I.jsx)(`div`,{className:`grid gap-2 grid-cols-2 md:grid-cols-3 xl:grid-cols-6`,children:Ag.map(e=>(0,I.jsxs)(`div`,{className:`min-w-0`,children:[(0,I.jsxs)(`div`,{className:`text-[11px] uppercase tracking-[0.08em] text-fg-faint mb-1.5 px-0.5 flex justify-between`,children:[(0,I.jsx)(`span`,{children:e.label}),(0,I.jsx)(`span`,{className:`num`,children:o(e.key).length})]}),(0,I.jsx)(`div`,{className:`grid gap-1.5 content-start min-h-[60px]`,children:o(e.key).map(e=>(0,I.jsx)(Ig,{t:e,onApprove:()=>t.refresh(),onOpen:()=>a(e.id)},e.id))})]},e.key))}),n&&(0,I.jsx)(Vg,{onClose:()=>{r(!1),t.refresh()}}),i&&(0,I.jsx)(Lg,{id:i,onClose:()=>{a(null),t.refresh()}})]})}function Mg({status:e,onEnabled:t}){let[n,r]=(0,l.useState)(!1),i=e.suggested_hive??`~/caprock-tasks`,a=e.suggested_repo??``;return(0,I.jsxs)(`div`,{className:`grid gap-3 max-w-[52rem] mx-auto`,children:[(0,I.jsxs)(L,{title:`Task runner`,right:(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:`off`}),children:[(0,I.jsxs)(`div`,{className:`grid gap-3 px-3 py-3`,children:[(0,I.jsxs)(`ol`,{className:`grid gap-2 md:grid-cols-3`,children:[(0,I.jsx)(Ng,{n:1,title:`You write a task`,children:`A title, a budget, and the commands that have to pass.`}),(0,I.jsxs)(Ng,{n:2,title:`Caprock runs it`,children:[`One Claude session per task, in its `,(0,I.jsx)(`span`,{className:`text-fg`,children:`own git worktree`}),` — your working tree is untouched.`]}),(0,I.jsxs)(Ng,{n:3,title:`Caprock checks it`,children:[(0,I.jsx)(`span`,{className:`text-fg`,children:`Caprock`}),` runs your commands, not the agent. Only green is done.`]})]}),(0,I.jsx)(`div`,{className:`text-[11px] text-fg-faint`,children:`Best for independent tasks — nothing here merges branches. The queue directory is created for you; your repository is not modified.`})]}),(0,I.jsxs)(`footer`,{className:`px-3 py-2 border-t border-border flex items-center gap-2`,children:[(0,I.jsx)(`button`,{onClick:()=>r(!0),className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm text-[12px] hover:bg-accent/25`,children:`Turn on the task runner`}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:`No restart. Nothing runs until you start it.`})]})]}),n&&(0,I.jsx)(Pg,{hive:i,repo:a,onClose:()=>r(!1),onDone:t})]})}function Ng({n:e,title:t,children:n}){return(0,I.jsxs)(`li`,{className:`border border-border bg-panel-2/60 rounded-sm px-2.5 py-2 grid gap-1 content-start`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-1.5`,children:[(0,I.jsx)(`span`,{className:`num text-[11px] text-accent`,children:e}),(0,I.jsx)(`span`,{className:`text-[12px] font-medium`,children:t})]}),(0,I.jsx)(`div`,{className:`text-[11px] text-fg-muted leading-[1.45]`,children:n})]})}function Pg({hive:e,repo:t,onClose:n,onDone:r}){let[i,a]=(0,l.useState)(e),[o,s]=(0,l.useState)(t),[c,u]=(0,l.useState)(!1),[d,f]=(0,l.useState)(``);return(0,I.jsx)(`div`,{className:`fixed inset-0 z-20 bg-black/50 flex items-start justify-center pt-24`,onClick:n,children:(0,I.jsxs)(`div`,{className:`border border-border-strong bg-panel rounded-[var(--radius-panel)] w-[560px] max-w-[92vw]`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`px-3 py-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`h2`,{className:`text-[12px] uppercase tracking-[0.08em] text-fg-muted`,children:`Turn on the task runner`}),(0,I.jsx)(`button`,{onClick:n,className:`ml-auto text-fg-muted hover:text-fg`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`px-4 py-3 grid gap-3 text-[13px]`,children:[(0,I.jsxs)(`ul`,{className:`grid gap-1 text-[12px] text-fg-muted`,children:[(0,I.jsx)(`li`,{children:`· Creates the queue directory below, with a README and an example task.`}),(0,I.jsxs)(`li`,{children:[`· Lets Caprock spawn Claude sessions `,(0,I.jsx)(`span`,{className:`text-fg`,children:`with permission prompts skipped`}),`, one git worktree each under the repo below.`]}),(0,I.jsx)(`li`,{children:`· Starts nothing yet — you start the orchestrator, and only then does work begin.`})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[`Queue directory`,(0,I.jsx)(`span`,{className:`text-fg-faint`,children:` · created if missing`})]}),(0,I.jsx)(`input`,{className:`input mono`,value:i,onChange:e=>a(e.target.value)})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[`Repository`,(0,I.jsx)(`span`,{className:`text-fg-faint`,children:` · workers branch from here`})]}),(0,I.jsx)(`input`,{className:`input mono`,value:o,onChange:e=>s(e.target.value)})]}),d&&(0,I.jsx)(`div`,{className:`text-danger text-[12px]`,children:d})]}),(0,I.jsxs)(`footer`,{className:`px-4 py-2 border-t border-border flex gap-2 justify-end`,children:[(0,I.jsx)(`button`,{onClick:n,className:`border border-border px-3 py-1 rounded-sm text-fg-muted hover:text-fg`,children:`Cancel`}),(0,I.jsx)(`button`,{onClick:async()=>{u(!0),f(``);try{await N.enableHive(i.trim(),o.trim()),n(),r()}catch(e){f(oe(e))}finally{u(!1)}},disabled:c,className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm hover:bg-accent/25 disabled:opacity-50`,children:c?`turning on…`:`Turn it on`})]})]})})}function Fg({available:e}){let[t,n]=(0,l.useState)(!1),[r,i]=(0,l.useState)(``);return(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[(0,I.jsx)(`button`,{disabled:t||!e,onClick:async()=>{n(!0),i(``);try{let e=await N.startOrchestrator();i(`orchestrator: `+e.session_id.slice(0,8))}catch(e){i(oe(e))}finally{n(!1)}},title:e?`spawn the orchestrator session`:`claude not found — cannot spawn`,className:`border border-border text-fg-muted px-2 py-1 rounded-sm text-[12px] hover:text-fg disabled:opacity-50`,children:t?`starting…`:`▶ Start orchestrator`}),!e&&(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` was not found on this machine, so Caprock cannot spawn the orchestrator. It still observes every session you start yourself.`]}),r&&(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint mono`,children:r})]})}function Ig({t:e,onApprove:t,onOpen:n}){let r=e.budget_usd>0&&e.cost_usd>e.budget_usd,i=e.assignee!==``;return(0,I.jsxs)(`div`,{className:`border border-border bg-panel rounded-[var(--radius-panel)] px-2 py-1.5`,children:[(0,I.jsxs)(`button`,{className:`w-full text-left disabled:cursor-default`,disabled:!i,onClick:n,title:i?`show the diff, the checks that ran, and where the branch is`:`nothing to show yet — no worker has picked this up`,children:[(0,I.jsx)(`div`,{className:`text-[12px] font-medium truncate ${i?`hover:text-accent`:``}`,title:e.title,children:e.title||e.id}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2 mt-1 text-[10px] text-fg-faint`,children:[(0,I.jsx)(`span`,{className:`mono`,children:T(e.id)}),e.assignee&&(0,I.jsxs)(`span`,{className:`mono text-fg-muted`,children:[`→ `,e.assignee]}),(0,I.jsxs)(`span`,{className:`num ml-auto ${r?`text-danger`:`text-fg-muted`}`,children:[S(e.cost_usd),e.budget_usd>0?` / ${S(e.budget_usd)}`:``]})]})]}),i&&(0,I.jsxs)(`div`,{className:`mt-1 text-[10px] text-fg-faint mono truncate`,children:[`caprock/`,e.assignee]}),e.status===`needs_you`&&(0,I.jsxs)(`div`,{className:`flex gap-1 mt-1.5`,children:[(0,I.jsx)(`button`,{onClick:()=>N.approve(e.id,!0).then(t),className:`flex-1 text-[11px] border border-ok/40 text-ok rounded-sm hover:bg-ok/10`,children:`approve`}),(0,I.jsx)(`button`,{onClick:()=>N.approve(e.id,!1).then(t),className:`flex-1 text-[11px] border border-danger/40 text-danger rounded-sm hover:bg-danger/10`,children:`reject`})]})]})}function Lg({id:e,onClose:t}){let n=F(()=>N.task(e),[e],{intervalMs:6e3}),r=n.data,i=r?.work,a=i?.sessions?.[0];return(0,I.jsx)(`div`,{className:`fixed inset-0 z-20 bg-black/50 flex items-start justify-center pt-16`,onClick:t,children:(0,I.jsxs)(`div`,{className:`border border-border-strong bg-panel rounded-[var(--radius-panel)] w-[820px] max-w-[94vw] max-h-[82vh] overflow-auto`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`px-3 py-2 border-b border-border flex items-center gap-2 sticky top-0 bg-panel z-10`,children:[(0,I.jsx)(`h2`,{className:`text-[12px] uppercase tracking-[0.08em] text-fg-muted`,children:`Task`}),r&&(0,I.jsx)(`span`,{className:`text-[12px] truncate`,children:r.task.title||r.task.id}),r&&(0,I.jsx)(`span`,{className:`mono text-[10px] text-fg-faint`,children:r.task.status}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-fg-muted hover:text-fg`,children:`✕`})]}),!r&&!n.error&&(0,I.jsx)(St,{rows:5}),n.error&&!r&&(0,I.jsx)(z,{title:`Cannot load the task`,children:n.error.message}),r&&(0,I.jsxs)(`div`,{className:`px-3 py-3 grid gap-3`,children:[(0,I.jsx)(Rg,{work:i,assignee:r.task.assignee}),(0,I.jsx)(zg,{criteria:r.done_criteria,runs:i?.verifications,status:r.task.status}),(0,I.jsx)(Bg,{sessionID:a?.session_id,assignee:r.task.assignee}),r.body&&(0,I.jsx)(L,{title:`Brief`,children:(0,I.jsx)(`pre`,{className:`mono text-[11px] leading-[1.45] px-3 py-2 whitespace-pre-wrap`,children:r.body})})]})]})})}function Rg({work:e,assignee:t}){return e?.branch?(0,I.jsx)(L,{title:`Where the work is`,children:(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsxs)(`tbody`,{children:[(0,I.jsxs)(`tr`,{className:`border-b border-border/60`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 text-fg-muted w-32`,children:`branch`}),(0,I.jsx)(`td`,{className:`px-3 py-1 mono break-all`,children:e.branch})]}),e.worktree&&(0,I.jsxs)(`tr`,{className:`border-b border-border/60`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 text-fg-muted w-32`,children:`worktree`}),(0,I.jsx)(`td`,{className:`px-3 py-1 mono break-all`,children:e.worktree})]}),(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 text-fg-muted w-32 align-top`,children:`take it`}),(0,I.jsxs)(`td`,{className:`px-3 py-1 grid gap-1 justify-items-start`,children:[(0,I.jsx)(Ct,{command:`git merge --no-ff ${e.branch}`}),(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-faint`,children:[`Run it from `,e.repo?(0,I.jsx)(`span`,{className:`mono`,children:e.repo}):`your repo`,`, on the branch you want the work on. Prefer `,(0,I.jsx)(`span`,{className:`mono`,children:`git cherry-pick`}),` if you only want some of it. Worker`,` `,(0,I.jsx)(`span`,{className:`mono`,children:t}),` may still be running — check the diff below first.`]})]})]})]})})}):(0,I.jsx)(L,{title:`Where the work is`,children:(0,I.jsx)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:`No worker has been assigned yet, so there is no branch. One is created the moment the orchestrator assigns this task.`})})}function zg({criteria:e,runs:t,status:n}){let r=t?.[0],i=r?t.filter(e=>e.round===r.round):[],a=r?`round ${r.round}`:void 0;return(0,I.jsxs)(L,{title:`What has to pass`,right:a,children:[i.length===0&&(0,I.jsxs)(`div`,{className:`px-3 py-2 grid gap-1`,children:[(0,I.jsx)(`div`,{className:`text-[12px] text-fg-faint`,children:n===`done`?`This task was marked done without a recorded check.`:`Not run yet. Caprock runs these itself, in the worker’s worktree, when the worker reports it has finished.`}),(0,I.jsx)(`ul`,{className:`grid gap-0.5`,children:(e??[]).map(e=>(0,I.jsxs)(`li`,{className:`mono text-[11px] text-fg-muted`,children:[`$ `,e]},e))}),(e??[]).length===0&&(0,I.jsx)(`div`,{className:`mono text-[11px] text-danger`,children:`no done_criteria — Caprock cannot verify this task`})]}),i.length>0&&(0,I.jsx)(`ul`,{children:i.map(e=>(0,I.jsxs)(`li`,{className:`border-b border-border/60 last:border-0 px-3 py-1.5 flex items-center gap-3`,children:[(0,I.jsx)(`span`,{className:`text-[10px] w-14 shrink-0 mono ${e.exit_code===0?`text-ok`:`text-danger`}`,children:e.exit_code===0?`passed`:`exit ${e.exit_code}`}),(0,I.jsx)(`span`,{className:`mono text-[12px] truncate`,title:e.command,children:e.command})]},e.command))})]})}function Bg({sessionID:e,assignee:t}){let n=F(()=>e?N.diff(e):Promise.resolve(void 0),[e],{intervalMs:8e3}),[r,i]=(0,l.useState)(null);if(!e)return(0,I.jsx)(L,{title:`What changed`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:[`No session has been attributed to this task yet`,t?` (worker ${t})`:``,`, so there is nothing to diff.`]})});if(n.error&&!n.data){let e=n.error;if(e instanceof j&&e.status===409){let t=e.body;return(0,I.jsx)(L,{title:`What changed`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:[t?.error,t?.cwd?(0,I.jsxs)(I.Fragment,{children:[` · `,(0,I.jsx)(`span`,{className:`mono`,children:t.cwd})]}):null]})})}return(0,I.jsx)(L,{title:`What changed`,children:(0,I.jsx)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:e.message})})}let a=n.data;return a?(0,I.jsxs)(L,{title:`What changed`,right:(0,I.jsxs)(`span`,{className:`num`,children:[a.files.length,` files`]}),children:[a.files.length===0&&(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:[`Nothing uncommitted in `,(0,I.jsx)(`span`,{className:`mono`,children:a.branch||`the worktree`}),`. If the worker committed its work, the branch above holds it.`]}),(0,I.jsx)(`ul`,{children:a.files.map(e=>(0,I.jsxs)(`li`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsxs)(`button`,{className:`w-full text-left px-3 py-1.5 flex items-center gap-3 hover:bg-panel-2`,onClick:()=>i(r===e.path?null:e.path),children:[(0,I.jsx)(`span`,{className:`mono text-[10px] w-16 shrink-0 ${e.status===`added`||e.status===`untracked`?`text-ok`:e.status===`deleted`?`text-danger`:`text-fg-muted`}`,children:e.status}),(0,I.jsx)(`span`,{className:`mono text-[12px] truncate`,children:e.path}),(0,I.jsxs)(`span`,{className:`ml-auto num text-[11px] shrink-0`,children:[(0,I.jsxs)(`span`,{className:`text-ok`,children:[`+`,e.additions]}),` `,(0,I.jsxs)(`span`,{className:`text-danger`,children:[`−`,e.deletions]})]})]}),r===e.path&&e.patch&&(0,I.jsx)(`pre`,{className:`mono text-[11px] leading-[1.35] px-3 pb-2 overflow-auto max-h-[40vh]`,children:e.patch.split(` -`).map((e,t)=>{let n=e.startsWith(`+`)&&!e.startsWith(`+++`)?`text-ok`:e.startsWith(`-`)&&!e.startsWith(`---`)?`text-danger`:e.startsWith(`@@`)?`text-info`:`text-fg-muted`;return(0,I.jsx)(`div`,{className:n,children:e||` `},t)})}),r===e.path&&!e.patch&&(0,I.jsx)(`div`,{className:`px-3 pb-2 text-[11px] text-fg-faint`,children:e.binary?`binary file`:`no patch`})]},e.path))})]}):(0,I.jsx)(L,{title:`What changed`,children:(0,I.jsx)(St,{rows:3})})}function Vg({onClose:e}){let[t,n]=(0,l.useState)(``),[r,i]=(0,l.useState)(`3`),[a,o]=(0,l.useState)(`go test ./... +`).map((e,t)=>{let n=e.startsWith(`+`)&&!e.startsWith(`+++`)?`text-ok`:e.startsWith(`-`)&&!e.startsWith(`---`)?`text-danger`:e.startsWith(`@@`)?`text-info`:`text-fg-muted`;return(0,I.jsx)(`div`,{className:n,children:e||` `},t)})})}function cg({s:e,only:t}){let n=t??e.files,r=e.files.length(0,I.jsxs)(`li`,{className:`px-3 py-1 border-b border-border/60 last:border-0 flex gap-2 items-baseline`,children:[(0,I.jsx)(`span`,{className:`mono text-[12px]`,children:E(e)}),(0,I.jsx)(`span`,{className:`mono text-[10px] text-fg-faint truncate`,children:e})]},e))})]})}function lg({id:e}){let[t,n]=(0,l.useState)(``),r=async t=>{n(t);try{await N.signal(e,t)}catch{}finally{n(``)}};return(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[10px] uppercase tracking-wider text-ok border border-ok/40 rounded-sm px-1`,children:`owned`}),(0,I.jsx)(`button`,{disabled:!!t,onClick:()=>r(`pause`),className:`text-[11px] border border-border px-1.5 rounded-sm text-fg-muted hover:text-fg`,children:`pause`}),(0,I.jsx)(`button`,{disabled:!!t,onClick:()=>r(`resume`),className:`text-[11px] border border-border px-1.5 rounded-sm text-fg-muted hover:text-fg`,children:`resume`}),(0,I.jsx)(`button`,{disabled:!!t,onClick:()=>r(`kill`),className:`text-[11px] border border-danger/40 text-danger px-1.5 rounded-sm hover:bg-danger/10`,children:`kill`})]})}function ug(e){if(!Number.isFinite(e)||e<=0)return[];let t=e/3,n=10**Math.floor(Math.log10(t)),r=[1,2,5,10].map(e=>e*n).find(e=>e>=t)??n*10,i=[];for(let t=r;t<=e*1.0001;t+=r)i.push(t);return i}function dg({bars:e,active:t,onActive:n,height:r=112,showDayLabels:i=!0}){let a=e=>typeof e==`number`&&Number.isFinite(e)?e:0,o=Math.max(...e.map(e=>a(e.cost)),1e-9),s=r-16,c=ug(o);return(0,I.jsxs)(`div`,{className:`relative px-3 py-3 flex items-end gap-[3px]`,style:{height:r},onMouseLeave:()=>n(null),children:[c.map(e=>(0,I.jsx)(`div`,{className:`pointer-events-none absolute left-3 right-3 border-t border-border/60`,style:{bottom:16+Math.round(s*e/o)},"aria-hidden":!0,children:(0,I.jsx)(`span`,{className:`num absolute -top-[7px] right-0 bg-panel pl-1 text-[9px] text-fg-faint`,children:S(e)})},e)),e.map(e=>{let r=t===e.day;return(0,I.jsxs)(`button`,{type:`button`,className:`flex-1 flex flex-col items-center justify-end gap-1 min-w-0 h-full cursor-default focus:outline-none`,onMouseEnter:()=>n(e.day),onFocus:()=>n(e.day),onBlur:()=>n(null),"aria-label":`${e.day}: ${S(a(e.cost))}`,children:[(0,I.jsx)(`div`,{className:`w-full rounded-t-sm transition-colors ${r?`bg-accent`:`bg-accent/70`}`,style:{height:Math.max(2,Math.round(s*a(e.cost)/o))}}),i&&(0,I.jsx)(`div`,{className:`num text-[9px] ${r?`text-fg`:`text-fg-faint`}`,children:e.day.slice(8)})]},e.day)})]})}function fg({bars:e,active:t,total:n}){let r=t?e.find(e=>e.day===t):void 0;return r?(0,I.jsxs)(`span`,{className:`num flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:r.day}),(0,I.jsx)(`span`,{className:`text-fg`,children:S(r.cost)}),(0,I.jsx)(`span`,{className:`text-fg-faint`,children:C(r.tokens)}),r.sessions!==void 0&&r.sessions>0&&(0,I.jsxs)(`span`,{className:`text-fg-faint`,children:[r.sessions,` `,r.sessions===1?`session`:`sessions`]})]}):(0,I.jsx)(`span`,{className:`num`,children:S(n)})}var pg=[`M`,`T`,`W`,`T`,`F`,`S`,`S`];function mg(e){return(new Date(`${e}T00:00:00Z`).getUTCDay()+6)%7}function hg(e,t){if(!(e>0))return`bg-border/60`;let n=Math.sqrt(e/Math.max(t,1e-9));return n>.75?`bg-accent`:n>.5?`bg-accent/75`:n>.25?`bg-accent/50`:`bg-accent/25`}function gg({bars:e,active:t,onActive:n,maxCell:r=44}){let i=e=>typeof e==`number`&&Number.isFinite(e)?e:0,a=Math.max(...e.map(e=>i(e.cost)),1e-9),o=e[0],s=o?mg(o.day):0;return(0,I.jsxs)(`div`,{className:`px-3 py-3`,onMouseLeave:()=>n(null),children:[(0,I.jsxs)(`div`,{className:`grid gap-1`,style:{gridTemplateColumns:`repeat(7, minmax(0, 1fr))`,maxWidth:r*7+24},children:[pg.map((e,t)=>(0,I.jsx)(`div`,{className:`text-center text-[9px] text-fg-faint`,"aria-hidden":!0,children:e},t)),Array.from({length:s},(e,t)=>(0,I.jsx)(`div`,{"aria-hidden":!0},`lead-${t}`)),e.map(e=>{let r=i(e.cost),o=t===e.day;return(0,I.jsx)(`button`,{type:`button`,className:`flex aspect-square items-center justify-center focus:outline-none cursor-default`,onMouseEnter:()=>n(e.day),onFocus:()=>n(e.day),onBlur:()=>n(null),"aria-label":`${e.day}: ${S(r)}`,children:(0,I.jsx)(`span`,{className:`h-full w-full rounded-[3px] transition-colors ${hg(r,a)} ${o?`ring-1 ring-accent ring-offset-1 ring-offset-panel`:``}`})},e.day)})]}),(0,I.jsxs)(`div`,{className:`mt-3 flex items-center gap-1.5 text-[9px] text-fg-faint`,children:[(0,I.jsx)(`span`,{children:`$0`}),[`bg-border/60`,`bg-accent/25`,`bg-accent/50`,`bg-accent/75`,`bg-accent`].map(e=>(0,I.jsx)(`span`,{className:`h-2 w-2 rounded-[2px] ${e}`,"aria-hidden":!0},e)),(0,I.jsx)(`span`,{className:`num`,children:S(a)})]})]})}var _g=e=>e===1?`day`:`days`;function vg({summary:e,plan:t,days:n}){if(!e)return null;let r=e.cost_usd;if(!t?.plan_kind)return(0,I.jsx)(L,{title:`Plan value`,children:(0,I.jsx)(`div`,{className:`px-3 py-3 text-[12px] text-fg-muted`,children:`Set your plan in the header and Caprock will show what this usage is worth against what you actually pay. It can't detect your plan, so it won't guess.`})});if(t.plan_kind===`metered`)return(0,I.jsx)(L,{title:`Spend`,right:(0,I.jsxs)(`span`,{className:`num text-[12px] text-fg-muted`,children:[t.plan_label||`API`,` · billed per token`]}),children:(0,I.jsxs)(`div`,{className:`px-3 py-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num text-3xl text-fg`,children:S(r)}),(0,I.jsxs)(`span`,{className:`text-[12px] text-fg-muted`,children:[`over the last `,n,` `,_g(n)]})]}),(0,I.jsxs)(`p`,{className:`text-[11px] text-fg-faint mt-2 max-w-[60ch]`,children:[`You are billed per token, so this is approximately your actual cost — at Anthropic list prices (`,e.pricing_version,`). Not a saving.`]})]})});let i=t.plan_usd_per_month*n/30,a=i>0?r/i:0;return(0,I.jsxs)(L,{title:`Plan value`,right:(0,I.jsxs)(`span`,{className:`num text-[12px] text-fg-muted`,children:[t.plan_label,` · `,S(t.plan_usd_per_month),`/mo`]}),children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-3 divide-y sm:divide-y-0 sm:divide-x divide-border`,children:[(0,I.jsx)(R,{label:`you pay · ${n}d`,value:S(i),sub:t.plan_label}),(0,I.jsx)(R,{label:`same usage at API list`,value:S(r),sub:`at list prices ${e.pricing_version}`,tone:`ok`}),(0,I.jsx)(R,{label:`which is`,value:a>0?`${a.toFixed(1)}×`:`—`,sub:a>0?`what ${n} ${_g(n)} would cost through the API`:`not enough measured usage yet`,tone:a>0?`ok`:void 0,size:`hero`})]}),(0,I.jsx)(`p`,{className:`border-t border-border px-3 py-2 text-[11px] text-fg-faint leading-relaxed`,children:`Not a discount you received, and not money back — without the plan you would not have run this much.`})]})}function yg({feature:e,title:t,children:n}){let[r,i]=(0,l.useState)(!1);return F(()=>N.premium(),[]).data?.license?.active?(0,I.jsx)(I.Fragment,{children:n}):(0,I.jsxs)(`div`,{className:`relative overflow-hidden rounded-[var(--radius-panel)] border border-border`,children:[(0,I.jsx)(`div`,{"aria-hidden":!0,className:`pointer-events-none select-none opacity-90`,children:n}),(0,I.jsxs)(`div`,{className:`absolute inset-0 flex flex-col items-center justify-center gap-2.5 px-4 text-center`,children:[(0,I.jsx)(`span`,{className:`rounded-sm bg-panel/95 px-3 py-1 text-[15px] font-medium text-fg shadow-[0_2px_12px_var(--color-bg)]`,children:t}),(0,I.jsx)(`button`,{onClick:()=>i(!0),className:`rounded-sm bg-premium px-3.5 py-1.5 text-[13px] font-medium text-white shadow-[0_2px_12px_var(--color-bg)] hover:brightness-110`,children:`Unlock with Premium`})]}),r&&(0,I.jsx)(nt,{feature:e,onClose:()=>i(!1)})]})}function bg({suggestion:e}){let t=F(()=>N.settings(),[],{live:!1}),[n,r]=(0,l.useState)(``),[i,a]=(0,l.useState)(!1),[o,s]=(0,l.useState)(``),[c,u]=(0,l.useState)(!1),[d,f]=(0,l.useState)(!1),p=t.data?.cap_usd_per_day;(0,l.useEffect)(()=>{d||p===void 0||(r(p?String(p):``),f(!0))},[p,d]);let m=t.data?.cap_usd_per_day??0,h=m>0,g=async e=>{a(!0),s(``),u(!1);try{await N.saveSettings({cap_usd_per_day:e}),r(e?String(e):``),u(!0),t.refresh()}catch(e){s(e instanceof Error?e.message:String(e))}finally{a(!1)}},_=()=>{let e=n.trim().replace(/^\$/,``).replace(/,/g,``),t=Number(e);if(e===``||!Number.isFinite(t)||t<0){s(`A daily cap has to be a positive number of dollars.`);return}g(t)};return(0,I.jsx)(L,{title:`Daily spend cap`,right:(0,I.jsx)(`span`,{className:h?`text-premium-strong`:`text-fg-faint`,children:h?`on`:`off`}),children:(0,I.jsxs)(`div`,{className:`grid gap-2.5 px-3 py-3 text-[13px]`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`Stop the day at`}),(0,I.jsx)(`span`,{className:`text-fg-muted`,children:`$`}),(0,I.jsx)(`input`,{className:`input w-28`,inputMode:`decimal`,placeholder:`0`,value:n,onChange:e=>{r(e.target.value),u(!1)},onKeyDown:e=>e.key===`Enter`&&_(),"aria-label":`Daily spend cap in dollars`}),(0,I.jsx)(`button`,{onClick:_,disabled:i,className:`rounded-sm bg-premium px-3 py-1 text-[12px] font-medium text-white hover:brightness-110 disabled:opacity-50`,children:i?`Saving…`:`Save`}),h&&(0,I.jsx)(`button`,{onClick:()=>void g(0),disabled:i,className:`text-[12px] text-fg-faint hover:text-fg`,children:`turn off`}),c&&!o&&(0,I.jsx)(`span`,{className:`text-[12px] text-fg-faint`,children:`saved`})]}),!h&&e?(0,I.jsxs)(`p`,{className:`text-[12px] text-fg-faint`,children:[`Your days run about `,S(e/2),`.`,` `,(0,I.jsxs)(`button`,{onClick:()=>void g(e),className:`text-premium-strong hover:underline`,children:[`Use `,S(e)]}),` `,`— twice that, so an ordinary day never trips it.`]}):null,o&&(0,I.jsx)(`p`,{className:`text-[12px] text-danger`,children:o}),(0,I.jsx)(`p`,{className:`border-t border-border pt-2 text-[12px] leading-relaxed text-fg-faint`,children:h?(0,I.jsxs)(I.Fragment,{children:[`When today crosses `,S(m),`, Caprock pauses the sessions it started — paused, not killed, so resuming keeps the conversation. Sessions you started yourself are never touched.`]}):(0,I.jsx)(I.Fragment,{children:`Off. Nothing is paused, whatever the day costs. Sessions you started yourself are never touched either way.`})})]})})}function xg(){let e=F(()=>N.gemini(),[],{live:!1,intervalMs:3e4}),[t,n]=(0,l.useState)(``),[r,i]=(0,l.useState)(null),[a,o]=(0,l.useState)(!1),[s,c]=(0,l.useState)(``),u=e.data,d=!!u?.available,f=async()=>{let e=t.trim();if(!(!e||a)){o(!0),c(``);try{i(await N.askGemini(e)),n(``)}catch(e){c(oe(e))}finally{o(!1)}}};return(0,I.jsx)(L,{title:`Ask Gemini`,right:(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:d?u?.model:`your key, your bill`}),children:d?(0,I.jsxs)(`div`,{className:`px-3 py-3 grid gap-2`,children:[(0,I.jsx)(`textarea`,{className:`input min-h-[70px] resize-y`,placeholder:`Ask about your sessions, your spend, anything…`,value:t,onChange:e=>n(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&f()}}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(`button`,{onClick:()=>void f(),disabled:a||!t.trim(),className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm text-[12px] hover:bg-accent/25 disabled:opacity-50`,children:a?`asking…`:`Ask`}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:`⌘↵ to send`})]}),s&&(0,I.jsx)(`div`,{className:`text-danger text-[12px]`,children:s}),r&&(0,I.jsxs)(`div`,{className:`grid gap-2 border-t border-border pt-2`,children:[(0,I.jsx)(`div`,{className:`text-[13px] whitespace-pre-wrap`,children:r.text}),(0,I.jsxs)(`div`,{className:`text-[11px] text-fg-faint num flex gap-3 flex-wrap`,children:[(0,I.jsx)(`span`,{children:r.model}),(0,I.jsxs)(`span`,{children:[`in `,C(r.usage.prompt_tokens)]}),(0,I.jsxs)(`span`,{children:[`out `,C(r.usage.output_tokens)]}),r.usage.thoughts_tokens>0&&(0,I.jsxs)(`span`,{title:`Google bills thinking tokens as output`,children:[`thinking `,C(r.usage.thoughts_tokens)]}),r.usage.cached_tokens>0&&(0,I.jsxs)(`span`,{children:[`cached `,C(r.usage.cached_tokens)]})]})]})]}):(0,I.jsxs)(`div`,{className:`px-3 py-3 text-[12px] text-fg-muted grid gap-2`,children:[(0,I.jsx)(`p`,{className:`m-0`,children:`Caprock can ask Google's Gemini on your own key. It never stores the key — set it in the daemon's environment and restart:`}),(0,I.jsxs)(`code`,{className:`mono text-[11px] bg-panel-2 px-2 py-1.5 rounded-sm text-fg block overflow-x-auto`,children:[`export `,u?.env_var??`GEMINI_API_KEY`,`=…`]}),(0,I.jsx)(`p`,{className:`m-0 text-fg-faint`,children:`Get one from Google AI Studio. You pay Google directly; Caprock only counts what it sent.`})]})})}function Sg(){let[e,t]=(0,l.useState)(`30d`),n=Date.now(),r=F(()=>N.summary(e),[e],{intervalMs:5e3}),i=F(()=>N.daily(30),[],{intervalMs:3e4}),[a]=De(),[o,s]=(0,l.useState)(null),[c,u]=(0,l.useState)(`calendar`),d=r.data,f=!!d&&d.turns>0,p=Cg(i.data??[]),m=Tg(p.map(e=>e.cost));return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-1`,children:[[`today`,`7d`,`30d`,`all`].map(n=>(0,I.jsx)(`button`,{onClick:()=>t(n),className:`px-2 py-1 text-[12px] rounded-sm ${e===n?`bg-panel-2 text-fg`:`text-fg-muted hover:text-fg`}`,children:n},n)),(0,I.jsxs)(`span`,{className:`ml-auto text-[11px] text-fg-faint`,children:[un(a),d?` (table ${d.pricing_version})`:``]})]}),r.error&&!d&&(0,I.jsx)(z,{title:`Cannot reach the daemon`,children:r.error.message}),e!==`today`&&d&&(0,I.jsx)(En,{costUSD:p.reduce((e,t)=>e+t.cost,0),days:p.filter(e=>e.cost>0).length,now:n}),(0,I.jsx)(vg,{summary:d,plan:a,days:wg(e,d?.from_ms)}),(0,I.jsxs)(L,{title:`Totals · ${e}`,children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 divide-x divide-border`,children:[(0,I.jsx)(R,{label:`Cost`,value:f?S(d.cost_usd):`—`,sub:(0,I.jsx)(`span`,{title:un(a),children:f?ln(a):`nothing measured in this range`}),tone:`info`,size:`hero`}),(0,I.jsx)(R,{label:`Burn now`,value:f?`${S(d.burn.usd_per_hour)}/h`:`—`,sub:f?`${C(Math.round(d.burn.tokens_per_min))} tok/min · ${d.sessions} sessions`:void 0}),(0,I.jsx)(R,{label:`Input`,value:f?C(d.tokens_in):`—`,sub:`fresh, full price`}),(0,I.jsx)(R,{label:`Output`,value:f?C(d.tokens_out):`—`,sub:f?`${d.turns} turns`:void 0}),(0,I.jsx)(R,{label:`Cache read`,value:f?C(d.cache_read):`—`,sub:f?(0,I.jsxs)(`span`,{className:`inline-flex items-baseline gap-1.5`,children:[(0,I.jsxs)(`span`,{children:[w(d.savings.hit_rate*100),` hit rate`]}),(()=>{let e=mn(d.savings.hit_rate*100);return e?(0,I.jsx)(`span`,{className:e.color||`text-fg-faint`,children:e.label}):null})()]}):void 0}),(0,I.jsx)(R,{label:`Cache write`,value:f?C(d.cache_write):`—`,sub:f?`${w(d.savings.cut_pct)} input cost cut by cache`:void 0})]}),(0,I.jsx)(Sr,{u:d?.unpriced,className:`mx-3 mb-2.5`})]}),(0,I.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-2 xl:grid-cols-3`,children:[(0,I.jsxs)(L,{title:`Model mix`,right:(0,I.jsx)(`span`,{children:`by cost`}),children:[d?d.models.length===0&&(0,I.jsx)(z,{title:`No priced turns in range`}):(0,I.jsx)(St,{rows:4}),(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:(d?.models??[]).map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 mono`,title:e.model||void 0,children:e.model?re(e.model):`unknown`}),(0,I.jsxs)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:[e.turns,` turns`]}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:(d?.unpriced?.models??[]).includes(e.model)?(0,I.jsx)(`span`,{className:`text-warn`,title:`this model is not in the pricing table, so its cost is unknown`,children:`unpriced`}):S(e.cost_usd)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-faint w-14`,children:d&&d.cost_usd>0&&!(d.unpriced?.models??[]).includes(e.model)?w(100*e.cost_usd/d.cost_usd):`—`})]},e.model))})})]}),(0,I.jsx)(Et,{summary:d}),(0,I.jsxs)(L,{title:`Per project`,right:(0,I.jsx)(`span`,{children:`by cost`}),children:[d?d.projects.length===0&&(0,I.jsx)(z,{title:`No priced turns in range`}):(0,I.jsx)(St,{rows:4}),(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:(d?.projects??[]).map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1`,children:e.project||`unknown`}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:S(e.cost_usd)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-faint w-14`,children:d&&d.cost_usd>0?w(100*e.cost_usd/d.cost_usd):`—`})]},e.project))})})]})]}),(0,I.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-3`,children:[(0,I.jsxs)(L,{className:`lg:col-span-2`,title:`Last 30 days`,right:(0,I.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,I.jsx)(fg,{bars:p,active:o,total:p.reduce((e,t)=>e+t.cost,0)}),(0,I.jsx)(`span`,{className:`flex items-center gap-1`,children:[`calendar`,`bars`].map(e=>(0,I.jsx)(`button`,{onClick:()=>u(e),className:`px-1.5 py-0.5 rounded-sm text-[11px] ${c===e?`bg-panel-2 text-fg`:`text-fg-faint hover:text-fg`}`,children:e},e))})]}),children:[i.data?p.length===0&&(0,I.jsx)(z,{title:`No history yet`}):(0,I.jsx)(St,{rows:2}),p.length>0&&(c===`calendar`?(0,I.jsx)(gg,{bars:p,active:o,onActive:s}):(0,I.jsx)(dg,{bars:p,active:o,onActive:s}))]}),(0,I.jsx)(yg,{feature:`cap`,title:`Stop the day at a number you choose`,children:(0,I.jsx)(bg,{suggestion:m})}),(0,I.jsx)(yg,{feature:`gemini`,title:`Ask a second model, on your own key`,children:(0,I.jsx)(xg,{})}),d&&(0,I.jsxs)(L,{title:`Plan limits`,children:[d.rate_limits?(0,I.jsxs)(`div`,{className:`flex flex-col gap-2 px-3 pt-1`,children:[d.rate_limits.five_hour&&(0,I.jsx)(_n,{label:`5-hour window`,w:d.rate_limits.five_hour,now:n}),d.rate_limits.seven_day&&(0,I.jsx)(_n,{label:`7-day window`,w:d.rate_limits.seven_day,now:n})]}):(0,I.jsxs)(`div`,{className:`px-3 pt-1 text-sm text-fg-muted`,children:[`No window state yet. Caprock reads this from Claude Code's status line, so it appears once a Pro or Max session has run with `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:`caprock statusline`}),` registered —`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` caprock up`}),` offers to do that. API-billed usage has no windows to report.`]}),(0,I.jsx)(`div`,{className:`mt-2 px-3 pb-3 text-[11px] text-fg-faint leading-relaxed`,children:`Live from Claude Code's status line (Pro/Max). The percentage is your usage of the window; a forecast is shown only when your measured pace would reach the limit before the window resets.`})]})]}),(0,I.jsxs)(`div`,{className:`text-[11px] text-fg-faint`,children:[d&&d.throttles>0?`${d.throttles} rate-limit / overloaded event${d.throttles===1?``:`s`} observed in this range (from Claude Code's StopFailure hook).`:`No rate-limit events observed in this range.`,` `,`Everything here is measured — no invented numbers.`]})]})}function Cg(e){let t=new Map;for(let n of e){let e=t.get(n.day)??{day:n.day,cost:0,tokens:0,sessions:0};e.cost+=n.cost_usd,e.tokens+=n.tokens_total,e.sessions+=n.sessions,t.set(n.day,e)}return[...t.values()].sort((e,t)=>e.day.localeCompare(t.day))}function wg(e,t){switch(e){case`today`:return 1;case`7d`:return 7;case`30d`:return 30;default:return t?Math.max(1,Math.ceil((Date.now()-t)/864e5)):30}}function Tg(e){let t=e.filter(e=>e>0).sort((e,t)=>e-t);if(t.length<3)return 0;let n=t[Math.floor(t.length/2)]*2,r=n<10?1:n<100?5:10;return Math.round(n/r)*r}function Eg({plan:e,save:t}){let[n,r]=(0,l.useState)(e.license_key??``),i=F(()=>N.premium(),[e.license_key]).data?.license;(0,l.useEffect)(()=>{r(e.license_key??``)},[e.license_key]);let a=n.trim()!==(e.license_key??``).trim();return(0,I.jsxs)(`div`,{className:`border-t border-border pt-2`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`w-28 shrink-0 text-fg-muted`,children:`Licence`}),(0,I.jsx)(`input`,{className:`input flex-1 min-w-0`,placeholder:`CR-…`,spellCheck:!1,value:n,onChange:e=>r(e.target.value),onKeyDown:r=>{r.key===`Enter`&&a&&t({...e,license_key:n.trim()})}}),(0,I.jsx)(`button`,{disabled:!a,onClick:()=>t({...e,license_key:n.trim()}),className:`rounded-sm border border-border px-2 py-0.5 text-fg-muted hover:border-border-strong hover:text-fg disabled:opacity-40`,children:`save`})]}),(0,I.jsxs)(`p`,{className:`mt-1.5 pl-[7.5rem] text-[11px] leading-relaxed`,children:[i?.active&&!i.in_grace&&(0,I.jsxs)(`span`,{className:`text-ok`,children:[`Premium is on`,i.expires_at?` — renews ${i.expires_at.slice(0,10)}`:``,`.`]}),i?.active&&i.in_grace&&(0,I.jsxs)(`span`,{className:`text-warn`,children:[i.reason,`. Update your key or payment method.`]}),i&&!i.active&&(0,I.jsxs)(`span`,{className:`text-fg-muted`,children:[e.license_key?i.reason:`No key — the free product is unaffected.`,` `,(0,I.jsx)(`a`,{href:`https://caprock.dev/premium/`,target:`_blank`,rel:`noreferrer`,className:`link`,children:`what Premium does`})]}),(0,I.jsx)(`span`,{className:`block text-fg-faint`,children:`Checked on this machine against the date inside the key. Caprock makes no call to us to verify it.`})]})]})}function Dg(){let e=F(()=>N.status(),[],{live:!1,intervalMs:5e3}),t=e.data;if(e.error&&!t)return(0,I.jsx)(z,{title:`Cannot reach the daemon`,children:e.error.message});if(!t)return(0,I.jsx)(`div`,{className:`text-fg-muted`,children:`loading…`});let n=[[`version`,t.version],[`url`,t.url],[`pid`,String(t.pid)],[`uptime`,te(t.uptime_s*1e3)],[`data dir`,t.data_dir],[`pricing`,`${t.pricing.version} · ${t.pricing.models} models · fetched ${t.pricing.fetched_at}${t.pricing.user_override?` · user override`:``}`],[`pricing source`,t.pricing.source],[`loop rule`,`≥ ${t.loop_k} same-tool calls in ${t.loop_t_minutes} min · ${t.active_loops} active`],[`events stored`,`${t.events.toLocaleString()}${t.retention_days>0?` · pruned after ${t.retention_days}d`:` · kept forever (set retention_days to cap DB growth)`}`],[`orchestration`,t.orchestration?`on (--hive)`:`off`],[`claude`,t.claude_available?`found on PATH — Caprock can start sessions for you`:`not found on PATH — Caprock cannot start sessions, but still observes every session you start yourself`],[`dashboard`,t.ui_built?`embedded build`:`dev server / placeholder`]];if(t.hooks&&n.push([`hooks`,`${(t.hooks.installed??[]).length}/${(t.hooks.installed??[]).length+(t.hooks.missing??[]).length} events registered in ${t.hooks.settings_path}${t.hooks.shim_exists?``:` (shim missing)`}`]),t.desktop){let e=t.desktop;n.push([`claude desktop`,`${e.five_hour_pct}% of the 5-hour window · ${e.seven_day_pct}% of the 7-day${e.stale?` · last seen `+new Date(e.at).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})+`, app closed since`:` · now`}`])}return t.ingest_error&&n.push([`ingest error`,`STOPPED: ${t.ingest_error} — nothing is being captured`]),t.ingest&&n.push([`ingest`,`${t.ingest.files_known} transcripts · ${t.ingest.events_stored} events stored · ${t.ingest.events_deduped} deduped · ${t.ingest.lines_malformed} malformed lines · backfill ${t.ingest.backfill_done?`done`:`running`}`]),(0,I.jsxs)(`div`,{className:`grid gap-3 max-w-3xl`,children:[(0,I.jsx)(Og,{}),(0,I.jsx)(L,{title:`Daemon`,children:(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:n.map(([e,t])=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 text-fg-muted w-32`,children:e}),(0,I.jsx)(`td`,{className:`px-3 py-1 mono break-all`,children:t})]},e))})})}),t.ingest_error&&(0,I.jsx)(L,{title:`Ingest stopped`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-muted`,children:[`No new sessions are being captured: `,(0,I.jsx)(`span`,{className:`mono text-fg`,children:t.ingest_error}),`. Check that`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` ~/.claude`}),` is readable, then restart with`,(0,I.jsx)(`span`,{className:`mono text-fg`,children:` caprock down && caprock up`}),`.`]})}),!t.claude_available&&(0,I.jsx)(L,{title:`claude not found`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-muted`,children:[`The `,(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` binary was not found on this machine, so Caprock cannot spawn sessions. It still observes every session you start yourself. Install Claude Code, or make sure`,(0,I.jsx)(`span`,{className:`mono`,children:` claude`}),` is on the PATH the daemon was started with.`]})}),t.hooks&&(t.hooks.missing??[]).length>0&&(0,I.jsx)(L,{title:`Hooks not fully installed`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-muted`,children:[`Missing: `,(0,I.jsx)(`span`,{className:`mono`,children:(t.hooks.missing??[]).join(`, `)}),`. Run `,(0,I.jsx)(`span`,{className:`mono`,children:`caprock hooks install`}),` for real-time activity; transcript tailing keeps working with a few seconds of delay.`]})})]})}function Og(){let[e,t]=De();return e?(0,I.jsx)(L,{title:`Settings`,children:(0,I.jsxs)(`div`,{className:`grid gap-2 px-3 py-2.5 text-[12px]`,children:[(0,I.jsxs)(`label`,{className:`flex items-start gap-2 cursor-pointer`,children:[(0,I.jsx)(`input`,{type:`checkbox`,className:`accent-[var(--color-accent)] mt-0.5`,checked:e.update_checks,onChange:n=>t({...e,update_checks:n.target.checked})}),(0,I.jsxs)(`span`,{children:[(0,I.jsx)(`span`,{className:`text-fg`,children:`Check GitHub for new releases`}),(0,I.jsx)(`span`,{className:`block text-[11px] text-fg-muted`,children:`The only outbound call Caprock makes. No usage data is sent, and it is checked at most once a day.`})]})]}),(0,I.jsxs)(`div`,{className:`flex items-baseline gap-2 border-t border-border pt-2`,children:[(0,I.jsx)(`span`,{className:`text-fg-muted w-28 shrink-0`,children:`Your plan`}),(0,I.jsx)(`span`,{className:`mono text-fg`,children:e.plan_kind===`metered`?`${e.plan_label||`API`} · billed per token`:e.plan_kind===`flat`?`${e.plan_label||`plan`} · ${S(e.plan_usd_per_month)}/mo`:`not set`}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint ml-auto`,children:`change it in the header`})]}),(0,I.jsx)(Eg,{plan:e,save:t})]})}):null}var kg=[`your-api`,`your-web`];function Ag(){let[e,t]=(0,l.useState)(`all`),[n,r]=(0,l.useState)(null),i=F(()=>N.history(e),[e],{intervalMs:15e3}),[a]=De(),o=i.data,s=!!o&&o.totals.turns>0,c=Cg(o?.daily??[]),u=(F(()=>N.summary(`7d`),[],{intervalMs:6e4}).data?.projects??[]).slice(0,4).map(e=>e.project),d=Math.max(...(o?.tools??[]).map(e=>e.count),1);return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-1`,children:[[`today`,`7d`,`30d`,`all`].map(n=>(0,I.jsx)(`button`,{onClick:()=>t(n),className:`px-2 py-1 text-[12px] rounded-sm ${e===n?`bg-panel-2 text-fg`:`text-fg-muted hover:text-fg`}`,children:n},n)),(0,I.jsx)(`span`,{className:`ml-auto text-[11px] text-fg-faint`,children:`Everything you ever ran through Caprock. Measured, not estimated.`})]}),s&&o&&(0,I.jsx)(En,{costUSD:o.totals.cost_usd,days:o.totals.days,now:Date.now()}),i.error&&!o&&(0,I.jsx)(z,{title:`Cannot reach the daemon`,children:i.error.message}),(0,I.jsxs)(L,{title:`Lifetime · ${e}`,children:[(0,I.jsxs)(`div`,{className:`grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-7 divide-x divide-border`,children:[(0,I.jsx)(R,{size:`compact`,label:`Sessions`,value:s?o.totals.sessions:`—`,sub:s?`${o.totals.owned_sessions} spawned by caprock`:void 0}),(0,I.jsx)(R,{size:`compact`,label:`Active days`,value:s?o.totals.days:`—`}),(0,I.jsx)(R,{size:`compact`,label:`Turns`,value:s?C(o.totals.turns):`—`,sub:s?`${C(o.totals.tool_calls)} tool calls`:void 0}),(0,I.jsx)(R,{size:`compact`,label:`Files touched`,value:s?C(o.totals.files_touched):`—`,sub:`summed per session`}),(0,I.jsx)(R,{size:`compact`,label:`Avg session span`,value:s?te(Math.round(o.totals.avg_session_sec*1e3)):`—`,sub:`first to last event`}),(0,I.jsx)(hn,{hitRate:o?.savings.hit_rate,cutPct:o?.savings.cut_pct,measured:s}),(0,I.jsx)(R,{label:`Cost`,value:s?S(o.totals.cost_usd):`—`,sub:(0,I.jsx)(`span`,{title:un(a),children:s?ln(a):`nothing measured yet`}),tone:`info`,size:`hero`})]}),(0,I.jsx)(Sr,{u:o?.totals.unpriced,className:`mx-3 mb-2.5`})]}),(0,I.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-2`,children:[(0,I.jsxs)(L,{title:`Tool usage`,right:(0,I.jsx)(`span`,{children:`by calls`}),children:[o?o.tools.length===0&&(0,I.jsx)(z,{title:`No tool calls yet`}):(0,I.jsx)(St,{rows:5}),(0,I.jsx)(`ul`,{className:`py-1`,children:(o?.tools??[]).slice(0,18).map(e=>(0,I.jsxs)(`li`,{className:`flex items-center gap-2 px-3 py-[3px]`,children:[(0,I.jsx)(`span`,{className:`mono text-[12px] w-44 shrink-0 truncate`,title:e.tool,children:ne(e.tool)}),(0,I.jsx)(`div`,{className:`flex-1 h-2 bg-panel-2 rounded-sm overflow-hidden`,children:(0,I.jsx)(`div`,{className:`h-full bg-accent/70`,style:{width:`${100*e.count/d}%`}})}),(0,I.jsx)(`span`,{className:`num text-[11px] text-fg-muted w-12 text-right`,children:C(e.count)})]},e.tool))})]}),(0,I.jsxs)(`div`,{className:`grid gap-3 content-start`,children:[(0,I.jsxs)(L,{title:`Model mix`,right:(0,I.jsx)(`span`,{children:`by cost`}),children:[o?o.summary.models.length===0&&(0,I.jsx)(z,{title:`No priced turns`}):(0,I.jsx)(St,{rows:3}),(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:(o?.summary.models??[]).map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 mono`,children:e.model||`unknown`}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:S(e.cost_usd)})]},e.model))})})]}),(0,I.jsx)(yg,{feature:`report`,title:`Get this every Monday, without opening the dashboard`,children:(0,I.jsx)(L,{title:`Weekly report`,right:(0,I.jsx)(`span`,{children:`Mondays, 09:00`}),children:(0,I.jsxs)(`div`,{className:`px-3 py-3 text-[13px]`,children:[(0,I.jsxs)(`p`,{className:`text-fg-muted`,children:[(0,I.jsx)(`span`,{className:`text-fg-faint`,children:`To:`}),` your Telegram bot or webhook`]}),(0,I.jsx)(`p`,{className:`mt-2 text-fg`,children:`Last week, by repository:`}),(0,I.jsx)(`div`,{className:`mt-1.5 grid gap-1`,children:(u.length?u:kg).map(e=>(0,I.jsxs)(`div`,{className:`flex items-baseline justify-between gap-3`,children:[(0,I.jsx)(`span`,{className:`truncate text-fg-muted`,children:e||`unknown`}),(0,I.jsx)(`span`,{"aria-hidden":!0,className:`h-1.5 w-24 shrink-0 rounded-full bg-fg-faint/25`})]},e))}),(0,I.jsx)(`p`,{className:`mt-2.5 border-t border-border pt-2 text-[12px] text-fg-faint`,children:`…and the same by model, in your inbox before you open a terminal.`})]})})}),(0,I.jsx)(L,{title:`Top projects`,right:(0,I.jsx)(`span`,{children:`by cost`}),children:(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsx)(`tbody`,{children:(o?.summary.projects??[]).slice(0,8).map(e=>(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1`,children:e.project||`unknown`}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right text-fg-muted`,children:C(e.tokens)}),(0,I.jsx)(`td`,{className:`px-3 py-1 num text-right`,children:S(e.cost_usd)})]},e.project))})})})]})]}),(0,I.jsxs)(L,{title:`Daily cost`,right:(0,I.jsx)(fg,{bars:c,active:n,total:c.reduce((e,t)=>e+t.cost,0)}),children:[i.data?c.length===0&&(0,I.jsx)(z,{title:`No history yet`}):(0,I.jsx)(St,{rows:2}),c.length>0&&(0,I.jsx)(dg,{bars:c,active:n,onActive:r,height:96,showDayLabels:!1})]})]})}var jg=[{key:`inbox`,label:`Inbox`},{key:`assigned`,label:`Assigned`},{key:`in_progress`,label:`In progress`},{key:`verifying`,label:`Verifying`},{key:`needs_you`,label:`Needs you`},{key:`done`,label:`Done`}];function Mg(){let e=F(()=>N.status(),[],{live:!1,intervalMs:3e4}),t=F(()=>N.tasks(),[],{intervalMs:4e3}),[n,r]=(0,l.useState)(!1),[i,a]=(0,l.useState)(null);if(e.data&&e.data.orchestration===!1)return(0,I.jsx)(Ng,{status:e.data,onEnabled:()=>{e.refresh(),t.refresh()}});let o=e=>(t.data??[]).filter(t=>t.status===e||e===`done`&&t.status===`failed`);return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,I.jsx)(`button`,{onClick:()=>r(!0),className:`border border-accent/50 text-accent bg-accent/10 px-2 py-1 rounded-sm text-[12px] hover:bg-accent/20`,children:`+ New task`}),(0,I.jsx)(Ig,{available:e.data?.claude_available??!1}),(t.data??[]).some(e=>e.assignee!==``&&e.status!==`done`&&e.status!==`failed`)&&(0,I.jsx)(`a`,{href:`#/graph`,className:`link text-[12px] border border-border px-2 py-1 rounded-sm hover:border-border-strong`,children:`view graph`}),(0,I.jsxs)(`span`,{className:`ml-auto text-[11px] text-fg-faint`,children:[`Tasks are files on disk (`,(0,I.jsx)(`span`,{className:`mono`,children:`tasks/.md`}),`); the orchestrator moves them. Nothing reaches Done until its `,(0,I.jsx)(`span`,{className:`mono`,children:`done_criteria`}),` pass.`]})]}),t.error&&!t.data&&(0,I.jsx)(z,{title:`Cannot reach the daemon`,children:t.error.message}),t.data&&t.data.length===0&&(0,I.jsxs)(`div`,{className:`border border-border bg-panel-2/60 rounded-sm px-3 py-2 text-[12px] text-fg-muted`,children:[`Start here: `,(0,I.jsx)(`span`,{className:`text-fg`,children:`+ New task`}),` — a title and the commands that have to pass. Then `,(0,I.jsx)(`span`,{className:`text-fg`,children:`▶ Start orchestrator`}),`, which assigns it to a worker and keeps going until the checks are green.`]}),(0,I.jsx)(`div`,{className:`grid gap-2 grid-cols-2 md:grid-cols-3 xl:grid-cols-6`,children:jg.map(e=>(0,I.jsxs)(`div`,{className:`min-w-0`,children:[(0,I.jsxs)(`div`,{className:`text-[11px] uppercase tracking-[0.08em] text-fg-faint mb-1.5 px-0.5 flex justify-between`,children:[(0,I.jsx)(`span`,{children:e.label}),(0,I.jsx)(`span`,{className:`num`,children:o(e.key).length})]}),(0,I.jsx)(`div`,{className:`grid gap-1.5 content-start min-h-[60px]`,children:o(e.key).map(e=>(0,I.jsx)(Lg,{t:e,onApprove:()=>t.refresh(),onOpen:()=>a(e.id)},e.id))})]},e.key))}),n&&(0,I.jsx)(Hg,{onClose:()=>{r(!1),t.refresh()}}),i&&(0,I.jsx)(Rg,{id:i,onClose:()=>{a(null),t.refresh()}})]})}function Ng({status:e,onEnabled:t}){let[n,r]=(0,l.useState)(!1),i=e.suggested_hive??`~/caprock-tasks`,a=e.suggested_repo??``;return(0,I.jsxs)(`div`,{className:`grid gap-3 max-w-[52rem] mx-auto`,children:[(0,I.jsxs)(L,{title:`Task runner`,right:(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:`off`}),children:[(0,I.jsxs)(`div`,{className:`grid gap-3 px-3 py-3`,children:[(0,I.jsxs)(`ol`,{className:`grid gap-2 md:grid-cols-3`,children:[(0,I.jsx)(Pg,{n:1,title:`You write a task`,children:`A title, a budget, and the commands that have to pass.`}),(0,I.jsxs)(Pg,{n:2,title:`Caprock runs it`,children:[`One Claude session per task, in its `,(0,I.jsx)(`span`,{className:`text-fg`,children:`own git worktree`}),` — your working tree is untouched.`]}),(0,I.jsxs)(Pg,{n:3,title:`Caprock checks it`,children:[(0,I.jsx)(`span`,{className:`text-fg`,children:`Caprock`}),` runs your commands, not the agent. Only green is done.`]})]}),(0,I.jsx)(`div`,{className:`text-[11px] text-fg-faint`,children:`Best for independent tasks — nothing here merges branches. The queue directory is created for you; your repository is not modified.`})]}),(0,I.jsxs)(`footer`,{className:`px-3 py-2 border-t border-border flex items-center gap-2`,children:[(0,I.jsx)(`button`,{onClick:()=>r(!0),className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm text-[12px] hover:bg-accent/25`,children:`Turn on the task runner`}),(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:`No restart. Nothing runs until you start it.`})]})]}),n&&(0,I.jsx)(Fg,{hive:i,repo:a,onClose:()=>r(!1),onDone:t})]})}function Pg({n:e,title:t,children:n}){return(0,I.jsxs)(`li`,{className:`border border-border bg-panel-2/60 rounded-sm px-2.5 py-2 grid gap-1 content-start`,children:[(0,I.jsxs)(`div`,{className:`flex items-baseline gap-1.5`,children:[(0,I.jsx)(`span`,{className:`num text-[11px] text-accent`,children:e}),(0,I.jsx)(`span`,{className:`text-[12px] font-medium`,children:t})]}),(0,I.jsx)(`div`,{className:`text-[11px] text-fg-muted leading-[1.45]`,children:n})]})}function Fg({hive:e,repo:t,onClose:n,onDone:r}){let[i,a]=(0,l.useState)(e),[o,s]=(0,l.useState)(t),[c,u]=(0,l.useState)(!1),[d,f]=(0,l.useState)(``);return(0,I.jsx)(`div`,{className:`fixed inset-0 z-20 bg-black/50 flex items-start justify-center pt-24`,onClick:n,children:(0,I.jsxs)(`div`,{className:`border border-border-strong bg-panel rounded-[var(--radius-panel)] w-[560px] max-w-[92vw]`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`px-3 py-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`h2`,{className:`text-[12px] uppercase tracking-[0.08em] text-fg-muted`,children:`Turn on the task runner`}),(0,I.jsx)(`button`,{onClick:n,className:`ml-auto text-fg-muted hover:text-fg`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`px-4 py-3 grid gap-3 text-[13px]`,children:[(0,I.jsxs)(`ul`,{className:`grid gap-1 text-[12px] text-fg-muted`,children:[(0,I.jsx)(`li`,{children:`· Creates the queue directory below, with a README and an example task.`}),(0,I.jsxs)(`li`,{children:[`· Lets Caprock spawn Claude sessions `,(0,I.jsx)(`span`,{className:`text-fg`,children:`with permission prompts skipped`}),`, one git worktree each under the repo below.`]}),(0,I.jsx)(`li`,{children:`· Starts nothing yet — you start the orchestrator, and only then does work begin.`})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[`Queue directory`,(0,I.jsx)(`span`,{className:`text-fg-faint`,children:` · created if missing`})]}),(0,I.jsx)(`input`,{className:`input mono`,value:i,onChange:e=>a(e.target.value)})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[`Repository`,(0,I.jsx)(`span`,{className:`text-fg-faint`,children:` · workers branch from here`})]}),(0,I.jsx)(`input`,{className:`input mono`,value:o,onChange:e=>s(e.target.value)})]}),d&&(0,I.jsx)(`div`,{className:`text-danger text-[12px]`,children:d})]}),(0,I.jsxs)(`footer`,{className:`px-4 py-2 border-t border-border flex gap-2 justify-end`,children:[(0,I.jsx)(`button`,{onClick:n,className:`border border-border px-3 py-1 rounded-sm text-fg-muted hover:text-fg`,children:`Cancel`}),(0,I.jsx)(`button`,{onClick:async()=>{u(!0),f(``);try{await N.enableHive(i.trim(),o.trim()),n(),r()}catch(e){f(oe(e))}finally{u(!1)}},disabled:c,className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm hover:bg-accent/25 disabled:opacity-50`,children:c?`turning on…`:`Turn it on`})]})]})})}function Ig({available:e}){let[t,n]=(0,l.useState)(!1),[r,i]=(0,l.useState)(``);return(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[(0,I.jsx)(`button`,{disabled:t||!e,onClick:async()=>{n(!0),i(``);try{let e=await N.startOrchestrator();i(`orchestrator: `+e.session_id.slice(0,8))}catch(e){i(oe(e))}finally{n(!1)}},title:e?`spawn the orchestrator session`:`claude not found — cannot spawn`,className:`border border-border text-fg-muted px-2 py-1 rounded-sm text-[12px] hover:text-fg disabled:opacity-50`,children:t?`starting…`:`▶ Start orchestrator`}),!e&&(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[(0,I.jsx)(`span`,{className:`mono`,children:`claude`}),` was not found on this machine, so Caprock cannot spawn the orchestrator. It still observes every session you start yourself.`]}),r&&(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint mono`,children:r})]})}function Lg({t:e,onApprove:t,onOpen:n}){let r=e.budget_usd>0&&e.cost_usd>e.budget_usd,i=e.assignee!==``;return(0,I.jsxs)(`div`,{className:`border border-border bg-panel rounded-[var(--radius-panel)] px-2 py-1.5`,children:[(0,I.jsxs)(`button`,{className:`w-full text-left disabled:cursor-default`,disabled:!i,onClick:n,title:i?`show the diff, the checks that ran, and where the branch is`:`nothing to show yet — no worker has picked this up`,children:[(0,I.jsx)(`div`,{className:`text-[12px] font-medium truncate ${i?`hover:text-accent`:``}`,title:e.title,children:e.title||e.id}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2 mt-1 text-[10px] text-fg-faint`,children:[(0,I.jsx)(`span`,{className:`mono`,children:T(e.id)}),e.assignee&&(0,I.jsxs)(`span`,{className:`mono text-fg-muted`,children:[`→ `,e.assignee]}),(0,I.jsxs)(`span`,{className:`num ml-auto ${r?`text-danger`:`text-fg-muted`}`,children:[S(e.cost_usd),e.budget_usd>0?` / ${S(e.budget_usd)}`:``]})]})]}),i&&(0,I.jsxs)(`div`,{className:`mt-1 text-[10px] text-fg-faint mono truncate`,children:[`caprock/`,e.assignee]}),e.status===`needs_you`&&(0,I.jsxs)(`div`,{className:`flex gap-1 mt-1.5`,children:[(0,I.jsx)(`button`,{onClick:()=>N.approve(e.id,!0).then(t),className:`flex-1 text-[11px] border border-ok/40 text-ok rounded-sm hover:bg-ok/10`,children:`approve`}),(0,I.jsx)(`button`,{onClick:()=>N.approve(e.id,!1).then(t),className:`flex-1 text-[11px] border border-danger/40 text-danger rounded-sm hover:bg-danger/10`,children:`reject`})]})]})}function Rg({id:e,onClose:t}){let n=F(()=>N.task(e),[e],{intervalMs:6e3}),r=n.data,i=r?.work,a=i?.sessions?.[0];return(0,I.jsx)(`div`,{className:`fixed inset-0 z-20 bg-black/50 flex items-start justify-center pt-16`,onClick:t,children:(0,I.jsxs)(`div`,{className:`border border-border-strong bg-panel rounded-[var(--radius-panel)] w-[820px] max-w-[94vw] max-h-[82vh] overflow-auto`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`px-3 py-2 border-b border-border flex items-center gap-2 sticky top-0 bg-panel z-10`,children:[(0,I.jsx)(`h2`,{className:`text-[12px] uppercase tracking-[0.08em] text-fg-muted`,children:`Task`}),r&&(0,I.jsx)(`span`,{className:`text-[12px] truncate`,children:r.task.title||r.task.id}),r&&(0,I.jsx)(`span`,{className:`mono text-[10px] text-fg-faint`,children:r.task.status}),(0,I.jsx)(`button`,{onClick:t,className:`ml-auto text-fg-muted hover:text-fg`,children:`✕`})]}),!r&&!n.error&&(0,I.jsx)(St,{rows:5}),n.error&&!r&&(0,I.jsx)(z,{title:`Cannot load the task`,children:n.error.message}),r&&(0,I.jsxs)(`div`,{className:`px-3 py-3 grid gap-3`,children:[(0,I.jsx)(zg,{work:i,assignee:r.task.assignee}),(0,I.jsx)(Bg,{criteria:r.done_criteria,runs:i?.verifications,status:r.task.status}),(0,I.jsx)(Vg,{sessionID:a?.session_id,assignee:r.task.assignee}),r.body&&(0,I.jsx)(L,{title:`Brief`,children:(0,I.jsx)(`pre`,{className:`mono text-[11px] leading-[1.45] px-3 py-2 whitespace-pre-wrap`,children:r.body})})]})]})})}function zg({work:e,assignee:t}){return e?.branch?(0,I.jsx)(L,{title:`Where the work is`,children:(0,I.jsx)(`table`,{className:`w-full text-[12px]`,children:(0,I.jsxs)(`tbody`,{children:[(0,I.jsxs)(`tr`,{className:`border-b border-border/60`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 text-fg-muted w-32`,children:`branch`}),(0,I.jsx)(`td`,{className:`px-3 py-1 mono break-all`,children:e.branch})]}),e.worktree&&(0,I.jsxs)(`tr`,{className:`border-b border-border/60`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 text-fg-muted w-32`,children:`worktree`}),(0,I.jsx)(`td`,{className:`px-3 py-1 mono break-all`,children:e.worktree})]}),(0,I.jsxs)(`tr`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsx)(`td`,{className:`px-3 py-1 text-fg-muted w-32 align-top`,children:`take it`}),(0,I.jsxs)(`td`,{className:`px-3 py-1 grid gap-1 justify-items-start`,children:[(0,I.jsx)(Ct,{command:`git merge --no-ff ${e.branch}`}),(0,I.jsxs)(`span`,{className:`text-[11px] text-fg-faint`,children:[`Run it from `,e.repo?(0,I.jsx)(`span`,{className:`mono`,children:e.repo}):`your repo`,`, on the branch you want the work on. Prefer `,(0,I.jsx)(`span`,{className:`mono`,children:`git cherry-pick`}),` if you only want some of it. Worker`,` `,(0,I.jsx)(`span`,{className:`mono`,children:t}),` may still be running — check the diff below first.`]})]})]})]})})}):(0,I.jsx)(L,{title:`Where the work is`,children:(0,I.jsx)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:`No worker has been assigned yet, so there is no branch. One is created the moment the orchestrator assigns this task.`})})}function Bg({criteria:e,runs:t,status:n}){let r=t?.[0],i=r?t.filter(e=>e.round===r.round):[],a=r?`round ${r.round}`:void 0;return(0,I.jsxs)(L,{title:`What has to pass`,right:a,children:[i.length===0&&(0,I.jsxs)(`div`,{className:`px-3 py-2 grid gap-1`,children:[(0,I.jsx)(`div`,{className:`text-[12px] text-fg-faint`,children:n===`done`?`This task was marked done without a recorded check.`:`Not run yet. Caprock runs these itself, in the worker’s worktree, when the worker reports it has finished.`}),(0,I.jsx)(`ul`,{className:`grid gap-0.5`,children:(e??[]).map(e=>(0,I.jsxs)(`li`,{className:`mono text-[11px] text-fg-muted`,children:[`$ `,e]},e))}),(e??[]).length===0&&(0,I.jsx)(`div`,{className:`mono text-[11px] text-danger`,children:`no done_criteria — Caprock cannot verify this task`})]}),i.length>0&&(0,I.jsx)(`ul`,{children:i.map(e=>(0,I.jsxs)(`li`,{className:`border-b border-border/60 last:border-0 px-3 py-1.5 flex items-center gap-3`,children:[(0,I.jsx)(`span`,{className:`text-[10px] w-14 shrink-0 mono ${e.exit_code===0?`text-ok`:`text-danger`}`,children:e.exit_code===0?`passed`:`exit ${e.exit_code}`}),(0,I.jsx)(`span`,{className:`mono text-[12px] truncate`,title:e.command,children:e.command})]},e.command))})]})}function Vg({sessionID:e,assignee:t}){let n=F(()=>e?N.diff(e):Promise.resolve(void 0),[e],{intervalMs:8e3}),[r,i]=(0,l.useState)(null);if(!e)return(0,I.jsx)(L,{title:`What changed`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:[`No session has been attributed to this task yet`,t?` (worker ${t})`:``,`, so there is nothing to diff.`]})});if(n.error&&!n.data){let e=n.error;if(e instanceof j&&e.status===409){let t=e.body;return(0,I.jsx)(L,{title:`What changed`,children:(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:[t?.error,t?.cwd?(0,I.jsxs)(I.Fragment,{children:[` · `,(0,I.jsx)(`span`,{className:`mono`,children:t.cwd})]}):null]})})}return(0,I.jsx)(L,{title:`What changed`,children:(0,I.jsx)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:e.message})})}let a=n.data;return a?(0,I.jsxs)(L,{title:`What changed`,right:(0,I.jsxs)(`span`,{className:`num`,children:[a.files.length,` files`]}),children:[a.files.length===0&&(0,I.jsxs)(`div`,{className:`px-3 py-2 text-[12px] text-fg-faint`,children:[`Nothing uncommitted in `,(0,I.jsx)(`span`,{className:`mono`,children:a.branch||`the worktree`}),`. If the worker committed its work, the branch above holds it.`]}),(0,I.jsx)(`ul`,{children:a.files.map(e=>(0,I.jsxs)(`li`,{className:`border-b border-border/60 last:border-0`,children:[(0,I.jsxs)(`button`,{className:`w-full text-left px-3 py-1.5 flex items-center gap-3 hover:bg-panel-2`,onClick:()=>i(r===e.path?null:e.path),children:[(0,I.jsx)(`span`,{className:`mono text-[10px] w-16 shrink-0 ${e.status===`added`||e.status===`untracked`?`text-ok`:e.status===`deleted`?`text-danger`:`text-fg-muted`}`,children:e.status}),(0,I.jsx)(`span`,{className:`mono text-[12px] truncate`,children:e.path}),(0,I.jsxs)(`span`,{className:`ml-auto num text-[11px] shrink-0`,children:[(0,I.jsxs)(`span`,{className:`text-ok`,children:[`+`,e.additions]}),` `,(0,I.jsxs)(`span`,{className:`text-danger`,children:[`−`,e.deletions]})]})]}),r===e.path&&e.patch&&(0,I.jsx)(`pre`,{className:`mono text-[11px] leading-[1.35] px-3 pb-2 overflow-auto max-h-[40vh]`,children:e.patch.split(` +`).map((e,t)=>{let n=e.startsWith(`+`)&&!e.startsWith(`+++`)?`text-ok`:e.startsWith(`-`)&&!e.startsWith(`---`)?`text-danger`:e.startsWith(`@@`)?`text-info`:`text-fg-muted`;return(0,I.jsx)(`div`,{className:n,children:e||` `},t)})}),r===e.path&&!e.patch&&(0,I.jsx)(`div`,{className:`px-3 pb-2 text-[11px] text-fg-faint`,children:e.binary?`binary file`:`no patch`})]},e.path))})]}):(0,I.jsx)(L,{title:`What changed`,children:(0,I.jsx)(St,{rows:3})})}function Hg({onClose:e}){let[t,n]=(0,l.useState)(``),[r,i]=(0,l.useState)(`3`),[a,o]=(0,l.useState)(`go test ./... go vet ./...`),[s,c]=(0,l.useState)(``),[u,d]=(0,l.useState)(!1),[f,p]=(0,l.useState)(``),m=a.split(` -`).map(e=>e.trim()).filter(Boolean);return(0,I.jsx)(`div`,{className:`fixed inset-0 z-20 bg-black/50 flex items-start justify-center pt-24`,onClick:e,children:(0,I.jsxs)(`div`,{className:`border border-border-strong bg-panel rounded-[var(--radius-panel)] w-[560px] max-w-[92vw]`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`px-3 py-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`h2`,{className:`text-[12px] uppercase tracking-[0.08em] text-fg-muted`,children:`New task`}),(0,I.jsx)(`button`,{onClick:e,className:`ml-auto text-fg-muted hover:text-fg`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`px-4 py-3 grid gap-3 text-[13px]`,children:[(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:`Title`}),(0,I.jsx)(`input`,{autoFocus:!0,className:`input`,value:t,onChange:e=>n(e.target.value),placeholder:`Add /healthz endpoint`})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:`Budget (USD)`}),(0,I.jsx)(`input`,{className:`input`,value:r,onChange:e=>i(e.target.value)})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:`Done criteria · one command per line`}),(0,I.jsx)(`textarea`,{className:`input`,rows:3,value:a,onChange:e=>o(e.target.value)})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:`Description`}),(0,I.jsx)(`textarea`,{className:`input`,rows:3,value:s,onChange:e=>c(e.target.value)})]}),f&&(0,I.jsx)(`div`,{className:`text-danger text-[12px]`,children:f})]}),(0,I.jsxs)(`footer`,{className:`px-4 py-2 border-t border-border flex gap-2 justify-end`,children:[(0,I.jsx)(`button`,{onClick:e,className:`border border-border px-3 py-1 rounded-sm text-fg-muted hover:text-fg`,children:`Cancel`}),(0,I.jsx)(`button`,{onClick:async()=>{if(!t.trim()){p(`Title is required.`);return}if(m.length===0){p(`At least one done criterion is required — it is what decides when the task is done.`);return}d(!0),p(``);try{await N.createTask({title:t.trim(),budget_usd:parseFloat(r)||0,done_criteria:m,body:s}),e()}catch(e){p(oe(e))}finally{d(!1)}},disabled:u,className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm hover:bg-accent/25 disabled:opacity-50`,children:u?`creating…`:`Create task`})]})]})})}var Hg=72,Ug=38,Wg=.62;function Gg(e){return{cx:e.width/2,cy:e.height/2,r:Math.max(80,Math.min(e.width,e.height)/2-Hg-Ug),nodeR:Ug,gateT:Wg}}function Kg(e){return Math.max(e,6)}function qg(e,t){return-Math.PI/2+2*Math.PI*e/t}function Jg(e,t,n){let r=Kg(e.length),i=[];return e.forEach((e,a)=>{if(!t.has(e))return;let o=qg(a,r);i.push({id:e,angle:o,x:n.cx+n.r*Math.cos(o),y:n.cy+n.r*Math.sin(o)})}),i}function Yg(e,t,n){return{x:t.cx+(e.x-t.cx)*n,y:t.cy+(e.y-t.cy)*n}}var Xg={assigned:.18,in_progress:.45,verifying:Wg,done:.85,needs_you:.5,failed:.5,inbox:.08};function Zg(e){return Xg[e]??.3}function Qg(e){return e!==``&&e!==`orchestrator`&&e!==`verifier`}function $g(e,t){let n=e.registry.slice(),r=new Set(e.workers);Qg(t.assignee)&&!n.includes(t.assignee)&&(n.push(t.assignee),n.sort()),Qg(t.assignee)&&r.add(t.assignee);let i=new Map(e.tasks);return i.set(t.id,t),{registry:n,workers:r,tasks:i}}function e_(){return{registry:[],workers:new Set,tasks:new Map}}function t_(e,t=[]){let n={registry:t.slice(),workers:new Set,tasks:new Map};for(let t of e)n=$g(n,{id:t.id,title:t.title,assignee:t.assignee,status:t.status});return n}function n_(e){return{id:e.id,title:e.title,assignee:e.assignee,status:e.status}}function r_(){let e=F(()=>N.tasks(),[],{intervalMs:8e3}),t=(0,l.useRef)([]),[n,r]=(0,l.useState)(e_);return(0,l.useEffect)(()=>{if(!e.data)return;let n=t_(e.data,t.current);t.current=n.registry,r(n)},[e.data]),(0,l.useEffect)(()=>d.onFrame(e=>{e.type===`task`&&r(n=>{let r=$g(n,n_(e.data));return t.current=r.registry,r})}),[]),n}function i_(e){return e.workers.size>0||e.tasks.size>0}function a_(e){let t=new Map;for(let n of e.tasks.values()){if(!Qg(n.assignee))continue;let e=t.get(n.assignee)??[];e.push(n),t.set(n.assignee,e)}return t}var o_=260;function s_(e,t,n,r=o_){let i=e+(t-e)*(1-Math.exp(-n/r));return Math.abs(t-i)<.001?t:i}function c_(e){let t=0,n=performance.now(),r=i=>{let a=Math.min(i-n,64);n=i,e(a),t=requestAnimationFrame(r)};return t=requestAnimationFrame(r),{stop:()=>cancelAnimationFrame(t)}}var l_=class{cur=new Map;setTarget(e,t){this.cur.has(e)||this.cur.set(e,t),this.targets.set(e,t)}targets=new Map;step(e,t){let n=!1;for(let r of Array.from(this.cur.keys())){if(!t.has(r)){this.cur.delete(r),this.targets.delete(r);continue}let i=this.targets.get(r)??this.cur.get(r),a=s_(this.cur.get(r),i,e);a!==this.cur.get(r)&&(n=!0),this.cur.set(r,a)}return n}get(e){return this.cur.get(e)}};function u_(e){let t=(0,l.useRef)(new l_),[,n]=(0,l.useState)(0),r=new Set(e.tasks.keys());for(let n of e.tasks.values())t.current.setTarget(n.id,Zg(n.status));return(0,l.useEffect)(()=>{let e=c_(e=>{t.current.step(e,r)&&n(e=>e+1)});return()=>e.stop()},[]),(e,n)=>t.current.get(e)??Zg(n)}function d_(e){switch(e){case`done`:return`var(--color-ok)`;case`needs_you`:return`var(--color-warn)`;case`failed`:return`var(--color-danger)`;case`verifying`:case`in_progress`:case`assigned`:return`var(--color-accent)`;default:return`var(--color-fg-muted)`}}function f_(e){return e.some(e=>e.status!==`done`&&e.status!==`failed`)}function p_({model:e,viewport:t,centerLabel:n=`orchestrator`}){let r=Gg(t),i=Jg(e.registry,e.workers,r),a=a_(e),o=u_(e);return(0,I.jsxs)(`svg`,{width:t.width,height:t.height,className:`block`,role:`img`,"aria-label":`orchestration graph`,children:[i.map(e=>(0,I.jsx)(g_,{node:e,g:r,gateStatus:h_(a.get(e.id)??[])},`spoke-${e.id}`)),i.map(e=>(a.get(e.id)??[]).map((t,n)=>{let i=Yg(e,r,o(t.id,t.status)),s=(n-(a.get(e.id).length-1)/2)*12,c=-(e.y-r.cy),l=e.x-r.cx,u=Math.hypot(c,l)||1;return(0,I.jsx)(m_,{task:t,cx:i.x+c/u*s,cy:i.y+l/u*s},`task-${t.id}`)})),i.map(e=>{let t=a.get(e.id)??[],n=f_(t),i=e.x>=r.cx?1:-1,o=i===1?`start`:`end`,s=i*(r.nodeR+10),c=t.find(e=>e.status!==`done`&&e.status!==`failed`)??t[0];return(0,I.jsxs)(`g`,{transform:`translate(${e.x},${e.y})`,children:[(0,I.jsx)(`circle`,{className:n?`graph-breathe`:void 0,r:r.nodeR,fill:`var(--color-panel)`,stroke:n?`var(--color-accent)`:`var(--color-border-strong)`,strokeWidth:n?2.5:1.5}),(0,I.jsx)(`text`,{textAnchor:`middle`,dy:`0.32em`,fontSize:`13`,fill:`var(--color-fg)`,className:`mono`,children:y_(e.id)}),c&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`text`,{x:s,y:-4,textAnchor:o,fontSize:`12`,fill:`var(--color-fg)`,children:v_(c.title,26)}),(0,I.jsx)(`text`,{x:s,y:12,textAnchor:o,fontSize:`11`,fill:d_(c.status),className:`mono`,children:__(c.status)})]})]},`node-${e.id}`)}),(0,I.jsxs)(`g`,{transform:`translate(${r.cx},${r.cy})`,children:[(0,I.jsx)(`circle`,{r:r.nodeR+6,fill:`var(--color-panel-2)`,stroke:`var(--color-accent)`,strokeWidth:2}),(0,I.jsx)(`text`,{textAnchor:`middle`,dy:`0.32em`,fontSize:`12`,fill:`var(--color-fg)`,className:`mono`,children:n===`orchestrator`?`orch`:n})]})]})}function m_({task:e,cx:t,cy:n}){let r=(0,l.useRef)(e.status),[i,a]=(0,l.useState)(!1);return(0,l.useEffect)(()=>{if(r.current!==`done`&&e.status===`done`){a(!0);let t=setTimeout(()=>a(!1),600);return r.current=e.status,()=>clearTimeout(t)}r.current=e.status},[e.status]),(0,I.jsx)(`circle`,{className:`graph-dot${i?` graph-verified`:``}`,cx:t,cy:n,r:8,fill:d_(e.status),children:(0,I.jsx)(`title`,{children:`${e.title} · ${e.status}`})})}function h_(e){return e.some(e=>e.status===`done`)?`done`:e.some(e=>e.status===`verifying`)?`verifying`:`idle`}function g_({node:e,g:t,gateStatus:n}){let r=Yg(e,t,t.gateT),i=n===`done`?`var(--color-ok)`:n===`verifying`?`var(--color-accent)`:`var(--color-bg)`,a=n===`done`?`var(--color-ok)`:n===`verifying`?`var(--color-accent)`:`var(--color-border-strong)`;return(0,I.jsxs)(`g`,{children:[(0,I.jsx)(`line`,{x1:t.cx,y1:t.cy,x2:e.x,y2:e.y,stroke:`var(--color-border)`,strokeWidth:1.5}),(0,I.jsx)(`rect`,{className:`graph-gate`,x:r.x-7,y:r.y-7,width:14,height:14,transform:`rotate(45 ${r.x} ${r.y})`,fill:i,stroke:a,strokeWidth:1.5,children:(0,I.jsx)(`title`,{children:`verify gate — a task turns green only after its tests pass`})})]})}function __(e){switch(e){case`assigned`:return`assigned`;case`in_progress`:return`working…`;case`verifying`:return`running tests…`;case`done`:return`✓ verified`;case`needs_you`:return`needs you`;case`failed`:return`failed`;default:return e}}function v_(e,t){return e.length>t?e.slice(0,t-1)+`…`:e}function y_(e){let t=/^worker-(\d+)$/.exec(e);return t?`w${t[1]}`:e===`verifier`?`vfy`:e.slice(0,4)}function b_(e){switch(e){case`working`:return`var(--color-ok)`;case`waiting-on-you`:return`var(--color-warn)`;case`looping`:case`error`:return`var(--color-danger)`;case`ended`:return`var(--color-fg-faint)`;default:return`var(--color-fg-muted)`}}function x_({sessions:e,viewport:t}){let n=Gg(t),r=e.map(e=>e.id).sort(),i=Jg(r,new Set(r),n),a=new Map(e.map(e=>[e.id,e]));return(0,I.jsxs)(`svg`,{width:t.width,height:t.height,className:`block`,role:`img`,"aria-label":`session graph`,children:[i.map(e=>(0,I.jsx)(`line`,{x1:n.cx,y1:n.cy,x2:e.x,y2:e.y,stroke:`var(--color-border)`,strokeWidth:1.5},`edge-${e.id}`)),i.map(e=>{let t=a.get(e.id),r=b_(t.health);return(0,I.jsxs)(`g`,{transform:`translate(${e.x},${e.y})`,children:[(0,I.jsx)(`circle`,{className:t.health===`working`?`graph-breathe`:void 0,r:n.nodeR,fill:`var(--color-panel)`,stroke:r,strokeWidth:2}),(0,I.jsx)(`text`,{textAnchor:`middle`,dy:`0.32em`,fontSize:`9`,fill:`var(--color-fg-muted)`,className:`mono`,children:t.label}),(0,I.jsx)(`title`,{children:`${t.label} · ${t.health}`})]},`sess-${e.id}`)}),(0,I.jsxs)(`g`,{transform:`translate(${n.cx},${n.cy})`,children:[(0,I.jsx)(`circle`,{r:n.nodeR+4,fill:`var(--color-panel-2)`,stroke:`var(--color-border-strong)`,strokeWidth:1.5}),(0,I.jsx)(`text`,{textAnchor:`middle`,dy:`0.32em`,fontSize:`10`,fill:`var(--color-fg-muted)`,className:`mono`,children:`caprock`})]})]})}function S_(){let e=r_(),t=F(()=>N.sessions(!0),[],{intervalMs:4e3}),n=(0,l.useRef)(null),[r,i]=(0,l.useState)({width:900,height:560});(0,l.useEffect)(()=>{if(!n.current)return;let e=n.current,t=new ResizeObserver(()=>{i({width:e.clientWidth,height:Math.max(420,e.clientHeight)})});return t.observe(e),i({width:e.clientWidth,height:Math.max(420,e.clientHeight)}),()=>t.disconnect()},[]);let a=i_(e),o=(t.data??[]).filter(e=>e.status!==`ended`).map(e=>({id:e.session_id,label:T(e.session_id),health:e.activity.health})),s=Array.from(e.tasks.values()),c=s.filter(e=>e.status===`done`).length,u=s.filter(e=>[`assigned`,`in_progress`,`verifying`].includes(e.status)).length;return(0,I.jsxs)(`div`,{className:`grid gap-2`,children:[a&&(0,I.jsxs)(`div`,{className:`flex items-baseline gap-6 border border-border bg-panel rounded-[var(--radius-panel)] px-4 py-3`,children:[(0,I.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num text-2xl text-ok`,children:c}),(0,I.jsx)(`span`,{className:`text-[12px] text-fg-muted`,children:`verified — tests passed, not just claimed`})]}),(0,I.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num text-2xl text-accent`,children:u}),(0,I.jsx)(`span`,{className:`text-[12px] text-fg-muted`,children:`in flight`})]}),(0,I.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num text-2xl text-fg`,children:e.workers.size}),(0,I.jsx)(`span`,{className:`text-[12px] text-fg-muted`,children:`workers`})]})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-fg-faint px-0.5`,children:[(0,I.jsx)(C_,{orchestration:a}),(0,I.jsx)(`span`,{className:`ml-auto`,children:a?`live · the orchestrator assigns work; a task turns green only after its tests pass`:(0,I.jsxs)(I.Fragment,{children:[`your live sessions — start an orchestrator with `,(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:`caprock up --hive `}),` to see the verified team`]})})]}),(0,I.jsx)(`div`,{ref:n,className:`relative w-full h-[70vh] rounded-[var(--radius-panel)] border border-border bg-panel/40 overflow-hidden`,children:a?(0,I.jsx)(p_,{model:e,viewport:r}):(0,I.jsx)(x_,{sessions:o,viewport:r})})]})}function C_({orchestration:e}){let t=(e,t)=>(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,I.jsx)(`span`,{className:`inline-block w-2 h-2 rounded-full`,style:{background:e}}),t]});return(0,I.jsx)(`span`,{className:`inline-flex items-center gap-3`,children:e?(0,I.jsxs)(I.Fragment,{children:[t(`var(--color-accent)`,`in flight`),t(`var(--color-ok)`,`verified`),t(`var(--color-warn)`,`needs you`),t(`var(--color-danger)`,`failed`)]}):(0,I.jsxs)(I.Fragment,{children:[t(`var(--color-ok)`,`working`),t(`var(--color-warn)`,`waiting on you`),t(`var(--color-danger)`,`loop / error`),t(`var(--color-fg-muted)`,`idle`)]})})}var w_=200;function T_(){let[e,t]=(0,l.useState)(``),[n,r]=(0,l.useState)(``),i=ie(3e4),[a,o]=(0,l.useState)(!1),s=F(()=>N.searchNotes(n,w_),[n],{live:!1,intervalMs:0}),[c,u]=(0,l.useState)([]),[d,f]=(0,l.useState)(!1),[p,m]=(0,l.useState)(!1);(0,l.useEffect)(()=>{u([]),m(!1)},[n]);let h=[...s.data??[],...c];async function g(){let e=h[h.length-1];if(!(!e||d)){f(!0);try{let t=await N.searchNotes(n,w_,e.event_id);t.length===0?m(!0):u(e=>[...e,...t])}catch{m(!0)}finally{f(!1)}}}let _=a||n?h:h.filter(e=>!e.fragment),v=h.length-_.length;return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`form`,{className:`flex items-center gap-2`,onSubmit:t=>{t.preventDefault(),r(e.trim())},children:[(0,I.jsx)(`input`,{className:`input max-w-[520px]`,value:e,onChange:e=>t(e.target.value),placeholder:`Search what Claude told you — a name, an error, a decision…`,"aria-label":`Search Claude's answers`}),(0,I.jsx)(`button`,{type:`submit`,className:`text-[12px] border border-accent/50 text-accent bg-accent/10 px-2 py-1 rounded-sm hover:bg-accent/20`,children:`search`}),n&&(0,I.jsx)(`button`,{type:`button`,className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-1 rounded-sm`,onClick:()=>{t(``),r(``)},children:`clear`}),v>0&&(0,I.jsx)(`button`,{type:`button`,className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-1 rounded-sm`,onClick:()=>o(e=>!e),children:a?`hide short remarks`:`+${v} short remarks`}),(0,I.jsx)(`span`,{className:`ml-auto text-[11px] text-fg-faint`,children:`Claude's written answers, across every session. Local only.`})]}),s.error&&!s.data&&(0,I.jsx)(z,{title:`Cannot search`,children:s.error.message}),!s.data&&!s.error&&(0,I.jsx)(St,{rows:5,className:`border border-border rounded-[var(--radius-panel)] bg-panel`}),s.data&&_.length===0&&(0,I.jsx)(z,{title:n?`Nothing found for "${n}"`:`No answers captured yet`,children:n?`Try a shorter phrase — this matches the words Claude wrote, not what you asked.`:`Run a session and Claude’s written answers will be searchable here.`}),_.length>0&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`text-[11px] text-fg-faint px-0.5`,children:[_.length,` `,_.length===1?`answer`:`answers`,n?` matching "${n}"`:` · most recent`,` · subagent chatter excluded`]}),(0,I.jsx)(`div`,{className:`grid gap-2`,children:_.map(e=>(0,I.jsx)(Ur,{note:e,now:i,showSession:!0},e.event_id))}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3 px-0.5`,children:[!p&&(0,I.jsx)(`button`,{className:`text-[11px] text-fg-muted hover:text-fg border border-border px-2 py-1 rounded-sm`,onClick:()=>void g(),disabled:d,children:d?`loading…`:`load older answers`}),p&&(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:`that is everything`})]})]})]})}function E_(){let e=_();return(0,I.jsx)(dt,{route:e,children:(0,I.jsxs)(_t,{label:e.name,children:[e.name===`now`&&(0,I.jsx)(Ir,{}),e.name===`session`&&(0,I.jsx)(eg,{id:e.id,tab:e.tab,at:e.at},e.id),e.name===`cost`&&(0,I.jsx)(xg,{}),e.name===`settings`&&(0,I.jsx)(Eg,{}),e.name===`history`&&(0,I.jsx)(kg,{}),e.name===`tasks`&&(0,I.jsx)(jg,{}),e.name===`graph`&&(0,I.jsx)(S_,{}),e.name===`notes`&&(0,I.jsx)(T_,{})]})})}(0,u.createRoot)(document.getElementById(`root`)).render((0,I.jsx)(l.StrictMode,{children:(0,I.jsx)(E_,{})})); \ No newline at end of file +`).map(e=>e.trim()).filter(Boolean);return(0,I.jsx)(`div`,{className:`fixed inset-0 z-20 bg-black/50 flex items-start justify-center pt-24`,onClick:e,children:(0,I.jsxs)(`div`,{className:`border border-border-strong bg-panel rounded-[var(--radius-panel)] w-[560px] max-w-[92vw]`,onClick:e=>e.stopPropagation(),children:[(0,I.jsxs)(`header`,{className:`px-3 py-2 border-b border-border flex items-center`,children:[(0,I.jsx)(`h2`,{className:`text-[12px] uppercase tracking-[0.08em] text-fg-muted`,children:`New task`}),(0,I.jsx)(`button`,{onClick:e,className:`ml-auto text-fg-muted hover:text-fg`,children:`✕`})]}),(0,I.jsxs)(`div`,{className:`px-4 py-3 grid gap-3 text-[13px]`,children:[(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:`Title`}),(0,I.jsx)(`input`,{autoFocus:!0,className:`input`,value:t,onChange:e=>n(e.target.value),placeholder:`Add /healthz endpoint`})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:`Budget (USD)`}),(0,I.jsx)(`input`,{className:`input`,value:r,onChange:e=>i(e.target.value)})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:`Done criteria · one command per line`}),(0,I.jsx)(`textarea`,{className:`input`,rows:3,value:a,onChange:e=>o(e.target.value)})]}),(0,I.jsxs)(`label`,{className:`grid gap-1`,children:[(0,I.jsx)(`span`,{className:`text-[11px] text-fg-muted`,children:`Description`}),(0,I.jsx)(`textarea`,{className:`input`,rows:3,value:s,onChange:e=>c(e.target.value)})]}),f&&(0,I.jsx)(`div`,{className:`text-danger text-[12px]`,children:f})]}),(0,I.jsxs)(`footer`,{className:`px-4 py-2 border-t border-border flex gap-2 justify-end`,children:[(0,I.jsx)(`button`,{onClick:e,className:`border border-border px-3 py-1 rounded-sm text-fg-muted hover:text-fg`,children:`Cancel`}),(0,I.jsx)(`button`,{onClick:async()=>{if(!t.trim()){p(`Title is required.`);return}if(m.length===0){p(`At least one done criterion is required — it is what decides when the task is done.`);return}d(!0),p(``);try{await N.createTask({title:t.trim(),budget_usd:parseFloat(r)||0,done_criteria:m,body:s}),e()}catch(e){p(oe(e))}finally{d(!1)}},disabled:u,className:`border border-accent bg-accent/15 text-accent px-3 py-1 rounded-sm hover:bg-accent/25 disabled:opacity-50`,children:u?`creating…`:`Create task`})]})]})})}var Ug=72,Wg=38,Gg=.62;function Kg(e){return{cx:e.width/2,cy:e.height/2,r:Math.max(80,Math.min(e.width,e.height)/2-Ug-Wg),nodeR:Wg,gateT:Gg}}function qg(e){return Math.max(e,6)}function Jg(e,t){return-Math.PI/2+2*Math.PI*e/t}function Yg(e,t,n){let r=qg(e.length),i=[];return e.forEach((e,a)=>{if(!t.has(e))return;let o=Jg(a,r);i.push({id:e,angle:o,x:n.cx+n.r*Math.cos(o),y:n.cy+n.r*Math.sin(o)})}),i}function Xg(e,t,n){return{x:t.cx+(e.x-t.cx)*n,y:t.cy+(e.y-t.cy)*n}}var Zg={assigned:.18,in_progress:.45,verifying:Gg,done:.85,needs_you:.5,failed:.5,inbox:.08};function Qg(e){return Zg[e]??.3}function $g(e){return e!==``&&e!==`orchestrator`&&e!==`verifier`}function e_(e,t){let n=e.registry.slice(),r=new Set(e.workers);$g(t.assignee)&&!n.includes(t.assignee)&&(n.push(t.assignee),n.sort()),$g(t.assignee)&&r.add(t.assignee);let i=new Map(e.tasks);return i.set(t.id,t),{registry:n,workers:r,tasks:i}}function t_(){return{registry:[],workers:new Set,tasks:new Map}}function n_(e,t=[]){let n={registry:t.slice(),workers:new Set,tasks:new Map};for(let t of e)n=e_(n,{id:t.id,title:t.title,assignee:t.assignee,status:t.status});return n}function r_(e){return{id:e.id,title:e.title,assignee:e.assignee,status:e.status}}function i_(){let e=F(()=>N.tasks(),[],{intervalMs:8e3}),t=(0,l.useRef)([]),[n,r]=(0,l.useState)(t_);return(0,l.useEffect)(()=>{if(!e.data)return;let n=n_(e.data,t.current);t.current=n.registry,r(n)},[e.data]),(0,l.useEffect)(()=>d.onFrame(e=>{e.type===`task`&&r(n=>{let r=e_(n,r_(e.data));return t.current=r.registry,r})}),[]),n}function a_(e){return e.workers.size>0||e.tasks.size>0}function o_(e){let t=new Map;for(let n of e.tasks.values()){if(!$g(n.assignee))continue;let e=t.get(n.assignee)??[];e.push(n),t.set(n.assignee,e)}return t}var s_=260;function c_(e,t,n,r=s_){let i=e+(t-e)*(1-Math.exp(-n/r));return Math.abs(t-i)<.001?t:i}function l_(e){let t=0,n=performance.now(),r=i=>{let a=Math.min(i-n,64);n=i,e(a),t=requestAnimationFrame(r)};return t=requestAnimationFrame(r),{stop:()=>cancelAnimationFrame(t)}}var u_=class{cur=new Map;setTarget(e,t){this.cur.has(e)||this.cur.set(e,t),this.targets.set(e,t)}targets=new Map;step(e,t){let n=!1;for(let r of Array.from(this.cur.keys())){if(!t.has(r)){this.cur.delete(r),this.targets.delete(r);continue}let i=this.targets.get(r)??this.cur.get(r),a=c_(this.cur.get(r),i,e);a!==this.cur.get(r)&&(n=!0),this.cur.set(r,a)}return n}get(e){return this.cur.get(e)}};function d_(e){let t=(0,l.useRef)(new u_),[,n]=(0,l.useState)(0),r=new Set(e.tasks.keys());for(let n of e.tasks.values())t.current.setTarget(n.id,Qg(n.status));return(0,l.useEffect)(()=>{let e=l_(e=>{t.current.step(e,r)&&n(e=>e+1)});return()=>e.stop()},[]),(e,n)=>t.current.get(e)??Qg(n)}function f_(e){switch(e){case`done`:return`var(--color-ok)`;case`needs_you`:return`var(--color-warn)`;case`failed`:return`var(--color-danger)`;case`verifying`:case`in_progress`:case`assigned`:return`var(--color-accent)`;default:return`var(--color-fg-muted)`}}function p_(e){return e.some(e=>e.status!==`done`&&e.status!==`failed`)}function m_({model:e,viewport:t,centerLabel:n=`orchestrator`}){let r=Kg(t),i=Yg(e.registry,e.workers,r),a=o_(e),o=d_(e);return(0,I.jsxs)(`svg`,{width:t.width,height:t.height,className:`block`,role:`img`,"aria-label":`orchestration graph`,children:[i.map(e=>(0,I.jsx)(__,{node:e,g:r,gateStatus:g_(a.get(e.id)??[])},`spoke-${e.id}`)),i.map(e=>(a.get(e.id)??[]).map((t,n)=>{let i=Xg(e,r,o(t.id,t.status)),s=(n-(a.get(e.id).length-1)/2)*12,c=-(e.y-r.cy),l=e.x-r.cx,u=Math.hypot(c,l)||1;return(0,I.jsx)(h_,{task:t,cx:i.x+c/u*s,cy:i.y+l/u*s},`task-${t.id}`)})),i.map(e=>{let t=a.get(e.id)??[],n=p_(t),i=e.x>=r.cx?1:-1,o=i===1?`start`:`end`,s=i*(r.nodeR+10),c=t.find(e=>e.status!==`done`&&e.status!==`failed`)??t[0];return(0,I.jsxs)(`g`,{transform:`translate(${e.x},${e.y})`,children:[(0,I.jsx)(`circle`,{className:n?`graph-breathe`:void 0,r:r.nodeR,fill:`var(--color-panel)`,stroke:n?`var(--color-accent)`:`var(--color-border-strong)`,strokeWidth:n?2.5:1.5}),(0,I.jsx)(`text`,{textAnchor:`middle`,dy:`0.32em`,fontSize:`13`,fill:`var(--color-fg)`,className:`mono`,children:b_(e.id)}),c&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`text`,{x:s,y:-4,textAnchor:o,fontSize:`12`,fill:`var(--color-fg)`,children:y_(c.title,26)}),(0,I.jsx)(`text`,{x:s,y:12,textAnchor:o,fontSize:`11`,fill:f_(c.status),className:`mono`,children:v_(c.status)})]})]},`node-${e.id}`)}),(0,I.jsxs)(`g`,{transform:`translate(${r.cx},${r.cy})`,children:[(0,I.jsx)(`circle`,{r:r.nodeR+6,fill:`var(--color-panel-2)`,stroke:`var(--color-accent)`,strokeWidth:2}),(0,I.jsx)(`text`,{textAnchor:`middle`,dy:`0.32em`,fontSize:`12`,fill:`var(--color-fg)`,className:`mono`,children:n===`orchestrator`?`orch`:n})]})]})}function h_({task:e,cx:t,cy:n}){let r=(0,l.useRef)(e.status),[i,a]=(0,l.useState)(!1);return(0,l.useEffect)(()=>{if(r.current!==`done`&&e.status===`done`){a(!0);let t=setTimeout(()=>a(!1),600);return r.current=e.status,()=>clearTimeout(t)}r.current=e.status},[e.status]),(0,I.jsx)(`circle`,{className:`graph-dot${i?` graph-verified`:``}`,cx:t,cy:n,r:8,fill:f_(e.status),children:(0,I.jsx)(`title`,{children:`${e.title} · ${e.status}`})})}function g_(e){return e.some(e=>e.status===`done`)?`done`:e.some(e=>e.status===`verifying`)?`verifying`:`idle`}function __({node:e,g:t,gateStatus:n}){let r=Xg(e,t,t.gateT),i=n===`done`?`var(--color-ok)`:n===`verifying`?`var(--color-accent)`:`var(--color-bg)`,a=n===`done`?`var(--color-ok)`:n===`verifying`?`var(--color-accent)`:`var(--color-border-strong)`;return(0,I.jsxs)(`g`,{children:[(0,I.jsx)(`line`,{x1:t.cx,y1:t.cy,x2:e.x,y2:e.y,stroke:`var(--color-border)`,strokeWidth:1.5}),(0,I.jsx)(`rect`,{className:`graph-gate`,x:r.x-7,y:r.y-7,width:14,height:14,transform:`rotate(45 ${r.x} ${r.y})`,fill:i,stroke:a,strokeWidth:1.5,children:(0,I.jsx)(`title`,{children:`verify gate — a task turns green only after its tests pass`})})]})}function v_(e){switch(e){case`assigned`:return`assigned`;case`in_progress`:return`working…`;case`verifying`:return`running tests…`;case`done`:return`✓ verified`;case`needs_you`:return`needs you`;case`failed`:return`failed`;default:return e}}function y_(e,t){return e.length>t?e.slice(0,t-1)+`…`:e}function b_(e){let t=/^worker-(\d+)$/.exec(e);return t?`w${t[1]}`:e===`verifier`?`vfy`:e.slice(0,4)}function x_(e){switch(e){case`working`:return`var(--color-ok)`;case`waiting-on-you`:return`var(--color-warn)`;case`looping`:case`error`:return`var(--color-danger)`;case`ended`:return`var(--color-fg-faint)`;default:return`var(--color-fg-muted)`}}function S_({sessions:e,viewport:t}){let n=Kg(t),r=e.map(e=>e.id).sort(),i=Yg(r,new Set(r),n),a=new Map(e.map(e=>[e.id,e]));return(0,I.jsxs)(`svg`,{width:t.width,height:t.height,className:`block`,role:`img`,"aria-label":`session graph`,children:[i.map(e=>(0,I.jsx)(`line`,{x1:n.cx,y1:n.cy,x2:e.x,y2:e.y,stroke:`var(--color-border)`,strokeWidth:1.5},`edge-${e.id}`)),i.map(e=>{let t=a.get(e.id),r=x_(t.health);return(0,I.jsxs)(`g`,{transform:`translate(${e.x},${e.y})`,children:[(0,I.jsx)(`circle`,{className:t.health===`working`?`graph-breathe`:void 0,r:n.nodeR,fill:`var(--color-panel)`,stroke:r,strokeWidth:2}),(0,I.jsx)(`text`,{textAnchor:`middle`,dy:`0.32em`,fontSize:`9`,fill:`var(--color-fg-muted)`,className:`mono`,children:t.label}),(0,I.jsx)(`title`,{children:`${t.label} · ${t.health}`})]},`sess-${e.id}`)}),(0,I.jsxs)(`g`,{transform:`translate(${n.cx},${n.cy})`,children:[(0,I.jsx)(`circle`,{r:n.nodeR+4,fill:`var(--color-panel-2)`,stroke:`var(--color-border-strong)`,strokeWidth:1.5}),(0,I.jsx)(`text`,{textAnchor:`middle`,dy:`0.32em`,fontSize:`10`,fill:`var(--color-fg-muted)`,className:`mono`,children:`caprock`})]})]})}function C_(){let e=i_(),t=F(()=>N.sessions(!0),[],{intervalMs:4e3}),n=(0,l.useRef)(null),[r,i]=(0,l.useState)({width:900,height:560});(0,l.useEffect)(()=>{if(!n.current)return;let e=n.current,t=new ResizeObserver(()=>{i({width:e.clientWidth,height:Math.max(420,e.clientHeight)})});return t.observe(e),i({width:e.clientWidth,height:Math.max(420,e.clientHeight)}),()=>t.disconnect()},[]);let a=a_(e),o=(t.data??[]).filter(e=>e.status!==`ended`).map(e=>({id:e.session_id,label:T(e.session_id),health:e.activity.health})),s=Array.from(e.tasks.values()),c=s.filter(e=>e.status===`done`).length,u=s.filter(e=>[`assigned`,`in_progress`,`verifying`].includes(e.status)).length;return(0,I.jsxs)(`div`,{className:`grid gap-2`,children:[a&&(0,I.jsxs)(`div`,{className:`flex items-baseline gap-6 border border-border bg-panel rounded-[var(--radius-panel)] px-4 py-3`,children:[(0,I.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num text-2xl text-ok`,children:c}),(0,I.jsx)(`span`,{className:`text-[12px] text-fg-muted`,children:`verified — tests passed, not just claimed`})]}),(0,I.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num text-2xl text-accent`,children:u}),(0,I.jsx)(`span`,{className:`text-[12px] text-fg-muted`,children:`in flight`})]}),(0,I.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,I.jsx)(`span`,{className:`num text-2xl text-fg`,children:e.workers.size}),(0,I.jsx)(`span`,{className:`text-[12px] text-fg-muted`,children:`workers`})]})]}),(0,I.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-fg-faint px-0.5`,children:[(0,I.jsx)(w_,{orchestration:a}),(0,I.jsx)(`span`,{className:`ml-auto`,children:a?`live · the orchestrator assigns work; a task turns green only after its tests pass`:(0,I.jsxs)(I.Fragment,{children:[`your live sessions — start an orchestrator with `,(0,I.jsx)(`span`,{className:`mono text-fg-muted`,children:`caprock up --hive `}),` to see the verified team`]})})]}),(0,I.jsx)(`div`,{ref:n,className:`relative w-full h-[70vh] rounded-[var(--radius-panel)] border border-border bg-panel/40 overflow-hidden`,children:a?(0,I.jsx)(m_,{model:e,viewport:r}):(0,I.jsx)(S_,{sessions:o,viewport:r})})]})}function w_({orchestration:e}){let t=(e,t)=>(0,I.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,I.jsx)(`span`,{className:`inline-block w-2 h-2 rounded-full`,style:{background:e}}),t]});return(0,I.jsx)(`span`,{className:`inline-flex items-center gap-3`,children:e?(0,I.jsxs)(I.Fragment,{children:[t(`var(--color-accent)`,`in flight`),t(`var(--color-ok)`,`verified`),t(`var(--color-warn)`,`needs you`),t(`var(--color-danger)`,`failed`)]}):(0,I.jsxs)(I.Fragment,{children:[t(`var(--color-ok)`,`working`),t(`var(--color-warn)`,`waiting on you`),t(`var(--color-danger)`,`loop / error`),t(`var(--color-fg-muted)`,`idle`)]})})}var T_=200;function E_(){let[e,t]=(0,l.useState)(``),[n,r]=(0,l.useState)(``),i=ie(3e4),[a,o]=(0,l.useState)(!1),s=F(()=>N.searchNotes(n,T_),[n],{live:!1,intervalMs:0}),[c,u]=(0,l.useState)([]),[d,f]=(0,l.useState)(!1),[p,m]=(0,l.useState)(!1);(0,l.useEffect)(()=>{u([]),m(!1)},[n]);let h=[...s.data??[],...c];async function g(){let e=h[h.length-1];if(!(!e||d)){f(!0);try{let t=await N.searchNotes(n,T_,e.event_id);t.length===0?m(!0):u(e=>[...e,...t])}catch{m(!0)}finally{f(!1)}}}let _=a||n?h:h.filter(e=>!e.fragment),v=h.length-_.length;return(0,I.jsxs)(`div`,{className:`grid gap-3`,children:[(0,I.jsxs)(`form`,{className:`flex items-center gap-2`,onSubmit:t=>{t.preventDefault(),r(e.trim())},children:[(0,I.jsx)(`input`,{className:`input max-w-[520px]`,value:e,onChange:e=>t(e.target.value),placeholder:`Search what Claude told you — a name, an error, a decision…`,"aria-label":`Search Claude's answers`}),(0,I.jsx)(`button`,{type:`submit`,className:`text-[12px] border border-accent/50 text-accent bg-accent/10 px-2 py-1 rounded-sm hover:bg-accent/20`,children:`search`}),n&&(0,I.jsx)(`button`,{type:`button`,className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-1 rounded-sm`,onClick:()=>{t(``),r(``)},children:`clear`}),v>0&&(0,I.jsx)(`button`,{type:`button`,className:`text-[11px] text-fg-muted hover:text-fg border border-border px-1.5 py-1 rounded-sm`,onClick:()=>o(e=>!e),children:a?`hide short remarks`:`+${v} short remarks`}),(0,I.jsx)(`span`,{className:`ml-auto text-[11px] text-fg-faint`,children:`Claude's written answers, across every session. Local only.`})]}),s.error&&!s.data&&(0,I.jsx)(z,{title:`Cannot search`,children:s.error.message}),!s.data&&!s.error&&(0,I.jsx)(St,{rows:5,className:`border border-border rounded-[var(--radius-panel)] bg-panel`}),s.data&&_.length===0&&(0,I.jsx)(z,{title:n?`Nothing found for "${n}"`:`No answers captured yet`,children:n?`Try a shorter phrase — this matches the words Claude wrote, not what you asked.`:`Run a session and Claude’s written answers will be searchable here.`}),_.length>0&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`div`,{className:`text-[11px] text-fg-faint px-0.5`,children:[_.length,` `,_.length===1?`answer`:`answers`,n?` matching "${n}"`:` · most recent`,` · subagent chatter excluded`]}),(0,I.jsx)(`div`,{className:`grid gap-2`,children:_.map(e=>(0,I.jsx)(Ur,{note:e,now:i,showSession:!0},e.event_id))}),(0,I.jsxs)(`div`,{className:`flex items-center gap-3 px-0.5`,children:[!p&&(0,I.jsx)(`button`,{className:`text-[11px] text-fg-muted hover:text-fg border border-border px-2 py-1 rounded-sm`,onClick:()=>void g(),disabled:d,children:d?`loading…`:`load older answers`}),p&&(0,I.jsx)(`span`,{className:`text-[11px] text-fg-faint`,children:`that is everything`})]})]})]})}function D_(){let e=_();return(0,I.jsx)(dt,{route:e,children:(0,I.jsxs)(_t,{label:e.name,children:[e.name===`now`&&(0,I.jsx)(Ir,{}),e.name===`session`&&(0,I.jsx)(eg,{id:e.id,tab:e.tab,at:e.at},e.id),e.name===`cost`&&(0,I.jsx)(Sg,{}),e.name===`settings`&&(0,I.jsx)(Dg,{}),e.name===`history`&&(0,I.jsx)(Ag,{}),e.name===`tasks`&&(0,I.jsx)(Mg,{}),e.name===`graph`&&(0,I.jsx)(C_,{}),e.name===`notes`&&(0,I.jsx)(E_,{})]})})}(0,u.createRoot)(document.getElementById(`root`)).render((0,I.jsx)(l.StrictMode,{children:(0,I.jsx)(D_,{})})); \ No newline at end of file diff --git a/internal/api/dist/assets/index-Y5As_TQv.css b/internal/api/dist/assets/index-Y5As_TQv.css new file mode 100644 index 0000000..5dcf4a8 --- /dev/null +++ b/internal/api/dist/assets/index-Y5As_TQv.css @@ -0,0 +1 @@ +@font-face{font-family:Hanken Grotesk Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(data:font/woff2;base64,d09GMgABAAAAAAaEABMAAAAADFgAAAYdAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbbhwoP0hWQVJpBmA/U1RBVIE4AFwvbBEICoJ8gkMLFAAwhCoBNgIkAyIEIAWGUAdiDAcbvgpRVHJOI/viwCYyfSFrJjFIG8raYpYj9+IeSF0s6zD+Lk/4OGrZHhHV+wvt2ffuWPwlA51lIICIosSVmyOKEs5Uzlx3NKeXIgn1ssCydUybDV0IHga+SszIyfrQe9bLTFNxjayzgs76hNsDoSYtRe32fiJ4gxBjrP8L+w//zzHjv7Yqyr9o2vOBDXhCo2jMtr4uwAK/gV1U0PxAq/EAD+yW9EoKOL1KLw8rHrFgCSgRTQRzBzpeXVhweEDlyfY8gIoOa2CQJzrTAHIIoitTMVV2dyFwpJ2iAEQTpSkhPitxD3YwuZHEagTcAhyKAcBmUyPdhTovJThOw6HYiaF2M/J7erdi2OUutor6ES6Ac88AvfZvKpb6fJoArohb524042j6Jij36NI7P8Pb7s721naN9gcTtcjXQP4l+8BKEzFVGMxxoHqlq8Ul4LGneFJBDFaOdKpLPcg8P14YSDwIcn75hdlyJLTBlZ4voL6tT46yC/njunXqpJ0/bSvmrH1o3kRlwZ+j0DBogkF3KbDRVBlbOc+fY5HVXwPoT9hfekPnyZMaEmenYLMSg5npqegFOsgXsBv1IoF9aIVfSCNHkk6+gIzILsiYuhWQCfUtZEpbkRntQxBZgw7MwFbMcRvwJrAnBlDqs7isLtL7pO84Xru1i7ah7tckH1Wreqq6K9u0amxU1bcff/s2Y1ni3rh2I8zHzqkm3PGvv3mzC6NDBz/UcOBIg+nm88rxN8MbdtypvHUL5o1c2zG0urYpRmW+VHZdiba6GXN/3v0B3i3nt4RBsbfAu8ftLqRcTIlZ4VYheFTAS5nXLS65VZrbuW3daF2Ze1ChyGXWZN6u9nUuH1LfyTERifZXEpIueMe28vF8FOoTnsONzw+1djo9P71lZGx1vM8mH/BhvSa2HDsRZ1+Ul+RmpnPOIaEuwWnZZdkgQWAAyCDDZ1wk+0sh7wseAAwA6UlHxbftCgYAAwKAgwIAEA7ACfHIRbV7J6dwF/ZzcRRmAjXUYKAGWAlDCCFmKnH+LJEQfHKEmVrfmKwSEab36AcubXQBoDYJV/aRV+funFD8wAXLSLYbwr9+DR+h/qZIKCfeqRG5ghHpdY0zcV2nuz5iJMhAFjaTDwOcoyKGG9JHrCfdp4cC+kCvUrxc7+bliIMiHj95sPIbUeWZEP/HLnN2tlr9EBeRiktHuWvErx98fRz1MuEvHO3FDRgtsSzL/P0hsDLK2n5/uHMOjvTst0HD6t+80ZN798j7j//kjqHxIOZDFPR/FxurFD6/HxGbB799RPHLx5F89MoBOub9jVuOWtmPH3o9H3r26DIuff+LqPLwff/xryDRmiAYmjxiK0GwS9XU+k8QpUrHsCTs4qH89Fv44ubWbQmOE51M7J8Pt8+h+NKt3zZpa2L9zZqcRlyEc4MaNGdfjQCxgIygn78ne4yAzcLWA3zAJ6RRGbijvHr1W+XN8ywrG0EoZSySb0/A9KsllI7Q/Pq8hLu76tfTy5cF4X8bQxTtYp2vr6/+1oI4AhgAlNYFryt62VaX9ktO6VsAeDLeWx6fff4vdV1ts7N6+gw9GCsQnqPB0QUttB9nEc7Aaf4XM0NQ90VJ+HV1rG04znGCmXcpPCA9+nxdMPgPlT7Dz83NMfZuMJaNeRqbc+tjd2QER/b0B44d7nv5Rif7VC8svYkx9SKWwb3YzN2M3cY8jSNLl+PYZqfjxNTxOLXVCmfmduDc0ty1kLbjeiGfIrDFJXWPTTMD5TKupR8cpZgJeXTofId8NoUj6E8XfAc2k4WPdbCberDYAp8Q7L5dUo8wE8cs9QINZYvwXKzvBS4v/n+fQZkGrrFysKEIuFBgjQpxiHH1XA+ZBI+C+oAoxhYKECc42rGOc8L4mYhsiThGfFjOcKmFubPpDgwnY1918Fwo8ouenDJxvGP96HFWJ28hiOy251oKjkcbGz2POMme8CTMThx6wqOPsFtPI6j6HhDyDTxFQYnL88FcXGAGHl3ZuueRbEuxbK6Hc84ZDvRrREtLzyjj8Xkd/uShR1b0sYd8Nh8/c8znxCnadxQcf2nFVWIyw1g+4StXav9j75s+CQAA)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Hanken Grotesk Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/hanken-grotesk-vietnamese-wght-normal-CHiFlh_0.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Hanken Grotesk Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/hanken-grotesk-latin-ext-wght-normal-Dg-wlmqe.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Hanken Grotesk Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/hanken-grotesk-latin-wght-normal-CaVRRdDk.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAfsABQAAAAAEAwAAAeCAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoP0hWQVJbBmA/U1RBVIFiJyYAdC9qEQgKhGSEAAsgADCGCAE2AiQDOgQgBYlMB4EUDAcbLQ4onoexrSC/2ZyLAa8p8VHB8/x3Vue+V0hVJalMJg2nx/TCrQXxBeqLjQG7FyM1WEa/X1tEXN7cFz9EJEMmMUz3RihWSSKeQCbcIou0izz/C8v+fq3VfajEa9gDD11CImXS7qL/RJFVzC1qiB6KmKeD6TZdQ6IRGv78dL6uSVVCfgni5mzu7kcgQBgAEAQTQRCoL++STTYybkJxNfQxAAIAGu8OdEB9teW2jh4BpgDqFjAeSEByW3zFP0CBBgNMsMCGEDjgggdhiEAUAeIIED7ABTDUEnkIE9Q9ahFgKttcVhApo4ACB4qobHaccgDfEjFO6aaWUhjMLt2SyIvHKoDqoA4CSUwEIYQCEjhAO9R1G6keDeDZGjNo+AhxOjCEGTr1WeIF3kYBiLAOKvkJSMiKX0VdAyQt3SDJClCkxJCHkCzfqyVTriJZLcolS32JZHUekq2TYNkYtCtjYHMQXSxGjXDz2t/yLWXzDzxz+o3zFwDEaN23F+13pyMdQAEaSKAR9vcGq4A4MTSKCElGW+M7UcY7xqkggITb28ZJhlqc9q2twYKTt0NjixBgYvO9BIihEBLYuOFXQzfIQ7dXGUEEEgFDooBfAzqiQbpJrhiWSuKJCRFKYbHCyJKI2G5GiZbNAvgAu5pc3vwx4G+g3aDkhklABiSz0BICXrYghtYhx/cdJ+44rY2oZ0aMNRFz3VZjb6W33F3gzltqtOCV8tTHSpOeXuItfvr5lCdfzFpqtEitvqdcdGGFd28ZqqC0tPbeChGXgrIlnhSWu/eUso4uKWFLugyDzQJhflY4659+WjQ++6x72WUMv9G8mw6QJl7BVxX5fe/kpUsOvnZwee9uQ0cGXYd0o89XB2748sDSnt8d2VphdOTTgceDVvOds0v9P/s7HPq15aGun/6Vllb56f1dl0t1LejqrNkpdRZsG8TOnM5vkBG5oiVyVGnS8LHps5cfNWJs6qKPfaNSxiQNBUm3cKNWROr0GSur7Za31k1vieq7LH11VF+jXdRIasRKflc7jkobm1Z9te1IyZA0pDkhLR98+H37Zf1c/8at+dB7x+7GfVyTfJMPiYztsnl59Y5l4j+0n1RXlpHnF3Tq7HecmNF/CJodEMAikruxiyJaGLvHOdAfoA+oDvpjBm2b91cHGRZMU9n25xEU0A8fgEEAdKI3Q1iDtc034sug5YVMkE2jsE+BIkwSoQ3gxXMqz9tELp48bd0cFKOKS7xYjEuXBnZP5ia7DyiO/X/YI+PQSbt2uSdqAkWL9nQbV1XB94/+uPfdZz8dnXYFBYrcTl2SIR/ybxJNJPz/Gupb0JaZeens2ekC7EKr8t+Ls/P5VJPYJdHKyqfg2nqU6bhlidzcddQV/7MmecTzJ5VPcKXkNKSEogHjYFx6QZ7rQ+FSe8njaiNuOnXS8H2ScQ619c2mC3VTtauL0rRbXd/CkSOP37FY9Zkjz8+GibYUMOEWF+RdrFS8Ecv1SHOpPUPZGEIpjPvFyU5cXKjd6OXqorTqy9GwRd++HVufPGnVsW+aO3vggKZ18jR9sXaTC1PWTEsVUaK0FkNySbTQDqlm2PfDjZcu4aalnSLKjnOoYQ0nUlqqXcGpPu/4VgV/xU2pAqW4BW3qzhQ8/hFKhV2qE3+BKAtDqBXjfgnVdH4y0wg5tbVNRenNdTWOrenWLcupQdmsbq5b+18piTe/xRdp1xbILxNPJGInm2z6hoB21Lal0i+ePTtd7B45+3XhFJ329evskXm7qurUVREotqSluSo/L29d3qDhI4YOQqWhI4YNvBNfsMHeXKemXrxQfKeuPOGRVayA3JtkJKEgbPp+dXUDluddutRYLFoXGXWX6N3WFaGLbQtRSitVYNacTNSdy7AaG/HSaUEANcBoGXNdcZvZsOqQ1icBDv21/gzAoYPHH/WDW0qNR3QTYKEAEHig6o13NXbND06CQPlRtYjGNnSktRc09k1mAMDvAlDKfQjgy6fssInlfzmNAjKkDxoxHOBLdVRAIVt9j4qo+hA1w9T1aNBNTUOTTNUHLbqokE+UAfJXCIGw/IxCSL5GRUJeR40rL/UxTm4Q08H6MbCs70ObuNyIIXrINHQYInF06UUlevTjbQzTh5upiDMzMMogUtEnjPs/Y7jAHCJeB0GBHh04tC6FiB6ZFB1oArUSIoFoqhzCeAN6lHwm0T4C3VVPWvjpSMXReuWesMEcoqrmgtNBGd2noWeV0hNAz9rFeShNJxHGsPa3HXeKTk8b55hahySYHaYKKFFLpCfN8rsoaJn01CR04Gkc+5k7KVTCmClX8Q10HCrUEkVlSX+XO33oQR9609tJ516H497WSobWs5Up6TLaS10/dessIskgJSLiDlWvHVUywpkQ7hdPZqGyiEF0uVQerVcPamT1A3eKXdyI1vG9OoflrSXihZ1qqGE3nhmAgiIbRCQgPLEPtOM3UQwTLYaYYomNlpA44opnjV6jkD6id80OOrzf6BzmMD6eEa1zKyeYG1fzfEf16V6jw9XYOaar1/b2kP/IYX8oR2mcFvv2GtBV3JXgd437AQAA)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2)format("woff2-variations");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-divide-y-reverse:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:"Hanken Grotesk Variable", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;--font-mono:"JetBrains Mono Variable", "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-3xl:48rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-normal:0em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#1b1b1a;--color-panel:#211f1d;--color-panel-2:#262422;--color-border:#2b2927;--color-border-strong:#3a3835;--color-fg:#e8e6e2;--color-fg-muted:#a9a59e;--color-fg-faint:#837f78;--color-ok:#4fbf6b;--color-warn:#e0a33c;--color-danger:#ff8080;--color-info:#feb157;--color-accent:#feb157;--color-accent-strong:#ffcb85;--color-premium:#4d5cf0;--color-premium-strong:#6f7bff;--shadow-panel:0 12px 32px -18px #000000a6;--radius-panel:6px;--animate-flash:flash .15s ease-out}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.-top-1{top:calc(var(--spacing) * -1)}.-top-4{top:calc(var(--spacing) * -4)}.-top-\[7px\]{top:-7px}.top-0{top:0}.top-7{top:calc(var(--spacing) * 7)}.top-full{top:100%}.right-0{right:0}.right-3{right:calc(var(--spacing) * 3)}.bottom-0{bottom:0}.left-0{left:0}.left-0\.5{left:calc(var(--spacing) * .5)}.left-1\/2{left:50%}.left-3{left:calc(var(--spacing) * 3)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-auto{margin-top:auto}.-mr-1{margin-right:calc(var(--spacing) * -1)}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.h-0\.5{height:calc(var(--spacing) * .5)}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-\[2px\]{height:2px}.h-\[14px\]{height:14px}.h-\[44px\]{height:44px}.h-\[70vh\]{height:70vh}.h-\[92px\]{height:92px}.h-\[168px\]{height:168px}.h-full{height:100%}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[40vh\]{max-height:40vh}.max-h-\[50vh\]{max-height:50vh}.max-h-\[70vh\]{max-height:70vh}.max-h-\[76vh\]{max-height:76vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[82vh\]{max-height:82vh}.max-h-\[420px\]{max-height:420px}.min-h-\[60px\]{min-height:60px}.min-h-\[70px\]{min-height:70px}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-36{width:calc(var(--spacing) * 36)}.w-44{width:calc(var(--spacing) * 44)}.w-\[268px\]{width:268px}.w-\[420px\]{width:420px}.w-\[440px\]{width:440px}.w-\[520px\]{width:520px}.w-\[560px\]{width:560px}.w-\[820px\]{width:820px}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-\[12ch\]{max-width:12ch}.max-w-\[50\%\]{max-width:50%}.max-w-\[52ch\]{max-width:52ch}.max-w-\[52rem\]{max-width:52rem}.max-w-\[60ch\]{max-width:60ch}.max-w-\[92vw\]{max-width:92vw}.max-w-\[94vw\]{max-width:94vw}.max-w-\[220px\]{max-width:220px}.max-w-\[520px\]{max-width:520px}.max-w-\[560px\]{max-width:560px}.max-w-\[620px\]{max-width:620px}.max-w-\[660px\]{max-width:660px}.max-w-\[720px\]{max-width:720px}.max-w-\[1600px\]{max-width:1600px}.max-w-full{max-width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[1px\]{--tw-translate-y:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-flash{animation:var(--animate-flash)}.animate-pulse{animation:var(--animate-pulse)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-y{resize:vertical}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[1fr_128px_auto\]{grid-template-columns:1fr 128px auto}.grid-cols-\[1fr_auto\]{grid-template-columns:1fr auto}.grid-cols-\[132px_1fr_92px_104px\]{grid-template-columns:132px 1fr 92px 104px}.grid-cols-\[auto_auto_1fr_auto\]{grid-template-columns:auto auto 1fr auto}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.content-start{align-content:flex-start}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-items-start{justify-items:start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-\[3px\]{gap:3px}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-x-8{column-gap:calc(var(--spacing) * 8)}.gap-y-1{row-gap:var(--spacing)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}.gap-y-5{row-gap:calc(var(--spacing) * 5)}.gap-y-6{row-gap:calc(var(--spacing) * 6)}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--color-border)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[2px\]{border-radius:2px}.rounded-\[3px\]{border-radius:3px}.rounded-\[5px\]{border-radius:5px}.rounded-\[var\(--radius-panel\)\]{border-radius:var(--radius-panel)}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-t-\[var\(--radius-panel\)\]{border-top-left-radius:var(--radius-panel);border-top-right-radius:var(--radius-panel)}.rounded-t-sm{border-top-left-radius:var(--radius-sm);border-top-right-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-accent{border-color:var(--color-accent)}.border-accent\/35{border-color:#feb15759}@supports (color:color-mix(in lab, red, red)){.border-accent\/35{border-color:color-mix(in oklab, var(--color-accent) 35%, transparent)}}.border-accent\/40{border-color:#feb15766}@supports (color:color-mix(in lab, red, red)){.border-accent\/40{border-color:color-mix(in oklab, var(--color-accent) 40%, transparent)}}.border-accent\/45{border-color:#feb15773}@supports (color:color-mix(in lab, red, red)){.border-accent\/45{border-color:color-mix(in oklab, var(--color-accent) 45%, transparent)}}.border-accent\/50{border-color:#feb15780}@supports (color:color-mix(in lab, red, red)){.border-accent\/50{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.border-accent\/60{border-color:#feb15799}@supports (color:color-mix(in lab, red, red)){.border-accent\/60{border-color:color-mix(in oklab, var(--color-accent) 60%, transparent)}}.border-border{border-color:var(--color-border)}.border-border-strong{border-color:var(--color-border-strong)}.border-border\/60{border-color:#2b292799}@supports (color:color-mix(in lab, red, red)){.border-border\/60{border-color:color-mix(in oklab, var(--color-border) 60%, transparent)}}.border-danger\/40{border-color:#ff808066}@supports (color:color-mix(in lab, red, red)){.border-danger\/40{border-color:color-mix(in oklab, var(--color-danger) 40%, transparent)}}.border-danger\/50{border-color:#ff808080}@supports (color:color-mix(in lab, red, red)){.border-danger\/50{border-color:color-mix(in oklab, var(--color-danger) 50%, transparent)}}.border-ok\/40{border-color:#4fbf6b66}@supports (color:color-mix(in lab, red, red)){.border-ok\/40{border-color:color-mix(in oklab, var(--color-ok) 40%, transparent)}}.border-premium\/60{border-color:#4d5cf099}@supports (color:color-mix(in lab, red, red)){.border-premium\/60{border-color:color-mix(in oklab, var(--color-premium) 60%, transparent)}}.border-transparent{border-color:#0000}.border-warn\/40{border-color:#e0a33c66}@supports (color:color-mix(in lab, red, red)){.border-warn\/40{border-color:color-mix(in oklab, var(--color-warn) 40%, transparent)}}.border-warn\/50{border-color:#e0a33c80}@supports (color:color-mix(in lab, red, red)){.border-warn\/50{border-color:color-mix(in oklab, var(--color-warn) 50%, transparent)}}.border-l-accent{border-left-color:var(--color-accent)}.bg-accent{background-color:var(--color-accent)}.bg-accent\/5{background-color:#feb1570d}@supports (color:color-mix(in lab, red, red)){.bg-accent\/5{background-color:color-mix(in oklab, var(--color-accent) 5%, transparent)}}.bg-accent\/10{background-color:#feb1571a}@supports (color:color-mix(in lab, red, red)){.bg-accent\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.bg-accent\/15{background-color:#feb15726}@supports (color:color-mix(in lab, red, red)){.bg-accent\/15{background-color:color-mix(in oklab, var(--color-accent) 15%, transparent)}}.bg-accent\/25{background-color:#feb15740}@supports (color:color-mix(in lab, red, red)){.bg-accent\/25{background-color:color-mix(in oklab, var(--color-accent) 25%, transparent)}}.bg-accent\/40{background-color:#feb15766}@supports (color:color-mix(in lab, red, red)){.bg-accent\/40{background-color:color-mix(in oklab, var(--color-accent) 40%, transparent)}}.bg-accent\/50{background-color:#feb15780}@supports (color:color-mix(in lab, red, red)){.bg-accent\/50{background-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.bg-accent\/70{background-color:#feb157b3}@supports (color:color-mix(in lab, red, red)){.bg-accent\/70{background-color:color-mix(in oklab, var(--color-accent) 70%, transparent)}}.bg-accent\/75{background-color:#feb157bf}@supports (color:color-mix(in lab, red, red)){.bg-accent\/75{background-color:color-mix(in oklab, var(--color-accent) 75%, transparent)}}.bg-accent\/\[0\.07\]{background-color:#feb15712}@supports (color:color-mix(in lab, red, red)){.bg-accent\/\[0\.07\]{background-color:color-mix(in oklab, var(--color-accent) 7.0%, transparent)}}.bg-accent\/\[0\.08\]{background-color:#feb15714}@supports (color:color-mix(in lab, red, red)){.bg-accent\/\[0\.08\]{background-color:color-mix(in oklab, var(--color-accent) 8%, transparent)}}.bg-bg{background-color:var(--color-bg)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-border\/60{background-color:#2b292799}@supports (color:color-mix(in lab, red, red)){.bg-border\/60{background-color:color-mix(in oklab, var(--color-border) 60%, transparent)}}.bg-danger{background-color:var(--color-danger)}.bg-danger\/10{background-color:#ff80801a}@supports (color:color-mix(in lab, red, red)){.bg-danger\/10{background-color:color-mix(in oklab, var(--color-danger) 10%, transparent)}}.bg-fg-faint{background-color:var(--color-fg-faint)}.bg-fg-faint\/25{background-color:#837f7840}@supports (color:color-mix(in lab, red, red)){.bg-fg-faint\/25{background-color:color-mix(in oklab, var(--color-fg-faint) 25%, transparent)}}.bg-fg-faint\/30{background-color:#837f784d}@supports (color:color-mix(in lab, red, red)){.bg-fg-faint\/30{background-color:color-mix(in oklab, var(--color-fg-faint) 30%, transparent)}}.bg-ok{background-color:var(--color-ok)}.bg-ok\/10{background-color:#4fbf6b1a}@supports (color:color-mix(in lab, red, red)){.bg-ok\/10{background-color:color-mix(in oklab, var(--color-ok) 10%, transparent)}}.bg-panel{background-color:var(--color-panel)}.bg-panel-2{background-color:var(--color-panel-2)}.bg-panel-2\/30{background-color:#2624224d}@supports (color:color-mix(in lab, red, red)){.bg-panel-2\/30{background-color:color-mix(in oklab, var(--color-panel-2) 30%, transparent)}}.bg-panel-2\/50{background-color:#26242280}@supports (color:color-mix(in lab, red, red)){.bg-panel-2\/50{background-color:color-mix(in oklab, var(--color-panel-2) 50%, transparent)}}.bg-panel-2\/60{background-color:#26242299}@supports (color:color-mix(in lab, red, red)){.bg-panel-2\/60{background-color:color-mix(in oklab, var(--color-panel-2) 60%, transparent)}}.bg-panel\/40{background-color:#211f1d66}@supports (color:color-mix(in lab, red, red)){.bg-panel\/40{background-color:color-mix(in oklab, var(--color-panel) 40%, transparent)}}.bg-panel\/70{background-color:#211f1db3}@supports (color:color-mix(in lab, red, red)){.bg-panel\/70{background-color:color-mix(in oklab, var(--color-panel) 70%, transparent)}}.bg-panel\/95{background-color:#211f1df2}@supports (color:color-mix(in lab, red, red)){.bg-panel\/95{background-color:color-mix(in oklab, var(--color-panel) 95%, transparent)}}.bg-premium{background-color:var(--color-premium)}.bg-premium-strong{background-color:var(--color-premium-strong)}.bg-premium\/75{background-color:#4d5cf0bf}@supports (color:color-mix(in lab, red, red)){.bg-premium\/75{background-color:color-mix(in oklab, var(--color-premium) 75%, transparent)}}.bg-transparent{background-color:#0000}.bg-warn{background-color:var(--color-warn)}.bg-warn\/10{background-color:#e0a33c1a}@supports (color:color-mix(in lab, red, red)){.bg-warn\/10{background-color:color-mix(in oklab, var(--color-warn) 10%, transparent)}}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-panel{--tw-gradient-from:var(--color-panel);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-\[1px\]{padding-block:1px}.py-\[3px\]{padding-block:3px}.py-px{padding-block:1px}.pt-1{padding-top:var(--spacing)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-16{padding-top:calc(var(--spacing) * 16)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pt-\[10vh\]{padding-top:10vh}.pt-\[12vh\]{padding-top:12vh}.pt-\[14vh\]{padding-top:14vh}.pr-1{padding-right:var(--spacing)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:var(--spacing)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-1{padding-left:var(--spacing)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-3\.5{padding-left:calc(var(--spacing) * 3.5)}.pl-5{padding-left:calc(var(--spacing) * 5)}.pl-7{padding-left:calc(var(--spacing) * 7)}.pl-\[7\.5rem\]{padding-left:7.5rem}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[22px\]{font-size:22px}.text-\[24px\]{font-size:24px}.text-\[34px\]{font-size:34px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-\[1\.1\]{--tw-leading:1.1;line-height:1.1}.leading-\[1\.4\]{--tw-leading:1.4;line-height:1.4}.leading-\[1\.05\]{--tw-leading:1.05;line-height:1.05}.leading-\[1\.35\]{--tw-leading:1.35;line-height:1.35}.leading-\[1\.45\]{--tw-leading:1.45;line-height:1.45}.leading-\[1\.55\]{--tw-leading:1.55;line-height:1.55}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.01em\]{--tw-tracking:-.01em;letter-spacing:-.01em}.tracking-\[0\.08em\]{--tw-tracking:.08em;letter-spacing:.08em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--color-accent)}.text-bg{color:var(--color-bg)}.text-danger{color:var(--color-danger)}.text-fg{color:var(--color-fg)}.text-fg-faint{color:var(--color-fg-faint)}.text-fg-muted{color:var(--color-fg-muted)}.text-info{color:var(--color-info)}.text-ok{color:var(--color-ok)}.text-panel{color:var(--color-panel)}.text-premium-strong{color:var(--color-premium-strong)}.text-warn{color:var(--color-warn)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.accent-\[var\(--color-accent\)\]{accent-color:var(--color-accent)}.opacity-35{opacity:.35}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.shadow-\[0_2px_12px_var\(--color-bg\)\]{--tw-shadow:0 2px 12px var(--tw-shadow-color,var(--color-bg));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[var\(--shadow-panel\)\]{--tw-shadow:var(--shadow-panel);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-accent{--tw-ring-color:var(--color-accent)}.ring-offset-1{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.ring-offset-panel{--tw-ring-offset-color:var(--color-panel)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}@media (hover:hover){.group-hover\:text-accent-strong:is(:where(.group):hover *){color:var(--color-accent-strong)}.group-hover\:text-fg:is(:where(.group):hover *){color:var(--color-fg)}}.marker\:content-none ::marker{--tw-content:none;content:none}.marker\:content-none::marker{--tw-content:none;content:none}.marker\:content-none ::-webkit-details-marker{--tw-content:none;content:none}.marker\:content-none::-webkit-details-marker{--tw-content:none;content:none}.first\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}@media (hover:hover){.hover\:border-accent\/50:hover{border-color:#feb15780}@supports (color:color-mix(in lab, red, red)){.hover\:border-accent\/50:hover{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.hover\:border-border-strong:hover{border-color:var(--color-border-strong)}.hover\:bg-accent\/20:hover{background-color:#feb15733}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/20:hover{background-color:color-mix(in oklab, var(--color-accent) 20%, transparent)}}.hover\:bg-accent\/25:hover{background-color:#feb15740}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/25:hover{background-color:color-mix(in oklab, var(--color-accent) 25%, transparent)}}.hover\:bg-accent\/90:hover{background-color:#feb157e6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/90:hover{background-color:color-mix(in oklab, var(--color-accent) 90%, transparent)}}.hover\:bg-accent\/\[0\.16\]:hover{background-color:#feb15729}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/\[0\.16\]:hover{background-color:color-mix(in oklab, var(--color-accent) 16%, transparent)}}.hover\:bg-danger\/10:hover{background-color:#ff80801a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-danger\/10:hover{background-color:color-mix(in oklab, var(--color-danger) 10%, transparent)}}.hover\:bg-ok\/10:hover{background-color:#4fbf6b1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-ok\/10:hover{background-color:color-mix(in oklab, var(--color-ok) 10%, transparent)}}.hover\:bg-panel:hover{background-color:var(--color-panel)}.hover\:bg-panel-2:hover{background-color:var(--color-panel-2)}.hover\:bg-panel-2\/50:hover{background-color:#26242280}@supports (color:color-mix(in lab, red, red)){.hover\:bg-panel-2\/50:hover{background-color:color-mix(in oklab, var(--color-panel-2) 50%, transparent)}}.hover\:bg-premium:hover{background-color:var(--color-premium)}.hover\:bg-premium\/10:hover{background-color:#4d5cf01a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-premium\/10:hover{background-color:color-mix(in oklab, var(--color-premium) 10%, transparent)}}.hover\:bg-warn\/20:hover{background-color:#e0a33c33}@supports (color:color-mix(in lab, red, red)){.hover\:bg-warn\/20:hover{background-color:color-mix(in oklab, var(--color-warn) 20%, transparent)}}.hover\:text-accent:hover{color:var(--color-accent)}.hover\:text-accent-strong:hover{color:var(--color-accent-strong)}.hover\:text-fg:hover{color:var(--color-fg)}.hover\:text-fg-muted:hover{color:var(--color-fg-muted)}.hover\:no-underline:hover{text-decoration-line:none}.hover\:underline:hover{text-decoration-line:underline}.hover\:brightness-110:hover{--tw-brightness:brightness(110%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-default:disabled{cursor:default}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:inline{display:inline}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}:where(.sm\:divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.sm\:divide-y-0>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(0px * var(--tw-divide-y-reverse));border-bottom-width:calc(0px * calc(1 - var(--tw-divide-y-reverse)))}}@media (width>=48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (width>=64rem){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.lg\:grid-cols-\[1\.4fr_1fr_1fr_1fr_1fr_1fr\]{grid-template-columns:1.4fr 1fr 1fr 1fr 1fr 1fr}.lg\:grid-cols-\[minmax\(0\,1fr\)_260px\]{grid-template-columns:minmax(0,1fr) 260px}}@media (width>=80rem){.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}}[data-theme=light]{--color-bg:#faf9f7;--color-panel:#fff;--color-panel-2:#f2f0ec;--color-border:#e6e2db;--color-border-strong:#c9c3b8;--color-fg:#24211c;--color-fg-muted:#5f5a51;--color-fg-faint:#8a8479;--color-ok:#2e9e4f;--color-warn:#9a6700;--color-danger:#d64545;--color-info:#b8730d;--color-accent:#b8730d;--color-accent-strong:#8f5808;--color-premium:#3341d8;--color-premium-strong:#232fb0;--shadow-panel:0 8px 20px -14px #3c321e38}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;background:var(--color-bg);color:var(--color-fg);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;font-size:16px;line-height:1.45}[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}.num,.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1, "zero" 1}*{border-color:var(--color-border)}a:where(:not([class*=text-])){color:var(--color-info)}a{text-decoration:none}a.link:hover{text-decoration:underline}::selection{background:#feb15759}@supports (color:color-mix(in lab, red, red)){::selection{background:color-mix(in srgb, var(--color-accent) 35%, transparent)}}.graph-dot{transition:fill .45s}.graph-gate{transition:fill .45s,stroke .45s}.graph-verified{transform-box:fill-box;transform-origin:50%;animation:.55s cubic-bezier(.2,.7,.2,1) verifyPop}@keyframes verifyPop{0%{transform:scale(1)}40%{transform:scale(1.55)}to{transform:scale(1)}}.graph-breathe{transform-box:fill-box;transform-origin:50%;animation:2.8s ease-in-out infinite graphBreathe}@keyframes graphBreathe{0%,to{opacity:.9}50%{opacity:1;filter:drop-shadow(0 0 3px color-mix(in srgb, var(--color-ok) 55%, transparent))}}@media (prefers-reduced-motion:reduce){.graph-dot,.graph-gate{transition:none}.graph-verified,.graph-breathe{animation:none}}*{scrollbar-width:thin;scrollbar-color:var(--color-border-strong) transparent}.stale-dot{background:var(--color-warn);border-radius:9999px;width:6px;height:6px;display:inline-block}.input{background:var(--color-panel-2);border:1px solid var(--color-border-strong);color:var(--color-fg);font-family:var(--font-mono);border-radius:3px;width:100%;padding:4px 8px;font-size:12px}.input:focus{outline:1px solid var(--color-accent);border-color:var(--color-accent)}.skeleton-pulse{animation:1.4s ease-in-out infinite skeletonPulse}@keyframes skeletonPulse{0%,to{opacity:.5}50%{opacity:.9}}@media (prefers-reduced-motion:reduce){.skeleton-pulse{opacity:.6;animation:none}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}@keyframes flash{0%{background-color:color-mix(in srgb, var(--color-accent) 22%, transparent)}to{background-color:#0000}}.xterm{cursor:text;-webkit-user-select:none;user-select:none;position:relative}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{z-index:5;position:absolute;top:0}.xterm .xterm-helper-textarea{opacity:0;z-index:-5;white-space:nowrap;resize:none;border:0;width:0;height:0;margin:0;padding:0;position:absolute;top:0;left:-9999em;overflow:hidden}.xterm .composition-view{color:#fff;white-space:nowrap;z-index:1;background:#000;display:none;position:absolute}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{cursor:default;background-color:#000;position:absolute;inset:0;overflow-y:scroll}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;top:0;left:0}.xterm-char-measure-element{visibility:hidden;line-height:normal;display:inline-block;position:absolute;top:0;left:-9999em}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{z-index:10;color:#0000;pointer-events:none;position:absolute;inset:0}.xterm .xterm-accessibility-tree:not(.debug) ::selection{color:#0000}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre;font-family:monospace}.xterm .xterm-accessibility-tree>div{transform-origin:0;width:fit-content}.xterm .live-region{width:1px;height:1px;position:absolute;left:-9999px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:underline double;text-decoration:underline double}.xterm-underline-3{-webkit-text-decoration:underline wavy;text-decoration:underline wavy}.xterm-underline-4{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.xterm-underline-5{-webkit-text-decoration:underline dashed;text-decoration:underline dashed}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:underline overline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;pointer-events:none;position:absolute;top:0;right:0}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;z-index:11;background:0 0;transition:opacity .1s linear}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{display:none;position:absolute}.xterm .xterm-scrollable-element>.shadow.top{width:100%;height:3px;box-shadow:var(--vscode-scrollbar-shadow,#000) 0 6px 6px -6px inset;display:block;top:0;left:3px}.xterm .xterm-scrollable-element>.shadow.left{width:3px;height:100%;box-shadow:var(--vscode-scrollbar-shadow,#000) 6px 0 6px -6px inset;display:block;top:3px;left:0}.xterm .xterm-scrollable-element>.shadow.top-left-corner{width:3px;height:3px;display:block;top:0;left:0}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow,#000) 6px 0 6px -6px inset} diff --git a/internal/api/dist/assets/index-shYzKSwp.css b/internal/api/dist/assets/index-shYzKSwp.css deleted file mode 100644 index 7a66412..0000000 --- a/internal/api/dist/assets/index-shYzKSwp.css +++ /dev/null @@ -1 +0,0 @@ -@font-face{font-family:Hanken Grotesk Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(data:font/woff2;base64,d09GMgABAAAAAAaEABMAAAAADFgAAAYdAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbbhwoP0hWQVJpBmA/U1RBVIE4AFwvbBEICoJ8gkMLFAAwhCoBNgIkAyIEIAWGUAdiDAcbvgpRVHJOI/viwCYyfSFrJjFIG8raYpYj9+IeSF0s6zD+Lk/4OGrZHhHV+wvt2ffuWPwlA51lIICIosSVmyOKEs5Uzlx3NKeXIgn1ssCydUybDV0IHga+SszIyfrQe9bLTFNxjayzgs76hNsDoSYtRe32fiJ4gxBjrP8L+w//zzHjv7Yqyr9o2vOBDXhCo2jMtr4uwAK/gV1U0PxAq/EAD+yW9EoKOL1KLw8rHrFgCSgRTQRzBzpeXVhweEDlyfY8gIoOa2CQJzrTAHIIoitTMVV2dyFwpJ2iAEQTpSkhPitxD3YwuZHEagTcAhyKAcBmUyPdhTovJThOw6HYiaF2M/J7erdi2OUutor6ES6Ac88AvfZvKpb6fJoArohb524042j6Jij36NI7P8Pb7s721naN9gcTtcjXQP4l+8BKEzFVGMxxoHqlq8Ul4LGneFJBDFaOdKpLPcg8P14YSDwIcn75hdlyJLTBlZ4voL6tT46yC/njunXqpJ0/bSvmrH1o3kRlwZ+j0DBogkF3KbDRVBlbOc+fY5HVXwPoT9hfekPnyZMaEmenYLMSg5npqegFOsgXsBv1IoF9aIVfSCNHkk6+gIzILsiYuhWQCfUtZEpbkRntQxBZgw7MwFbMcRvwJrAnBlDqs7isLtL7pO84Xru1i7ah7tckH1Wreqq6K9u0amxU1bcff/s2Y1ni3rh2I8zHzqkm3PGvv3mzC6NDBz/UcOBIg+nm88rxN8MbdtypvHUL5o1c2zG0urYpRmW+VHZdiba6GXN/3v0B3i3nt4RBsbfAu8ftLqRcTIlZ4VYheFTAS5nXLS65VZrbuW3daF2Ze1ChyGXWZN6u9nUuH1LfyTERifZXEpIueMe28vF8FOoTnsONzw+1djo9P71lZGx1vM8mH/BhvSa2HDsRZ1+Ul+RmpnPOIaEuwWnZZdkgQWAAyCDDZ1wk+0sh7wseAAwA6UlHxbftCgYAAwKAgwIAEA7ACfHIRbV7J6dwF/ZzcRRmAjXUYKAGWAlDCCFmKnH+LJEQfHKEmVrfmKwSEab36AcubXQBoDYJV/aRV+funFD8wAXLSLYbwr9+DR+h/qZIKCfeqRG5ghHpdY0zcV2nuz5iJMhAFjaTDwOcoyKGG9JHrCfdp4cC+kCvUrxc7+bliIMiHj95sPIbUeWZEP/HLnN2tlr9EBeRiktHuWvErx98fRz1MuEvHO3FDRgtsSzL/P0hsDLK2n5/uHMOjvTst0HD6t+80ZN798j7j//kjqHxIOZDFPR/FxurFD6/HxGbB799RPHLx5F89MoBOub9jVuOWtmPH3o9H3r26DIuff+LqPLwff/xryDRmiAYmjxiK0GwS9XU+k8QpUrHsCTs4qH89Fv44ubWbQmOE51M7J8Pt8+h+NKt3zZpa2L9zZqcRlyEc4MaNGdfjQCxgIygn78ne4yAzcLWA3zAJ6RRGbijvHr1W+XN8ywrG0EoZSySb0/A9KsllI7Q/Pq8hLu76tfTy5cF4X8bQxTtYp2vr6/+1oI4AhgAlNYFryt62VaX9ktO6VsAeDLeWx6fff4vdV1ts7N6+gw9GCsQnqPB0QUttB9nEc7Aaf4XM0NQ90VJ+HV1rG04znGCmXcpPCA9+nxdMPgPlT7Dz83NMfZuMJaNeRqbc+tjd2QER/b0B44d7nv5Rif7VC8svYkx9SKWwb3YzN2M3cY8jSNLl+PYZqfjxNTxOLXVCmfmduDc0ty1kLbjeiGfIrDFJXWPTTMD5TKupR8cpZgJeXTofId8NoUj6E8XfAc2k4WPdbCberDYAp8Q7L5dUo8wE8cs9QINZYvwXKzvBS4v/n+fQZkGrrFysKEIuFBgjQpxiHH1XA+ZBI+C+oAoxhYKECc42rGOc8L4mYhsiThGfFjOcKmFubPpDgwnY1918Fwo8ouenDJxvGP96HFWJ28hiOy251oKjkcbGz2POMme8CTMThx6wqOPsFtPI6j6HhDyDTxFQYnL88FcXGAGHl3ZuueRbEuxbK6Hc84ZDvRrREtLzyjj8Xkd/uShR1b0sYd8Nh8/c8znxCnadxQcf2nFVWIyw1g+4StXav9j75s+CQAA)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Hanken Grotesk Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/hanken-grotesk-vietnamese-wght-normal-CHiFlh_0.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Hanken Grotesk Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/hanken-grotesk-latin-ext-wght-normal-Dg-wlmqe.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Hanken Grotesk Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/hanken-grotesk-latin-wght-normal-CaVRRdDk.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAfsABQAAAAAEAwAAAeCAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoP0hWQVJbBmA/U1RBVIFiJyYAdC9qEQgKhGSEAAsgADCGCAE2AiQDOgQgBYlMB4EUDAcbLQ4onoexrSC/2ZyLAa8p8VHB8/x3Vue+V0hVJalMJg2nx/TCrQXxBeqLjQG7FyM1WEa/X1tEXN7cFz9EJEMmMUz3RihWSSKeQCbcIou0izz/C8v+fq3VfajEa9gDD11CImXS7qL/RJFVzC1qiB6KmKeD6TZdQ6IRGv78dL6uSVVCfgni5mzu7kcgQBgAEAQTQRCoL++STTYybkJxNfQxAAIAGu8OdEB9teW2jh4BpgDqFjAeSEByW3zFP0CBBgNMsMCGEDjgggdhiEAUAeIIED7ABTDUEnkIE9Q9ahFgKttcVhApo4ACB4qobHaccgDfEjFO6aaWUhjMLt2SyIvHKoDqoA4CSUwEIYQCEjhAO9R1G6keDeDZGjNo+AhxOjCEGTr1WeIF3kYBiLAOKvkJSMiKX0VdAyQt3SDJClCkxJCHkCzfqyVTriJZLcolS32JZHUekq2TYNkYtCtjYHMQXSxGjXDz2t/yLWXzDzxz+o3zFwDEaN23F+13pyMdQAEaSKAR9vcGq4A4MTSKCElGW+M7UcY7xqkggITb28ZJhlqc9q2twYKTt0NjixBgYvO9BIihEBLYuOFXQzfIQ7dXGUEEEgFDooBfAzqiQbpJrhiWSuKJCRFKYbHCyJKI2G5GiZbNAvgAu5pc3vwx4G+g3aDkhklABiSz0BICXrYghtYhx/cdJ+44rY2oZ0aMNRFz3VZjb6W33F3gzltqtOCV8tTHSpOeXuItfvr5lCdfzFpqtEitvqdcdGGFd28ZqqC0tPbeChGXgrIlnhSWu/eUso4uKWFLugyDzQJhflY4659+WjQ++6x72WUMv9G8mw6QJl7BVxX5fe/kpUsOvnZwee9uQ0cGXYd0o89XB2748sDSnt8d2VphdOTTgceDVvOds0v9P/s7HPq15aGun/6Vllb56f1dl0t1LejqrNkpdRZsG8TOnM5vkBG5oiVyVGnS8LHps5cfNWJs6qKPfaNSxiQNBUm3cKNWROr0GSur7Za31k1vieq7LH11VF+jXdRIasRKflc7jkobm1Z9te1IyZA0pDkhLR98+H37Zf1c/8at+dB7x+7GfVyTfJMPiYztsnl59Y5l4j+0n1RXlpHnF3Tq7HecmNF/CJodEMAikruxiyJaGLvHOdAfoA+oDvpjBm2b91cHGRZMU9n25xEU0A8fgEEAdKI3Q1iDtc034sug5YVMkE2jsE+BIkwSoQ3gxXMqz9tELp48bd0cFKOKS7xYjEuXBnZP5ia7DyiO/X/YI+PQSbt2uSdqAkWL9nQbV1XB94/+uPfdZz8dnXYFBYrcTl2SIR/ybxJNJPz/Gupb0JaZeens2ekC7EKr8t+Ls/P5VJPYJdHKyqfg2nqU6bhlidzcddQV/7MmecTzJ5VPcKXkNKSEogHjYFx6QZ7rQ+FSe8njaiNuOnXS8H2ScQ619c2mC3VTtauL0rRbXd/CkSOP37FY9Zkjz8+GibYUMOEWF+RdrFS8Ecv1SHOpPUPZGEIpjPvFyU5cXKjd6OXqorTqy9GwRd++HVufPGnVsW+aO3vggKZ18jR9sXaTC1PWTEsVUaK0FkNySbTQDqlm2PfDjZcu4aalnSLKjnOoYQ0nUlqqXcGpPu/4VgV/xU2pAqW4BW3qzhQ8/hFKhV2qE3+BKAtDqBXjfgnVdH4y0wg5tbVNRenNdTWOrenWLcupQdmsbq5b+18piTe/xRdp1xbILxNPJGInm2z6hoB21Lal0i+ePTtd7B45+3XhFJ329evskXm7qurUVREotqSluSo/L29d3qDhI4YOQqWhI4YNvBNfsMHeXKemXrxQfKeuPOGRVayA3JtkJKEgbPp+dXUDluddutRYLFoXGXWX6N3WFaGLbQtRSitVYNacTNSdy7AaG/HSaUEANcBoGXNdcZvZsOqQ1icBDv21/gzAoYPHH/WDW0qNR3QTYKEAEHig6o13NXbND06CQPlRtYjGNnSktRc09k1mAMDvAlDKfQjgy6fssInlfzmNAjKkDxoxHOBLdVRAIVt9j4qo+hA1w9T1aNBNTUOTTNUHLbqokE+UAfJXCIGw/IxCSL5GRUJeR40rL/UxTm4Q08H6MbCs70ObuNyIIXrINHQYInF06UUlevTjbQzTh5upiDMzMMogUtEnjPs/Y7jAHCJeB0GBHh04tC6FiB6ZFB1oArUSIoFoqhzCeAN6lHwm0T4C3VVPWvjpSMXReuWesMEcoqrmgtNBGd2noWeV0hNAz9rFeShNJxHGsPa3HXeKTk8b55hahySYHaYKKFFLpCfN8rsoaJn01CR04Gkc+5k7KVTCmClX8Q10HCrUEkVlSX+XO33oQR9609tJ516H497WSobWs5Up6TLaS10/dessIskgJSLiDlWvHVUywpkQ7hdPZqGyiEF0uVQerVcPamT1A3eKXdyI1vG9OoflrSXihZ1qqGE3nhmAgiIbRCQgPLEPtOM3UQwTLYaYYomNlpA44opnjV6jkD6id80OOrzf6BzmMD6eEa1zKyeYG1fzfEf16V6jw9XYOaar1/b2kP/IYX8oR2mcFvv2GtBV3JXgd437AQAA)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2)format("woff2-variations");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-divide-y-reverse:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:"Hanken Grotesk Variable", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;--font-mono:"JetBrains Mono Variable", "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-3xl:48rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-normal:0em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#1b1b1a;--color-panel:#211f1d;--color-panel-2:#262422;--color-border:#2b2927;--color-border-strong:#3a3835;--color-fg:#e8e6e2;--color-fg-muted:#a9a59e;--color-fg-faint:#837f78;--color-ok:#4fbf6b;--color-warn:#e0a33c;--color-danger:#ff8080;--color-info:#feb157;--color-accent:#feb157;--color-accent-strong:#ffcb85;--color-premium:#4d5cf0;--color-premium-strong:#6f7bff;--shadow-panel:0 12px 32px -18px #000000a6;--radius-panel:6px;--animate-flash:flash .15s ease-out}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.-top-1{top:calc(var(--spacing) * -1)}.-top-4{top:calc(var(--spacing) * -4)}.-top-\[7px\]{top:-7px}.top-0{top:0}.top-7{top:calc(var(--spacing) * 7)}.top-full{top:100%}.right-0{right:0}.right-3{right:calc(var(--spacing) * 3)}.bottom-0{bottom:0}.left-0{left:0}.left-0\.5{left:calc(var(--spacing) * .5)}.left-1\/2{left:50%}.left-3{left:calc(var(--spacing) * 3)}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-auto{margin-top:auto}.-mr-1{margin-right:calc(var(--spacing) * -1)}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.h-0\.5{height:calc(var(--spacing) * .5)}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-\[2px\]{height:2px}.h-\[14px\]{height:14px}.h-\[44px\]{height:44px}.h-\[70vh\]{height:70vh}.h-\[92px\]{height:92px}.h-\[168px\]{height:168px}.h-full{height:100%}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[40vh\]{max-height:40vh}.max-h-\[50vh\]{max-height:50vh}.max-h-\[70vh\]{max-height:70vh}.max-h-\[76vh\]{max-height:76vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[82vh\]{max-height:82vh}.max-h-\[420px\]{max-height:420px}.min-h-\[60px\]{min-height:60px}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-36{width:calc(var(--spacing) * 36)}.w-44{width:calc(var(--spacing) * 44)}.w-\[268px\]{width:268px}.w-\[420px\]{width:420px}.w-\[440px\]{width:440px}.w-\[520px\]{width:520px}.w-\[560px\]{width:560px}.w-\[820px\]{width:820px}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-\[12ch\]{max-width:12ch}.max-w-\[50\%\]{max-width:50%}.max-w-\[52ch\]{max-width:52ch}.max-w-\[52rem\]{max-width:52rem}.max-w-\[60ch\]{max-width:60ch}.max-w-\[92vw\]{max-width:92vw}.max-w-\[94vw\]{max-width:94vw}.max-w-\[220px\]{max-width:220px}.max-w-\[520px\]{max-width:520px}.max-w-\[560px\]{max-width:560px}.max-w-\[620px\]{max-width:620px}.max-w-\[660px\]{max-width:660px}.max-w-\[720px\]{max-width:720px}.max-w-\[1600px\]{max-width:1600px}.max-w-full{max-width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[1px\]{--tw-translate-y:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-flash{animation:var(--animate-flash)}.animate-pulse{animation:var(--animate-pulse)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-y{resize:vertical}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[1fr_128px_auto\]{grid-template-columns:1fr 128px auto}.grid-cols-\[1fr_auto\]{grid-template-columns:1fr auto}.grid-cols-\[132px_1fr_92px_104px\]{grid-template-columns:132px 1fr 92px 104px}.grid-cols-\[auto_auto_1fr_auto\]{grid-template-columns:auto auto 1fr auto}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.content-start{align-content:flex-start}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-items-start{justify-items:start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-\[3px\]{gap:3px}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-x-8{column-gap:calc(var(--spacing) * 8)}.gap-y-1{row-gap:var(--spacing)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}.gap-y-5{row-gap:calc(var(--spacing) * 5)}.gap-y-6{row-gap:calc(var(--spacing) * 6)}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--color-border)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[2px\]{border-radius:2px}.rounded-\[3px\]{border-radius:3px}.rounded-\[5px\]{border-radius:5px}.rounded-\[var\(--radius-panel\)\]{border-radius:var(--radius-panel)}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-t-\[var\(--radius-panel\)\]{border-top-left-radius:var(--radius-panel);border-top-right-radius:var(--radius-panel)}.rounded-t-sm{border-top-left-radius:var(--radius-sm);border-top-right-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-accent{border-color:var(--color-accent)}.border-accent\/35{border-color:#feb15759}@supports (color:color-mix(in lab, red, red)){.border-accent\/35{border-color:color-mix(in oklab, var(--color-accent) 35%, transparent)}}.border-accent\/40{border-color:#feb15766}@supports (color:color-mix(in lab, red, red)){.border-accent\/40{border-color:color-mix(in oklab, var(--color-accent) 40%, transparent)}}.border-accent\/45{border-color:#feb15773}@supports (color:color-mix(in lab, red, red)){.border-accent\/45{border-color:color-mix(in oklab, var(--color-accent) 45%, transparent)}}.border-accent\/50{border-color:#feb15780}@supports (color:color-mix(in lab, red, red)){.border-accent\/50{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.border-accent\/60{border-color:#feb15799}@supports (color:color-mix(in lab, red, red)){.border-accent\/60{border-color:color-mix(in oklab, var(--color-accent) 60%, transparent)}}.border-border{border-color:var(--color-border)}.border-border-strong{border-color:var(--color-border-strong)}.border-border\/60{border-color:#2b292799}@supports (color:color-mix(in lab, red, red)){.border-border\/60{border-color:color-mix(in oklab, var(--color-border) 60%, transparent)}}.border-danger\/40{border-color:#ff808066}@supports (color:color-mix(in lab, red, red)){.border-danger\/40{border-color:color-mix(in oklab, var(--color-danger) 40%, transparent)}}.border-danger\/50{border-color:#ff808080}@supports (color:color-mix(in lab, red, red)){.border-danger\/50{border-color:color-mix(in oklab, var(--color-danger) 50%, transparent)}}.border-ok\/40{border-color:#4fbf6b66}@supports (color:color-mix(in lab, red, red)){.border-ok\/40{border-color:color-mix(in oklab, var(--color-ok) 40%, transparent)}}.border-premium\/60{border-color:#4d5cf099}@supports (color:color-mix(in lab, red, red)){.border-premium\/60{border-color:color-mix(in oklab, var(--color-premium) 60%, transparent)}}.border-transparent{border-color:#0000}.border-warn\/40{border-color:#e0a33c66}@supports (color:color-mix(in lab, red, red)){.border-warn\/40{border-color:color-mix(in oklab, var(--color-warn) 40%, transparent)}}.border-warn\/50{border-color:#e0a33c80}@supports (color:color-mix(in lab, red, red)){.border-warn\/50{border-color:color-mix(in oklab, var(--color-warn) 50%, transparent)}}.border-l-accent{border-left-color:var(--color-accent)}.bg-accent{background-color:var(--color-accent)}.bg-accent\/5{background-color:#feb1570d}@supports (color:color-mix(in lab, red, red)){.bg-accent\/5{background-color:color-mix(in oklab, var(--color-accent) 5%, transparent)}}.bg-accent\/10{background-color:#feb1571a}@supports (color:color-mix(in lab, red, red)){.bg-accent\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.bg-accent\/15{background-color:#feb15726}@supports (color:color-mix(in lab, red, red)){.bg-accent\/15{background-color:color-mix(in oklab, var(--color-accent) 15%, transparent)}}.bg-accent\/25{background-color:#feb15740}@supports (color:color-mix(in lab, red, red)){.bg-accent\/25{background-color:color-mix(in oklab, var(--color-accent) 25%, transparent)}}.bg-accent\/40{background-color:#feb15766}@supports (color:color-mix(in lab, red, red)){.bg-accent\/40{background-color:color-mix(in oklab, var(--color-accent) 40%, transparent)}}.bg-accent\/50{background-color:#feb15780}@supports (color:color-mix(in lab, red, red)){.bg-accent\/50{background-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.bg-accent\/70{background-color:#feb157b3}@supports (color:color-mix(in lab, red, red)){.bg-accent\/70{background-color:color-mix(in oklab, var(--color-accent) 70%, transparent)}}.bg-accent\/75{background-color:#feb157bf}@supports (color:color-mix(in lab, red, red)){.bg-accent\/75{background-color:color-mix(in oklab, var(--color-accent) 75%, transparent)}}.bg-accent\/\[0\.07\]{background-color:#feb15712}@supports (color:color-mix(in lab, red, red)){.bg-accent\/\[0\.07\]{background-color:color-mix(in oklab, var(--color-accent) 7.0%, transparent)}}.bg-accent\/\[0\.08\]{background-color:#feb15714}@supports (color:color-mix(in lab, red, red)){.bg-accent\/\[0\.08\]{background-color:color-mix(in oklab, var(--color-accent) 8%, transparent)}}.bg-bg{background-color:var(--color-bg)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-border\/60{background-color:#2b292799}@supports (color:color-mix(in lab, red, red)){.bg-border\/60{background-color:color-mix(in oklab, var(--color-border) 60%, transparent)}}.bg-danger{background-color:var(--color-danger)}.bg-danger\/10{background-color:#ff80801a}@supports (color:color-mix(in lab, red, red)){.bg-danger\/10{background-color:color-mix(in oklab, var(--color-danger) 10%, transparent)}}.bg-fg-faint{background-color:var(--color-fg-faint)}.bg-fg-faint\/25{background-color:#837f7840}@supports (color:color-mix(in lab, red, red)){.bg-fg-faint\/25{background-color:color-mix(in oklab, var(--color-fg-faint) 25%, transparent)}}.bg-fg-faint\/30{background-color:#837f784d}@supports (color:color-mix(in lab, red, red)){.bg-fg-faint\/30{background-color:color-mix(in oklab, var(--color-fg-faint) 30%, transparent)}}.bg-ok{background-color:var(--color-ok)}.bg-ok\/10{background-color:#4fbf6b1a}@supports (color:color-mix(in lab, red, red)){.bg-ok\/10{background-color:color-mix(in oklab, var(--color-ok) 10%, transparent)}}.bg-panel{background-color:var(--color-panel)}.bg-panel-2{background-color:var(--color-panel-2)}.bg-panel-2\/30{background-color:#2624224d}@supports (color:color-mix(in lab, red, red)){.bg-panel-2\/30{background-color:color-mix(in oklab, var(--color-panel-2) 30%, transparent)}}.bg-panel-2\/50{background-color:#26242280}@supports (color:color-mix(in lab, red, red)){.bg-panel-2\/50{background-color:color-mix(in oklab, var(--color-panel-2) 50%, transparent)}}.bg-panel-2\/60{background-color:#26242299}@supports (color:color-mix(in lab, red, red)){.bg-panel-2\/60{background-color:color-mix(in oklab, var(--color-panel-2) 60%, transparent)}}.bg-panel\/40{background-color:#211f1d66}@supports (color:color-mix(in lab, red, red)){.bg-panel\/40{background-color:color-mix(in oklab, var(--color-panel) 40%, transparent)}}.bg-panel\/70{background-color:#211f1db3}@supports (color:color-mix(in lab, red, red)){.bg-panel\/70{background-color:color-mix(in oklab, var(--color-panel) 70%, transparent)}}.bg-panel\/95{background-color:#211f1df2}@supports (color:color-mix(in lab, red, red)){.bg-panel\/95{background-color:color-mix(in oklab, var(--color-panel) 95%, transparent)}}.bg-premium{background-color:var(--color-premium)}.bg-premium-strong{background-color:var(--color-premium-strong)}.bg-premium\/75{background-color:#4d5cf0bf}@supports (color:color-mix(in lab, red, red)){.bg-premium\/75{background-color:color-mix(in oklab, var(--color-premium) 75%, transparent)}}.bg-transparent{background-color:#0000}.bg-warn{background-color:var(--color-warn)}.bg-warn\/10{background-color:#e0a33c1a}@supports (color:color-mix(in lab, red, red)){.bg-warn\/10{background-color:color-mix(in oklab, var(--color-warn) 10%, transparent)}}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-panel{--tw-gradient-from:var(--color-panel);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-\[1px\]{padding-block:1px}.py-\[3px\]{padding-block:3px}.py-px{padding-block:1px}.pt-1{padding-top:var(--spacing)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-16{padding-top:calc(var(--spacing) * 16)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pt-\[10vh\]{padding-top:10vh}.pt-\[12vh\]{padding-top:12vh}.pt-\[14vh\]{padding-top:14vh}.pr-1{padding-right:var(--spacing)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:var(--spacing)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-1{padding-left:var(--spacing)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-3\.5{padding-left:calc(var(--spacing) * 3.5)}.pl-5{padding-left:calc(var(--spacing) * 5)}.pl-7{padding-left:calc(var(--spacing) * 7)}.pl-\[7\.5rem\]{padding-left:7.5rem}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[22px\]{font-size:22px}.text-\[24px\]{font-size:24px}.text-\[34px\]{font-size:34px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-\[1\.1\]{--tw-leading:1.1;line-height:1.1}.leading-\[1\.4\]{--tw-leading:1.4;line-height:1.4}.leading-\[1\.05\]{--tw-leading:1.05;line-height:1.05}.leading-\[1\.35\]{--tw-leading:1.35;line-height:1.35}.leading-\[1\.45\]{--tw-leading:1.45;line-height:1.45}.leading-\[1\.55\]{--tw-leading:1.55;line-height:1.55}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.01em\]{--tw-tracking:-.01em;letter-spacing:-.01em}.tracking-\[0\.08em\]{--tw-tracking:.08em;letter-spacing:.08em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--color-accent)}.text-bg{color:var(--color-bg)}.text-danger{color:var(--color-danger)}.text-fg{color:var(--color-fg)}.text-fg-faint{color:var(--color-fg-faint)}.text-fg-muted{color:var(--color-fg-muted)}.text-info{color:var(--color-info)}.text-ok{color:var(--color-ok)}.text-panel{color:var(--color-panel)}.text-premium-strong{color:var(--color-premium-strong)}.text-warn{color:var(--color-warn)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.accent-\[var\(--color-accent\)\]{accent-color:var(--color-accent)}.opacity-35{opacity:.35}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.shadow-\[0_2px_12px_var\(--color-bg\)\]{--tw-shadow:0 2px 12px var(--tw-shadow-color,var(--color-bg));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[var\(--shadow-panel\)\]{--tw-shadow:var(--shadow-panel);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-accent{--tw-ring-color:var(--color-accent)}.ring-offset-1{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.ring-offset-panel{--tw-ring-offset-color:var(--color-panel)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}@media (hover:hover){.group-hover\:text-accent-strong:is(:where(.group):hover *){color:var(--color-accent-strong)}.group-hover\:text-fg:is(:where(.group):hover *){color:var(--color-fg)}}.marker\:content-none ::marker{--tw-content:none;content:none}.marker\:content-none::marker{--tw-content:none;content:none}.marker\:content-none ::-webkit-details-marker{--tw-content:none;content:none}.marker\:content-none::-webkit-details-marker{--tw-content:none;content:none}.first\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}@media (hover:hover){.hover\:border-accent\/50:hover{border-color:#feb15780}@supports (color:color-mix(in lab, red, red)){.hover\:border-accent\/50:hover{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.hover\:border-border-strong:hover{border-color:var(--color-border-strong)}.hover\:bg-accent\/20:hover{background-color:#feb15733}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/20:hover{background-color:color-mix(in oklab, var(--color-accent) 20%, transparent)}}.hover\:bg-accent\/25:hover{background-color:#feb15740}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/25:hover{background-color:color-mix(in oklab, var(--color-accent) 25%, transparent)}}.hover\:bg-accent\/90:hover{background-color:#feb157e6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/90:hover{background-color:color-mix(in oklab, var(--color-accent) 90%, transparent)}}.hover\:bg-accent\/\[0\.16\]:hover{background-color:#feb15729}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/\[0\.16\]:hover{background-color:color-mix(in oklab, var(--color-accent) 16%, transparent)}}.hover\:bg-danger\/10:hover{background-color:#ff80801a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-danger\/10:hover{background-color:color-mix(in oklab, var(--color-danger) 10%, transparent)}}.hover\:bg-ok\/10:hover{background-color:#4fbf6b1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-ok\/10:hover{background-color:color-mix(in oklab, var(--color-ok) 10%, transparent)}}.hover\:bg-panel:hover{background-color:var(--color-panel)}.hover\:bg-panel-2:hover{background-color:var(--color-panel-2)}.hover\:bg-panel-2\/50:hover{background-color:#26242280}@supports (color:color-mix(in lab, red, red)){.hover\:bg-panel-2\/50:hover{background-color:color-mix(in oklab, var(--color-panel-2) 50%, transparent)}}.hover\:bg-premium:hover{background-color:var(--color-premium)}.hover\:bg-premium\/10:hover{background-color:#4d5cf01a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-premium\/10:hover{background-color:color-mix(in oklab, var(--color-premium) 10%, transparent)}}.hover\:bg-warn\/20:hover{background-color:#e0a33c33}@supports (color:color-mix(in lab, red, red)){.hover\:bg-warn\/20:hover{background-color:color-mix(in oklab, var(--color-warn) 20%, transparent)}}.hover\:text-accent:hover{color:var(--color-accent)}.hover\:text-accent-strong:hover{color:var(--color-accent-strong)}.hover\:text-fg:hover{color:var(--color-fg)}.hover\:text-fg-muted:hover{color:var(--color-fg-muted)}.hover\:no-underline:hover{text-decoration-line:none}.hover\:underline:hover{text-decoration-line:underline}.hover\:brightness-110:hover{--tw-brightness:brightness(110%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-default:disabled{cursor:default}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:inline{display:inline}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}:where(.sm\:divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.sm\:divide-y-0>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(0px * var(--tw-divide-y-reverse));border-bottom-width:calc(0px * calc(1 - var(--tw-divide-y-reverse)))}}@media (width>=48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (width>=64rem){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.lg\:grid-cols-\[1\.4fr_1fr_1fr_1fr_1fr_1fr\]{grid-template-columns:1.4fr 1fr 1fr 1fr 1fr 1fr}.lg\:grid-cols-\[minmax\(0\,1fr\)_260px\]{grid-template-columns:minmax(0,1fr) 260px}}@media (width>=80rem){.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}}[data-theme=light]{--color-bg:#faf9f7;--color-panel:#fff;--color-panel-2:#f2f0ec;--color-border:#e6e2db;--color-border-strong:#c9c3b8;--color-fg:#24211c;--color-fg-muted:#5f5a51;--color-fg-faint:#8a8479;--color-ok:#2e9e4f;--color-warn:#9a6700;--color-danger:#d64545;--color-info:#b8730d;--color-accent:#b8730d;--color-accent-strong:#8f5808;--color-premium:#3341d8;--color-premium-strong:#232fb0;--shadow-panel:0 8px 20px -14px #3c321e38}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;background:var(--color-bg);color:var(--color-fg);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;font-size:16px;line-height:1.45}[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}.num,.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1, "zero" 1}*{border-color:var(--color-border)}a:where(:not([class*=text-])){color:var(--color-info)}a{text-decoration:none}a.link:hover{text-decoration:underline}::selection{background:#feb15759}@supports (color:color-mix(in lab, red, red)){::selection{background:color-mix(in srgb, var(--color-accent) 35%, transparent)}}.graph-dot{transition:fill .45s}.graph-gate{transition:fill .45s,stroke .45s}.graph-verified{transform-box:fill-box;transform-origin:50%;animation:.55s cubic-bezier(.2,.7,.2,1) verifyPop}@keyframes verifyPop{0%{transform:scale(1)}40%{transform:scale(1.55)}to{transform:scale(1)}}.graph-breathe{transform-box:fill-box;transform-origin:50%;animation:2.8s ease-in-out infinite graphBreathe}@keyframes graphBreathe{0%,to{opacity:.9}50%{opacity:1;filter:drop-shadow(0 0 3px color-mix(in srgb, var(--color-ok) 55%, transparent))}}@media (prefers-reduced-motion:reduce){.graph-dot,.graph-gate{transition:none}.graph-verified,.graph-breathe{animation:none}}*{scrollbar-width:thin;scrollbar-color:var(--color-border-strong) transparent}.stale-dot{background:var(--color-warn);border-radius:9999px;width:6px;height:6px;display:inline-block}.input{background:var(--color-panel-2);border:1px solid var(--color-border-strong);color:var(--color-fg);font-family:var(--font-mono);border-radius:3px;width:100%;padding:4px 8px;font-size:12px}.input:focus{outline:1px solid var(--color-accent);border-color:var(--color-accent)}.skeleton-pulse{animation:1.4s ease-in-out infinite skeletonPulse}@keyframes skeletonPulse{0%,to{opacity:.5}50%{opacity:.9}}@media (prefers-reduced-motion:reduce){.skeleton-pulse{opacity:.6;animation:none}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}@keyframes flash{0%{background-color:color-mix(in srgb, var(--color-accent) 22%, transparent)}to{background-color:#0000}}.xterm{cursor:text;-webkit-user-select:none;user-select:none;position:relative}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{z-index:5;position:absolute;top:0}.xterm .xterm-helper-textarea{opacity:0;z-index:-5;white-space:nowrap;resize:none;border:0;width:0;height:0;margin:0;padding:0;position:absolute;top:0;left:-9999em;overflow:hidden}.xterm .composition-view{color:#fff;white-space:nowrap;z-index:1;background:#000;display:none;position:absolute}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{cursor:default;background-color:#000;position:absolute;inset:0;overflow-y:scroll}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;top:0;left:0}.xterm-char-measure-element{visibility:hidden;line-height:normal;display:inline-block;position:absolute;top:0;left:-9999em}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{z-index:10;color:#0000;pointer-events:none;position:absolute;inset:0}.xterm .xterm-accessibility-tree:not(.debug) ::selection{color:#0000}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre;font-family:monospace}.xterm .xterm-accessibility-tree>div{transform-origin:0;width:fit-content}.xterm .live-region{width:1px;height:1px;position:absolute;left:-9999px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:underline double;text-decoration:underline double}.xterm-underline-3{-webkit-text-decoration:underline wavy;text-decoration:underline wavy}.xterm-underline-4{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.xterm-underline-5{-webkit-text-decoration:underline dashed;text-decoration:underline dashed}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:underline overline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;pointer-events:none;position:absolute;top:0;right:0}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;z-index:11;background:0 0;transition:opacity .1s linear}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{display:none;position:absolute}.xterm .xterm-scrollable-element>.shadow.top{width:100%;height:3px;box-shadow:var(--vscode-scrollbar-shadow,#000) 0 6px 6px -6px inset;display:block;top:0;left:3px}.xterm .xterm-scrollable-element>.shadow.left{width:3px;height:100%;box-shadow:var(--vscode-scrollbar-shadow,#000) 6px 0 6px -6px inset;display:block;top:3px;left:0}.xterm .xterm-scrollable-element>.shadow.top-left-corner{width:3px;height:3px;display:block;top:0;left:0}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow,#000) 6px 0 6px -6px inset} diff --git a/internal/api/dist/index.html b/internal/api/dist/index.html index cdbff8b..64f9118 100644 --- a/internal/api/dist/index.html +++ b/internal/api/dist/index.html @@ -20,8 +20,8 @@ } catch (e) {} })(); - - + +
diff --git a/internal/api/gemini.go b/internal/api/gemini.go new file mode 100644 index 0000000..c1776bb --- /dev/null +++ b/internal/api/gemini.go @@ -0,0 +1,80 @@ +package api + +import ( + "encoding/json" + "errors" + "io" + "net/http" + + "github.com/dspv/caprock/internal/gemini" + "github.com/dspv/caprock/internal/license" +) + +// handleGeminiStatus says whether the feature is usable here, without ever +// revealing the key. It answers the two questions the UI has — is there a key, +// and is this a paying user — so the screen can say which one is missing +// instead of showing a dead button. +func (s *Server) handleGeminiStatus(w http.ResponseWriter, r *http.Request) { + st := license.Parse(s.d.Settings.Get().LicenseKey, s.d.Now()) + writeJSON(w, http.StatusOK, map[string]any{ + "available": gemini.Available(), + "env_var": gemini.EnvKey, + "licensed": st.Active, + "model": gemini.DefaultModel, + }) +} + +// handleGeminiAsk sends one prompt to Google on the user's key. +// +// The licence is checked HERE, on the server, which the spend cap deliberately +// does not do. The difference is what the two features cost when the check is +// skipped: a cap spends nothing, while this spends the user's Gemini quota and +// opens an outbound connection. ADR-023 records the reasoning and the limit — +// server-side checks belong to features that spend money or reach the network, +// not to features that draw a panel. +func (s *Server) handleGeminiAsk(w http.ResponseWriter, r *http.Request) { + if s.d.AskGemini == nil { + http.Error(w, "gemini not configured", http.StatusNotImplemented) + return + } + if !gemini.Available() { + // Not an error the user did wrong: the feature is simply not set up. + writeJSON(w, http.StatusPreconditionFailed, map[string]string{ + "error": "no api key", + "detail": "set " + gemini.EnvKey + " in the daemon's environment and restart it", + }) + return + } + if st := license.Parse(s.d.Settings.Get().LicenseKey, s.d.Now()); !st.Active { + writeJSON(w, http.StatusPaymentRequired, map[string]string{ + "error": "premium required", + "detail": "asking Gemini is a paid feature; the key stays yours either way", + }) + return + } + + var body struct { + Prompt string `json:"prompt"` + Model string `json:"model"` + } + if err := json.NewDecoder(io.LimitReader(r.Body, 1<<20)).Decode(&body); err != nil { + http.Error(w, "bad request", http.StatusBadRequest) + return + } + if body.Prompt == "" { + http.Error(w, "empty prompt", http.StatusBadRequest) + return + } + + rep, err := s.d.AskGemini(r.Context(), body.Model, body.Prompt) + if err != nil { + if errors.Is(err, gemini.ErrNoKey) { + writeJSON(w, http.StatusPreconditionFailed, map[string]string{"error": "no api key"}) + return + } + // Google's own message is more useful than anything we could write. + writeJSON(w, http.StatusBadGateway, map[string]string{"error": err.Error()}) + return + } + writeJSON(w, http.StatusOK, rep) +} diff --git a/internal/api/gemini_test.go b/internal/api/gemini_test.go new file mode 100644 index 0000000..5674c87 --- /dev/null +++ b/internal/api/gemini_test.go @@ -0,0 +1,170 @@ +package api + +import ( + "bytes" + "context" + "encoding/json" + "net/http" + "testing" + "time" + + "github.com/dspv/caprock/internal/bus" + "github.com/dspv/caprock/internal/cost" + "github.com/dspv/caprock/internal/gemini" + "github.com/dspv/caprock/internal/license" + "github.com/dspv/caprock/internal/rollup" + "github.com/dspv/caprock/internal/store" + + "net/http/httptest" +) + +// geminiEnv is a server with the Gemini dependency wired to a spy, so a test +// can tell whether a request would actually have left the machine. +type geminiEnv struct { + srv *httptest.Server + settings *fakeSettings + called *int +} + +func newGeminiEnv(t *testing.T) *geminiEnv { + t.Helper() + st, err := store.Open(context.Background(), ":memory:", nil) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { _ = st.Close() }) + tb, _ := cost.Embedded() + b := bus.New() + rec := rollup.New(st, tb, b, nil) + now := time.Date(2026, 9, 1, 12, 0, 0, 0, time.UTC) + rec.Now = func() time.Time { return now } + settings := &fakeSettings{} + called := 0 + + s := New(Deps{ + Store: st, Bus: b, Table: tb, Version: "test", Settings: settings, + Now: func() time.Time { return now }, + AskGemini: func(ctx context.Context, model, prompt string) (any, error) { + called++ + return map[string]any{"text": "ok", "model": "gemini-3.5-flash-lite"}, nil + }, + }) + srv := httptest.NewServer(s) + t.Cleanup(srv.Close) + return &geminiEnv{srv: srv, settings: settings, called: &called} +} + +func (e *geminiEnv) ask(t *testing.T, prompt string) int { + t.Helper() + body, _ := json.Marshal(map[string]string{"prompt": prompt}) + req, _ := http.NewRequest(http.MethodPost, e.srv.URL+"/v1/gemini/ask", bytes.NewReader(body)) + req.Header.Set("Content-Type", "application/json") + res, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + return res.StatusCode +} + +func (e *geminiEnv) license(t *testing.T, key string) { + t.Helper() + cur := e.settings.Get() + cur.LicenseKey = key + if err := e.settings.Set(cur); err != nil { + t.Fatal(err) + } +} + +// The whole reason this endpoint checks the licence server-side, unlike the +// spend cap: a call here spends the user's Gemini quota and opens an outbound +// connection, so a React-only paywall would be a paywall a curl walks past. +func TestAskRequiresALicenceOnTheServer(t *testing.T) { + t.Setenv(gemini.EnvKey, "test-key") + e := newGeminiEnv(t) + + if code := e.ask(t, "hello"); code != http.StatusPaymentRequired { + t.Fatalf("unlicensed ask: got %d, want 402", code) + } + if *e.called != 0 { + t.Error("an unlicensed request reached Google — the gate must run before the call") + } + + e.license(t, license.Issue(time.Date(2027, 1, 1, 0, 0, 0, 0, time.UTC), license.RandomSuffix)) + if code := e.ask(t, "hello"); code != http.StatusOK { + t.Fatalf("licensed ask: got %d, want 200", code) + } + if *e.called != 1 { + t.Errorf("licensed request did not reach the client (called=%d)", *e.called) + } +} + +// Without a key the answer is "not set up here", not "you did something wrong" +// and not "pay us" — the distinction is what lets the screen say which of the +// two things is missing. +func TestAskWithoutAKeySaysSoBeforeTheLicence(t *testing.T) { + t.Setenv(gemini.EnvKey, "") + e := newGeminiEnv(t) + if code := e.ask(t, "hello"); code != http.StatusPreconditionFailed { + t.Fatalf("no key: got %d, want 412", code) + } + if *e.called != 0 { + t.Error("called the client with no key") + } +} + +func TestStatusNeverRevealsTheKey(t *testing.T) { + t.Setenv(gemini.EnvKey, "super-secret-value") + e := newGeminiEnv(t) + + res, err := http.Get(e.srv.URL + "/v1/gemini") + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + var raw bytes.Buffer + _, _ = raw.ReadFrom(res.Body) + + if bytes.Contains(raw.Bytes(), []byte("super-secret-value")) { + t.Fatalf("the status endpoint echoed the key back:\n%s", raw.String()) + } + var out map[string]any + _ = json.Unmarshal(raw.Bytes(), &out) + if out["available"] != true { + t.Errorf("available should be true with a key set: %v", out) + } + // It names the variable so the UI can tell the user what to set, which is + // the one thing about the key that is safe to say. + if out["env_var"] != gemini.EnvKey { + t.Errorf("env_var %v", out["env_var"]) + } +} + +// The key must not appear in the ordinary settings surface either — that is +// the endpoint a page on 127.0.0.1 can reach through the CSRF guard. +func TestSettingsDoNotCarryTheGeminiKey(t *testing.T) { + t.Setenv(gemini.EnvKey, "super-secret-value") + e := newGeminiEnv(t) + res, err := http.Get(e.srv.URL + "/v1/settings") + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + var raw bytes.Buffer + _, _ = raw.ReadFrom(res.Body) + if bytes.Contains(raw.Bytes(), []byte("super-secret-value")) { + t.Fatalf("GET /v1/settings leaked the Gemini key:\n%s", raw.String()) + } +} + +func TestEmptyPromptIsRefusedBeforeTheNetwork(t *testing.T) { + t.Setenv(gemini.EnvKey, "k") + e := newGeminiEnv(t) + e.license(t, license.Issue(time.Date(2027, 1, 1, 0, 0, 0, 0, time.UTC), license.RandomSuffix)) + if code := e.ask(t, ""); code != http.StatusBadRequest { + t.Fatalf("empty prompt: got %d, want 400", code) + } + if *e.called != 0 { + t.Error("an empty prompt reached the client") + } +} diff --git a/internal/daemon/daemon.go b/internal/daemon/daemon.go index e7708ea..b0e6760 100644 --- a/internal/daemon/daemon.go +++ b/internal/daemon/daemon.go @@ -286,7 +286,8 @@ func (d *Daemon) run(ctx context.Context) error { Status: d.status, ActiveLoops: d.activeLoop, IdleAfter: d.opt.IdleAfter, Token: rt.Token, Shutdown: cancel, Agents: &agentAdapter{m: d.mgr}, Tasks: &boardAdapter{d: d}, Settings: &settingsAdapter{d: d}, Update: d.upd, - DataDir: d.opt.DataDir, + AskGemini: d.askGemini, + DataDir: d.opt.DataDir, }) srv := &http.Server{Handler: d.api, ReadHeaderTimeout: 10 * time.Second} diff --git a/internal/daemon/gemini.go b/internal/daemon/gemini.go new file mode 100644 index 0000000..5c073d6 --- /dev/null +++ b/internal/daemon/gemini.go @@ -0,0 +1,93 @@ +package daemon + +import ( + "context" + "encoding/json" + "fmt" + "time" + + "github.com/dspv/caprock/internal/event" + "github.com/dspv/caprock/internal/gemini" + "github.com/dspv/caprock/internal/rollup" +) + +// geminiSessionID is the session every Gemini answer is recorded under. +// +// One session rather than one per question: the value of the screen is "what +// has Gemini cost me", and a hundred one-turn sessions would bury that under a +// list nobody reads. It reads as a long-running conversation with the model, +// which is what it is. +const geminiSessionID = "caprock-gemini" + +// askGemini sends one prompt and records the exchange in the same event stream +// as everything else, so a Gemini answer is counted, priced and searchable +// beside a Claude turn rather than living in a corner of its own. +// +// The recorded turn carries tokens and a model but no cost: rollup prices it +// from the same table (ADR-023), because unlike OpenCode there is no vendor +// figure to carry — Google reports per project, never per call. +func (d *Daemon) askGemini(ctx context.Context, model, prompt string) (any, error) { + c := &gemini.Client{} + rep, err := c.Ask(ctx, model, geminiSystemPrompt, prompt) + if err != nil { + return nil, err + } + + info := rollup.SessionInfo{ + Cwd: d.opt.RepoCwd, + Model: rep.Model, + Agent: gemini.Agent, + } + now := time.Now() + + // The question, then the answer — the same two-event shape a Claude turn + // has, so narration, search and the activity feed need no special case. + ask := &event.Event{ + Ts: now, SessionID: geminiSessionID, Source: event.SourceGemini, + Kind: event.KindTurnUser, Payload: mustJSON(map[string]any{"prompt": prompt}), + Key: fmt.Sprintf("gem-ask:%d", now.UnixNano()), + } + if _, err := d.rec.Record(ctx, ask, info); err != nil { + d.log.Warn("gemini: could not record the question", "component", "gemini", "err", err) + } + + u := rep.Usage + answer := &event.Event{ + Ts: time.Now(), SessionID: geminiSessionID, Source: event.SourceGemini, + Kind: event.KindTurnAssistant, Model: rep.Model, + Payload: mustJSON(map[string]any{ + "text": rep.Text, + "thoughts_tokens": u.ThoughtsTokens, + "elapsed_ms": rep.Elapsed.Milliseconds(), + }), + // Thinking tokens are billed as output by Google, so they are counted + // as output here — leaving them out would under-report the cost of + // exactly the models that reason the most. + Tokens: &event.TokenDelta{ + In: u.PromptTokens, + Out: u.OutputTokens + u.ThoughtsTokens, + CacheRead: u.CachedTokens, + }, + Key: fmt.Sprintf("gem-ans:%d", time.Now().UnixNano()), + } + if _, err := d.rec.Record(ctx, answer, info); err != nil { + d.log.Warn("gemini: could not record the answer", "component", "gemini", "err", err) + } + + return rep, nil +} + +// geminiSystemPrompt keeps answers short. A dashboard panel is not a chat +// window, and a model that writes five paragraphs into a box that fits three +// lines has spent the user's money on scrolling. +const geminiSystemPrompt = "You are answering inside a developer dashboard. " + + "Be brief and concrete: a few sentences, or a short list. " + + "No preamble, no restating the question." + +func mustJSON(v any) json.RawMessage { + b, err := json.Marshal(v) + if err != nil { + return json.RawMessage(`{}`) + } + return b +} diff --git a/internal/event/event.go b/internal/event/event.go index f3ea3ee..76542c1 100644 --- a/internal/event/event.go +++ b/internal/event/event.go @@ -52,6 +52,11 @@ const ( SourceOpenCode Source = "opencode" SourcePTY Source = "pty" SourceHarness Source = "harness" + // SourceGemini marks calls Caprock made to Google's Gemini on the user's + // own key. Unlike OpenCode these are priced by our own table, because the + // figures come from the response's usageMetadata and there is no vendor + // cost to carry — Google reports per project, not per call (ADR-023). + SourceGemini Source = "gemini" ) // TokenDelta carries per-turn token usage (turn.assistant only). diff --git a/internal/gemini/gemini.go b/internal/gemini/gemini.go new file mode 100644 index 0000000..fd26b41 --- /dev/null +++ b/internal/gemini/gemini.go @@ -0,0 +1,277 @@ +// Package gemini talks to Google's Gemini API on a key the user supplies +// through the environment. +// +// Caprock never stores that key. It is read from GEMINI_API_KEY at the moment +// of the call, never written to config.json, never accepted by PUT /v1/settings +// and never returned by GET /v1/settings — see ADR-023. The objection this +// answers is recorded in .ai/17-teams.md: a bug in a tool that holds no +// credential cannot leak one. +// +// This is the second outbound call in the product, after the release check, and +// the first that carries user content. Nothing here runs on a timer or in the +// background: a request leaves only when a person asked a question in that turn. +package gemini + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "os" + "strings" + "time" +) + +// Agent is the value the sessions table carries for Gemini work, alongside +// "claude" and "opencode". +const Agent = "gemini" + +// EnvKey is the variable the key is read from. The name matches what Google's +// own tooling uses, so a machine already set up for Gemini needs no new setup. +const EnvKey = "GEMINI_API_KEY" + +// Endpoint is the only host this package ever contacts. +const Endpoint = "https://generativelanguage.googleapis.com/v1beta" + +// DefaultModel is what a request without a model uses: the cheapest current +// Flash tier, because the common use is a question about the user's own +// sessions rather than deep reasoning, and it is their money. +const DefaultModel = "gemini-3.5-flash-lite" + +// ErrNoKey means the environment holds no key, which is also how the feature +// stays off: with nothing set there is no default-on path to disable. +var ErrNoKey = errors.New("no " + EnvKey + " in the environment") + +// Key returns the key from the environment, trimmed. Empty means absent — +// callers must treat that as "the feature does not exist here", not as an error +// to report. +func Key() string { return strings.TrimSpace(os.Getenv(EnvKey)) } + +// Available reports whether a key is present at all. +func Available() bool { return Key() != "" } + +// Client calls the API. The zero value is usable. +type Client struct { + HTTP *http.Client + // Base overrides the endpoint in tests. Empty means Endpoint. + Base string + // Now is injectable so timings are deterministic under test. + Now func() time.Time +} + +func (c *Client) httpClient() *http.Client { + if c.HTTP != nil { + return c.HTTP + } + // A generous but bounded timeout: a long answer on a slow line is normal, + // a hung connection holding a handler open is not. + return &http.Client{Timeout: 120 * time.Second} +} + +func (c *Client) base() string { + if c.Base != "" { + return c.Base + } + return Endpoint +} + +func (c *Client) now() time.Time { + if c.Now != nil { + return c.Now() + } + return time.Now() +} + +// Usage is what the response says it cost, in tokens. These are the figures +// Caprock prices; there is no per-key billing API to reconcile them against +// (Google reports per project), so the total is what Caprock sent rather than +// what Google billed, and the UI says so. +type Usage struct { + PromptTokens int64 `json:"prompt_tokens"` + OutputTokens int64 `json:"output_tokens"` + CachedTokens int64 `json:"cached_tokens"` + ThoughtsTokens int64 `json:"thoughts_tokens"` + TotalTokens int64 `json:"total_tokens"` +} + +// Reply is one answer plus what it cost. +type Reply struct { + Text string `json:"text"` + Model string `json:"model"` + Usage Usage `json:"usage"` + Elapsed time.Duration `json:"-"` +} + +// wire types: only the fields this package reads. Google adds fields freely and +// unknown ones must stay ignorable. +type genReq struct { + Contents []wireContent `json:"contents"` + System *wireContent `json:"systemInstruction,omitempty"` +} + +type wireContent struct { + Role string `json:"role,omitempty"` + Parts []wirePart `json:"parts"` +} + +type wirePart struct { + Text string `json:"text"` +} + +type genResp struct { + Candidates []struct { + Content wireContent `json:"content"` + FinishReason string `json:"finishReason"` + } `json:"candidates"` + UsageMetadata struct { + PromptTokenCount int64 `json:"promptTokenCount"` + CandidatesTokenCount int64 `json:"candidatesTokenCount"` + CachedContentTokenCount int64 `json:"cachedContentTokenCount"` + ThoughtsTokenCount int64 `json:"thoughtsTokenCount"` + TotalTokenCount int64 `json:"totalTokenCount"` + } `json:"usageMetadata"` + Error *wireError `json:"error"` +} + +type wireError struct { + Code int `json:"code"` + Message string `json:"message"` + Status string `json:"status"` +} + +func (e *wireError) Error() string { + if e.Status != "" { + return fmt.Sprintf("gemini: %s (%d): %s", e.Status, e.Code, e.Message) + } + return fmt.Sprintf("gemini: %d: %s", e.Code, e.Message) +} + +// MaxBody bounds what is read back. A runaway response must not become a +// runaway allocation in a daemon that is meant to sit quietly. +const MaxBody = 8 << 20 + +// Ask sends one prompt and returns the answer. system may be empty. +func (c *Client) Ask(ctx context.Context, model, system, prompt string) (*Reply, error) { + key := Key() + if key == "" { + return nil, ErrNoKey + } + if strings.TrimSpace(prompt) == "" { + return nil, errors.New("empty prompt") + } + if model == "" { + model = DefaultModel + } + + body := genReq{Contents: []wireContent{{Role: "user", Parts: []wirePart{{Text: prompt}}}}} + if s := strings.TrimSpace(system); s != "" { + body.System = &wireContent{Parts: []wirePart{{Text: s}}} + } + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + + url := fmt.Sprintf("%s/models/%s:generateContent", c.base(), model) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(buf)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + // The key rides in a header rather than the query string, so it cannot be + // captured by anything that logs URLs. + req.Header.Set("x-goog-api-key", key) + + start := c.now() + res, err := c.httpClient().Do(req) + if err != nil { + return nil, fmt.Errorf("gemini request: %w", err) + } + defer res.Body.Close() + + raw, err := io.ReadAll(io.LimitReader(res.Body, MaxBody)) + if err != nil { + return nil, fmt.Errorf("gemini read: %w", err) + } + + var out genResp + if err := json.Unmarshal(raw, &out); err != nil { + // A non-JSON body on a bad status is more useful reported as the status. + if res.StatusCode >= 400 { + return nil, fmt.Errorf("gemini: http %d", res.StatusCode) + } + return nil, fmt.Errorf("gemini decode: %w", err) + } + if out.Error != nil { + return nil, out.Error + } + if res.StatusCode >= 400 { + return nil, fmt.Errorf("gemini: http %d", res.StatusCode) + } + if len(out.Candidates) == 0 { + return nil, errors.New("gemini returned no answer") + } + + var sb strings.Builder + for _, p := range out.Candidates[0].Content.Parts { + sb.WriteString(p.Text) + } + + u := out.UsageMetadata + return &Reply{ + Text: sb.String(), + Model: model, + Usage: Usage{ + PromptTokens: u.PromptTokenCount, + OutputTokens: u.CandidatesTokenCount, + CachedTokens: u.CachedContentTokenCount, + ThoughtsTokens: u.ThoughtsTokenCount, + TotalTokens: u.TotalTokenCount, + }, + Elapsed: c.now().Sub(start), + }, nil +} + +// Check verifies the key by listing models. It is the cheapest call that +// proves the key works, and it sends no user content. +func (c *Client) Check(ctx context.Context) ([]string, error) { + key := Key() + if key == "" { + return nil, ErrNoKey + } + req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.base()+"/models", nil) + if err != nil { + return nil, err + } + req.Header.Set("x-goog-api-key", key) + res, err := c.httpClient().Do(req) + if err != nil { + return nil, fmt.Errorf("gemini request: %w", err) + } + defer res.Body.Close() + + raw, err := io.ReadAll(io.LimitReader(res.Body, MaxBody)) + if err != nil { + return nil, err + } + var out struct { + Models []struct { + Name string `json:"name"` + } `json:"models"` + Error *wireError `json:"error"` + } + if err := json.Unmarshal(raw, &out); err != nil { + return nil, fmt.Errorf("gemini: http %d", res.StatusCode) + } + if out.Error != nil { + return nil, out.Error + } + names := make([]string, 0, len(out.Models)) + for _, m := range out.Models { + names = append(names, strings.TrimPrefix(m.Name, "models/")) + } + return names, nil +} diff --git a/internal/gemini/gemini_test.go b/internal/gemini/gemini_test.go new file mode 100644 index 0000000..542a43c --- /dev/null +++ b/internal/gemini/gemini_test.go @@ -0,0 +1,134 @@ +package gemini + +import ( + "context" + "encoding/json" + "errors" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestAskParsesAnswerAndUsage(t *testing.T) { + t.Setenv(EnvKey, "test-key") + var gotPath, gotKey, gotQuery string + var gotBody map[string]any + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotPath, gotKey, gotQuery = r.URL.Path, r.Header.Get("x-goog-api-key"), r.URL.RawQuery + _ = json.NewDecoder(r.Body).Decode(&gotBody) + _, _ = w.Write([]byte(`{ + "candidates":[{"content":{"parts":[{"text":"hello "},{"text":"world"}]}}], + "usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":5, + "cachedContentTokenCount":8,"thoughtsTokenCount":3,"totalTokenCount":28} + }`)) + })) + defer srv.Close() + + c := &Client{Base: srv.URL} + rep, err := c.Ask(context.Background(), "gemini-3.5-flash-lite", "be brief", "hi") + if err != nil { + t.Fatal(err) + } + // Parts are concatenated: Google splits one answer across several. + if rep.Text != "hello world" { + t.Errorf("text %q", rep.Text) + } + if rep.Usage.PromptTokens != 12 || rep.Usage.OutputTokens != 5 || + rep.Usage.CachedTokens != 8 || rep.Usage.ThoughtsTokens != 3 { + t.Errorf("usage %+v", rep.Usage) + } + if !strings.Contains(gotPath, "gemini-3.5-flash-lite:generateContent") { + t.Errorf("path %q", gotPath) + } + if _, ok := gotBody["systemInstruction"]; !ok { + t.Error("system instruction not sent") + } + + // The key travels in a header, never the URL: anything that logs request + // lines — a proxy, a crash dump, the daemon's own log — must not capture it. + if gotKey != "test-key" { + t.Errorf("key header %q", gotKey) + } + if strings.Contains(gotQuery, "test-key") || strings.Contains(gotPath, "test-key") { + t.Errorf("key leaked into the URL: path=%q query=%q", gotPath, gotQuery) + } +} + +// With no key the feature does not exist. This is also the off switch: there is +// no default-on path, so nothing needs disabling. +func TestNoKeyIsNotAnError(t *testing.T) { + t.Setenv(EnvKey, "") + if Available() { + t.Error("Available() true with an empty key") + } + if _, err := (&Client{}).Ask(context.Background(), "", "", "hi"); !errors.Is(err, ErrNoKey) { + t.Errorf("Ask: %v, want ErrNoKey", err) + } + if _, err := (&Client{}).Check(context.Background()); !errors.Is(err, ErrNoKey) { + t.Errorf("Check: %v, want ErrNoKey", err) + } +} + +func TestKeyIsTrimmed(t *testing.T) { + // A key pasted from a web page arrives with a newline more often than not. + t.Setenv(EnvKey, " padded-key\n") + if Key() != "padded-key" { + t.Errorf("Key() = %q", Key()) + } +} + +// Google reports failures as HTTP 200 with an error object as often as it uses +// a status code, so the body is what decides. +func TestApiErrorIsReported(t *testing.T) { + t.Setenv(EnvKey, "bad") + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(400) + _, _ = w.Write([]byte(`{"error":{"code":400,"message":"API key not valid.","status":"INVALID_ARGUMENT"}}`)) + })) + defer srv.Close() + + _, err := (&Client{Base: srv.URL}).Ask(context.Background(), "", "", "hi") + if err == nil { + t.Fatal("expected an error") + } + if !strings.Contains(err.Error(), "API key not valid") { + t.Errorf("error should carry Google's own words, got: %v", err) + } +} + +func TestEmptyCandidatesIsAnError(t *testing.T) { + t.Setenv(EnvKey, "k") + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte(`{"candidates":[],"usageMetadata":{}}`)) + })) + defer srv.Close() + if _, err := (&Client{Base: srv.URL}).Ask(context.Background(), "", "", "hi"); err == nil { + t.Error("a reply with no candidates must not pass as an answer") + } +} + +func TestCheckListsModels(t *testing.T) { + t.Setenv(EnvKey, "k") + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte(`{"models":[{"name":"models/gemini-3.5-flash"},{"name":"models/gemini-2.5-pro"}]}`)) + })) + defer srv.Close() + got, err := (&Client{Base: srv.URL}).Check(context.Background()) + if err != nil { + t.Fatal(err) + } + // The "models/" prefix is Google's wire detail, not something a reader + // should meet on screen. + if len(got) != 2 || got[0] != "gemini-3.5-flash" { + t.Errorf("models %v", got) + } +} + +func TestEmptyPromptRefused(t *testing.T) { + t.Setenv(EnvKey, "k") + if _, err := (&Client{}).Ask(context.Background(), "", "", " "); err == nil { + t.Error("an empty prompt must not reach the network") + } +} diff --git a/pricing/pricing.json b/pricing/pricing.json index 9ca9dc8..2b2cc85 100644 --- a/pricing/pricing.json +++ b/pricing/pricing.json @@ -1,16 +1,20 @@ { - "version": "2026-08-30.1", + "version": "2026-09-01.1", "source": "https://platform.claude.com/docs/en/about-claude/pricing", "fetched_at": "2026-08-18", "currency": "USD", "unit": "per_million_tokens", "notes": [ "First-party Anthropic API prices. Amazon Bedrock and Google Vertex have separate partner pricing (regional endpoints +10%) and are not covered by this table (OQ-02).", - "cache_write_5m = 1.25x input, cache_write_1h = 2x input, cache_read = 0.1x input — per Anthropic's published multipliers.", + "cache_write_5m = 1.25x input, cache_write_1h = 2x input, cache_read = 0.1x input \u2014 per Anthropic's published multipliers.", "Model ids are matched by prefix against the `model` field observed in transcripts (e.g. claude-opus-5, claude-sonnet-4-5-20250929). Longest prefix wins.", "context_window is the model's maximum input context in tokens as published; used for the 'context fill %' badge (OQ-07).", "Non-Anthropic rows are the providers' own published list prices, fetched 2026-08-27: DeepSeek V4 Pro $0.435/$0.87 per 1M (its 75% cut, made permanent); MiniMax M3 $0.30/$1.20 per 1M standard tier with $0.06 cache read (its permanent 50% off). They are priced so a total that includes non-Anthropic usage is a total; Caprock still does not charge for any of it and cannot see a bill.", - "A model may have more than one row: a price that has been superseded keeps its own row with `until` (the last date it applied, inclusive, UTC), and the current price is the row with no `until`. Rows for one id are ordered oldest-first and a turn is priced by the row in force when it ran, so an expiring introductory rate never restates history at a price nobody was charged. Sonnet 5 is the first: $2/$10 introductory through 2026-08-30, $3/$15 from 2026-08-31 (claude.com/pricing, read 2026-08-30)." + "A model may have more than one row: a price that has been superseded keeps its own row with `until` (the last date it applied, inclusive, UTC), and the current price is the row with no `until`. Rows for one id are ordered oldest-first and a turn is priced by the row in force when it ran, so an expiring introductory rate never restates history at a price nobody was charged. Sonnet 5 is the first: $2/$10 introductory through 2026-08-30, $3/$15 from 2026-08-31 (claude.com/pricing, read 2026-08-30).", + "Gemini prices are Google AI Studio paid-tier rates read from https://ai.google.dev/gemini-api/docs/pricing on 2026-09-01, for the text models the chat feature can reach. Image, video, TTS, embedding and robotics models are omitted because no code path can bill them.", + "gemini-3.7-flash and gemini-3.6-flash carry introductory pricing through 2026-12-31; input doubles to $1.50 and output to $7.50 on 2027-01-01. This table must be refreshed before that date or those two rows will understate cost.", + "Gemini has no 5m/1h cache-write price: Google bills cache storage per hour ($0.50-$4.50 per 1M tokens/hour by model), which is time-based and has no per-token equivalent, so cache_write_* are 0 for Gemini rows and cached input is priced at cache_read.", + "gemini-3.1-pro-preview and gemini-2.5-pro are tiered by prompt size; the rate here is the =<200k tier. Prompts over 200k tokens bill at roughly double ($4.00/$18.00 and $2.50/$15.00 respectively) and are therefore under-reported by this table." ], "models": [ { @@ -213,6 +217,86 @@ "cache_read": 0.06, "output": 1.2, "context_window": 204800 + }, + { + "id": "gemini-3.7-flash", + "display": "Gemini 3.7 Flash", + "input": 0.75, + "cache_write_5m": 0.0, + "cache_write_1h": 0.0, + "cache_read": 0.075, + "output": 3.75, + "context_window": 1000000 + }, + { + "id": "gemini-3.6-flash", + "display": "Gemini 3.6 Flash", + "input": 0.75, + "cache_write_5m": 0.0, + "cache_write_1h": 0.0, + "cache_read": 0.075, + "output": 3.75, + "context_window": 1000000 + }, + { + "id": "gemini-3.5-flash", + "display": "Gemini 3.5 Flash", + "input": 1.5, + "cache_write_5m": 0.0, + "cache_write_1h": 0.0, + "cache_read": 0.15, + "output": 9.0, + "context_window": 1000000 + }, + { + "id": "gemini-3.5-flash-lite", + "display": "Gemini 3.5 Flash Lite", + "input": 0.3, + "cache_write_5m": 0.0, + "cache_write_1h": 0.0, + "cache_read": 0.03, + "output": 2.5, + "context_window": 1000000 + }, + { + "id": "gemini-3.1-pro-preview", + "display": "Gemini 3.1 Pro", + "input": 2.0, + "cache_write_5m": 0.0, + "cache_write_1h": 0.0, + "cache_read": 0.2, + "output": 12.0, + "context_window": 1000000 + }, + { + "id": "gemini-2.5-pro", + "display": "Gemini 2.5 Pro", + "input": 1.25, + "cache_write_5m": 0.0, + "cache_write_1h": 0.0, + "cache_read": 0.125, + "output": 10.0, + "context_window": 1000000 + }, + { + "id": "gemini-2.5-flash", + "display": "Gemini 2.5 Flash", + "input": 0.3, + "cache_write_5m": 0.0, + "cache_write_1h": 0.0, + "cache_read": 0.03, + "output": 2.5, + "context_window": 1000000 + }, + { + "id": "gemini-2.5-flash-lite", + "display": "Gemini 2.5 Flash Lite", + "input": 0.1, + "cache_write_5m": 0.0, + "cache_write_1h": 0.0, + "cache_read": 0.01, + "output": 0.4, + "context_window": 1000000 } ] } diff --git a/ui/src/components/Gemini.test.tsx b/ui/src/components/Gemini.test.tsx new file mode 100644 index 0000000..8a4b6f4 --- /dev/null +++ b/ui/src/components/Gemini.test.tsx @@ -0,0 +1,54 @@ +/** + * The Gemini panel has to keep two absences apart. + * + * "No key" is a setup problem with a free fix — a variable name. "No licence" + * is a purchase. Merging them into one greyed-out button tells a reader who + * has not set the variable that they should pay, which is both wrong and the + * kind of wrong that gets a refund request. + */ +import { render, screen, waitFor } from '@testing-library/react' +import { describe, expect, it, vi } from 'vitest' +import { GeminiPanel } from './Gemini' +import type { GeminiStatus } from '@/lib/api' + +const status = vi.hoisted(() => ({ value: {} as GeminiStatus })) + +vi.mock('@/lib/api', async (orig) => { + const actual = await orig() + return { ...actual, api: { ...actual.api, gemini: async () => status.value } } +}) + +describe('GeminiPanel', () => { + it('names the variable to set when there is no key', async () => { + status.value = { available: false, env_var: 'GEMINI_API_KEY', licensed: true, model: 'gemini-3.5-flash-lite' } + render() + // The fix, not a paywall: this reader has nothing to buy. + await waitFor(() => expect(screen.getByText(/GEMINI_API_KEY/)).toBeInTheDocument()) + expect(screen.queryByRole('button', { name: /ask/i })).not.toBeInTheDocument() + }) + + it('says the key stays with the user, since that is the whole trade', async () => { + status.value = { available: false, env_var: 'GEMINI_API_KEY', licensed: true, model: 'm' } + render() + await waitFor(() => expect(screen.getByText(/never stores the key/i)).toBeInTheDocument()) + // And who gets paid, so nobody expects Caprock to be reselling tokens. + expect(screen.getByText(/pay Google directly/i)).toBeInTheDocument() + }) + + it('offers the box once a key is set', async () => { + status.value = { available: true, env_var: 'GEMINI_API_KEY', licensed: true, model: 'gemini-3.5-flash-lite' } + render() + await waitFor(() => expect(screen.getByRole('button', { name: /ask/i })).toBeInTheDocument()) + expect(screen.getByPlaceholderText(/ask about your sessions/i)).toBeInTheDocument() + // The model is named: it is the reader's money, and different models cost + // very different amounts. + expect(screen.getByText('gemini-3.5-flash-lite')).toBeInTheDocument() + }) + + it('will not send an empty question', async () => { + status.value = { available: true, env_var: 'GEMINI_API_KEY', licensed: true, model: 'm' } + render() + const btn = await screen.findByRole('button', { name: /ask/i }) + expect(btn).toBeDisabled() + }) +}) diff --git a/ui/src/components/Gemini.tsx b/ui/src/components/Gemini.tsx new file mode 100644 index 0000000..5654a5d --- /dev/null +++ b/ui/src/components/Gemini.tsx @@ -0,0 +1,128 @@ +/** + * Ask Gemini — the second paid feature, and the first that spends money. + * + * The shape of it is set by one decision (ADR-023): the key is not ours. It + * lives in the daemon's environment, Caprock never stores it and this page + * never sees it, so a bug here cannot leak a credential. What that costs is a + * worse first run — you set a variable and restart — and the panel says so + * plainly rather than pretending a field is missing. + * + * Two things can be absent, and they are different problems with different + * fixes, so the panel never merges them into one dead button: + * + * - **No key.** Nothing to do with money. The feature is simply not set up on + * this machine, and the answer is a variable name. + * - **No licence.** The key works, the feature is bought rather than built. + * The server refuses the call, so this is not a decoration over a working + * button — see the 402 in internal/api/gemini.go. + * + * What it costs is shown after every answer, from the response's own token + * counts. That figure is what Caprock sent, not what Google billed: there is + * no per-key billing API to reconcile against, and saying so is cheaper than + * being caught rounding. + */ +import { useState } from 'react' +import { api, errText, type GeminiReply } from '@/lib/api' +import { useApi } from '@/lib/useApi' +import { Panel } from '@/components/ui' +import { fmtTokens } from '@/lib/format' + +export function GeminiPanel() { + const status = useApi(() => api.gemini(), [], { live: false, intervalMs: 30000 }) + const [prompt, setPrompt] = useState('') + const [reply, setReply] = useState(null) + const [busy, setBusy] = useState(false) + const [error, setError] = useState('') + + const st = status.data + const ready = !!st?.available + + const ask = async () => { + const q = prompt.trim() + if (!q || busy) return + setBusy(true) + setError('') + try { + setReply(await api.askGemini(q)) + setPrompt('') + } catch (e) { + setError(errText(e)) + } finally { + setBusy(false) + } + } + + return ( + + {ready ? st?.model : 'your key, your bill'} + + } + > + {/* The setup case comes first because it is the one a reader can act on + * without paying anything. */} + {!ready ? ( +
+

+ Caprock can ask Google's Gemini on your own key. It never stores the key — + set it in the daemon's environment and restart: +

+ + export {st?.env_var ?? 'GEMINI_API_KEY'}=… + +

+ Get one from Google AI Studio. You pay Google directly; Caprock only counts what it sent. +

+
+ ) : ( +
+