specrails-desktop 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/dist/assets/{ActivityFeedPage-CoWwVcty.js → ActivityFeedPage-LKqd18-G.js} +1 -1
- package/client/dist/assets/{AgentsPage-CgPvynWc.js → AgentsPage-Cb-b-6Ot.js} +1 -1
- package/client/dist/assets/AnalyticsPage-HVxQQ1wy.js +1 -0
- package/client/dist/assets/{BarChart-BKXQPcoW.js → BarChart-BOyHB0dw.js} +1 -1
- package/client/dist/assets/{CodePage-CYhXRKiI.js → CodePage-DnOnwKGB.js} +1 -1
- package/client/dist/assets/{DesktopAnalyticsPage-CBfPCT3q.js → DesktopAnalyticsPage-D2auU39x.js} +1 -1
- package/client/dist/assets/{DocsDialog-uRTBV-3T.js → DocsDialog-CTuDX3GK.js} +1 -1
- package/client/dist/assets/{DocsPage-gH0Lc54I.js → DocsPage-DRyMmu0Z.js} +1 -1
- package/client/dist/assets/{ExportDropdown-DAp7zWib.js → ExportDropdown-DO-GGiMh.js} +1 -1
- package/client/dist/assets/{IntegrationsPage-D40Si_7s.js → IntegrationsPage-BhbO4jFT.js} +1 -1
- package/client/dist/assets/{JobDetailPage-DSxAvB1n.js → JobDetailPage-DJooEg1s.js} +1 -1
- package/client/dist/assets/{JobsPage-ZMBc1BHE.js → JobsPage-BbaC-YOg.js} +1 -1
- package/client/dist/assets/{addspec-DeDOztDr.js → addspec-B-BKlvDj.js} +1 -1
- package/client/dist/assets/{addspec-v8j6A7CD.js → addspec-BErjOdNK.js} +1 -1
- package/client/dist/assets/{addspec-B1FTtI2a.js → addspec-CIGb34PS.js} +1 -1
- package/client/dist/assets/{addspec-GWm4ffKl.js → addspec-C_3NBarY.js} +1 -1
- package/client/dist/assets/{addspec-Dw-0Dg-4.js → addspec-DDvvnE6N.js} +1 -1
- package/client/dist/assets/{addspec-DpRgmfmx.js → addspec-RuL8Zd7w.js} +1 -1
- package/client/dist/assets/{addspec-rp496P_F.js → addspec-rmhOaH7N.js} +1 -1
- package/client/dist/assets/{addspec-BCT9vm_c.js → addspec-xjDbYZWL.js} +1 -1
- package/client/dist/assets/{dist-js-CKqmDyXR.js → dist-js-CiIVMsx3.js} +1 -1
- package/client/dist/assets/{dist-js-bTZuok_W.js → dist-js-Xc2lRKp2.js} +1 -1
- package/client/dist/assets/{index-B9IKK_QQ.js → index-DK214dak.js} +34 -34
- package/client/dist/assets/index-DgKfQFcf.css +2 -0
- package/client/dist/assets/{lib-B5mjOeEi.js → lib-Bo5s6xpe.js} +1 -1
- package/client/dist/assets/{useProjectCache-Cf83MBQh.js → useProjectCache-DVNypkmR.js} +1 -1
- package/client/dist/index.html +3 -3
- package/docs/adding-a-provider.md +107 -0
- package/docs/agy-cli-provider-study.md +179 -0
- package/docs/gemini-cli-provider-study.md +301 -0
- package/docs/gemini-core-support-evaluation.md +160 -0
- package/docs/gemini.md +106 -0
- package/package.json +1 -1
- package/server/dist/chat-manager.js +1 -1
- package/server/dist/core-package.js +6 -1
- package/server/dist/desktop-router.js +27 -8
- package/server/dist/explore-cwd-manager.js +1 -1
- package/server/dist/mobile/mobile-datachannel.js +65 -4
- package/server/dist/pricing.js +13 -0
- package/server/dist/project-router-tickets.js +63 -18
- package/server/dist/providers/gemini-adapter.js +234 -0
- package/server/dist/providers/index.js +4 -1
- package/server/dist/setup-manager.js +13 -7
- package/server/dist/setup-prerequisites.js +4 -0
- package/server/dist/spec-models.js +17 -3
- package/server/dist/util/cli-prompt.js +17 -1
- package/client/dist/assets/AnalyticsPage-ioz3Ub2D.js +0 -1
- package/client/dist/assets/index-BqAXaTbC.css +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PROVIDER_DEFAULT_MODEL = exports.CODEX_MODELS = exports.CLAUDE_MODELS = void 0;
|
|
3
|
+
exports.PROVIDER_DEFAULT_MODEL = exports.GEMINI_MODELS = exports.CODEX_MODELS = exports.CLAUDE_MODELS = void 0;
|
|
4
4
|
exports.getModelsForProvider = getModelsForProvider;
|
|
5
5
|
exports.isValidModelForProvider = isValidModelForProvider;
|
|
6
6
|
exports.getProviderDefault = getProviderDefault;
|
|
@@ -15,12 +15,26 @@ exports.CODEX_MODELS = [
|
|
|
15
15
|
{ value: 'gpt-5.4-mini', label: 'GPT-5.4 Mini' },
|
|
16
16
|
{ value: 'gpt-5.3-codex', label: 'GPT-5.3 Codex' },
|
|
17
17
|
];
|
|
18
|
+
// Mirrors GEMINI_MODELS in server/providers/gemini-adapter.ts.
|
|
19
|
+
exports.GEMINI_MODELS = [
|
|
20
|
+
{ value: 'gemini-3.5-flash', label: 'Gemini 3.5 Flash' },
|
|
21
|
+
{ value: 'gemini-3.1-pro-preview', label: 'Gemini 3.1 Pro (preview)' },
|
|
22
|
+
{ value: 'gemini-3.1-flash-lite', label: 'Gemini 3.1 Flash Lite' },
|
|
23
|
+
{ value: 'gemini-2.5-flash-lite', label: 'Gemini 2.5 Flash Lite' },
|
|
24
|
+
];
|
|
25
|
+
/** Per-provider model catalog. Lookup, not a branch — fallback is Claude's. */
|
|
26
|
+
const PROVIDER_MODELS = {
|
|
27
|
+
claude: exports.CLAUDE_MODELS,
|
|
28
|
+
codex: exports.CODEX_MODELS,
|
|
29
|
+
gemini: exports.GEMINI_MODELS,
|
|
30
|
+
};
|
|
18
31
|
exports.PROVIDER_DEFAULT_MODEL = {
|
|
19
32
|
claude: 'sonnet',
|
|
20
33
|
codex: 'gpt-5.5',
|
|
34
|
+
gemini: 'gemini-3.5-flash',
|
|
21
35
|
};
|
|
22
36
|
function getModelsForProvider(provider) {
|
|
23
|
-
return provider
|
|
37
|
+
return PROVIDER_MODELS[provider] ?? exports.CLAUDE_MODELS;
|
|
24
38
|
}
|
|
25
39
|
function isValidModelForProvider(model, provider) {
|
|
26
40
|
if (typeof model !== 'string' || model.length === 0)
|
|
@@ -28,5 +42,5 @@ function isValidModelForProvider(model, provider) {
|
|
|
28
42
|
return getModelsForProvider(provider).some((m) => m.value === model);
|
|
29
43
|
}
|
|
30
44
|
function getProviderDefault(provider) {
|
|
31
|
-
return exports.PROVIDER_DEFAULT_MODEL[provider];
|
|
45
|
+
return exports.PROVIDER_DEFAULT_MODEL[provider] ?? exports.PROVIDER_DEFAULT_MODEL.claude;
|
|
32
46
|
}
|
|
@@ -26,6 +26,7 @@ exports.transformCodexArgsForWindows = transformCodexArgsForWindows;
|
|
|
26
26
|
exports.ensureStdinPipe = ensureStdinPipe;
|
|
27
27
|
exports.spawnClaude = spawnClaude;
|
|
28
28
|
exports.spawnCodex = spawnCodex;
|
|
29
|
+
exports.spawnGemini = spawnGemini;
|
|
29
30
|
exports.spawnAiCli = spawnAiCli;
|
|
30
31
|
const win_spawn_1 = require("./win-spawn");
|
|
31
32
|
const isWin = process.platform === 'win32';
|
|
@@ -167,9 +168,22 @@ function spawnCodex(args, options = {}) {
|
|
|
167
168
|
return child;
|
|
168
169
|
/* c8 ignore stop */
|
|
169
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Spawn `gemini` headless. Injects `GEMINI_CLI_TRUST_WORKSPACE=true` so the CLI
|
|
173
|
+
* does not silently override `--yolo` back to "default" (which blocks EVERY tool
|
|
174
|
+
* call) when the project dir is not a "trusted folder" — the documented escape
|
|
175
|
+
* hatch for headless/automated environments. Validated empirically: without it,
|
|
176
|
+
* a headless `gemini -p` run executes zero tool calls and the rail does nothing.
|
|
177
|
+
* No multi-line argv quirk (the prompt rides on a single `-p` value), so the
|
|
178
|
+
* Windows path is identical to POSIX.
|
|
179
|
+
*/
|
|
180
|
+
function spawnGemini(args, options = {}) {
|
|
181
|
+
const env = { ...(options.env ?? process.env), GEMINI_CLI_TRUST_WORKSPACE: 'true' };
|
|
182
|
+
return (0, win_spawn_1.spawnCli)('gemini', args, { ...options, env });
|
|
183
|
+
}
|
|
170
184
|
/**
|
|
171
185
|
* Convenience: dispatch on binary name. Use when callsite picks the
|
|
172
|
-
* binary dynamically (claude vs codex). Anything else routes through
|
|
186
|
+
* binary dynamically (claude vs codex vs gemini). Anything else routes through
|
|
173
187
|
* the underlying spawnCli unchanged.
|
|
174
188
|
*/
|
|
175
189
|
function spawnAiCli(binary, args, options = {}) {
|
|
@@ -177,5 +191,7 @@ function spawnAiCli(binary, args, options = {}) {
|
|
|
177
191
|
return spawnClaude(args, options);
|
|
178
192
|
if (binary === 'codex')
|
|
179
193
|
return spawnCodex(args, options);
|
|
194
|
+
if (binary === 'gemini')
|
|
195
|
+
return spawnGemini(args, options);
|
|
180
196
|
return (0, win_spawn_1.spawnCli)(binary, args, options);
|
|
181
197
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{t}from"./clsx-CnH-HMk3.js";import{$t as n,Et as r,K as i,Lt as a,Rt as o,Tt as s,an as c,bt as l,c as u,s as d,sn as f,tn as p,v as m,wt as h,zt as g}from"./index-B9IKK_QQ.js";import{t as _}from"./ExportDropdown-DAp7zWib.js";import{A as v,B as y,C as b,D as x,E as S,F as C,G as w,H as T,I as E,J as D,K as O,L as k,M as A,N as j,O as M,P as N,Q as P,R as F,S as I,T as L,V as R,X as z,Z as B,_ as V,_t as ee,a as H,at as te,b as ne,c as re,ct as ie,et as ae,f as oe,g as se,gt as ce,h as le,i as ue,j as de,k as fe,l as pe,lt as U,m as me,n as he,nt as ge,o as _e,ot as ve,p as ye,pt as W,q as be,r as xe,rt as G,s as Se,st as Ce,t as we,tt as Te,ut as K,v as Ee,x as De,y as Oe,z as ke}from"./BarChart-BKXQPcoW.js";var Ae=h(`arrow-down-right`,[[`path`,{d:`m7 7 10 10`,key:`1fmybs`}],[`path`,{d:`M17 7v10H7`,key:`6fjiku`}]]),q=e(f(),1),J=o();function Y(e){return e>=100?`$${e.toFixed(0)}`:e>=10?`$${e.toFixed(1)}`:`$${e.toFixed(2)}`}function je(e){return e>=1e3?`$${(e/1e3).toFixed(1)}k`:`$${e.toFixed(2)}`}function Me(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:`${e}`}var Ne=[`job`,`explore-spec`,`quick-spec`,`ai-edit`,`smash`];function Pe({data:e,loading:t}){let{t:r}=n(`analytics`),[i,a]=(0,q.useState)(0),o=(0,q.useRef)(0);if((0,q.useEffect)(()=>{if(!e)return;let t=e.summary.totalCostUsd;if(o.current===0&&t>0){let e=performance.now(),n=r=>{let i=Math.min(1,(r-e)/600),o=1-(1-i)**3;a(0+(t-0)*o),i<1&&requestAnimationFrame(n)};requestAnimationFrame(n)}else a(t);o.current=t},[e]),t&&!e)return(0,J.jsx)(`div`,{className:`h-44 rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let s=e.summary.totalCostUsd,c=e.summary.totalRuns,f=e.summary.totalTokens??0,p=e.summary.totalEstimatedCostUsd??0,m=e.summary.deltaPct,h=e.trackingStartedAt,g=p>0,_=Ne.map(t=>{let n=e.bySurface.find(e=>e.surface===t);return{surface:t,costUsd:n?.costUsd??0,count:n?.count??0}});return(0,J.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-gradient-to-br from-card/80 to-card/40 p-5`,children:[(0,J.jsxs)(`div`,{className:`flex flex-wrap items-end justify-between gap-3 mb-4`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`text-[11px] uppercase tracking-wider text-muted-foreground mb-1`,children:r(`hero.spending`)}),(0,J.jsxs)(`div`,{className:`flex items-baseline gap-3`,children:[(0,J.jsx)(`div`,{className:`text-5xl font-semibold tabular-nums tracking-tight`,children:je(i)}),m!==null&&(0,J.jsxs)(`span`,{className:`inline-flex items-center gap-0.5 text-xs font-medium ${m>=0?`text-accent-warning`:`text-accent-success`}`,children:[m>=0?(0,J.jsx)(l,{className:`w-3 h-3`}):(0,J.jsx)(Ae,{className:`w-3 h-3`}),r(`hero.vsPrev`,{pct:Math.abs(m).toFixed(0)})]})]}),(0,J.jsxs)(`div`,{className:`text-xs text-muted-foreground mt-1 tabular-nums flex items-center gap-2`,children:[(0,J.jsx)(`span`,{children:r(`hero.invocations`,{count:c})}),f>0&&(0,J.jsx)(`span`,{className:`text-muted-foreground/80`,title:r(`hero.tokensTooltip`),children:r(`hero.tokens`,{tokens:Me(f)})}),g&&(0,J.jsx)(`span`,{className:`text-[10px] text-muted-foreground/70 italic`,title:r(`hero.includesEstimatedTooltip`,{amount:Y(p)}),children:r(`hero.includesEstimated`,{amount:Y(p)})})]})]}),c===0&&h&&(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:r(`hero.trackingStarted`,{date:h.slice(0,10)})})]}),c===0?(0,J.jsxs)(`div`,{className:`rounded-lg border border-dashed border-border/40 p-6 text-center`,children:[(0,J.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:r(`hero.emptyState`)}),(0,J.jsx)(`p`,{className:`text-xs text-muted-foreground/70 mt-1`,children:h?r(`hero.trackingStarted`,{date:h.slice(0,10)}):r(`hero.trackingStartedFallback`)})]}):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`div`,{className:`h-3 w-full rounded-full overflow-hidden bg-background-deep flex`,children:_.map(e=>{let t=s>0?e.costUsd/s*100:0;return t===0?null:(0,J.jsx)(`div`,{className:`h-full ${d[e.surface].dot}`,style:{width:`${t}%`},title:r(`hero.segmentTitle`,{label:u[e.surface],value:Y(e.costUsd)})},e.surface)})}),(0,J.jsx)(`div`,{className:`mt-3 flex flex-wrap items-center gap-x-5 gap-y-1.5 text-xs`,children:_.filter(e=>e.costUsd>0).map(e=>(0,J.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 tabular-nums`,children:[(0,J.jsx)(`span`,{className:`w-2 h-2 rounded-full ${d[e.surface].dot}`}),(0,J.jsx)(`span`,{className:`text-muted-foreground`,children:u[e.surface]}),(0,J.jsx)(`span`,{className:`text-foreground font-medium`,children:Y(e.costUsd)}),(0,J.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,J.jsx)(`span`,{className:`text-muted-foreground/80`,children:e.count})]},e.surface))})]})]})}var Fe={claude:`Claude`,codex:`Codex`},Ie={claude:`bg-accent-info`,codex:`bg-accent-highlight`};function Le(e){return e>=100?`$${e.toFixed(0)}`:e>=10?`$${e.toFixed(1)}`:e>=.01?`$${e.toFixed(2)}`:`$${e.toFixed(4)}`}function Re(e){return Fe[e]??e}function ze(e){return Ie[e]??`bg-accent-secondary`}function Be({data:e,loading:t}){let{t:r}=n(`analytics`);if(t&&!e)return(0,J.jsx)(`div`,{className:`h-32 rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e||e.byProvider.length===0||e.byProvider.length===1)return null;let i=e.byProvider.reduce((e,t)=>e+t.costUsd+t.estimatedCostUsd,0);return(0,J.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,J.jsx)(`div`,{className:`flex items-baseline justify-between mb-3`,children:(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`text-[11px] uppercase tracking-wider text-muted-foreground`,children:r(`providerCard.title`)}),(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground/70 mt-0.5`,children:(0,J.jsx)(p,{ns:`analytics`,i18nKey:`providerCard.description`,components:{tilde:(0,J.jsx)(`span`,{className:`font-medium`})}})})]})}),i===0?(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground italic`,children:r(`providerCard.noCost`)}):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`div`,{className:`h-2 w-full rounded-full overflow-hidden bg-background-deep flex mb-3`,children:e.byProvider.map(e=>{let t=e.costUsd+e.estimatedCostUsd,n=i>0?t/i*100:0;return n===0?null:(0,J.jsx)(`div`,{className:`h-full ${ze(e.provider)}`,style:{width:`${n}%`},title:r(`providerCard.segmentTitle`,{label:Re(e.provider),value:Le(t),count:e.count})},e.provider)})}),(0,J.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-2`,children:e.byProvider.map(e=>(0,J.jsx)(Ve,{entry:e},e.provider))})]})]})}function Ve({entry:e}){let{t}=n(`analytics`),r=e.costUsd+e.estimatedCostUsd,i=e.costUsd===0&&e.estimatedCostUsd>0;return(0,J.jsxs)(`div`,{className:`flex items-center gap-2.5 rounded-md border border-border/30 px-2.5 py-1.5`,children:[(0,J.jsx)(`span`,{className:`w-2 h-2 rounded-full shrink-0 ${ze(e.provider)}`}),(0,J.jsx)(`span`,{className:`text-xs font-medium`,children:Re(e.provider)}),(0,J.jsx)(`span`,{className:`text-[10px] text-muted-foreground tabular-nums`,children:t(`runs`,{count:e.count})}),(0,J.jsxs)(`span`,{className:`ml-auto text-xs font-medium tabular-nums`,children:[i?`~`:``,Le(r)]})]})}var He=[`option`,`isActive`];function X(){return X=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},X.apply(null,arguments)}function Ue(e,t){if(e==null)return{};var n,r,i=We(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function We(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function Ge(e){var{option:t,isActive:n}=e,r=Ue(e,He);return typeof t==`string`?q.createElement(I,X({option:q.createElement(Ce,X({type:t},r)),isActive:n,shapeType:`symbols`},r)):q.createElement(I,X({option:t,isActive:n,shapeType:`symbols`},r))}var Ke=ae([(e,t,n,r,i,a,o)=>F(e,void 0,void 0,o),(e,t,n,r,i,a,o)=>j(e,`xAxis`,t,o),(e,t,n,r,i,a,o)=>N(e,`xAxis`,t,o),(e,t,n,r,i,a,o)=>j(e,`yAxis`,n,o),(e,t,n,r,i,a,o)=>N(e,`yAxis`,n,o),(e,t,n,r)=>E(e,`zAxis`,r,!1),ae([C,(e,t,n,r,i)=>i],(e,t)=>e.filter(e=>e.type===`scatter`).find(e=>e.id===t)),(e,t,n,r,i,a)=>a],(e,t,n,r,i,a,o,s)=>{var{chartData:c,dataStartIndex:l,dataEndIndex:u}=e;if(o!=null){var d=o?.data!=null&&o.data.length>0?o.data:c?.slice(l,u+1);if(!(d==null||t==null||r==null||n==null||i==null||n?.length===0||i?.length===0))return st({displayedData:d,xAxis:t,yAxis:r,zAxis:a,scatterSettings:o,xAxisTicks:n,yAxisTicks:i,cells:s})}}),qe=[`id`],Je=[`onMouseEnter`,`onClick`,`onMouseLeave`],Ye=[`animationBegin`,`animationDuration`,`animationEasing`,`hide`,`isAnimationActive`,`legendType`,`lineJointType`,`lineType`,`shape`,`xAxisId`,`yAxisId`,`zAxisId`];function Z(e,t){if(e==null)return{};var n,r,i=Xe(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function Xe(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function Q(){return Q=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Q.apply(null,arguments)}function Ze(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function $(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?Ze(Object(n),!0).forEach(function(t){Qe(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ze(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Qe(e,t,n){return(t=$e(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function $e(e){var t=et(e,`string`);return typeof t==`symbol`?t:t+``}function et(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var tt=e=>{var{dataKey:t,name:n,fill:r,legendType:i,hide:a}=e;return[{inactive:a,dataKey:t,type:i,color:r,value:B(n,t),payload:e}]},nt=q.memo(e=>{var{dataKey:t,points:n,stroke:r,strokeWidth:i,fill:a,name:o,hide:s,tooltipType:c,id:l}=e,u={dataDefinedOnItem:n?.map(e=>e.tooltipPayload),getPosition:e=>{var t;return n==null||(t=n[Number(e)])==null?void 0:t.tooltipPosition},settings:{stroke:r,strokeWidth:i,fill:a,nameKey:void 0,dataKey:t,name:B(o,t),hide:s,type:c,color:a,unit:``,graphicalItemId:l}};return q.createElement(Ee,{tooltipEntrySettings:u})});function rt(e){var{points:t,props:n}=e,{line:r,lineType:i,lineJointType:a}=n;if(!r)return null;var o=ce(n),s=ee(r),c,l;if(i===`joint`)c=t.map(e=>({x:e.cx??null,y:e.cy??null}));else if(i===`fitting`){var{xmin:u,xmax:d,a:f,b:p}=ie(t),m=e=>f*e+p;c=[{x:u,y:m(u)},{x:d,y:m(d)}]}var h=$($($({},o),{},{fill:`none`,stroke:o&&o.fill},s),{},{points:c});return l=q.isValidElement(r)?q.cloneElement(r,h):typeof r==`function`?r(h):q.createElement(R,Q({},h,{type:a})),q.createElement(W,{className:`recharts-scatter-line`,key:`recharts-scatter-line`},l)}function it(e){var{showLabels:t,points:n,children:r}=e,i=w(),a=(0,q.useMemo)(()=>n?.map(e=>{var t={x:e.x??0,y:e.y??0,width:e.width,height:e.height,lowerWidth:e.width,upperWidth:e.width};return $($({},t),{},{value:void 0,payload:e.payload,viewBox:t,parentViewBox:i,fill:void 0})}),[i,n]);return q.createElement(L,{value:t?a:void 0},r)}function at(e){var{points:t,allOtherScatterProps:n}=e,{shape:r,activeShape:i,dataKey:a}=n,{id:o}=n,s=Z(n,qe),c=ge(de),{onMouseEnter:l,onClick:u,onMouseLeave:d}=n,f=Z(n,Je),p=ne(l,a,o),m=De(d),h=Oe(u,a,o);if(!ve(t))return null;var g=ce(s);return q.createElement(q.Fragment,null,q.createElement(rt,{points:t,props:s}),t.map((e,t)=>{var n=i!=null&&i!==!1,a=n&&c===String(t),s=n&&a?i:r,l=$($($({},g),e),{},{index:t,[D]:String(o)});return q.createElement(v,{key:`symbol-${e?.cx}-${e?.cy}-${e?.size}-${t}`,zIndex:a?k.activeDot:void 0},q.createElement(W,Q({className:`recharts-scatter-symbol`},te(f,e,t),{onMouseEnter:p(e,t),onMouseLeave:m(e,t),onClick:h(e,t)}),q.createElement(Ge,Q({option:s,isActive:a},l))))}))}function ot(e){var{previousPointsRef:t,props:n}=e,{points:r,isAnimationActive:i,animationBegin:a,animationDuration:o,animationEasing:s}=n,c=t.current,l=ke(n,`recharts-scatter-`),[u,d]=(0,q.useState)(!1),f=(0,q.useCallback)(()=>{d(!1)},[]),p=(0,q.useCallback)(()=>{d(!0)},[]),m=!u;return q.createElement(it,{showLabels:m,points:r},n.children,q.createElement(y,{animationId:l,begin:a,duration:o,isActive:i,easing:s,onAnimationEnd:f,onAnimationStart:p,key:l},e=>{var i=e===1?r:r?.map((t,n)=>{var r=c&&c[n];return r?$($({},t),{},{cx:t.cx==null?void 0:U(r.cx,t.cx,e),cy:t.cy==null?void 0:U(r.cy,t.cy,e),size:U(r.size,t.size,e)}):$($({},t),{},{size:U(0,t.size,e)})});return e>0&&(t.current=i),q.createElement(W,null,q.createElement(at,{points:i,allOtherScatterProps:n,showLabels:m}))}),q.createElement(S,{label:n.label}))}function st(e){var{displayedData:t,xAxis:n,yAxis:r,zAxis:i,scatterSettings:a,xAxisTicks:o,yAxisTicks:s,cells:c}=e,l=K(n.dataKey)?a.dataKey:n.dataKey,u=K(r.dataKey)?a.dataKey:r.dataKey,d=i&&i.dataKey,f=i?i.range:A.range,p=f&&f[0],m=n.scale.bandwidth?n.scale.bandwidth():0,h=r.scale.bandwidth?r.scale.bandwidth():0;return t.map((e,t)=>{var f=P(e,l),g=P(e,u),_=!K(d)&&P(e,d)||`-`,v=[{name:K(n.dataKey)?a.name:n.name||String(n.dataKey),unit:n.unit||``,value:f,payload:e,dataKey:l,type:a.tooltipType,graphicalItemId:a.id},{name:K(r.dataKey)?a.name:r.name||String(r.dataKey),unit:r.unit||``,value:g,payload:e,dataKey:u,type:a.tooltipType,graphicalItemId:a.id}];_!==`-`&&i!=null&&v.push({name:i.name||i.dataKey,unit:i.unit||``,value:_,payload:e,dataKey:d,type:a.tooltipType,graphicalItemId:a.id});var y=z({axis:n,ticks:o,bandSize:m,entry:e,index:t,dataKey:l}),b=z({axis:r,ticks:s,bandSize:h,entry:e,index:t,dataKey:u}),x=_!==`-`&&i!=null?i.scale.map(_):p,S=x==null?0:Math.sqrt(Math.max(x,0)/Math.PI);return $($({},e),{},{cx:y,cy:b,x:y==null?void 0:y-S,y:b==null?void 0:b-S,width:2*S,height:2*S,size:x,node:{x:f,y:g,z:_},tooltipPayload:v,tooltipPosition:{x:y,y:b},payload:e},c&&c[t]&&c[t].props)})}var ct=(e,t,n)=>({x:e.cx,y:e.cy,value:Number(n===`x`?e.node.x:e.node.y),errorVal:P(e,t)});function lt(e){var{hide:n,points:r,className:i,needClip:a,xAxisId:o,yAxisId:s,id:c}=e,l=(0,q.useRef)(null);if(n)return null;var u=t(`recharts-scatter`,i),d=c;return q.createElement(v,{zIndex:e.zIndex},q.createElement(W,{className:u,clipPath:a?`url(#clipPath-${d})`:void 0,id:c},a&&q.createElement(`defs`,null,q.createElement(_e,{clipPathId:d,xAxisId:o,yAxisId:s})),q.createElement(re,{xAxisId:o,yAxisId:s,data:r,dataPointFormatter:ct,errorBarOffset:0},q.createElement(W,{key:`recharts-scatter-symbols`},q.createElement(ot,{props:e,previousPointsRef:l})))))}var ut={xAxisId:0,yAxisId:0,zAxisId:0,label:!1,line:!1,legendType:`circle`,lineType:`joint`,lineJointType:`linear`,shape:`circle`,hide:!1,isAnimationActive:`auto`,animationBegin:0,animationDuration:400,animationEasing:`linear`,zIndex:k.scatter};function dt(e){var t=G(e,ut),{animationBegin:n,animationDuration:r,animationEasing:i,hide:a,isAnimationActive:o,legendType:s,lineJointType:c,lineType:l,shape:u,xAxisId:d,yAxisId:f,zAxisId:p}=t,m=Z(t,Ye),{needClip:h}=Se(d,f),g=(0,q.useMemo)(()=>b(e.children,x),[e.children]),_=be(),v=ge(t=>Ke(t,d,f,p,e.id,g,_));return h==null||v==null?null:q.createElement(q.Fragment,null,q.createElement(nt,{dataKey:e.dataKey,points:v,stroke:e.stroke,strokeWidth:e.strokeWidth,fill:e.fill,name:e.name,hide:e.hide,tooltipType:e.tooltipType,id:e.id}),q.createElement(lt,Q({},m,{xAxisId:d,yAxisId:f,zAxisId:p,lineType:l,lineJointType:c,legendType:s,shape:u,hide:a,isAnimationActive:o,animationBegin:n,animationDuration:r,animationEasing:i,points:v,needClip:h})))}function ft(e){var t=G(e,ut),n=be();return q.createElement(se,{id:t.id,type:`scatter`},e=>q.createElement(q.Fragment,null,q.createElement(V,{legendPayload:tt(t)}),q.createElement(le,{type:`scatter`,id:e,data:t.data,xAxisId:t.xAxisId,yAxisId:t.yAxisId,zAxisId:t.zAxisId,dataKey:t.dataKey,hide:t.hide,name:t.name,tooltipType:t.tooltipType,isPanorama:n}),q.createElement(dt,Q({},t,{id:e}))))}var pt=q.memo(ft,T);pt.displayName=`Scatter`;function mt(e){var t=Te(),n=(0,q.useRef)(null);return(0,q.useLayoutEffect)(()=>{n.current===null?t(oe(e)):n.current!==e&&t(me({prev:n.current,next:e})),n.current=e},[e,t]),(0,q.useLayoutEffect)(()=>()=>{n.current&&=(t(ye(n.current)),null)},[t]),null}var ht={zAxisId:0,range:A.range,scale:A.scale,type:A.type};function gt(e){var t=G(e,ht);return q.createElement(mt,{domain:t.domain,id:t.zAxisId,dataKey:t.dataKey,name:t.name,unit:t.unit,range:t.range,scale:t.scale,type:t.type,allowDuplicatedCategory:A.allowDuplicatedCategory,allowDataOverflow:A.allowDataOverflow,reversed:A.reversed,includeHidden:A.includeHidden})}gt.displayName=`ZAxis`;var _t=[`item`],vt=(0,q.forwardRef)((e,t)=>q.createElement(he,{chartName:`ScatterChart`,defaultTooltipEventType:`item`,validateTooltipEventTypes:_t,tooltipPayloadSearcher:fe,categoricalChartProps:e,ref:t}));function yt({data:e,loading:t}){let{t:r}=n(`analytics`);if(t&&!e)return(0,J.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let i={jobs:r(`surfaces.job`),explore:r(`surfaces.exploreSpec`),quick:r(`surfaces.quickSpec`),refine:r(`surfaces.aiEdit`),fileSummaries:r(`surfaces.fileSummary`)},a=e.dailyTimeline.map(e=>({date:e.date.slice(5),[i.jobs]:e.jobsCostUsd,[i.explore]:e.exploreCostUsd,[i.quick]:e.quickCostUsd,[i.refine]:e.aiEditCostUsd,[i.fileSummaries]:e.fileSummaryCostUsd??0})),o=e.dailyTimeline.every(e=>e.jobsCostUsd+e.exploreCostUsd+e.quickCostUsd+e.aiEditCostUsd+(e.fileSummaryCostUsd??0)===0);return(0,J.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,J.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,J.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:r(`timeline.title`)}),(0,J.jsx)(`span`,{className:`text-[10px] text-muted-foreground/70`,children:r(`timeline.subtitle`)})]}),o?(0,J.jsx)(`div`,{className:`h-40 flex items-center justify-center text-xs text-muted-foreground/70`,children:r(`timeline.empty`)}):(0,J.jsx)(`div`,{className:`h-[220px]`,children:(0,J.jsx)(O,{width:`100%`,height:`100%`,children:(0,J.jsxs)(we,{data:a,margin:{top:10,right:10,left:-8,bottom:0},children:[(0,J.jsx)(pe,{strokeDasharray:`2 4`,stroke:`currentColor`,className:`text-border/30`,vertical:!1}),(0,J.jsx)(ue,{dataKey:`date`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`}),(0,J.jsx)(xe,{tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,tickFormatter:e=>`$${e}`}),(0,J.jsx)(M,{contentStyle:{backgroundColor:`var(--popover)`,border:`1px solid var(--border)`,fontSize:11,borderRadius:6},formatter:(e,t)=>[`$${typeof e==`number`?e.toFixed(2):`—`}`,String(t)]}),(0,J.jsx)(H,{dataKey:i.jobs,stackId:`a`,fill:`var(--accent-info, #5fa8d3)`}),(0,J.jsx)(H,{dataKey:i.explore,stackId:`a`,fill:`var(--accent-highlight, #c084fc)`}),(0,J.jsx)(H,{dataKey:i.quick,stackId:`a`,fill:`var(--accent-secondary, #f7768e)`}),(0,J.jsx)(H,{dataKey:i.refine,stackId:`a`,fill:`var(--accent-success, #50fa7b)`}),(0,J.jsx)(H,{dataKey:i.fileSummaries,stackId:`a`,fill:`var(--accent-warning, #f1fa8c)`})]})})})]})}function bt(e){return e==null?`—`:e<.005?`$${e.toFixed(4)}`:e<1?`$${e.toFixed(3)}`:`$${e.toFixed(2)}`}function xt(e){return e==null?`—`:e<1e3?`${e} ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3)}s`}function St({values:e}){let t=Math.max(1e-4,...e);return(0,J.jsx)(`div`,{className:`flex items-end gap-[1px] h-5`,children:e.map((e,n)=>(0,J.jsx)(`div`,{className:`w-[3px] rounded-sm bg-foreground/40`,style:{height:`${Math.max(2,e/t*20)}px`}},n))})}function Ct({mode:e,label:t,accentClass:r}){let{t:i}=n(`analytics`),a=e.mode===`explore`&&e.totalRuns<5;return(0,J.jsxs)(`div`,{className:`flex-1 p-4 first:pr-2 last:pl-2`,children:[(0,J.jsxs)(`div`,{className:`flex items-center gap-2 mb-2`,children:[(0,J.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full ${r}`}),(0,J.jsx)(`span`,{className:`text-xs font-medium uppercase tracking-wider text-muted-foreground`,children:t})]}),a?(0,J.jsxs)(`div`,{className:`py-3`,children:[(0,J.jsx)(`p`,{className:`text-sm text-foreground`,children:i(`quickVsExplore.sparseCta`)}),(0,J.jsx)(`p`,{className:`text-xs text-muted-foreground mt-1`,children:i(`quickVsExplore.runsSoFar`,{count:e.totalRuns})})]}):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`div`,{className:`text-3xl font-semibold tabular-nums tracking-tight`,children:bt(e.avgCostPerSpec)}),(0,J.jsx)(`div`,{className:`text-[11px] text-muted-foreground mt-0.5`,children:i(`quickVsExplore.perSpec`)}),(0,J.jsx)(`div`,{className:`mt-3`,children:(0,J.jsx)(St,{values:e.sparkline.length>0?e.sparkline:[0]})}),(0,J.jsxs)(`div`,{className:`mt-3 space-y-0.5 text-xs tabular-nums text-muted-foreground`,children:[(0,J.jsx)(`div`,{children:(0,J.jsx)(p,{ns:`analytics`,i18nKey:`quickVsExplore.createdRuns`,values:{created:e.ticketsCreated,runs:e.totalRuns},components:{strong:(0,J.jsx)(`span`,{className:`text-foreground font-medium`})}})}),(0,J.jsx)(`div`,{children:i(`quickVsExplore.avgDuration`,{duration:xt(e.avgDurationMs)})}),(0,J.jsx)(`div`,{className:`truncate`,children:e.dominantModel??`—`})]})]})]})}function wt({data:e,loading:t}){let{t:r}=n(`analytics`);if(t&&!e)return(0,J.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let i=e.byMode.find(e=>e.mode===`quick`),a=e.byMode.find(e=>e.mode===`explore`);if(!i||!a)return null;let o=i.avgCostPerSpec&&a.avgCostPerSpec&&i.avgCostPerSpec>0?a.avgCostPerSpec/i.avgCostPerSpec:null,s=o!==null&&i.totalRuns>=1&&a.totalRuns>=5;return(0,J.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40`,children:[(0,J.jsx)(`div`,{className:`px-4 pt-3 pb-1`,children:(0,J.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:r(`quickVsExplore.title`)})}),(0,J.jsxs)(`div`,{className:`flex divide-x divide-border/40`,children:[(0,J.jsx)(Ct,{mode:i,label:r(`quickVsExplore.quick`),accentClass:`bg-accent-secondary`}),(0,J.jsx)(Ct,{mode:a,label:r(`quickVsExplore.explore`),accentClass:`bg-accent-highlight`})]}),s&&(0,J.jsx)(`div`,{className:`px-4 pb-3 -mt-1`,children:(0,J.jsx)(`div`,{className:`text-center text-[11px] text-muted-foreground tabular-nums`,children:(0,J.jsxs)(`span`,{className:`px-2`,children:[`━━━━━━ `,r(`quickVsExplore.ratio`,{ratio:o.toFixed(1)}),` ━━━━━━`]})})})]})}function Tt({data:e,loading:t,onSelectModel:r,activeModel:i}){let{t:a}=n(`analytics`);if(t&&!e)return(0,J.jsx)(`div`,{className:`h-[220px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let o=e.byModel.reduce((e,t)=>e+t.costUsd,0),s=e.byModel.slice(0,5);return(0,J.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,J.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3`,children:a(`models.title`)}),s.length===0?(0,J.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:a(`models.empty`)}):(0,J.jsx)(`ul`,{className:`space-y-1.5`,children:s.map(e=>{let t=o>0?e.costUsd/o*100:0,n=i===e.model;return(0,J.jsx)(`li`,{children:(0,J.jsxs)(`button`,{type:`button`,onClick:()=>r(e.model),className:`w-full text-left group rounded-md px-2 py-1.5 transition-colors ${n?`bg-accent-highlight/10 ring-1 ring-accent-highlight/30`:`hover:bg-accent/30`}`,children:[(0,J.jsxs)(`div`,{className:`flex items-center justify-between text-[12px] mb-1 tabular-nums`,children:[(0,J.jsx)(`span`,{className:`truncate font-medium`,children:e.model}),(0,J.jsxs)(`span`,{className:`text-muted-foreground`,children:[`$`,e.costUsd.toFixed(2),` · `,e.count]})]}),(0,J.jsx)(`div`,{className:`h-1.5 rounded-full bg-background-deep overflow-hidden`,children:(0,J.jsx)(`div`,{className:`h-full ${n?`bg-accent-highlight`:`bg-foreground/40 group-hover:bg-foreground/60`} transition-colors`,style:{width:`${t}%`}})})]})},e.model)})})]})}var Et={job:`var(--accent-info, #5fa8d3)`,"quick-spec":`var(--accent-secondary, #f7768e)`,"explore-spec":`var(--accent-highlight, #c084fc)`,"ai-edit":`var(--accent-success, #50fa7b)`,smash:`var(--accent-highlight, #c084fc)`};function Dt({data:e,loading:t,onSelectPoint:r}){let{t:i}=n(`analytics`);if(t&&!e)return(0,J.jsx)(`div`,{className:`h-[260px] rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let a=[`job`,`quick-spec`,`explore-spec`,`ai-edit`,`smash`],o=a.map(t=>({surface:t,points:e.scatter.filter(e=>e.surface===t).map(e=>({id:e.id,x:e.numTurns??Math.round((e.durationMs??0)/1e3),y:e.costUsd,surface:t,ticketId:e.ticketId,startedAt:e.startedAt,raw:e}))})),s=e.scatter.length===0;return(0,J.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,J.jsxs)(`div`,{className:`flex items-center justify-between mb-2`,children:[(0,J.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:i(`scatter.title`)}),(0,J.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 text-[10px]`,children:a.map(e=>(0,J.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,J.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full`,style:{background:Et[e]}}),(0,J.jsx)(`span`,{className:`text-muted-foreground`,children:u[e]})]},e))})]}),s?(0,J.jsx)(`div`,{className:`h-40 flex items-center justify-center text-xs text-muted-foreground/70`,children:i(`scatter.empty`)}):(0,J.jsx)(`div`,{className:`h-[260px]`,children:(0,J.jsx)(O,{width:`100%`,height:`100%`,children:(0,J.jsxs)(vt,{margin:{top:10,right:10,left:-8,bottom:5},children:[(0,J.jsx)(pe,{strokeDasharray:`2 4`,stroke:`currentColor`,className:`text-border/30`}),(0,J.jsx)(ue,{type:`number`,dataKey:`x`,name:`turns`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,label:{value:i(`scatter.turnsLabel`),position:`insideBottomRight`,offset:-2,fontSize:10,fill:`currentColor`}}),(0,J.jsx)(xe,{type:`number`,dataKey:`y`,name:`cost`,tick:{fontSize:10},stroke:`currentColor`,className:`text-muted-foreground`,tickFormatter:e=>`$${e.toFixed(e<1?2:0)}`}),(0,J.jsx)(gt,{range:[40,80]}),(0,J.jsx)(M,{cursor:{strokeDasharray:`3 3`},contentStyle:{backgroundColor:`var(--popover)`,border:`1px solid var(--border)`,fontSize:11,borderRadius:6},formatter:(e,t)=>{let n=String(t);return n===`cost`&&typeof e==`number`?[`$${e.toFixed(3)}`,i(`scatter.costLabel`)]:[String(e),n===`turns`?i(`scatter.turnsLabel`):n]}}),o.map(e=>(0,J.jsx)(pt,{data:e.points,fill:Et[e.surface],onClick:e=>{let t=e;t?.raw&&r(t.raw)}},e.surface))]})})})]})}function Ot({data:e,loading:t,onSelectTicket:r}){let{t:i}=n(`analytics`);if(t&&!e)return(0,J.jsx)(`div`,{className:`h-40 rounded-xl border border-border/40 bg-card/40 animate-pulse`});if(!e)return null;let a=e.topTickets;return(0,J.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,J.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3`,children:i(`topTickets.title`)}),a.length===0?(0,J.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:i(`topTickets.empty`)}):(0,J.jsx)(`ul`,{className:`divide-y divide-border/30`,children:a.map((e,t)=>{let n=Object.entries(e.bySurface).filter(([,e])=>e.count>0).map(([e,t])=>i(`topTickets.breakdownItem`,{n:t.count,label:u[e].toLowerCase()})).join(` + `),a=e.isUnattributed,o=a?i(`topTickets.unattributed`):e.ticketTitle?`#${e.ticketId} ${e.ticketTitle}`:i(`topTickets.deletedTicket`,{id:e.ticketId});return(0,J.jsx)(`li`,{children:(0,J.jsxs)(`button`,{type:`button`,onClick:()=>r(e.ticketId),className:`w-full text-left flex items-center justify-between gap-3 py-2 px-1 hover:bg-accent/30 rounded transition-colors ${!e.ticketTitle&&!a?`opacity-50`:``}`,disabled:a,children:[(0,J.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,J.jsx)(`div`,{className:`text-sm truncate`,children:o}),(0,J.jsx)(`div`,{className:`text-[11px] text-muted-foreground truncate`,children:n||`—`})]}),(0,J.jsxs)(`div`,{className:`text-right tabular-nums`,children:[(0,J.jsxs)(`div`,{className:`text-sm font-medium`,children:[`$`,e.totalCostUsd.toFixed(2)]}),(0,J.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:i(`runs`,{count:e.totalRuns})})]})]})},`${e.ticketId??`u`}-${t}`)})})]})}function kt(e){return e==null?`—`:e<.005?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`}function At(e){return e==null?`—`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function jt(e){return e.surface_ref_id?.startsWith(`contract-refine:`)?!0:e.surface===`explore-spec`&&e.ticket_id!=null&&e.conversation_id!=null&&e.surface_ref_id===e.conversation_id&&e.model==null}function Mt(e){let t=new Map;for(let n of e)n.model&&(n.conversation_id&&t.set(`conversation:${n.conversation_id}`,n.model),n.ticket_id!=null&&n.surface===`explore-spec`&&t.set(`ticket:${n.ticket_id}:explore-spec`,n.model),n.ticket_id!=null&&n.surface===`quick-spec`&&t.set(`ticket:${n.ticket_id}:quick-spec`,n.model));return t}function Nt(e,t){if(e.model)return e.model;if(!jt(e))return null;if(e.conversation_id){let n=t.get(`conversation:${e.conversation_id}`);if(n)return n}return e.ticket_id==null?null:t.get(`ticket:${e.ticket_id}:${e.surface}`)??null}function Pt({rows:e,loading:t,truncated:r,totalAvailable:i,tableFilters:a,onTableFiltersChange:o}){let{t:s}=n(`analytics`),[c,l]=(0,q.useState)(null),f=Mt(e);return(0,J.jsxs)(`div`,{className:`rounded-xl border border-border/50 bg-card/40 p-4`,children:[(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 mb-3`,children:[(0,J.jsx)(`h2`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wider`,children:s(`table.title`)}),(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-[11px]`,children:[(0,J.jsxs)(`select`,{value:a.status??``,onChange:e=>o({...a,status:e.target.value||void 0}),className:`h-7 px-2 rounded-md bg-background-deep border border-border/60 text-xs`,"aria-label":s(`table.statusFilterAria`),children:[(0,J.jsx)(`option`,{value:``,children:s(`table.allStatus`)}),(0,J.jsx)(`option`,{value:`success`,children:s(`table.success`)}),(0,J.jsx)(`option`,{value:`failed`,children:s(`table.failed`)}),(0,J.jsx)(`option`,{value:`aborted`,children:s(`table.aborted`)})]}),(0,J.jsx)(`input`,{type:`number`,step:`0.01`,min:`0`,placeholder:s(`table.minCostPlaceholder`),value:a.minCostUsd??``,onChange:e=>{let t=e.target.value===``?void 0:parseFloat(e.target.value);o({...a,minCostUsd:Number.isNaN(t)?void 0:t})},className:`h-7 w-24 px-2 rounded-md bg-background-deep border border-border/60 text-xs tabular-nums`,"aria-label":s(`table.minCostFilterAria`)})]})]}),t?(0,J.jsx)(`div`,{className:`h-32 rounded bg-card/30 animate-pulse`}):e.length===0?(0,J.jsx)(`div`,{className:`h-32 flex items-center justify-center text-xs text-muted-foreground/70`,children:s(`table.empty`)}):(0,J.jsx)(`div`,{className:`overflow-x-auto`,children:(0,J.jsxs)(`table`,{className:`w-full text-[12px] tabular-nums`,children:[(0,J.jsx)(`thead`,{className:`text-[10px] uppercase tracking-wider text-muted-foreground`,children:(0,J.jsxs)(`tr`,{className:`text-left`,children:[(0,J.jsx)(`th`,{className:`font-medium px-2 py-2`,children:s(`table.colSurface`)}),(0,J.jsx)(`th`,{className:`font-medium px-2 py-2`,children:s(`table.colTicket`)}),(0,J.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:s(`table.colCost`)}),(0,J.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:s(`table.colTurns`)}),(0,J.jsx)(`th`,{className:`font-medium px-2 py-2 text-right`,children:s(`table.colTokens`)}),(0,J.jsx)(`th`,{className:`font-medium px-2 py-2`,children:s(`table.colModel`)}),(0,J.jsx)(`th`,{className:`font-medium px-2 py-2`,children:s(`table.colStatus`)}),(0,J.jsx)(`th`,{className:`font-medium px-2 py-2`,children:s(`table.colStarted`)})]})}),(0,J.jsx)(`tbody`,{children:e.map(e=>{let t=e.surface,n=d[t],r=(e.tokens_in??0)+(e.tokens_out??0)+(e.tokens_cache_read??0)+(e.tokens_cache_create??0),i=jt(e),a=i?s(`table.contractLayer`):u[t],o=Nt(e,f);return(0,J.jsxs)(`tr`,{onClick:()=>l(c===e.id?null:e.id),className:`border-t border-border/30 hover:bg-accent/30 cursor-pointer`,children:[(0,J.jsx)(`td`,{className:`px-2 py-2`,children:(0,J.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-2 h-5 rounded-full text-[10px] font-medium ${n.bg} ${n.text}`,children:[(0,J.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full ${n.dot}`}),a]})}),(0,J.jsx)(`td`,{className:`px-2 py-2 max-w-[260px]`,children:e.ticket_id==null?e.ticket_title?(0,J.jsx)(`span`,{className:`truncate block text-muted-foreground/90 italic`,title:s(`table.provisionalTitleTooltip`),children:e.ticket_title}):(0,J.jsx)(`span`,{className:`text-muted-foreground/70`,children:`—`}):(0,J.jsxs)(`span`,{className:`truncate block`,children:[`#`,e.ticket_id,` `,i?(0,J.jsx)(`span`,{className:`text-muted-foreground/90`,children:s(`table.contractLayerRefinement`)}):e.ticket_title??(0,J.jsx)(`span`,{className:`text-muted-foreground/70 italic`,children:s(`table.deleted`)})]})}),(0,J.jsx)(`td`,{className:`px-2 py-2 text-right font-medium`,children:e.total_cost_usd_estimated===1&&e.total_cost_usd!=null?(0,J.jsxs)(`span`,{title:s(`table.estimatedCostTooltip`),className:`text-muted-foreground/90`,children:[`~`,kt(e.total_cost_usd)]}):kt(e.total_cost_usd)}),(0,J.jsx)(`td`,{className:`px-2 py-2 text-right`,children:At(e.num_turns)}),(0,J.jsx)(`td`,{className:`px-2 py-2 text-right`,children:r>0?At(r):`—`}),(0,J.jsxs)(`td`,{className:`px-2 py-2 max-w-[180px] truncate`,children:[o??`—`,o&&!e.model?(0,J.jsx)(`span`,{className:`ml-1 text-[10px] text-muted-foreground/70`,children:s(`table.inferred`)}):null]}),(0,J.jsxs)(`td`,{className:`px-2 py-2`,children:[e.status===`success`?(0,J.jsx)(`span`,{className:`text-accent-success/90`,children:`●`}):e.status===`failed`?(0,J.jsx)(`span`,{className:`text-accent-warning`,children:`⚠`}):(0,J.jsx)(`span`,{className:`text-muted-foreground`,children:`○`}),(0,J.jsx)(`span`,{className:`ml-1 text-muted-foreground`,children:s(`table.statusValue.${e.status}`)})]}),(0,J.jsx)(`td`,{className:`px-2 py-2 text-muted-foreground`,children:e.started_at.slice(0,16).replace(`T`,` `)})]},e.id)})})]})}),r&&(0,J.jsx)(`div`,{className:`mt-2 text-[11px] text-muted-foreground/80`,children:s(`table.truncated`,{shown:e.length,total:i.toLocaleString()})})]})}var Ft=[{value:`7d`,labelKey:`periods.d7`},{value:`30d`,labelKey:`periods.d30`},{value:`90d`,labelKey:`periods.d90`},{value:`all`,labelKey:`periods.all`}],It=[{value:`all`,labelKey:`page.all`},{value:`job`,labelKey:`surfaces.job`},{value:`explore-spec`,labelKey:`surfaces.exploreSpec`},{value:`quick-spec`,labelKey:`surfaces.quickSpec`},{value:`ai-edit`,labelKey:`surfaces.aiEdit`},{value:`smash`,labelKey:`surfaces.smash`},{value:`file-summary`,labelKey:`surfaces.fileSummary`}];function Lt(e){let t=new URLSearchParams;return e.period&&t.set(`period`,e.period),e.from&&t.set(`from`,e.from),e.to&&t.set(`to`,e.to),e.surface&&e.surface.length>0&&t.set(`surface`,e.surface.join(`,`)),e.provider&&e.provider.length>0&&t.set(`provider`,e.provider.join(`,`)),e.model&&e.model.length>0&&t.set(`model`,e.model.join(`,`)),e.status&&t.set(`status`,e.status),typeof e.minCostUsd==`number`&&t.set(`minCostUsd`,String(e.minCostUsd)),typeof e.ticketId==`number`&&t.set(`ticketId`,String(e.ticketId)),t.toString()}function Rt(){let{t:e}=n(`analytics`),{activeProjectId:t,projects:o}=r(),[l,u]=c(),d=o.find(e=>e.id===t),f=d?s(d):[`claude`],p=f.length>1,h=l.get(`period`)??`30d`,v=(l.get(`surface`)??``).split(`,`).filter(Boolean),y=(l.get(`provider`)??``).split(`,`).filter(Boolean),b=l.get(`ticketId`),[x,S]=(0,q.useState)({period:h,surface:v.length>0?v:void 0,provider:y.length>0?y:void 0,ticketId:b?Number(b):void 0}),[C,w]=(0,q.useState)(null),[T,E]=(0,q.useState)(!0),[D,O]=(0,q.useState)(null),[k,A]=(0,q.useState)({}),[j,M]=(0,q.useState)(null),N=(0,q.useRef)(new Map),P=(0,q.useRef)(0);(0,q.useEffect)(()=>{let e=new URLSearchParams;e.set(`period`,x.period),x.surface&&x.surface.length>0&&e.set(`surface`,x.surface.join(`,`)),x.provider&&x.provider.length>0&&e.set(`provider`,x.provider.join(`,`)),x.ticketId&&e.set(`ticketId`,String(x.ticketId)),u(e,{replace:!0})},[x.period,x.surface,x.provider,x.ticketId,u]);let F=(0,q.useCallback)(async()=>{if(!t)return;let e=++P.current;O(null);let n=`${t}:${Lt(x)}`,r=N.current.get(n);r?(w(r),E(!1)):E(!0);try{let t=await fetch(`${g()}/spending?${Lt(x)}`);if(!t.ok)throw Error(`HTTP ${t.status}`);if(e!==P.current)return;let r=await t.json();N.current.set(n,r),w(r),E(!1)}catch(t){if(e!==P.current)return;O(t.message),E(!1)}},[t,x]),I=(0,q.useCallback)(async()=>{if(!t)return;let e={...x};k.model&&(e.model=[k.model]),k.status&&(e.status=k.status),typeof k.minCostUsd==`number`&&(e.minCostUsd=k.minCostUsd);try{let t=await fetch(`${g()}/invocations?${Lt(e)}&limit=100`);if(!t.ok)throw Error(`HTTP ${t.status}`);M(await t.json())}catch{M(null)}},[t,x,k]);(0,q.useEffect)(()=>{F()},[F]),(0,q.useEffect)(()=>{I()},[I]);let L=(0,q.useRef)(null),R=a();(0,q.useEffect)(()=>{let e=`analytics-spending`;return R.registerHandler(e,e=>{let n=e;n.type===`spending.invalidated`&&n.projectId===t&&(L.current&&clearTimeout(L.current),L.current=setTimeout(()=>{N.current.clear(),F(),I()},500))}),()=>{R.unregisterHandler(e)}},[R,t,F,I]);function z(e){if(e===`all`){S(e=>({...e,surface:void 0}));return}S(t=>{let n=t.surface??[],r=n.includes(e)?n.filter(t=>t!==e):[...n,e];return{...t,surface:r.length>0?r:void 0}})}function B(e){if(e===`all`){S(e=>({...e,provider:void 0}));return}S(t=>{let n=t.provider??[],r=n.includes(e)?n.filter(t=>t!==e):[...n,e];return{...t,provider:r.length>0?r:void 0}})}let V=x.surface,ee=!V||V.length===0,H=x.provider,te=!H||H.length===0,ne=(0,q.useMemo)(()=>{let e={period:x.period};return x.surface&&x.surface.length>0&&(e.surface=x.surface.join(`,`)),x.provider&&x.provider.length>0&&(e.provider=x.provider.join(`,`)),x.ticketId&&(e.ticketId=String(x.ticketId)),e},[x]),re=C?C.summary.totalRuns===0:!1;return(0,J.jsxs)(`div`,{className:`flex flex-col gap-6 p-4 pb-12`,children:[(0,J.jsxs)(`div`,{className:`sticky top-0 z-10 -mx-4 px-4 py-3 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-b border-border/40`,children:[(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,J.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,J.jsx)(`h1`,{className:`text-base font-semibold tracking-tight`,children:e(`page.title`)}),x.ticketId&&(0,J.jsx)(`button`,{type:`button`,onClick:()=>S(e=>({...e,ticketId:void 0})),className:`inline-flex items-center gap-1 h-6 px-2 rounded-full text-[11px] font-medium bg-accent-highlight/15 text-accent-highlight ring-1 ring-accent-highlight/30 hover:bg-accent-highlight/25`,children:e(`page.ticketChip`,{id:x.ticketId})})]}),(0,J.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,J.jsx)(`div`,{className:`flex items-center gap-1 rounded-md border border-border/60 bg-card/40 p-0.5`,children:Ft.map(t=>(0,J.jsx)(`button`,{type:`button`,onClick:()=>S(e=>({...e,period:t.value})),className:`px-2.5 h-6 rounded text-[11px] font-medium transition-colors ${x.period===t.value?`bg-accent text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:e(t.labelKey)},t.value))}),(0,J.jsx)(_,{baseUrl:`${g()}/analytics/export`,params:ne,disabled:re}),(0,J.jsx)(`button`,{type:`button`,onClick:()=>{N.current.clear(),F(),I()},className:`h-7 w-7 inline-flex items-center justify-center rounded-md border border-border/60 bg-card/50 text-muted-foreground hover:text-foreground hover:bg-accent/60`,title:e(`common:actions.refresh`),children:(0,J.jsx)(i,{className:`w-3 h-3`})})]})]}),(0,J.jsx)(`div`,{className:`mt-3 flex flex-wrap items-center gap-1.5`,children:It.map(t=>(0,J.jsx)(`button`,{type:`button`,onClick:()=>z(t.value),className:`h-7 px-3 rounded-full text-[11px] font-medium transition-all ${(t.value===`all`?ee:V?.includes(t.value)??!1)?`bg-foreground/10 text-foreground ring-1 ring-foreground/20`:`text-muted-foreground hover:text-foreground hover:bg-accent/40`}`,children:e(t.labelKey)},t.value))}),p&&(0,J.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1.5`,"data-testid":`analytics-provider-chips`,children:[(0,J.jsx)(`span`,{className:`text-[10px] uppercase tracking-wide text-muted-foreground/70 mr-1`,children:e(`page.engine`)}),(0,J.jsx)(`button`,{type:`button`,onClick:()=>B(`all`),className:`h-7 px-3 rounded-full text-[11px] font-medium transition-all ${te?`bg-foreground/10 text-foreground ring-1 ring-foreground/20`:`text-muted-foreground hover:text-foreground hover:bg-accent/40`}`,children:e(`page.all`)}),f.map(e=>(0,J.jsx)(`button`,{type:`button`,onClick:()=>B(e),className:`h-7 px-3 rounded-full text-[11px] font-medium transition-all ${H?.includes(e)??!1?`bg-foreground/10 text-foreground ring-1 ring-foreground/20`:`text-muted-foreground hover:text-foreground hover:bg-accent/40`}`,children:m(e)},e))]})]}),D&&(0,J.jsxs)(`div`,{className:`rounded-lg border border-accent-warning/30 bg-accent-warning/10 p-4 flex items-center justify-between`,children:[(0,J.jsx)(`p`,{className:`text-sm text-accent-warning`,children:e(`page.failedToLoad`,{error:D})}),(0,J.jsxs)(`button`,{onClick:()=>F(),className:`flex items-center gap-1.5 h-7 px-3 rounded-md text-xs text-accent-warning border border-accent-warning/30 hover:bg-accent-warning/10`,children:[(0,J.jsx)(i,{className:`w-3 h-3`}),e(`common:actions.retry`)]})]}),(0,J.jsx)(Pe,{data:C,loading:T}),(0,J.jsx)(Be,{data:C,loading:T}),(0,J.jsx)(yt,{data:C,loading:T}),(0,J.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-4`,children:[(0,J.jsx)(wt,{data:C,loading:T}),(0,J.jsx)(Tt,{data:C,loading:T,onSelectModel:e=>S(t=>({...t,model:[e]})),activeModel:x.model?.[0]})]}),(0,J.jsx)(Dt,{data:C,loading:T,onSelectPoint:e=>{A(e=>({...e})),S(t=>({...t,ticketId:e.ticketId??void 0}))}}),(0,J.jsx)(Ot,{data:C,loading:T,onSelectTicket:e=>S(t=>({...t,ticketId:e??void 0}))}),(0,J.jsx)(Pt,{rows:j?.rows??[],loading:T&&!j,truncated:j?.truncated??!1,totalAvailable:j?.totalAvailable??0,tableFilters:k,onTableFiltersChange:A})]})}export{Rt as default};
|