openfox 1.6.73 → 1.6.75
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/dist/{auto-compaction-HQHEK75L.js → auto-compaction-OW4P2QWQ.js} +2 -2
- package/dist/{chat-handler-NNDQSDFI.js → chat-handler-KYMMXPP6.js} +4 -4
- package/dist/{chunk-ODUSHSK2.js → chunk-ETIXH35K.js} +13 -3
- package/dist/{chunk-EGIJKK4U.js → chunk-IA4O65CR.js} +2 -2
- package/dist/{chunk-PPSXSDMY.js → chunk-VIGOXEZG.js} +2 -2
- package/dist/{chunk-RTOWT3GF.js → chunk-XIZ6B6IS.js} +9 -9
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{orchestrator-T2EQZJS5.js → orchestrator-QP4O7MUM.js} +3 -3
- package/dist/package.json +1 -1
- package/dist/{processor-HF5SS6CR.js → processor-23O4HPSS.js} +2 -2
- package/dist/{serve-YCFUOOGT.js → serve-TW63YCNQ.js} +4 -4
- package/dist/server/index.js +3 -3
- package/dist/{tools-5MCH72FH.js → tools-RUAY6EVI.js} +2 -2
- package/dist/web/assets/{index-9GgVgB7B.js → index-CWdKiSP8.js} +1 -1
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
maybeAutoCompactContext,
|
|
3
3
|
performManualContextCompaction,
|
|
4
4
|
resolveCompactionStatsIdentity
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ETIXH35K.js";
|
|
6
6
|
import "./chunk-GQZGIMJO.js";
|
|
7
7
|
import "./chunk-7JPKRM6M.js";
|
|
8
8
|
import "./chunk-RBPOAAIZ.js";
|
|
@@ -24,4 +24,4 @@ export {
|
|
|
24
24
|
performManualContextCompaction,
|
|
25
25
|
resolveCompactionStatsIdentity
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=auto-compaction-
|
|
27
|
+
//# sourceMappingURL=auto-compaction-OW4P2QWQ.js.map
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
} from "./chunk-4CQ7CUQ6.js";
|
|
9
9
|
import {
|
|
10
10
|
runChatTurn
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-IA4O65CR.js";
|
|
12
|
+
import "./chunk-ETIXH35K.js";
|
|
13
13
|
import "./chunk-GQZGIMJO.js";
|
|
14
14
|
import "./chunk-7JPKRM6M.js";
|
|
15
15
|
import "./chunk-RBPOAAIZ.js";
|
|
@@ -61,7 +61,7 @@ async function startChatSession(sessionId, content, deps, options) {
|
|
|
61
61
|
sessionManager.setRunning(sessionId, true);
|
|
62
62
|
broadcastForSession(sessionId, createSessionRunningMessage(true));
|
|
63
63
|
try {
|
|
64
|
-
const { maybeAutoCompactContext } = await import("./auto-compaction-
|
|
64
|
+
const { maybeAutoCompactContext } = await import("./auto-compaction-OW4P2QWQ.js");
|
|
65
65
|
await maybeAutoCompactContext({
|
|
66
66
|
sessionManager,
|
|
67
67
|
sessionId,
|
|
@@ -170,4 +170,4 @@ export {
|
|
|
170
170
|
startChatSession,
|
|
171
171
|
stopSessionExecution
|
|
172
172
|
};
|
|
173
|
-
//# sourceMappingURL=chat-handler-
|
|
173
|
+
//# sourceMappingURL=chat-handler-KYMMXPP6.js.map
|
|
@@ -2075,7 +2075,17 @@ Make sure whitespace and indentation match exactly.`
|
|
|
2075
2075
|
newContent: edit.newContent
|
|
2076
2076
|
}))
|
|
2077
2077
|
}));
|
|
2078
|
-
const
|
|
2078
|
+
const normalizedNewString = normalizeToLF(args.new_string);
|
|
2079
|
+
let replacedContent;
|
|
2080
|
+
if (replaceAll) {
|
|
2081
|
+
replacedContent = normalizedContent.replaceAll(normalizedOldString, normalizedNewString);
|
|
2082
|
+
} else {
|
|
2083
|
+
const index = normalizedContent.indexOf(normalizedOldString);
|
|
2084
|
+
if (index === -1) {
|
|
2085
|
+
return helpers.error("old_string not found in file (unexpected)");
|
|
2086
|
+
}
|
|
2087
|
+
replacedContent = normalizedContent.slice(0, index) + normalizedNewString + normalizedContent.slice(index + normalizedOldString.length);
|
|
2088
|
+
}
|
|
2079
2089
|
const newContent = replacedContent.replace(/\n/g, fileLineEnding === "crlf" ? "\r\n" : fileLineEnding === "cr" ? "\r" : "\n");
|
|
2080
2090
|
await writeFile3(fullPath, newContent, "utf-8");
|
|
2081
2091
|
let output = `Successfully replaced ${replaceAll ? occurrences : 1} occurrence(s) in ${args.path}`;
|
|
@@ -3381,7 +3391,7 @@ var callSubAgentTool = {
|
|
|
3381
3391
|
};
|
|
3382
3392
|
}
|
|
3383
3393
|
try {
|
|
3384
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
3394
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-RUAY6EVI.js");
|
|
3385
3395
|
const toolRegistry = getToolRegistryForAgent2(agentDef);
|
|
3386
3396
|
const turnMetrics = new TurnMetrics();
|
|
3387
3397
|
const result = await executeSubAgent({
|
|
@@ -4535,4 +4545,4 @@ export {
|
|
|
4535
4545
|
getToolRegistryForAgent,
|
|
4536
4546
|
createToolRegistry
|
|
4537
4547
|
};
|
|
4538
|
-
//# sourceMappingURL=chunk-
|
|
4548
|
+
//# sourceMappingURL=chunk-ETIXH35K.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getToolRegistryForAgent,
|
|
14
14
|
loadAllAgentsDefault,
|
|
15
15
|
runTopLevelAgentLoop
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ETIXH35K.js";
|
|
17
17
|
import {
|
|
18
18
|
getCurrentContextWindowId,
|
|
19
19
|
getEventStore
|
|
@@ -295,4 +295,4 @@ export {
|
|
|
295
295
|
runBuilderTurn,
|
|
296
296
|
runVerifierTurn
|
|
297
297
|
};
|
|
298
|
-
//# sourceMappingURL=chunk-
|
|
298
|
+
//# sourceMappingURL=chunk-IA4O65CR.js.map
|
|
@@ -190,7 +190,7 @@ async function runCli(options) {
|
|
|
190
190
|
if (!configExists) {
|
|
191
191
|
await runNetworkSetup(mode);
|
|
192
192
|
}
|
|
193
|
-
const { runServe } = await import("./serve-
|
|
193
|
+
const { runServe } = await import("./serve-TW63YCNQ.js");
|
|
194
194
|
await runServe({
|
|
195
195
|
mode,
|
|
196
196
|
port: values.port ? parseInt(values.port) : void 0,
|
|
@@ -203,4 +203,4 @@ async function runCli(options) {
|
|
|
203
203
|
export {
|
|
204
204
|
runCli
|
|
205
205
|
};
|
|
206
|
-
//# sourceMappingURL=chunk-
|
|
206
|
+
//# sourceMappingURL=chunk-VIGOXEZG.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createVerifierNudgeConfig,
|
|
3
3
|
runBuilderTurn,
|
|
4
4
|
runChatTurn
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-IA4O65CR.js";
|
|
6
6
|
import {
|
|
7
7
|
TurnMetrics,
|
|
8
8
|
agentExists,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
setSkillEnabled,
|
|
38
38
|
skillExists,
|
|
39
39
|
spawnShellProcess
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-ETIXH35K.js";
|
|
41
41
|
import {
|
|
42
42
|
getProject
|
|
43
43
|
} from "./chunk-7JPKRM6M.js";
|
|
@@ -5014,7 +5014,7 @@ function createTerminalRoutes() {
|
|
|
5014
5014
|
}
|
|
5015
5015
|
|
|
5016
5016
|
// src/constants.ts
|
|
5017
|
-
var VERSION = "1.6.
|
|
5017
|
+
var VERSION = "1.6.75";
|
|
5018
5018
|
|
|
5019
5019
|
// src/server/index.ts
|
|
5020
5020
|
var __dirname2 = dirname5(fileURLToPath4(import.meta.url));
|
|
@@ -5317,7 +5317,7 @@ async function createServerHandle(config) {
|
|
|
5317
5317
|
if (!callId || approved === void 0) {
|
|
5318
5318
|
return res.status(400).json({ error: "callId and approved are required" });
|
|
5319
5319
|
}
|
|
5320
|
-
const { providePathConfirmation } = await import("./tools-
|
|
5320
|
+
const { providePathConfirmation } = await import("./tools-RUAY6EVI.js");
|
|
5321
5321
|
const result = providePathConfirmation(callId, approved, alwaysAllow);
|
|
5322
5322
|
if (!result.found) {
|
|
5323
5323
|
return res.status(404).json({ error: "No pending path confirmation with that ID" });
|
|
@@ -5341,7 +5341,7 @@ async function createServerHandle(config) {
|
|
|
5341
5341
|
if (!callId || !answer) {
|
|
5342
5342
|
return res.status(400).json({ error: "callId and answer are required" });
|
|
5343
5343
|
}
|
|
5344
|
-
const { provideAnswer: provideAnswer2 } = await import("./tools-
|
|
5344
|
+
const { provideAnswer: provideAnswer2 } = await import("./tools-RUAY6EVI.js");
|
|
5345
5345
|
const found = provideAnswer2(callId, answer);
|
|
5346
5346
|
if (!found) {
|
|
5347
5347
|
return res.status(404).json({ error: "No pending question with that ID" });
|
|
@@ -5377,8 +5377,8 @@ async function createServerHandle(config) {
|
|
|
5377
5377
|
if (!session) {
|
|
5378
5378
|
return res.status(404).json({ error: "Session not found" });
|
|
5379
5379
|
}
|
|
5380
|
-
const { stopSessionExecution } = await import("./chat-handler-
|
|
5381
|
-
const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-
|
|
5380
|
+
const { stopSessionExecution } = await import("./chat-handler-KYMMXPP6.js");
|
|
5381
|
+
const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-RUAY6EVI.js");
|
|
5382
5382
|
stopSessionExecution(sessionId, sessionManager);
|
|
5383
5383
|
abortSession(sessionId);
|
|
5384
5384
|
cancelQuestionsForSession(sessionId, "Session stopped by user");
|
|
@@ -5852,7 +5852,7 @@ async function createServerHandle(config) {
|
|
|
5852
5852
|
providerManager
|
|
5853
5853
|
);
|
|
5854
5854
|
const wss = wssExports.wss;
|
|
5855
|
-
const { QueueProcessor } = await import("./processor-
|
|
5855
|
+
const { QueueProcessor } = await import("./processor-23O4HPSS.js");
|
|
5856
5856
|
const queueProcessor = new QueueProcessor({
|
|
5857
5857
|
sessionManager,
|
|
5858
5858
|
providerManager,
|
|
@@ -5927,4 +5927,4 @@ export {
|
|
|
5927
5927
|
createServerHandle,
|
|
5928
5928
|
createServer
|
|
5929
5929
|
};
|
|
5930
|
-
//# sourceMappingURL=chunk-
|
|
5930
|
+
//# sourceMappingURL=chunk-XIZ6B6IS.js.map
|
package/dist/cli/dev.js
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
runBuilderTurn,
|
|
4
4
|
runChatTurn,
|
|
5
5
|
runVerifierTurn
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IA4O65CR.js";
|
|
7
7
|
import {
|
|
8
8
|
TurnMetrics,
|
|
9
9
|
createChatDoneEvent,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
createMessageStartEvent,
|
|
12
12
|
createToolCallEvent,
|
|
13
13
|
createToolResultEvent
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-ETIXH35K.js";
|
|
15
15
|
import "./chunk-GQZGIMJO.js";
|
|
16
16
|
import "./chunk-7JPKRM6M.js";
|
|
17
17
|
import "./chunk-RBPOAAIZ.js";
|
|
@@ -40,4 +40,4 @@ export {
|
|
|
40
40
|
runChatTurn,
|
|
41
41
|
runVerifierTurn
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=orchestrator-
|
|
43
|
+
//# sourceMappingURL=orchestrator-QP4O7MUM.js.map
|
package/dist/package.json
CHANGED
|
@@ -173,7 +173,7 @@ var QueueProcessor = class {
|
|
|
173
173
|
backend: provider?.backend ?? llmClient.getBackend(),
|
|
174
174
|
model: llmClient.getModel()
|
|
175
175
|
};
|
|
176
|
-
const { runChatTurn } = await import("./orchestrator-
|
|
176
|
+
const { runChatTurn } = await import("./orchestrator-QP4O7MUM.js");
|
|
177
177
|
const runChatTurnParams = buildRunChatTurnParams({
|
|
178
178
|
sessionManager,
|
|
179
179
|
sessionId,
|
|
@@ -210,4 +210,4 @@ var QueueProcessor = class {
|
|
|
210
210
|
export {
|
|
211
211
|
QueueProcessor
|
|
212
212
|
};
|
|
213
|
-
//# sourceMappingURL=processor-
|
|
213
|
+
//# sourceMappingURL=processor-23O4HPSS.js.map
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
VERSION,
|
|
8
8
|
createServer
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-XIZ6B6IS.js";
|
|
10
|
+
import "./chunk-IA4O65CR.js";
|
|
11
|
+
import "./chunk-ETIXH35K.js";
|
|
12
12
|
import "./chunk-GQZGIMJO.js";
|
|
13
13
|
import "./chunk-7JPKRM6M.js";
|
|
14
14
|
import "./chunk-RBPOAAIZ.js";
|
|
@@ -188,4 +188,4 @@ async function runServe(options) {
|
|
|
188
188
|
export {
|
|
189
189
|
runServe
|
|
190
190
|
};
|
|
191
|
-
//# sourceMappingURL=serve-
|
|
191
|
+
//# sourceMappingURL=serve-TW63YCNQ.js.map
|
package/dist/server/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer,
|
|
3
3
|
createServerHandle
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-XIZ6B6IS.js";
|
|
5
|
+
import "../chunk-IA4O65CR.js";
|
|
6
|
+
import "../chunk-ETIXH35K.js";
|
|
7
7
|
import "../chunk-GQZGIMJO.js";
|
|
8
8
|
import "../chunk-7JPKRM6M.js";
|
|
9
9
|
import "../chunk-RBPOAAIZ.js";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
requestPathAccess,
|
|
12
12
|
stepDoneTool,
|
|
13
13
|
validateToolAction
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-ETIXH35K.js";
|
|
15
15
|
import "./chunk-GQZGIMJO.js";
|
|
16
16
|
import "./chunk-7JPKRM6M.js";
|
|
17
17
|
import "./chunk-RBPOAAIZ.js";
|
|
@@ -49,4 +49,4 @@ export {
|
|
|
49
49
|
stepDoneTool,
|
|
50
50
|
validateToolAction
|
|
51
51
|
};
|
|
52
|
-
//# sourceMappingURL=tools-
|
|
52
|
+
//# sourceMappingURL=tools-RUAY6EVI.js.map
|
|
@@ -81,7 +81,7 @@ WARNING: This link could potentially be dangerous`)){const b=window.open();if(b)
|
|
|
81
81
|
w-[300px] bg-secondary border-r border-border flex flex-col
|
|
82
82
|
transition-all duration-300 ease-in-out
|
|
83
83
|
${r?"translate-x-0":"-translate-x-full"}
|
|
84
|
-
`,children:[o.jsxs("div",{className:"p-4 border-b border-border flex gap-2",children:[o.jsx(Fn,{href:`/p/${e}/new`,className:"flex-1 block text-center rounded font-medium transition-colors bg-accent-primary/25 text-text-primary hover:bg-accent-primary/40 px-3 py-1.5 text-sm","data-testid":"sidebar-new-session-button",children:"+ New Session"}),o.jsx(bo,{items:[{label:"Edit project settings",onClick:()=>u(!0)},{label:"Delete all sessions",onClick:_,danger:!0}],trigger:o.jsx("button",{className:"flex-shrink-0 p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Options",children:o.jsx(Bh,{})})}),s&&o.jsx(lo,{onClick:s,className:"md:hidden",variant:"sidebar",size:"md"})]}),k&&o.jsx(hC,{isOpen:c,onClose:()=>u(!1),project:k}),o.jsx("div",{className:"flex-1 overflow-y-auto",children:b.length===0?o.jsx("div",{className:"p-4 text-center text-text-muted text-xs",children:"No sessions"}):o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"divide-y divide-border",children:mC(b,l,d,x,e)}),S&&o.jsx("div",{className:"p-4 text-center text-text-muted text-xs",children:"Loading more..."}),o.jsx("div",{ref:C,className:"h-px"})]})})]})]})}function mC(e,r,s,i,c){const u=iy(e);return Array.from(u).map(([h,l])=>{const d=l[0];return d?o.jsxs("div",{children:[o.jsx("div",{className:"px-4 py-2 bg-bg-tertiary/30 text-text-muted text-xs font-medium",children:ry(d.updatedAt)}),l.map(f=>{const g=(r==null?void 0:r.id)===f.id,m=s.includes(f.id),v=f.isRunning;return o.jsx("div",{className:`w-full px-4 py-3 text-left hover:bg-bg-tertiary/50 transition-colors group ${g?"bg-bg-tertiary":""}`,children:o.jsxs(Fn,{href:`/p/${c}/s/${f.id}`,className:`block ${g?"text-accent-primary":"text-text-primary"} hover:text-accent-primary`,children:[o.jsxs("div",{className:"flex justify-between items-center mb-1",children:[o.jsx("span",{className:`font-medium truncate text-sm ${g?"text-accent-primary":"text-text-primary"}`,children:f.title??f.id.slice(0,6)}),o.jsx(bo,{items:[{label:"Delete session",onClick:S=>i(f.id,S),danger:!0}],trigger:o.jsx("button",{onClick:S=>S.preventDefault(),className:"p-1.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-all",title:"Options",children:o.jsx(Bh,{})})})]}),o.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[v?o.jsx(Nw,{}):m&&!g?o.jsx("span",{"aria-label":"Unread activity",title:"Unread activity",className:"w-2 h-2 rounded-full bg-amber-400 flex-shrink-0"}):null,o.jsx("span",{className:"text-text-muted text-xs flex-shrink-0",children:uc(f.updatedAt)}),o.jsxs("span",{className:"text-text-muted text-xs flex-shrink-0",children:[f.messageCount," messages"]})]})]})},f.id)})]},h):null})}const ab=["⠋","⠙","⠹","⠸","⠼","⠴"];function gC(){var l;const e=Ft(d=>d.currentProject),r=Ce(d=>d.currentSession),s=qv(),i=!1,c=P.useRef(0),u=P.useRef(null);P.useEffect(()=>(s?(u.current=window.setInterval(()=>{c.current=(c.current+1)%ab.length,h()},150),h()):(u.current&&(clearInterval(u.current),u.current=null),h()),()=>{u.current&&(clearInterval(u.current),u.current=null)}),[s,e,r,i]);const h=()=>{var m;const f=(m=r==null?void 0:r.metadata)==null?void 0:m.title,g=s?`${ab[c.current]} `:"";e&&f?document.title=`${g}${e.name} - ${f} | OpenFox`:e?document.title=`${g}${e.name} | OpenFox`:document.title=`${g}OpenFox`};return typeof window<"u"&&((l=r==null?void 0:r.metadata)!=null&&l.title)&&window.document.documentElement.setAttribute("data-session-title",r.metadata.title),null}function xC({isOpen:e,onClose:r,projectName:s,onConfirm:i}){const c=()=>{i(),r()};return o.jsx(At,{isOpen:e,onClose:r,title:"Delete Project",size:"sm",children:o.jsxs("div",{className:"space-y-4",children:[o.jsxs("p",{className:"text-text-secondary",children:["This will permanently delete the project ",o.jsx("span",{className:"font-semibold text-text-primary",children:s})," and all its sessions from OpenFox. The project files on disk will remain untouched."]}),o.jsxs("div",{className:"flex justify-end gap-2",children:[o.jsx(nt,{variant:"secondary",onClick:r,children:"Cancel"}),o.jsx(nt,{variant:"danger",onClick:c,children:"Delete"})]})]})})}const dc=P.forwardRef(({className:e="",...r},s)=>o.jsx("input",{ref:s,className:`bg-bg-tertiary border border-border rounded px-3 py-2 text-text-primary placeholder-text-muted focus:outline-none focus:ring-2 focus:ring-accent-primary/50 focus:border-accent-primary ${e}`,...r}));dc.displayName="Input";function bC(e){return!e||e.trim()===""?{valid:!1,error:"Project name cannot be empty"}:/^[a-zA-Z0-9._-]+$/.test(e)?{valid:!0}:{valid:!1,error:"Project name can only contain letters, numbers, hyphens, underscores, and dots"}}function vC({isOpen:e,onClose:r}){const[,s]=lr(),[i,c]=P.useState(""),[u,h]=P.useState(null),[l,d]=P.useState(!1),[f,g]=P.useState(""),m=P.useRef(null);P.useEffect(()=>{e&&(ke("/api/config").then(C=>C.json()).then(C=>{C.workdir&&g(C.workdir)}),c(""),h(null),d(!1),setTimeout(()=>{var C;(C=m.current)==null||C.focus()},100))},[e]);const v=P.useCallback(async C=>{C.preventDefault();const y=bC(i);if(!y.valid){h(y.error);return}d(!0),h(null);const b=`${f}/${i}`;try{const x=await ke("/api/projects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:i,workdir:b})});if(!x.ok){const A=await x.json().catch(()=>({}));throw new Error(A.error||"Failed to create project")}const j=(await x.json()).project;r(),s(`/p/${j.id}`)}catch(x){h(x instanceof Error?x.message:"Failed to create project"),d(!1)}},[i,s,r,f]),S=P.useCallback(()=>{c(""),h(null),r()},[r]),k=i?`${f}/${i}`:"";return o.jsx(At,{isOpen:e,onClose:S,title:"Create New Project",size:"sm",children:o.jsxs("form",{onSubmit:v,className:"space-y-4",children:[o.jsxs("div",{children:[o.jsx("label",{htmlFor:"project-name",className:"block text-sm font-medium text-text-secondary mb-2",children:"Project Name"}),o.jsx(dc,{ref:m,id:"project-name",value:i,onChange:C=>{c(C.target.value),h(null)},placeholder:"my-project",disabled:l,"data-testid":"create-project-name-input",className:"w-full"}),i&&o.jsxs("div",{className:"mt-2 text-xs text-text-muted",children:["Full path: ",o.jsx("span",{className:"font-mono",children:k})]}),u&&o.jsx("div",{className:"mt-3 p-3 bg-accent-error/10 border border-accent-error/30 rounded text-sm text-accent-error",children:u})]}),o.jsxs("div",{className:"flex justify-end gap-2",children:[o.jsx(nt,{type:"button",variant:"secondary",onClick:S,disabled:l,children:"Cancel"}),o.jsx(nt,{type:"submit",variant:"primary",disabled:l||!i.trim(),"data-testid":"create-project-submit-button",className:"min-w-[100px]",children:l?o.jsxs("span",{className:"flex items-center gap-2",children:[o.jsx(qi,{className:"h-4 w-4"}),"Creating..."]}):"Create"})]})]})})}const yC={sm:"w-4 h-4",md:"w-8 h-8",lg:"w-12 h-12"};function vo({size:e="md",className:r=""}){return o.jsx("div",{className:`animate-spin border-2 border-accent-primary border-t-transparent rounded-full ${yC[e]} ${r}`})}function _C({text:e,...r}){return o.jsxs("div",{className:"text-center",children:[o.jsx(vo,{...r,className:"mx-auto mb-4"}),e&&o.jsx("div",{className:"text-text-secondary",children:e})]})}function oy({onSelect:e,onClose:r,initialPath:s}){const[i,c]=P.useState(null),[u,h]=P.useState(!0),[l,d]=P.useState(""),[f,g]=P.useState(-1),m=P.useRef(null),v=P.useRef([]),S=P.useCallback(async x=>{h(!0),d(""),g(-1);try{const _=x?`/api/directories?path=${encodeURIComponent(x)}`:"/api/directories",A=await(await ke(_)).json();c(A)}catch(_){console.error("Failed to load directories:",_)}finally{h(!1)}},[]);P.useEffect(()=>{S(s)},[s,S]);const k=((i==null?void 0:i.current)??"").split("/").filter(Boolean).map((x,_,j)=>({name:x,path:"/"+j.slice(0,_+1).join("/")})),C=(i==null?void 0:i.directories.filter(x=>l===""||x.name.toLowerCase().includes(l.toLowerCase())))??[],y=[...i!=null&&i.parent?[{type:"parent",path:i.parent,name:".."}]:[],...C.map(x=>({type:"dir",path:x.path,name:x.name}))];P.useEffect(()=>{g(l?0:-1)},[l,C.length]),P.useEffect(()=>{var x;f>=0&&v.current[f]&&((x=v.current[f])==null||x.scrollIntoView({block:"nearest"}))},[f]);const b=x=>{var _;if(x.key==="ArrowDown")x.preventDefault(),g(j=>Math.min(j+1,y.length-1));else if(x.key==="ArrowUp")x.preventDefault(),g(j=>Math.max(j-1,0));else if(x.key==="Enter"){if(x.preventDefault(),f>=0&&y[f]){const j=y[f];j.type,S(j.path)}}else x.key==="Escape"&&(d(""),(_=m.current)==null||_.focus())};return o.jsxs(At,{isOpen:!0,onClose:r,title:"Select Folder",size:"lg",children:[i&&o.jsx("div",{className:"px-3 py-2 bg-bg-tertiary/30 -mx-4 -mt-4 mb-4 border-b border-border",children:o.jsxs("div",{className:"flex items-center text-xs overflow-x-auto",children:[k.map((x,_)=>o.jsxs("span",{className:"flex items-center shrink-0",children:[o.jsx("span",{className:"text-text-muted",children:"/"}),o.jsx("button",{onClick:()=>S(x.path),className:`px-1 ${_===k.length-1?"text-accent-primary font-medium":"text-text-secondary hover:text-accent-primary"}`,children:x.name})]},x.path)),k.length===0&&o.jsx("button",{onClick:()=>S("/"),className:"text-text-muted hover:text-accent-primary",children:"/"})]})}),o.jsx("div",{className:"px-4 mb-3",children:o.jsxs("div",{className:"relative",children:[o.jsx("span",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-text-muted pointer-events-none flex items-center justify-center",children:o.jsx(Hh,{})}),o.jsx(dc,{autoFocus:!0,ref:m,value:l,onChange:x=>d(x.target.value),onKeyDown:b,placeholder:"Filter directories...",className:"w-full pl-9"})]})}),o.jsx("div",{className:"flex-1 overflow-y-auto -mx-4",children:u?o.jsx("div",{className:"p-8 text-center",children:o.jsx(vo,{size:"sm"})}):y.length===0?o.jsx("div",{className:"p-8 text-center text-text-muted text-sm",children:l?"No matching directories":"No subdirectories"}):o.jsx("div",{className:"divide-y divide-border",children:y.map((x,_)=>o.jsxs("button",{ref:j=>{v.current[_]=j},onClick:()=>S(x.path),onDoubleClick:()=>e(x.path),className:`w-full p-3 flex items-center gap-3 text-left transition-colors ${_===f?"bg-accent-primary/20 text-accent-primary":"hover:bg-bg-tertiary/50"}`,children:[x.type==="parent"?o.jsx(hw,{className:"w-5 h-5 text-text-muted"}):o.jsx(zh,{className:"w-5 h-5"}),o.jsx("span",{className:"flex-1",children:x.name}),_===f&&o.jsx("span",{className:"text-xs text-text-muted",children:"⏎ navigate · dbl-click select"})]},x.path))})}),o.jsxs("div",{className:"flex flex-col gap-2 pt-4 border-t border-border mt-4 -mx-4 -mb-4 p-4",children:[(i==null?void 0:i.current)&&o.jsx("button",{onClick:()=>e(i.current),className:"w-full px-4 py-2 bg-accent-primary text-text-primary rounded-lg font-medium hover:bg-accent-primary/90 transition-colors",children:"Select this folder"}),o.jsx("button",{onClick:r,className:"w-full text-center text-text-muted hover:text-text-secondary text-sm",children:"Cancel"})]})]})}function SC({isOpen:e,onClose:r}){const[,s]=lr(),[i,c]=P.useState(!1),[u,h]=P.useState(null),[l,d]=P.useState(!1),f=Ft(N=>N.projects),g=Ft(N=>N.createProject),m=Ft(N=>N.listProjects),v=Ft(N=>N.deleteProject),[S,k]=P.useState(null),[C,y]=P.useState(null),b=(N,D=32)=>{if(N.length<=D)return N;const T=N.split("/").filter(Boolean);if(T.length<=2)return N;const z=T[0],O=T[T.length-1],q=T.slice(1,-1).join("/"),V=D-z.length-O.length-3;if(V<0)return N;const W=q.slice(0,Math.floor(V/2)),I=q.slice(-Math.ceil(V/2));return`/${z}/${W}...${I}/${O}`};P.useEffect(()=>{ke("/api/config").then(N=>N.json()).then(N=>{N.workdir&&h(N.workdir)})},[]),P.useEffect(()=>{e&&m()},[e,m]);const x=N=>{s(`/p/${N}`),r()},_=(N,D)=>{D.stopPropagation(),k(N)},j=()=>{S&&(v(S.id),k(null))},A=N=>{const D=N.split("/").filter(Boolean).pop()??"";g(D,N),m(),y(N)};return P.useEffect(()=>{if(C){const N=f.find(D=>D.workdir===C);N&&(s(`/p/${N.id}`),r(),y(null))}},[f,C,s,r]),e?o.jsxs(At,{isOpen:e,onClose:r,title:"Open Project",size:"xl",footer:o.jsx("div",{className:"flex justify-end gap-2",children:o.jsx(nt,{variant:"secondary",onClick:r,children:"Close"})}),children:[o.jsxs("div",{className:"flex flex-col sm:flex-row flex-1 -m-4",children:[o.jsxs("div",{className:"w-full sm:w-1/2 border-b sm:border-b-0 sm:border-r border-border flex flex-col max-h-[40vh] sm:max-h-[50vh]",children:[o.jsx("div",{className:"p-3 border-b border-border bg-bg-tertiary/30 shrink-0",children:o.jsx("h3",{className:"font-medium text-sm text-text-secondary",children:"Recent Projects"})}),o.jsx("div",{className:"flex-1 overflow-y-auto",children:f.length===0?o.jsxs("div",{className:"p-6 text-center text-text-muted text-sm",children:[o.jsx("p",{className:"mb-2",children:"No recent projects"}),o.jsx("p",{className:"text-xs",children:'Click "Create new project" to add one'})]}):o.jsx("div",{className:"divide-y divide-border",children:f.map(N=>o.jsxs("div",{className:"group flex items-center gap-3 p-3 hover:bg-bg-tertiary/50 transition-colors",children:[o.jsxs("button",{onClick:()=>x(N.id),className:"flex-1 flex items-center gap-3 text-left",children:[o.jsx(zh,{className:"w-5 h-5 text-accent-primary"}),o.jsxs("div",{className:"flex-1 min-w-0",children:[o.jsx("div",{className:"font-medium truncate",children:N.name}),o.jsx("div",{className:"text-xs text-text-muted truncate",children:b(N.workdir)})]})]}),o.jsx("button",{onClick:D=>_(N,D),className:"text-accent-error/70 hover:text-accent-error p-1",title:"Delete project",children:o.jsx(Ph,{className:"w-4 h-4"})})]},N.id))})})]}),o.jsx("div",{className:"w-full sm:w-1/2 flex flex-col items-center justify-center p-6 sm:p-8 text-center",children:o.jsxs("div",{className:"flex flex-col gap-3 w-full max-w-sm",children:[o.jsx(nt,{variant:"primary",onClick:()=>d(!0),children:"Select existing project"}),o.jsx(nt,{variant:"secondary",onClick:()=>c(!0),"data-testid":"open-project-create-button",children:"Create new project"})]})})]}),i&&o.jsx(vC,{isOpen:i,onClose:()=>c(!1)}),S&&o.jsx(xC,{isOpen:!0,onClose:()=>k(null),projectName:S.name,onConfirm:j}),l&&o.jsx(oy,{initialPath:u??void 0,onSelect:N=>{A(N),d(!1)},onClose:()=>d(!1)})]}):null}function wC(){const[e,r]=P.useState(!1),s=Ce(m=>m.sessions),i=Ft(m=>m.projects),c=Ft(m=>m.loading),u=Ft(m=>m.listProjects),h=Ce(m=>m.listSessions),l=Ce(m=>m.connectionStatus);P.useEffect(()=>{l==="connected"&&(u(),h())},[l,u,h]);const d=[...i].sort((m,v)=>{const S=s.filter(b=>b.workdir.startsWith(m.workdir)),k=s.filter(b=>b.workdir.startsWith(v.workdir)),C=S.length>0?new Date(S.reduce((b,x)=>new Date(x.updatedAt)>new Date(b.updatedAt)?x:b).updatedAt).getTime():new Date(m.updatedAt).getTime();return(k.length>0?new Date(k.reduce((b,x)=>new Date(x.updatedAt)>new Date(b.updatedAt)?x:b).updatedAt).getTime():new Date(v.updatedAt).getTime())-C}),f=m=>{const v=i.find(S=>S.id===m);return v?s.filter(S=>S.workdir.startsWith(v.workdir)).sort((S,k)=>new Date(k.updatedAt).getTime()-new Date(S.updatedAt).getTime()).slice(0,5):[]},g=()=>{r(!0)};return o.jsxs("div",{className:"flex-1 flex flex-col overflow-y-auto bg-primary",children:[o.jsxs("div",{className:"max-w-5xl mx-auto w-full p-4 md:p-8",children:[o.jsxs("div",{className:"mb-6 md:mb-8 flex items-center justify-between",children:[o.jsxs("div",{children:[o.jsx("h1",{className:"text-3xl font-bold text-accent-primary",children:"OpenFox"}),o.jsx("p",{className:"text-text-secondary",children:"Local LLM-powered coding assistant with contract-driven execution"})]}),o.jsx(nt,{variant:"primary",onClick:g,children:"Open Project"})]}),d.map(m=>{const v=f(m.id);return o.jsx("div",{className:"mb-6 md:mb-8",children:o.jsxs("div",{className:"bg-bg-secondary border border-border rounded-lg overflow-hidden",children:[o.jsxs("div",{className:"p-3 md:p-4 border-b border-border flex items-center justify-between gap-2",children:[o.jsxs(Fn,{href:`/p/${m.id}`,className:"flex items-center gap-2 cursor-pointer hover:opacity-80 transition-opacity flex-1",children:[o.jsx(zh,{className:"w-5 h-5 text-accent-primary flex-shrink-0"}),o.jsx("span",{className:"text-text-primary font-semibold",children:m.name})]}),o.jsx(Fn,{href:`/p/${m.id}/new`,className:"rounded font-medium transition-colors bg-accent-primary/25 text-text-primary hover:bg-accent-primary/40 px-1.5 py-1 text-xs",children:"+ New Session"})]}),o.jsx("div",{className:"divide-y divide-border",children:v.length>0?v.map(S=>{const k=i.find(y=>S.workdir.startsWith(y.workdir)),C=k?`/p/${k.id}/s/${S.id}`:"#";return o.jsx(Fn,{href:C,className:"block p-3 md:p-4 hover:bg-bg-tertiary/50 cursor-pointer transition-colors",children:o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[o.jsx("div",{className:"flex items-center gap-3 flex-1 min-w-0",children:o.jsx("div",{className:"flex-1 min-w-0",children:o.jsx("div",{className:"text-sm text-text-muted truncate",children:S.title??S.id.slice(0,8)})})}),o.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[o.jsx("span",{className:"text-text-muted text-xs",children:sC(S.updatedAt)}),o.jsxs("span",{className:"text-text-muted text-xs",children:[S.messageCount," msgs"]})]})]})},S.id)}):o.jsx("div",{className:"p-3 md:p-4 text-text-muted text-sm",children:"No sessions yet"})})]})},m.id)}),d.length===0&&!c&&o.jsx("div",{className:"text-center py-12 text-text-muted",children:"No projects yet. Open a project to get started."}),c&&o.jsx("div",{className:"flex justify-center py-12",children:o.jsx(vo,{})})]}),e&&o.jsx(SC,{isOpen:e,onClose:()=>r(!1)})]})}function CC(){const[,e]=Mh("/p/:projectId/new"),[,r]=lr(),s=e==null?void 0:e.projectId,i=Ce(c=>c.createSession);return P.useEffect(()=>{s&&(async()=>{const u=await i(s);r(u?`/p/${s}/s/${u.id}`:`/p/${s}`)})()},[s,i,r]),o.jsx("div",{className:"flex-1 flex items-center justify-center",children:o.jsx(vo,{})})}function kC(){const e=Ft(r=>r.currentProject);return o.jsx("div",{className:"h-full flex flex-col items-center justify-center p-8 text-center",children:o.jsxs("div",{className:"max-w-md",children:[o.jsx("h2",{className:"text-xl font-semibold text-text-primary mb-2",children:(e==null?void 0:e.name)??"Project"}),o.jsx("p",{className:"text-text-secondary mb-6",children:"No session selected"}),o.jsxs("div",{className:"flex flex-col gap-3",children:[e&&o.jsx(Fn,{href:`/p/${e.id}/new`,"data-testid":"create-new-session-button",className:"block w-full rounded font-medium transition-colors bg-accent-primary/25 text-text-primary hover:bg-accent-primary/40 px-3 py-2 text-center",children:"Create New Session"}),o.jsx("p",{className:"text-sm text-text-muted",children:"Or select an existing session from the sidebar"})]})]})})}const Ga=e=>Math.round(e*10)/10;function mh(e){return{providerId:e.providerId,providerName:e.providerName,backend:e.backend,model:e.model}}function EC(e){return`${e.providerId}::${e.model}`}function jC(e){return`${e.providerName} > ${e.model}`}function ob(e){let r=0,s=0,i=0,c=0,u=0,h=0;const l=[],d=[];let f=0;for(const[v,S]of e.entries()){const k=S.stats,C=mh(k);r+=k.totalTime,s+=k.toolTime,i+=k.prefillTokens,c+=k.generationTokens;const y=k.prefillSpeed>0?k.prefillTokens/k.prefillSpeed:0,b=k.generationSpeed>0?k.generationTokens/k.generationSpeed:0;u+=y,h+=b,l.push({messageId:S.id,timestamp:S.timestamp,...C,mode:k.mode,responseIndex:v+1,prefillTokens:k.prefillTokens,generationTokens:k.generationTokens,prefillSpeed:k.prefillSpeed,generationSpeed:k.generationSpeed,totalTime:k.totalTime,aiTime:k.totalTime-k.toolTime,toolTime:k.toolTime});const x=k.llmCalls??[];for(const _ of x)f+=1,d.push({messageId:S.id,timestamp:_.timestamp??S.timestamp,providerId:_.providerId,providerName:_.providerName,backend:_.backend,model:_.model,mode:k.mode,responseIndex:v+1,sessionCallIndex:f,callIndex:_.callIndex,promptTokens:_.promptTokens,completionTokens:_.completionTokens,ttft:_.ttft,completionTime:_.completionTime,prefillSpeed:_.prefillSpeed,generationSpeed:_.generationSpeed,totalTime:_.totalTime,..._.temperature!==void 0&&{temperature:_.temperature},..._.topP!==void 0&&{topP:_.topP},..._.topK!==void 0&&{topK:_.topK},..._.maxTokens!==void 0&&{maxTokens:_.maxTokens}})}const g=u>0?Ga(i/u):0,m=h>0?Ga(c/h):0;return{totalTime:Ga(r),aiTime:Ga(r-s),toolTime:Ga(s),prefillTokens:i,generationTokens:c,avgPrefillSpeed:g,avgGenerationSpeed:m,responseCount:e.length,llmCallCount:d.length,dataPoints:l,callDataPoints:d}}function NC(e){const r=e.filter(c=>c.stats!==void 0&&c.stats!==null).sort((c,u)=>new Date(c.timestamp).getTime()-new Date(u.timestamp).getTime());if(r.length===0)return null;const s=new Map;for(const c of r){const u=EC(mh(c.stats)),h=s.get(u)??[];s.set(u,[...h,c])}const i=Array.from(s.entries()).map(([c,u])=>{const h=mh(u[0].stats),l=ob(u);return{...h,key:c,label:jC(h),...l}});return{...ob(r),modelGroups:i}}function TC(e){return P.useMemo(()=>NC(e),[e])}function AC(e){const[r,s]=P.useState(null),[i,c]=P.useState(!0),[u,h]=P.useState(null),l=e||"";return P.useEffect(()=>{if(!l){c(!1);return}let d=!0,f=null;const g=async()=>{try{const v=await(await ke(`/api/branch?workdir=${encodeURIComponent(l)}`)).json();d&&(s(v.branch),h(v.error||null),c(!1))}catch(m){d&&(h(m instanceof Error?m.message:"Failed to fetch branch"),c(!1))}};return g(),f=setInterval(g,3e3),()=>{d=!1,f&&clearInterval(f)}},[l]),{branch:r,loading:i,error:u}}function Zl(e){return e.toLocaleString("en-US").replace(/,/g," ")}function lb(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function DC(e){if(e<60)return`${e.toFixed(1)}s`;const r=Math.floor(e/60),s=Math.round(e%60);return`${r}m${s}s`}const cb=["▁","▂","▃","▄","▅","▆","▇","█"];function RC(e,r,s){if(s===r)return 4;const i=(e-r)/(s-r);return Math.min(7,Math.max(0,Math.round(i*7)))}function LC(e,r){if(e===r){const c=Math.max(Math.abs(e)*.05,1);return{minY:e-c,maxY:r+c}}const s=r-e,i=Math.max(s*.1,.1);return{minY:e-i,maxY:r+i}}function OC(e,r){if(e.length===0||r<=0)return{blocks:"",minX:0,maxX:0,minY:0,maxY:0};const s=[...e].sort((m,v)=>m.x-v.x),i=s[0].x,c=s[s.length-1].x,u=Math.min(...s.map(m=>m.y)),h=Math.max(...s.map(m=>m.y)),{minY:l,maxY:d}=LC(u,h),f=Array.from({length:r},()=>" "),g=new Map;for(const m of s){const v=c===i?0:Math.round((m.x-i)/(c-i)*(r-1)),S=g.get(v)??[];g.set(v,[...S,m.y])}for(const[m,v]of g){const S=Math.max(...v);f[m]=cb[RC(S,l,d)]??cb[0]}return{blocks:f.join(""),minX:i,maxX:c,minY:l,maxY:d}}function ub(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function db({data:e,width:r=60,height:s=78,label:i,xLabel:c,yLabel:u,showAxes:h=!0,formatY:l=ub,formatX:d=ub}){const f=P.useMemo(()=>{const g=OC(e,r),m=Math.max(r*6,240),v=10,S=8,C=[...e].sort((_,j)=>_.x-j.x).map(_=>{const j=g.maxX===g.minX?m/2:v+(_.x-g.minX)/(g.maxX-g.minX)*(m-v*2),A=g.maxY===g.minY?s/2:S+(g.maxY-_.y)/(g.maxY-g.minY)*(s-S*2);return{..._,cx:j,cy:A,leftPercent:j/m*100,topPercent:A/s*100}}),y=C.map((_,j)=>`${j===0?"M":"L"} ${_.cx.toFixed(1)} ${_.cy.toFixed(1)}`).join(" "),x=[g.maxY,(g.maxY+g.minY)/2,g.minY].map(_=>({value:_,y:g.maxY===g.minY?s/2:S+(g.maxY-_)/(g.maxY-g.minY)*(s-S*2)}));return{...g,chartWidth:m,points:C,path:y,gridLines:x}},[e,s,r]);return e.length===0?o.jsxs("div",{className:"font-mono text-text-muted text-xs",children:[i&&o.jsx("div",{className:"mb-1",children:i}),o.jsx("div",{children:"No data"})]}):o.jsxs("div",{className:"font-mono text-xs",children:[i&&o.jsx("div",{className:"text-text-secondary mb-2",children:i}),o.jsxs("div",{className:"flex gap-3",children:[h&&o.jsx("div",{className:"w-12 h-[78px] flex flex-col justify-between text-right text-text-muted",children:f.gridLines.map(g=>o.jsx("span",{children:l(g.value)},`${g.value}-${g.y}`))}),o.jsx("div",{className:"flex-1 min-w-0",children:o.jsxs("div",{className:"relative h-[78px]",children:[o.jsxs("svg",{viewBox:`0 0 ${f.chartWidth} ${s}`,className:"w-full h-[78px] overflow-visible",preserveAspectRatio:"none","aria-hidden":"true",children:[f.gridLines.map(g=>o.jsx("line",{x1:"0",x2:f.chartWidth,y1:g.y,y2:g.y,stroke:"currentColor",strokeDasharray:"3 4",className:"text-border/60"},`grid-${g.y}`)),f.points.map(g=>o.jsx("line",{x1:g.cx,x2:g.cx,y1:s-4,y2:g.cy,stroke:"currentColor",className:"text-border/40"},`guide-${g.cx}-${g.cy}`)),f.points.length>1&&o.jsx("path",{d:f.path,fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-accent-primary/45"})]}),f.points.map(g=>o.jsx("div",{className:"absolute -translate-x-1/2 -translate-y-1/2",style:{left:`${g.leftPercent}%`,top:`${g.topPercent}%`},title:`${d(g.x)} -> ${l(g.y)}`,children:o.jsx("div",{className:"w-2.5 h-2.5 rounded-full bg-accent-primary/20 flex items-center justify-center",children:o.jsx("div",{className:"w-1.5 h-1.5 rounded-full bg-accent-primary"})})},`point-${g.x}-${g.y}`))]})})]}),h&&o.jsxs("div",{className:"flex items-start gap-3 text-text-muted mt-1",children:[o.jsx("span",{className:"w-12"}),o.jsxs("span",{className:"flex-1 flex justify-between",children:[o.jsx("span",{children:d(f.minX)}),o.jsx("span",{children:c}),o.jsx("span",{children:d(f.maxX)})]})]}),u&&h&&o.jsx("div",{className:"text-text-muted mt-1 text-center",children:u})]})}function MC({data:e,prefillLabel:r="Prefill Speed (tok/s) by Response",generationLabel:s="Generation Speed (tok/s) by Response",xLabel:i="response",width:c=60}){const u=e.map(l=>({x:l.x,y:l.ppSpeed})),h=e.map(l=>({x:l.x,y:l.tgSpeed}));return o.jsxs("div",{className:"space-y-5",children:[o.jsx(db,{data:u,width:c,label:r,xLabel:i}),o.jsx(db,{data:h,width:c,label:s,xLabel:i})]})}function IC(e){const r=new Map;for(const s of e.callDataPoints){const i=r.get(s.messageId)??[];r.set(s.messageId,[...i,s])}return e.dataPoints.map(s=>{const i=[...r.get(s.messageId)??[]].sort((c,u)=>c.callIndex-u.callIndex);return{...s,callCount:i.length,calls:i,isExpandable:i.length>1}})}function BC(e){return{mode:"responses",xLabel:"response",prefillLabel:"Prefill Speed (tok/s) by Response",generationLabel:"Generation Speed (tok/s) by Response",points:e.dataPoints.map(r=>({x:r.responseIndex,ppSpeed:r.prefillSpeed,tgSpeed:r.generationSpeed}))}}function zC(e){return{mode:"calls",xLabel:"context",prefillLabel:"Prefill Speed (tok/s) vs Context",generationLabel:"Generation Speed (tok/s) vs Context",points:e.callDataPoints.map(r=>({x:r.promptTokens,ppSpeed:r.prefillSpeed,tgSpeed:r.generationSpeed}))}}function PC(e){return e.callDataPoints.length>0?zC(e):BC(e)}function qd(e){if(e<60)return`${e.toFixed(1)}s`;const r=Math.floor(e/60),s=e%60;return`${r}m ${s.toFixed(0)}s`}function $s(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toString()}function to(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function HC(e){if(e.length===0)return"0 ctx";const r=Math.min(...e),s=Math.max(...e);return r===s?`${$s(r)} ctx`:`${$s(r)}-${$s(s)} ctx`}function Ql(e){return`${to(e)} t/s`}function ly(e){try{return new Date(e).toLocaleTimeString("en-US",{hour12:!1})}catch{return e}}function FC(e){return{exportedAt:new Date().toISOString(),providerId:e.providerId,providerName:e.providerName,backend:e.backend,model:e.model,label:e.label,summary:{totalTime:e.totalTime,aiTime:e.aiTime,toolTime:e.toolTime,prefillTokens:e.prefillTokens,generationTokens:e.generationTokens,avgPrefillSpeed:e.avgPrefillSpeed,avgGenerationSpeed:e.avgGenerationSpeed,responseCount:e.responseCount,llmCallCount:e.llmCallCount},responses:e.dataPoints.map(r=>({responseIndex:r.responseIndex,timestamp:r.timestamp,mode:r.mode,prefillTokens:r.prefillTokens,generationTokens:r.generationTokens,prefillSpeed:r.prefillSpeed,generationSpeed:r.generationSpeed,totalTime:r.totalTime,aiTime:r.aiTime,toolTime:r.toolTime})),llmCalls:e.callDataPoints.map(r=>({sessionCallIndex:r.sessionCallIndex,responseIndex:r.responseIndex,callIndex:r.callIndex,timestamp:r.timestamp,mode:r.mode,promptTokens:r.promptTokens,completionTokens:r.completionTokens,ttft:r.ttft,completionTime:r.completionTime,prefillSpeed:r.prefillSpeed,generationSpeed:r.generationSpeed,totalTime:r.totalTime}))}}function UC({isOpen:e,onClose:r,stats:s}){const i=P.useRef(null),[c,u]=P.useState({}),[h,l]=P.useState(()=>{var k;return((k=s.modelGroups[0])==null?void 0:k.key)??""});P.useEffect(()=>{var k;s.modelGroups.some(C=>C.key===h)||l(((k=s.modelGroups[0])==null?void 0:k.key)??"")},[h,s.modelGroups]);const d=P.useMemo(()=>s.modelGroups.find(k=>k.key===h)??s.modelGroups[0],[h,s.modelGroups]),f=P.useMemo(()=>d?IC(d):[],[d]),g=P.useMemo(()=>d?PC(d):{mode:"responses",xLabel:"response",prefillLabel:"",generationLabel:"",points:[]},[d]),m=P.useCallback(k=>{u(C=>({...C,[k]:!C[k]}))},[]),v=P.useCallback(()=>{if(!d)return;const k=FC(d);navigator.clipboard.writeText(JSON.stringify(k,null,2)).catch(C=>console.error("Failed to copy:",C))},[d]),S=P.useCallback(async()=>{if(i.current)try{const k=(await fh(async()=>{const{default:b}=await import("./html2canvas.esm-QH1iLAAe.js");return{default:b}},[])).default,C=await k(i.current,{backgroundColor:"#1a1a1a",scale:2}),y=document.createElement("a");y.download=`openfox-stats-${new Date().toISOString().slice(0,10)}.png`,y.href=C.toDataURL("image/png"),y.click()}catch(k){console.error("Failed to export PNG:",k),v()}},[v]);return o.jsx(At,{isOpen:e,onClose:r,title:"Session Stats",size:"lg",children:o.jsxs("div",{ref:i,className:"space-y-6",children:[o.jsx("section",{children:o.jsx("div",{className:"flex flex-wrap gap-2",children:s.modelGroups.map(k=>o.jsx("button",{onClick:()=>l(k.key),className:`px-3 py-1.5 rounded border text-xs transition-colors ${k.key===(d==null?void 0:d.key)?"border-accent-primary bg-accent-primary/10 text-accent-primary":"border-border text-text-muted hover:text-text-primary hover:bg-bg-tertiary/40"}`,title:k.label,children:k.label},k.key))})}),d&&o.jsxs("section",{children:[o.jsx("h3",{className:"text-sm font-semibold text-text-secondary mb-3 uppercase tracking-wide",children:"Summary"}),o.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-4",children:[o.jsx(Hr,{label:"AI Time",value:qd(d.aiTime)}),o.jsx(Hr,{label:"Total Time",value:qd(d.totalTime)}),o.jsx(Hr,{label:"Tool Time",value:qd(d.toolTime)}),o.jsx(Hr,{label:"Responses",value:d.responseCount.toString()}),o.jsx(Hr,{label:"LLM Calls",value:d.llmCallCount.toString()})]}),o.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 mt-3",children:[o.jsx(Hr,{label:"Prefill Tokens",value:$s(d.prefillTokens),subValue:`@ ${to(d.avgPrefillSpeed)} tok/s`}),o.jsx(Hr,{label:"Gen Tokens",value:$s(d.generationTokens),subValue:`@ ${to(d.avgGenerationSpeed)} tok/s`}),o.jsx(Hr,{label:"Avg PP Speed",value:`${to(d.avgPrefillSpeed)}`,subValue:"tok/s"}),o.jsx(Hr,{label:"Avg TG Speed",value:`${to(d.avgGenerationSpeed)}`,subValue:"tok/s"})]})]}),d&&g.points.length>1&&o.jsxs("section",{children:[o.jsxs("div",{className:"flex items-center justify-between mb-3",children:[o.jsx("h3",{className:"text-sm font-semibold text-text-secondary uppercase tracking-wide",children:"Performance Progression"}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("button",{onClick:v,className:"px-2 py-1 text-xs text-text-muted hover:text-text-primary hover:bg-bg-tertiary rounded transition-colors",children:"Copy JSON"}),o.jsx("button",{onClick:S,className:"px-2 py-1 text-xs text-text-muted hover:text-text-primary hover:bg-bg-tertiary rounded transition-colors",children:"Save PNG"})]})]}),o.jsx("div",{className:"bg-bg-tertiary/50 rounded p-4",children:o.jsx(MC,{data:g.points,width:50,prefillLabel:g.prefillLabel,generationLabel:g.generationLabel,xLabel:g.xLabel})})]}),d&&o.jsxs("section",{children:[o.jsxs("h3",{className:"text-sm font-semibold text-text-secondary mb-3 uppercase tracking-wide",children:["Response Log (",d.responseCount," responses)"]}),o.jsx("div",{className:"overflow-y-auto bg-bg-tertiary/30 rounded",children:o.jsxs("table",{className:"w-full table-fixed border-separate border-spacing-0 text-xs",children:[o.jsxs("colgroup",{children:[o.jsx("col",{className:"w-[7%]"}),o.jsx("col",{className:"w-[14%]"}),o.jsx("col",{className:"w-[10%]"}),o.jsx("col",{className:"w-[14%]"}),o.jsx("col",{className:"w-[14%]"}),o.jsx("col",{className:"w-[14%]"}),o.jsx("col",{className:"w-[11%]"}),o.jsx("col",{className:"w-[2%]"})]}),o.jsx("thead",{children:o.jsxs("tr",{className:"text-[10px] uppercase tracking-wide text-text-muted/80",children:[o.jsx("th",{className:"px-3 py-2 text-center font-medium",children:"#"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"At"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"Time"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"Context"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"PP t/s"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"TG t/s"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"Calls"}),o.jsx("th",{className:"px-2 py-2"})]})}),o.jsx("tbody",{children:f.map((k,C)=>o.jsxs(P.Fragment,{children:[o.jsx($C,{row:k,index:C,isExpanded:c[k.messageId]??!1,onToggle:k.isExpandable?()=>m(k.messageId):void 0}),(c[k.messageId]??!1)&&k.calls.map((y,b)=>o.jsx(qC,{dataPoint:y,index:b},`${y.messageId}-${y.callIndex}`))]},k.messageId))})]})})]})]})})}function Hr({label:e,value:r,subValue:s}){return o.jsxs("div",{className:"bg-bg-tertiary/50 rounded p-3",children:[o.jsx("div",{className:"text-text-muted text-xs mb-1",children:e}),o.jsx("div",{className:"text-text-primary text-lg font-semibold",children:r}),s&&o.jsx("div",{className:"text-text-muted text-xs",children:s})]})}function $C({row:e,index:r,isExpanded:s,onToggle:i}){const c=e.calls.length>0?HC(e.calls.map(u=>u.promptTokens)):`${$s(e.prefillTokens)} ctx`;return o.jsxs("tr",{onClick:i,className:`${r%2===0?"bg-bg-tertiary/20":""} ${i?"cursor-pointer hover:bg-bg-tertiary/35 transition-colors":""}`,children:[o.jsx("td",{className:"px-3 py-2 text-center text-text-muted align-middle",children:e.responseIndex}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted font-mono align-middle whitespace-nowrap",children:ly(e.timestamp)}),o.jsxs("td",{className:"px-2 py-2 text-center text-text-muted align-middle whitespace-nowrap",children:[e.totalTime.toFixed(1),"s"]}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:c.replace(/ ctx$/,"")}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:Ql(e.prefillSpeed)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:Ql(e.generationSpeed)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted font-mono align-middle whitespace-nowrap",children:e.callCount}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted align-middle whitespace-nowrap",children:e.isExpandable?s?"v":">":""})]})}function qC({dataPoint:e,index:r}){const s=e.temperature!==void 0||e.topP!==void 0||e.topK!==void 0||e.maxTokens!==void 0;return o.jsxs(o.Fragment,{children:[o.jsxs("tr",{className:`${r%2===0?"bg-bg-tertiary/10":"bg-bg-tertiary/5"}`,children:[o.jsxs("td",{className:"px-3 py-2 pl-6 text-center text-text-muted align-middle border-l border-border/60",children:["c",e.callIndex]}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted font-mono align-middle whitespace-nowrap",children:ly(e.timestamp)}),o.jsxs("td",{className:"px-2 py-2 text-center text-text-muted align-middle whitespace-nowrap",children:[e.totalTime.toFixed(1),"s"]}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:$s(e.promptTokens)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:Ql(e.prefillSpeed)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:Ql(e.generationSpeed)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted font-mono align-middle whitespace-nowrap",children:e.callIndex}),o.jsx("td",{className:"px-2 py-2"})]}),s&&o.jsx("tr",{className:`${r%2===0?"bg-bg-tertiary/5":"bg-bg-tertiary/[2.5%]"}`,children:o.jsx("td",{colSpan:8,className:"px-6 py-1.5 border-l border-border/60",children:o.jsxs("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-[10px] text-text-muted",children:[e.temperature!==void 0&&o.jsxs("span",{children:["temp: ",e.temperature.toFixed(2)]}),e.topP!==void 0&&o.jsxs("span",{children:["topP: ",e.topP.toFixed(2)]}),e.topK!==void 0&&o.jsxs("span",{children:["topK: ",e.topK]}),e.maxTokens!==void 0&&o.jsxs("span",{children:["maxTok: ",e.maxTokens]})]})})})]})}const WC={pending:{icon:"○",color:"text-text-muted",label:"Pending"},in_progress:{icon:"●",color:"text-accent-warning",label:"In Progress",animate:!0},completed:{icon:"◉",color:"text-purple-400",label:"Completed"},passed:{icon:"✓",color:"text-accent-success",label:"Passed"},failed:{icon:"✗",color:"text-accent-error",label:"Failed"}},VC=P.memo(function({criteria:r}){if(r.length===0)return o.jsx("div",{className:"text-text-muted text-sm text-center py-2",children:"No criteria yet"});const s={pending:0,in_progress:0,completed:0,passed:0,failed:0};for(const c of r){const u=c.status.type;u in s&&s[u]++}const i=Object.keys(s).filter(c=>s[c]>0);return o.jsxs("div",{className:"space-y-1",children:[o.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[o.jsx("span",{className:"font-semibold text-text-primary",children:"Total:"}),o.jsx("span",{className:"text-text-secondary",children:r.length})]}),o.jsx("div",{className:"space-y-1",children:i.map(c=>{const u=WC[c];return o.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[o.jsx("span",{className:`${u.color} ${u.animate?"animate-pulse":""} text-sm leading-tight`,children:u.icon}),o.jsxs("span",{className:"text-text-muted",children:[u.label,":"]}),o.jsx("span",{className:"text-text-primary font-medium",children:s[c]})]},c)})})]})});function GC({isOpen:e,onClose:r}){const s=gr(C=>C.config),i=gr(C=>C.saveConfig),[c,u]=P.useState(""),[h,l]=P.useState(""),[d,f]=P.useState(!1),[g,m]=P.useState(!1),[v,S]=P.useState(!1);P.useEffect(()=>{e&&(u((s==null?void 0:s.command)??""),l((s==null?void 0:s.url)??""),f((s==null?void 0:s.hotReload)??!1),m((s==null?void 0:s.disableInspect)??!1))},[e,s]);const k=async()=>{!c.trim()||!h.trim()||(S(!0),await i({command:c.trim(),url:h.trim(),hotReload:d,disableInspect:g}),S(!1),r())};return o.jsx(At,{isOpen:e,onClose:r,title:"Dev Server Config",size:"sm",children:o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{children:[o.jsx("label",{className:"block text-xs text-text-secondary mb-1",children:"Command"}),o.jsx("input",{className:"input w-full",type:"text",value:c,onChange:C=>u(C.target.value),placeholder:"npm run dev"})]}),o.jsxs("div",{children:[o.jsx("label",{className:"block text-xs text-text-secondary mb-1",children:"Dev URL"}),o.jsx("input",{className:"input w-full",type:"text",value:h,onChange:C=>l(C.target.value),placeholder:"http://localhost:3000"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("input",{type:"checkbox",id:"hotReload",checked:d,onChange:C=>f(C.target.checked),className:"rounded border-border bg-bg-tertiary"}),o.jsx("label",{htmlFor:"hotReload",className:"text-xs text-text-secondary",children:"Hot Reload"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("input",{type:"checkbox",id:"disableInspect",checked:g,onChange:C=>m(C.target.checked),className:"rounded border-border bg-bg-tertiary"}),o.jsx("label",{htmlFor:"disableInspect",className:"text-xs text-text-secondary",children:"Disable inspect feedback"})]}),o.jsxs("div",{className:"flex justify-end gap-2 pt-2",children:[o.jsx("button",{className:"btn btn-secondary",onClick:r,children:"Cancel"}),o.jsx("button",{className:"btn btn-primary",onClick:k,disabled:v||!c.trim()||!h.trim(),children:v?"Saving...":"Save"})]})]})})}const hb={30:"text-black",31:"text-red-400",32:"text-accent-success",33:"text-accent-warning",34:"text-blue-400",35:"text-purple-400",36:"text-cyan-400",37:"text-gray-300",90:"text-gray-500",91:"text-red-500",92:"text-green-500",93:"text-yellow-400",94:"text-blue-500",95:"text-pink-400",96:"text-cyan-500",97:"text-white"},KC={40:"bg-black",41:"bg-red-900",42:"bg-green-900",43:"bg-yellow-900",44:"bg-blue-900",45:"bg-purple-900",46:"bg-cyan-900",47:"bg-gray-700"},fb={1:"font-bold",2:"opacity-75",4:"underline",7:"bg-bg-secondary"},YC="text-text-primary";function XC(e){const r=[],s=/\x1b\[([0-9;]+)m/g;let i=0,c="text-text-primary",u;try{for(;(u=s.exec(e))!==null;){if(u.index>i){const f=e.slice(i,u.index);f&&r.push({text:f,className:c})}const h=u[1];if(!h)continue;const l=h.split(";").map(Number);if(l.length===0||l[0]===0){c="text-text-primary";continue}const d=[];for(const f of l)if(f>=30&&f<=37){const g=hb[f];g&&d.push(g)}else if(f>=40&&f<=47){const g=KC[f];g&&d.push(g)}else if(f>=90&&f<=97){const g=hb[f];g&&d.push(g)}else if(f in fb){const g=fb[f];g&&d.push(g)}else f===39?d.push(YC):f===49&&(c=c.split(" ").filter(g=>!g.startsWith("bg-")).join(" "));d.length>0&&(c=d.join(" ")),i=s.lastIndex}if(i<e.length){const h=e.slice(i);h&&r.push({text:h,className:c})}return r}catch(h){return console.warn("ANSI parsing failed, stripping codes:",h),[{text:ZC(e),className:"text-text-primary"}]}}function ZC(e){return e.replace(/\x1b\[([0-9;]+)m/g,"")}function co(e){const r=XC(e),s=[];return r.forEach((i,c)=>{const u=i.text.split(`
|
|
84
|
+
`,children:[o.jsxs("div",{className:"p-4 border-b border-border flex gap-2",children:[o.jsx(Fn,{href:`/p/${e}/new`,className:"flex-1 block text-center rounded font-medium transition-colors bg-accent-primary/25 text-text-primary hover:bg-accent-primary/40 px-3 py-1.5 text-sm","data-testid":"sidebar-new-session-button",children:"+ New Session"}),o.jsx(bo,{items:[{label:"Edit project settings",onClick:()=>u(!0)},{label:"Delete all sessions",onClick:_,danger:!0}],trigger:o.jsx("button",{className:"flex-shrink-0 p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Options",children:o.jsx(Bh,{})})}),s&&o.jsx(lo,{onClick:s,className:"md:hidden",variant:"sidebar",size:"md"})]}),k&&o.jsx(hC,{isOpen:c,onClose:()=>u(!1),project:k}),o.jsx("div",{className:"flex-1 overflow-y-auto",children:b.length===0?o.jsx("div",{className:"p-4 text-center text-text-muted text-xs",children:"No sessions"}):o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"divide-y divide-border",children:mC(b,l,d,x,e)}),S&&o.jsx("div",{className:"p-4 text-center text-text-muted text-xs",children:"Loading more..."}),o.jsx("div",{ref:C,className:"h-px"})]})})]})]})}function mC(e,r,s,i,c){const u=iy(e);return Array.from(u).map(([h,l])=>{const d=l[0];return d?o.jsxs("div",{children:[o.jsx("div",{className:"px-4 py-2 bg-bg-tertiary/30 text-text-muted text-xs font-medium",children:ry(d.updatedAt)}),l.map(f=>{const g=(r==null?void 0:r.id)===f.id,m=s.includes(f.id),v=f.isRunning;return o.jsx("div",{className:`w-full px-4 py-3 text-left hover:bg-bg-tertiary/50 transition-colors group ${g?"bg-bg-tertiary":""}`,children:o.jsxs(Fn,{href:`/p/${c}/s/${f.id}`,className:`block ${g?"text-accent-primary":"text-text-primary"} hover:text-accent-primary`,children:[o.jsxs("div",{className:"flex justify-between items-center mb-1",children:[o.jsx("span",{className:`font-medium truncate text-sm ${g?"text-accent-primary":"text-text-primary"}`,children:f.title??f.id.slice(0,6)}),o.jsx(bo,{items:[{label:"Delete session",onClick:S=>i(f.id,S),danger:!0}],trigger:o.jsx("button",{onClick:S=>S.preventDefault(),className:"p-1.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-all",title:"Options",children:o.jsx(Bh,{})})})]}),o.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[v?o.jsx(Nw,{}):m&&!g?o.jsx("span",{"aria-label":"Unread activity",title:"Unread activity",className:"w-2 h-2 rounded-full bg-amber-400 flex-shrink-0"}):null,o.jsx("span",{className:"text-text-muted text-xs flex-shrink-0",children:uc(f.updatedAt)}),o.jsxs("span",{className:"text-text-muted text-xs flex-shrink-0",children:[f.messageCount," messages"]})]})]})},f.id)})]},h):null})}const ab=["⠋","⠙","⠹","⠸","⠼","⠴"];function gC(){var l;const e=Ft(d=>d.currentProject),r=Ce(d=>d.currentSession),s=qv(),i=!1,c=P.useRef(0),u=P.useRef(null);P.useEffect(()=>(s?(u.current=window.setInterval(()=>{c.current=(c.current+1)%ab.length,h()},150),h()):(u.current&&(clearInterval(u.current),u.current=null),h()),()=>{u.current&&(clearInterval(u.current),u.current=null)}),[s,e,r,i]);const h=()=>{var m;const f=(m=r==null?void 0:r.metadata)==null?void 0:m.title,g=s?`${ab[c.current]} `:"";e&&f?document.title=`${g}${e.name} - ${f} | OpenFox`:e?document.title=`${g}${e.name} | OpenFox`:document.title=`${g}OpenFox`};return typeof window<"u"&&((l=r==null?void 0:r.metadata)!=null&&l.title)&&window.document.documentElement.setAttribute("data-session-title",r.metadata.title),null}function xC({isOpen:e,onClose:r,projectName:s,onConfirm:i}){const c=()=>{i(),r()};return o.jsx(At,{isOpen:e,onClose:r,title:"Delete Project",size:"sm",children:o.jsxs("div",{className:"space-y-4",children:[o.jsxs("p",{className:"text-text-secondary",children:["This will permanently delete the project ",o.jsx("span",{className:"font-semibold text-text-primary",children:s})," and all its sessions from OpenFox. The project files on disk will remain untouched."]}),o.jsxs("div",{className:"flex justify-end gap-2",children:[o.jsx(nt,{variant:"secondary",onClick:r,children:"Cancel"}),o.jsx(nt,{variant:"danger",onClick:c,children:"Delete"})]})]})})}const dc=P.forwardRef(({className:e="",...r},s)=>o.jsx("input",{ref:s,className:`bg-bg-tertiary border border-border rounded px-3 py-2 text-text-primary placeholder-text-muted focus:outline-none focus:ring-2 focus:ring-accent-primary/50 focus:border-accent-primary ${e}`,...r}));dc.displayName="Input";function bC(e){return!e||e.trim()===""?{valid:!1,error:"Project name cannot be empty"}:/^[a-zA-Z0-9._-]+$/.test(e)?{valid:!0}:{valid:!1,error:"Project name can only contain letters, numbers, hyphens, underscores, and dots"}}function vC({isOpen:e,onClose:r}){const[,s]=lr(),[i,c]=P.useState(""),[u,h]=P.useState(null),[l,d]=P.useState(!1),[f,g]=P.useState(""),m=P.useRef(null);P.useEffect(()=>{e&&(ke("/api/config").then(C=>C.json()).then(C=>{C.workdir&&g(C.workdir)}),c(""),h(null),d(!1),setTimeout(()=>{var C;(C=m.current)==null||C.focus()},100))},[e]);const v=P.useCallback(async C=>{C.preventDefault();const y=bC(i);if(!y.valid){h(y.error);return}d(!0),h(null);const b=`${f}/${i}`;try{const x=await ke("/api/projects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:i,workdir:b})});if(!x.ok){const A=await x.json().catch(()=>({}));throw new Error(A.error||"Failed to create project")}const j=(await x.json()).project;r(),s(`/p/${j.id}`)}catch(x){h(x instanceof Error?x.message:"Failed to create project"),d(!1)}},[i,s,r,f]),S=P.useCallback(()=>{c(""),h(null),r()},[r]),k=i?`${f}/${i}`:"";return o.jsx(At,{isOpen:e,onClose:S,title:"Create New Project",size:"sm",children:o.jsxs("form",{onSubmit:v,className:"space-y-4",children:[o.jsxs("div",{children:[o.jsx("label",{htmlFor:"project-name",className:"block text-sm font-medium text-text-secondary mb-2",children:"Project Name"}),o.jsx(dc,{ref:m,id:"project-name",value:i,onChange:C=>{c(C.target.value),h(null)},placeholder:"my-project",disabled:l,"data-testid":"create-project-name-input",className:"w-full"}),i&&o.jsxs("div",{className:"mt-2 text-xs text-text-muted",children:["Full path: ",o.jsx("span",{className:"font-mono",children:k})]}),u&&o.jsx("div",{className:"mt-3 p-3 bg-accent-error/10 border border-accent-error/30 rounded text-sm text-accent-error",children:u})]}),o.jsxs("div",{className:"flex justify-end gap-2",children:[o.jsx(nt,{type:"button",variant:"secondary",onClick:S,disabled:l,children:"Cancel"}),o.jsx(nt,{type:"submit",variant:"primary",disabled:l||!i.trim(),"data-testid":"create-project-submit-button",className:"min-w-[100px]",children:l?o.jsxs("span",{className:"flex items-center gap-2",children:[o.jsx(qi,{className:"h-4 w-4"}),"Creating..."]}):"Create"})]})]})})}const yC={sm:"w-4 h-4",md:"w-8 h-8",lg:"w-12 h-12"};function vo({size:e="md",className:r=""}){return o.jsx("div",{className:`animate-spin border-2 border-accent-primary border-t-transparent rounded-full ${yC[e]} ${r}`})}function _C({text:e,...r}){return o.jsxs("div",{className:"text-center",children:[o.jsx(vo,{...r,className:"mx-auto mb-4"}),e&&o.jsx("div",{className:"text-text-secondary",children:e})]})}function oy({onSelect:e,onClose:r,initialPath:s}){const[i,c]=P.useState(null),[u,h]=P.useState(!0),[l,d]=P.useState(""),[f,g]=P.useState(-1),m=P.useRef(null),v=P.useRef([]),S=P.useCallback(async x=>{h(!0),d(""),g(-1);try{const _=x?`/api/directories?path=${encodeURIComponent(x)}`:"/api/directories",A=await(await ke(_)).json();c(A)}catch(_){console.error("Failed to load directories:",_)}finally{h(!1)}},[]);P.useEffect(()=>{S(s)},[s,S]);const k=((i==null?void 0:i.current)??"").split("/").filter(Boolean).map((x,_,j)=>({name:x,path:"/"+j.slice(0,_+1).join("/")})),C=(i==null?void 0:i.directories.filter(x=>l===""||x.name.toLowerCase().includes(l.toLowerCase())))??[],y=[...i!=null&&i.parent?[{type:"parent",path:i.parent,name:".."}]:[],...C.map(x=>({type:"dir",path:x.path,name:x.name}))];P.useEffect(()=>{g(l?0:-1)},[l,C.length]),P.useEffect(()=>{var x;f>=0&&v.current[f]&&((x=v.current[f])==null||x.scrollIntoView({block:"nearest"}))},[f]);const b=x=>{var _;if(x.key==="ArrowDown")x.preventDefault(),g(j=>Math.min(j+1,y.length-1));else if(x.key==="ArrowUp")x.preventDefault(),g(j=>Math.max(j-1,0));else if(x.key==="Enter"){if(x.preventDefault(),f>=0&&y[f]){const j=y[f];j.type,S(j.path)}}else x.key==="Escape"&&(d(""),(_=m.current)==null||_.focus())};return o.jsxs(At,{isOpen:!0,onClose:r,title:"Select Folder",size:"lg",children:[i&&o.jsx("div",{className:"px-3 py-2 bg-bg-tertiary/30 -mx-4 -mt-4 mb-4 border-b border-border",children:o.jsxs("div",{className:"flex items-center text-xs overflow-x-auto",children:[k.map((x,_)=>o.jsxs("span",{className:"flex items-center shrink-0",children:[o.jsx("span",{className:"text-text-muted",children:"/"}),o.jsx("button",{onClick:()=>S(x.path),className:`px-1 ${_===k.length-1?"text-accent-primary font-medium":"text-text-secondary hover:text-accent-primary"}`,children:x.name})]},x.path)),k.length===0&&o.jsx("button",{onClick:()=>S("/"),className:"text-text-muted hover:text-accent-primary",children:"/"})]})}),o.jsx("div",{className:"px-4 mb-3",children:o.jsxs("div",{className:"relative",children:[o.jsx("span",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-text-muted pointer-events-none flex items-center justify-center",children:o.jsx(Hh,{})}),o.jsx(dc,{autoFocus:!0,ref:m,value:l,onChange:x=>d(x.target.value),onKeyDown:b,placeholder:"Filter directories...",className:"w-full pl-9"})]})}),o.jsx("div",{className:"flex-1 overflow-y-auto -mx-4",children:u?o.jsx("div",{className:"p-8 text-center",children:o.jsx(vo,{size:"sm"})}):y.length===0?o.jsx("div",{className:"p-8 text-center text-text-muted text-sm",children:l?"No matching directories":"No subdirectories"}):o.jsx("div",{className:"divide-y divide-border",children:y.map((x,_)=>o.jsxs("button",{ref:j=>{v.current[_]=j},onClick:()=>S(x.path),onDoubleClick:()=>e(x.path),className:`w-full p-3 flex items-center gap-3 text-left transition-colors ${_===f?"bg-accent-primary/20 text-accent-primary":"hover:bg-bg-tertiary/50"}`,children:[x.type==="parent"?o.jsx(hw,{className:"w-5 h-5 text-text-muted"}):o.jsx(zh,{className:"w-5 h-5"}),o.jsx("span",{className:"flex-1",children:x.name}),_===f&&o.jsx("span",{className:"text-xs text-text-muted",children:"⏎ navigate · dbl-click select"})]},x.path))})}),o.jsxs("div",{className:"flex flex-col gap-2 pt-4 border-t border-border mt-4 -mx-4 -mb-4 p-4",children:[(i==null?void 0:i.current)&&o.jsx("button",{onClick:()=>e(i.current),className:"w-full px-4 py-2 bg-accent-primary text-text-primary rounded-lg font-medium hover:bg-accent-primary/90 transition-colors",children:"Select this folder"}),o.jsx("button",{onClick:r,className:"w-full text-center text-text-muted hover:text-text-secondary text-sm",children:"Cancel"})]})]})}function SC({isOpen:e,onClose:r}){const[,s]=lr(),[i,c]=P.useState(!1),[u,h]=P.useState(null),[l,d]=P.useState(!1),f=Ft(N=>N.projects),g=Ft(N=>N.createProject),m=Ft(N=>N.listProjects),v=Ft(N=>N.deleteProject),[S,k]=P.useState(null),[C,y]=P.useState(null),b=(N,D=32)=>{if(N.length<=D)return N;const T=N.split("/").filter(Boolean);if(T.length<=2)return N;const z=T[0],O=T[T.length-1],q=T.slice(1,-1).join("/"),V=D-z.length-O.length-3;if(V<0)return N;const W=q.slice(0,Math.floor(V/2)),I=q.slice(-Math.ceil(V/2));return`/${z}/${W}...${I}/${O}`};P.useEffect(()=>{ke("/api/config").then(N=>N.json()).then(N=>{N.workdir&&h(N.workdir)})},[]),P.useEffect(()=>{e&&m()},[e,m]);const x=N=>{s(`/p/${N}`),r()},_=(N,D)=>{D.stopPropagation(),k(N)},j=()=>{S&&(v(S.id),k(null))},A=N=>{const D=N.split("/").filter(Boolean).pop()??"";g(D,N),m(),y(N)};return P.useEffect(()=>{if(C){const N=f.find(D=>D.workdir===C);N&&(s(`/p/${N.id}`),r(),y(null))}},[f,C,s,r]),e?o.jsxs(At,{isOpen:e,onClose:r,title:"Open Project",size:"xl",footer:o.jsx("div",{className:"flex justify-end gap-2",children:o.jsx(nt,{variant:"secondary",onClick:r,children:"Close"})}),children:[o.jsxs("div",{className:"flex flex-col sm:flex-row flex-1 -m-4",children:[o.jsxs("div",{className:"w-full sm:w-1/2 border-b sm:border-b-0 sm:border-r border-border flex flex-col max-h-[40vh] sm:max-h-[50vh]",children:[o.jsx("div",{className:"p-3 border-b border-border bg-bg-tertiary/30 shrink-0",children:o.jsx("h3",{className:"font-medium text-sm text-text-secondary",children:"Recent Projects"})}),o.jsx("div",{className:"flex-1 overflow-y-auto",children:f.length===0?o.jsxs("div",{className:"p-6 text-center text-text-muted text-sm",children:[o.jsx("p",{className:"mb-2",children:"No recent projects"}),o.jsx("p",{className:"text-xs",children:'Click "Create new project" to add one'})]}):o.jsx("div",{className:"divide-y divide-border",children:f.map(N=>o.jsxs("div",{className:"group flex items-center gap-3 p-3 hover:bg-bg-tertiary/50 transition-colors",children:[o.jsxs("button",{onClick:()=>x(N.id),className:"flex-1 flex items-center gap-3 text-left",children:[o.jsx(zh,{className:"w-5 h-5 text-accent-primary"}),o.jsxs("div",{className:"flex-1 min-w-0",children:[o.jsx("div",{className:"font-medium truncate",children:N.name}),o.jsx("div",{className:"text-xs text-text-muted truncate",children:b(N.workdir)})]})]}),o.jsx("button",{onClick:D=>_(N,D),className:"text-accent-error/70 hover:text-accent-error p-1",title:"Delete project",children:o.jsx(Ph,{className:"w-4 h-4"})})]},N.id))})})]}),o.jsx("div",{className:"w-full sm:w-1/2 flex flex-col items-center justify-center p-6 sm:p-8 text-center",children:o.jsxs("div",{className:"flex flex-col gap-3 w-full max-w-sm",children:[o.jsx(nt,{variant:"primary",onClick:()=>d(!0),children:"Select existing project"}),o.jsx(nt,{variant:"secondary",onClick:()=>c(!0),"data-testid":"open-project-create-button",children:"Create new project"})]})})]}),i&&o.jsx(vC,{isOpen:i,onClose:()=>c(!1)}),S&&o.jsx(xC,{isOpen:!0,onClose:()=>k(null),projectName:S.name,onConfirm:j}),l&&o.jsx(oy,{initialPath:u??void 0,onSelect:N=>{A(N),d(!1)},onClose:()=>d(!1)})]}):null}function wC(){const[e,r]=P.useState(!1),s=Ce(m=>m.sessions),i=Ft(m=>m.projects),c=Ft(m=>m.loading),u=Ft(m=>m.listProjects),h=Ce(m=>m.listSessions),l=Ce(m=>m.connectionStatus);P.useEffect(()=>{l==="connected"&&(u(),h())},[l,u,h]);const d=[...i].sort((m,v)=>{const S=s.filter(b=>b.workdir.startsWith(m.workdir)),k=s.filter(b=>b.workdir.startsWith(v.workdir)),C=S.length>0?new Date(S.reduce((b,x)=>new Date(x.updatedAt)>new Date(b.updatedAt)?x:b).updatedAt).getTime():new Date(m.updatedAt).getTime();return(k.length>0?new Date(k.reduce((b,x)=>new Date(x.updatedAt)>new Date(b.updatedAt)?x:b).updatedAt).getTime():new Date(v.updatedAt).getTime())-C}),f=m=>{const v=i.find(S=>S.id===m);return v?s.filter(S=>S.workdir.startsWith(v.workdir)).sort((S,k)=>new Date(k.updatedAt).getTime()-new Date(S.updatedAt).getTime()).slice(0,5):[]},g=()=>{r(!0)};return o.jsxs("div",{className:"flex-1 flex flex-col overflow-y-auto bg-primary",children:[o.jsxs("div",{className:"max-w-5xl mx-auto w-full p-4 md:p-8",children:[o.jsxs("div",{className:"mb-6 md:mb-8 flex items-center justify-between",children:[o.jsxs("div",{children:[o.jsx("h1",{className:"text-3xl font-bold text-accent-primary",children:"OpenFox"}),o.jsx("p",{className:"text-text-secondary",children:"Local LLM-powered coding assistant with contract-driven execution"})]}),o.jsx(nt,{variant:"primary",onClick:g,children:"Open Project"})]}),d.map(m=>{const v=f(m.id);return o.jsx("div",{className:"mb-6 md:mb-8",children:o.jsxs("div",{className:"bg-bg-secondary border border-border rounded-lg overflow-hidden",children:[o.jsxs("div",{className:"p-3 md:p-4 border-b border-border flex items-center justify-between gap-2",children:[o.jsxs(Fn,{href:`/p/${m.id}`,className:"flex items-center gap-2 cursor-pointer hover:opacity-80 transition-opacity flex-1",children:[o.jsx(zh,{className:"w-5 h-5 text-accent-primary flex-shrink-0"}),o.jsx("span",{className:"text-text-primary font-semibold",children:m.name})]}),o.jsx(Fn,{href:`/p/${m.id}/new`,className:"rounded font-medium transition-colors bg-accent-primary/25 text-text-primary hover:bg-accent-primary/40 px-1.5 py-1 text-xs",children:"+ New Session"})]}),o.jsx("div",{className:"divide-y divide-border",children:v.length>0?v.map(S=>{const k=i.find(y=>S.workdir.startsWith(y.workdir)),C=k?`/p/${k.id}/s/${S.id}`:"#";return o.jsx(Fn,{href:C,className:"block p-3 md:p-4 hover:bg-bg-tertiary/50 cursor-pointer transition-colors",children:o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[o.jsx("div",{className:"flex items-center gap-3 flex-1 min-w-0",children:o.jsx("div",{className:"flex-1 min-w-0",children:o.jsx("div",{className:"text-sm text-text-muted truncate",children:S.title??S.id.slice(0,8)})})}),o.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[o.jsx("span",{className:"text-text-muted text-xs",children:sC(S.updatedAt)}),o.jsxs("span",{className:"text-text-muted text-xs",children:[S.messageCount," msgs"]})]})]})},S.id)}):o.jsx("div",{className:"p-3 md:p-4 text-text-muted text-sm",children:"No sessions yet"})})]})},m.id)}),d.length===0&&!c&&o.jsx("div",{className:"text-center py-12 text-text-muted",children:"No projects yet. Open a project to get started."}),c&&o.jsx("div",{className:"flex justify-center py-12",children:o.jsx(vo,{})})]}),e&&o.jsx(SC,{isOpen:e,onClose:()=>r(!1)})]})}function CC(){const[,e]=Mh("/p/:projectId/new"),[,r]=lr(),s=e==null?void 0:e.projectId,i=Ce(h=>h.createSession),c=Ce(h=>h.resetPendingSessionCreate),u=P.useCallback(async()=>{if(!s)return;const h=await i(s);h?(r(`/p/${s}/s/${h.id}`),c()):(r(`/p/${s}`),c())},[s,i,r,c]);return P.useEffect(()=>{u()},[u]),o.jsx("div",{className:"flex-1 flex items-center justify-center",children:o.jsx(vo,{})})}function kC(){const e=Ft(r=>r.currentProject);return o.jsx("div",{className:"h-full flex flex-col items-center justify-center p-8 text-center",children:o.jsxs("div",{className:"max-w-md",children:[o.jsx("h2",{className:"text-xl font-semibold text-text-primary mb-2",children:(e==null?void 0:e.name)??"Project"}),o.jsx("p",{className:"text-text-secondary mb-6",children:"No session selected"}),o.jsxs("div",{className:"flex flex-col gap-3",children:[e&&o.jsx(Fn,{href:`/p/${e.id}/new`,"data-testid":"create-new-session-button",className:"block w-full rounded font-medium transition-colors bg-accent-primary/25 text-text-primary hover:bg-accent-primary/40 px-3 py-2 text-center",children:"Create New Session"}),o.jsx("p",{className:"text-sm text-text-muted",children:"Or select an existing session from the sidebar"})]})]})})}const Ga=e=>Math.round(e*10)/10;function mh(e){return{providerId:e.providerId,providerName:e.providerName,backend:e.backend,model:e.model}}function EC(e){return`${e.providerId}::${e.model}`}function jC(e){return`${e.providerName} > ${e.model}`}function ob(e){let r=0,s=0,i=0,c=0,u=0,h=0;const l=[],d=[];let f=0;for(const[v,S]of e.entries()){const k=S.stats,C=mh(k);r+=k.totalTime,s+=k.toolTime,i+=k.prefillTokens,c+=k.generationTokens;const y=k.prefillSpeed>0?k.prefillTokens/k.prefillSpeed:0,b=k.generationSpeed>0?k.generationTokens/k.generationSpeed:0;u+=y,h+=b,l.push({messageId:S.id,timestamp:S.timestamp,...C,mode:k.mode,responseIndex:v+1,prefillTokens:k.prefillTokens,generationTokens:k.generationTokens,prefillSpeed:k.prefillSpeed,generationSpeed:k.generationSpeed,totalTime:k.totalTime,aiTime:k.totalTime-k.toolTime,toolTime:k.toolTime});const x=k.llmCalls??[];for(const _ of x)f+=1,d.push({messageId:S.id,timestamp:_.timestamp??S.timestamp,providerId:_.providerId,providerName:_.providerName,backend:_.backend,model:_.model,mode:k.mode,responseIndex:v+1,sessionCallIndex:f,callIndex:_.callIndex,promptTokens:_.promptTokens,completionTokens:_.completionTokens,ttft:_.ttft,completionTime:_.completionTime,prefillSpeed:_.prefillSpeed,generationSpeed:_.generationSpeed,totalTime:_.totalTime,..._.temperature!==void 0&&{temperature:_.temperature},..._.topP!==void 0&&{topP:_.topP},..._.topK!==void 0&&{topK:_.topK},..._.maxTokens!==void 0&&{maxTokens:_.maxTokens}})}const g=u>0?Ga(i/u):0,m=h>0?Ga(c/h):0;return{totalTime:Ga(r),aiTime:Ga(r-s),toolTime:Ga(s),prefillTokens:i,generationTokens:c,avgPrefillSpeed:g,avgGenerationSpeed:m,responseCount:e.length,llmCallCount:d.length,dataPoints:l,callDataPoints:d}}function NC(e){const r=e.filter(c=>c.stats!==void 0&&c.stats!==null).sort((c,u)=>new Date(c.timestamp).getTime()-new Date(u.timestamp).getTime());if(r.length===0)return null;const s=new Map;for(const c of r){const u=EC(mh(c.stats)),h=s.get(u)??[];s.set(u,[...h,c])}const i=Array.from(s.entries()).map(([c,u])=>{const h=mh(u[0].stats),l=ob(u);return{...h,key:c,label:jC(h),...l}});return{...ob(r),modelGroups:i}}function TC(e){return P.useMemo(()=>NC(e),[e])}function AC(e){const[r,s]=P.useState(null),[i,c]=P.useState(!0),[u,h]=P.useState(null),l=e||"";return P.useEffect(()=>{if(!l){c(!1);return}let d=!0,f=null;const g=async()=>{try{const v=await(await ke(`/api/branch?workdir=${encodeURIComponent(l)}`)).json();d&&(s(v.branch),h(v.error||null),c(!1))}catch(m){d&&(h(m instanceof Error?m.message:"Failed to fetch branch"),c(!1))}};return g(),f=setInterval(g,3e3),()=>{d=!1,f&&clearInterval(f)}},[l]),{branch:r,loading:i,error:u}}function Zl(e){return e.toLocaleString("en-US").replace(/,/g," ")}function lb(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function DC(e){if(e<60)return`${e.toFixed(1)}s`;const r=Math.floor(e/60),s=Math.round(e%60);return`${r}m${s}s`}const cb=["▁","▂","▃","▄","▅","▆","▇","█"];function RC(e,r,s){if(s===r)return 4;const i=(e-r)/(s-r);return Math.min(7,Math.max(0,Math.round(i*7)))}function LC(e,r){if(e===r){const c=Math.max(Math.abs(e)*.05,1);return{minY:e-c,maxY:r+c}}const s=r-e,i=Math.max(s*.1,.1);return{minY:e-i,maxY:r+i}}function OC(e,r){if(e.length===0||r<=0)return{blocks:"",minX:0,maxX:0,minY:0,maxY:0};const s=[...e].sort((m,v)=>m.x-v.x),i=s[0].x,c=s[s.length-1].x,u=Math.min(...s.map(m=>m.y)),h=Math.max(...s.map(m=>m.y)),{minY:l,maxY:d}=LC(u,h),f=Array.from({length:r},()=>" "),g=new Map;for(const m of s){const v=c===i?0:Math.round((m.x-i)/(c-i)*(r-1)),S=g.get(v)??[];g.set(v,[...S,m.y])}for(const[m,v]of g){const S=Math.max(...v);f[m]=cb[RC(S,l,d)]??cb[0]}return{blocks:f.join(""),minX:i,maxX:c,minY:l,maxY:d}}function ub(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function db({data:e,width:r=60,height:s=78,label:i,xLabel:c,yLabel:u,showAxes:h=!0,formatY:l=ub,formatX:d=ub}){const f=P.useMemo(()=>{const g=OC(e,r),m=Math.max(r*6,240),v=10,S=8,C=[...e].sort((_,j)=>_.x-j.x).map(_=>{const j=g.maxX===g.minX?m/2:v+(_.x-g.minX)/(g.maxX-g.minX)*(m-v*2),A=g.maxY===g.minY?s/2:S+(g.maxY-_.y)/(g.maxY-g.minY)*(s-S*2);return{..._,cx:j,cy:A,leftPercent:j/m*100,topPercent:A/s*100}}),y=C.map((_,j)=>`${j===0?"M":"L"} ${_.cx.toFixed(1)} ${_.cy.toFixed(1)}`).join(" "),x=[g.maxY,(g.maxY+g.minY)/2,g.minY].map(_=>({value:_,y:g.maxY===g.minY?s/2:S+(g.maxY-_)/(g.maxY-g.minY)*(s-S*2)}));return{...g,chartWidth:m,points:C,path:y,gridLines:x}},[e,s,r]);return e.length===0?o.jsxs("div",{className:"font-mono text-text-muted text-xs",children:[i&&o.jsx("div",{className:"mb-1",children:i}),o.jsx("div",{children:"No data"})]}):o.jsxs("div",{className:"font-mono text-xs",children:[i&&o.jsx("div",{className:"text-text-secondary mb-2",children:i}),o.jsxs("div",{className:"flex gap-3",children:[h&&o.jsx("div",{className:"w-12 h-[78px] flex flex-col justify-between text-right text-text-muted",children:f.gridLines.map(g=>o.jsx("span",{children:l(g.value)},`${g.value}-${g.y}`))}),o.jsx("div",{className:"flex-1 min-w-0",children:o.jsxs("div",{className:"relative h-[78px]",children:[o.jsxs("svg",{viewBox:`0 0 ${f.chartWidth} ${s}`,className:"w-full h-[78px] overflow-visible",preserveAspectRatio:"none","aria-hidden":"true",children:[f.gridLines.map(g=>o.jsx("line",{x1:"0",x2:f.chartWidth,y1:g.y,y2:g.y,stroke:"currentColor",strokeDasharray:"3 4",className:"text-border/60"},`grid-${g.y}`)),f.points.map(g=>o.jsx("line",{x1:g.cx,x2:g.cx,y1:s-4,y2:g.cy,stroke:"currentColor",className:"text-border/40"},`guide-${g.cx}-${g.cy}`)),f.points.length>1&&o.jsx("path",{d:f.path,fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-accent-primary/45"})]}),f.points.map(g=>o.jsx("div",{className:"absolute -translate-x-1/2 -translate-y-1/2",style:{left:`${g.leftPercent}%`,top:`${g.topPercent}%`},title:`${d(g.x)} -> ${l(g.y)}`,children:o.jsx("div",{className:"w-2.5 h-2.5 rounded-full bg-accent-primary/20 flex items-center justify-center",children:o.jsx("div",{className:"w-1.5 h-1.5 rounded-full bg-accent-primary"})})},`point-${g.x}-${g.y}`))]})})]}),h&&o.jsxs("div",{className:"flex items-start gap-3 text-text-muted mt-1",children:[o.jsx("span",{className:"w-12"}),o.jsxs("span",{className:"flex-1 flex justify-between",children:[o.jsx("span",{children:d(f.minX)}),o.jsx("span",{children:c}),o.jsx("span",{children:d(f.maxX)})]})]}),u&&h&&o.jsx("div",{className:"text-text-muted mt-1 text-center",children:u})]})}function MC({data:e,prefillLabel:r="Prefill Speed (tok/s) by Response",generationLabel:s="Generation Speed (tok/s) by Response",xLabel:i="response",width:c=60}){const u=e.map(l=>({x:l.x,y:l.ppSpeed})),h=e.map(l=>({x:l.x,y:l.tgSpeed}));return o.jsxs("div",{className:"space-y-5",children:[o.jsx(db,{data:u,width:c,label:r,xLabel:i}),o.jsx(db,{data:h,width:c,label:s,xLabel:i})]})}function IC(e){const r=new Map;for(const s of e.callDataPoints){const i=r.get(s.messageId)??[];r.set(s.messageId,[...i,s])}return e.dataPoints.map(s=>{const i=[...r.get(s.messageId)??[]].sort((c,u)=>c.callIndex-u.callIndex);return{...s,callCount:i.length,calls:i,isExpandable:i.length>1}})}function BC(e){return{mode:"responses",xLabel:"response",prefillLabel:"Prefill Speed (tok/s) by Response",generationLabel:"Generation Speed (tok/s) by Response",points:e.dataPoints.map(r=>({x:r.responseIndex,ppSpeed:r.prefillSpeed,tgSpeed:r.generationSpeed}))}}function zC(e){return{mode:"calls",xLabel:"context",prefillLabel:"Prefill Speed (tok/s) vs Context",generationLabel:"Generation Speed (tok/s) vs Context",points:e.callDataPoints.map(r=>({x:r.promptTokens,ppSpeed:r.prefillSpeed,tgSpeed:r.generationSpeed}))}}function PC(e){return e.callDataPoints.length>0?zC(e):BC(e)}function qd(e){if(e<60)return`${e.toFixed(1)}s`;const r=Math.floor(e/60),s=e%60;return`${r}m ${s.toFixed(0)}s`}function $s(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toString()}function to(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function HC(e){if(e.length===0)return"0 ctx";const r=Math.min(...e),s=Math.max(...e);return r===s?`${$s(r)} ctx`:`${$s(r)}-${$s(s)} ctx`}function Ql(e){return`${to(e)} t/s`}function ly(e){try{return new Date(e).toLocaleTimeString("en-US",{hour12:!1})}catch{return e}}function FC(e){return{exportedAt:new Date().toISOString(),providerId:e.providerId,providerName:e.providerName,backend:e.backend,model:e.model,label:e.label,summary:{totalTime:e.totalTime,aiTime:e.aiTime,toolTime:e.toolTime,prefillTokens:e.prefillTokens,generationTokens:e.generationTokens,avgPrefillSpeed:e.avgPrefillSpeed,avgGenerationSpeed:e.avgGenerationSpeed,responseCount:e.responseCount,llmCallCount:e.llmCallCount},responses:e.dataPoints.map(r=>({responseIndex:r.responseIndex,timestamp:r.timestamp,mode:r.mode,prefillTokens:r.prefillTokens,generationTokens:r.generationTokens,prefillSpeed:r.prefillSpeed,generationSpeed:r.generationSpeed,totalTime:r.totalTime,aiTime:r.aiTime,toolTime:r.toolTime})),llmCalls:e.callDataPoints.map(r=>({sessionCallIndex:r.sessionCallIndex,responseIndex:r.responseIndex,callIndex:r.callIndex,timestamp:r.timestamp,mode:r.mode,promptTokens:r.promptTokens,completionTokens:r.completionTokens,ttft:r.ttft,completionTime:r.completionTime,prefillSpeed:r.prefillSpeed,generationSpeed:r.generationSpeed,totalTime:r.totalTime}))}}function UC({isOpen:e,onClose:r,stats:s}){const i=P.useRef(null),[c,u]=P.useState({}),[h,l]=P.useState(()=>{var k;return((k=s.modelGroups[0])==null?void 0:k.key)??""});P.useEffect(()=>{var k;s.modelGroups.some(C=>C.key===h)||l(((k=s.modelGroups[0])==null?void 0:k.key)??"")},[h,s.modelGroups]);const d=P.useMemo(()=>s.modelGroups.find(k=>k.key===h)??s.modelGroups[0],[h,s.modelGroups]),f=P.useMemo(()=>d?IC(d):[],[d]),g=P.useMemo(()=>d?PC(d):{mode:"responses",xLabel:"response",prefillLabel:"",generationLabel:"",points:[]},[d]),m=P.useCallback(k=>{u(C=>({...C,[k]:!C[k]}))},[]),v=P.useCallback(()=>{if(!d)return;const k=FC(d);navigator.clipboard.writeText(JSON.stringify(k,null,2)).catch(C=>console.error("Failed to copy:",C))},[d]),S=P.useCallback(async()=>{if(i.current)try{const k=(await fh(async()=>{const{default:b}=await import("./html2canvas.esm-QH1iLAAe.js");return{default:b}},[])).default,C=await k(i.current,{backgroundColor:"#1a1a1a",scale:2}),y=document.createElement("a");y.download=`openfox-stats-${new Date().toISOString().slice(0,10)}.png`,y.href=C.toDataURL("image/png"),y.click()}catch(k){console.error("Failed to export PNG:",k),v()}},[v]);return o.jsx(At,{isOpen:e,onClose:r,title:"Session Stats",size:"lg",children:o.jsxs("div",{ref:i,className:"space-y-6",children:[o.jsx("section",{children:o.jsx("div",{className:"flex flex-wrap gap-2",children:s.modelGroups.map(k=>o.jsx("button",{onClick:()=>l(k.key),className:`px-3 py-1.5 rounded border text-xs transition-colors ${k.key===(d==null?void 0:d.key)?"border-accent-primary bg-accent-primary/10 text-accent-primary":"border-border text-text-muted hover:text-text-primary hover:bg-bg-tertiary/40"}`,title:k.label,children:k.label},k.key))})}),d&&o.jsxs("section",{children:[o.jsx("h3",{className:"text-sm font-semibold text-text-secondary mb-3 uppercase tracking-wide",children:"Summary"}),o.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-4",children:[o.jsx(Hr,{label:"AI Time",value:qd(d.aiTime)}),o.jsx(Hr,{label:"Total Time",value:qd(d.totalTime)}),o.jsx(Hr,{label:"Tool Time",value:qd(d.toolTime)}),o.jsx(Hr,{label:"Responses",value:d.responseCount.toString()}),o.jsx(Hr,{label:"LLM Calls",value:d.llmCallCount.toString()})]}),o.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 mt-3",children:[o.jsx(Hr,{label:"Prefill Tokens",value:$s(d.prefillTokens),subValue:`@ ${to(d.avgPrefillSpeed)} tok/s`}),o.jsx(Hr,{label:"Gen Tokens",value:$s(d.generationTokens),subValue:`@ ${to(d.avgGenerationSpeed)} tok/s`}),o.jsx(Hr,{label:"Avg PP Speed",value:`${to(d.avgPrefillSpeed)}`,subValue:"tok/s"}),o.jsx(Hr,{label:"Avg TG Speed",value:`${to(d.avgGenerationSpeed)}`,subValue:"tok/s"})]})]}),d&&g.points.length>1&&o.jsxs("section",{children:[o.jsxs("div",{className:"flex items-center justify-between mb-3",children:[o.jsx("h3",{className:"text-sm font-semibold text-text-secondary uppercase tracking-wide",children:"Performance Progression"}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("button",{onClick:v,className:"px-2 py-1 text-xs text-text-muted hover:text-text-primary hover:bg-bg-tertiary rounded transition-colors",children:"Copy JSON"}),o.jsx("button",{onClick:S,className:"px-2 py-1 text-xs text-text-muted hover:text-text-primary hover:bg-bg-tertiary rounded transition-colors",children:"Save PNG"})]})]}),o.jsx("div",{className:"bg-bg-tertiary/50 rounded p-4",children:o.jsx(MC,{data:g.points,width:50,prefillLabel:g.prefillLabel,generationLabel:g.generationLabel,xLabel:g.xLabel})})]}),d&&o.jsxs("section",{children:[o.jsxs("h3",{className:"text-sm font-semibold text-text-secondary mb-3 uppercase tracking-wide",children:["Response Log (",d.responseCount," responses)"]}),o.jsx("div",{className:"overflow-y-auto bg-bg-tertiary/30 rounded",children:o.jsxs("table",{className:"w-full table-fixed border-separate border-spacing-0 text-xs",children:[o.jsxs("colgroup",{children:[o.jsx("col",{className:"w-[7%]"}),o.jsx("col",{className:"w-[14%]"}),o.jsx("col",{className:"w-[10%]"}),o.jsx("col",{className:"w-[14%]"}),o.jsx("col",{className:"w-[14%]"}),o.jsx("col",{className:"w-[14%]"}),o.jsx("col",{className:"w-[11%]"}),o.jsx("col",{className:"w-[2%]"})]}),o.jsx("thead",{children:o.jsxs("tr",{className:"text-[10px] uppercase tracking-wide text-text-muted/80",children:[o.jsx("th",{className:"px-3 py-2 text-center font-medium",children:"#"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"At"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"Time"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"Context"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"PP t/s"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"TG t/s"}),o.jsx("th",{className:"px-2 py-2 text-center font-medium",children:"Calls"}),o.jsx("th",{className:"px-2 py-2"})]})}),o.jsx("tbody",{children:f.map((k,C)=>o.jsxs(P.Fragment,{children:[o.jsx($C,{row:k,index:C,isExpanded:c[k.messageId]??!1,onToggle:k.isExpandable?()=>m(k.messageId):void 0}),(c[k.messageId]??!1)&&k.calls.map((y,b)=>o.jsx(qC,{dataPoint:y,index:b},`${y.messageId}-${y.callIndex}`))]},k.messageId))})]})})]})]})})}function Hr({label:e,value:r,subValue:s}){return o.jsxs("div",{className:"bg-bg-tertiary/50 rounded p-3",children:[o.jsx("div",{className:"text-text-muted text-xs mb-1",children:e}),o.jsx("div",{className:"text-text-primary text-lg font-semibold",children:r}),s&&o.jsx("div",{className:"text-text-muted text-xs",children:s})]})}function $C({row:e,index:r,isExpanded:s,onToggle:i}){const c=e.calls.length>0?HC(e.calls.map(u=>u.promptTokens)):`${$s(e.prefillTokens)} ctx`;return o.jsxs("tr",{onClick:i,className:`${r%2===0?"bg-bg-tertiary/20":""} ${i?"cursor-pointer hover:bg-bg-tertiary/35 transition-colors":""}`,children:[o.jsx("td",{className:"px-3 py-2 text-center text-text-muted align-middle",children:e.responseIndex}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted font-mono align-middle whitespace-nowrap",children:ly(e.timestamp)}),o.jsxs("td",{className:"px-2 py-2 text-center text-text-muted align-middle whitespace-nowrap",children:[e.totalTime.toFixed(1),"s"]}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:c.replace(/ ctx$/,"")}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:Ql(e.prefillSpeed)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:Ql(e.generationSpeed)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted font-mono align-middle whitespace-nowrap",children:e.callCount}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted align-middle whitespace-nowrap",children:e.isExpandable?s?"v":">":""})]})}function qC({dataPoint:e,index:r}){const s=e.temperature!==void 0||e.topP!==void 0||e.topK!==void 0||e.maxTokens!==void 0;return o.jsxs(o.Fragment,{children:[o.jsxs("tr",{className:`${r%2===0?"bg-bg-tertiary/10":"bg-bg-tertiary/5"}`,children:[o.jsxs("td",{className:"px-3 py-2 pl-6 text-center text-text-muted align-middle border-l border-border/60",children:["c",e.callIndex]}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted font-mono align-middle whitespace-nowrap",children:ly(e.timestamp)}),o.jsxs("td",{className:"px-2 py-2 text-center text-text-muted align-middle whitespace-nowrap",children:[e.totalTime.toFixed(1),"s"]}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:$s(e.promptTokens)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:Ql(e.prefillSpeed)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-primary font-mono align-middle whitespace-nowrap",children:Ql(e.generationSpeed)}),o.jsx("td",{className:"px-2 py-2 text-center text-text-muted font-mono align-middle whitespace-nowrap",children:e.callIndex}),o.jsx("td",{className:"px-2 py-2"})]}),s&&o.jsx("tr",{className:`${r%2===0?"bg-bg-tertiary/5":"bg-bg-tertiary/[2.5%]"}`,children:o.jsx("td",{colSpan:8,className:"px-6 py-1.5 border-l border-border/60",children:o.jsxs("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-[10px] text-text-muted",children:[e.temperature!==void 0&&o.jsxs("span",{children:["temp: ",e.temperature.toFixed(2)]}),e.topP!==void 0&&o.jsxs("span",{children:["topP: ",e.topP.toFixed(2)]}),e.topK!==void 0&&o.jsxs("span",{children:["topK: ",e.topK]}),e.maxTokens!==void 0&&o.jsxs("span",{children:["maxTok: ",e.maxTokens]})]})})})]})}const WC={pending:{icon:"○",color:"text-text-muted",label:"Pending"},in_progress:{icon:"●",color:"text-accent-warning",label:"In Progress",animate:!0},completed:{icon:"◉",color:"text-purple-400",label:"Completed"},passed:{icon:"✓",color:"text-accent-success",label:"Passed"},failed:{icon:"✗",color:"text-accent-error",label:"Failed"}},VC=P.memo(function({criteria:r}){if(r.length===0)return o.jsx("div",{className:"text-text-muted text-sm text-center py-2",children:"No criteria yet"});const s={pending:0,in_progress:0,completed:0,passed:0,failed:0};for(const c of r){const u=c.status.type;u in s&&s[u]++}const i=Object.keys(s).filter(c=>s[c]>0);return o.jsxs("div",{className:"space-y-1",children:[o.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[o.jsx("span",{className:"font-semibold text-text-primary",children:"Total:"}),o.jsx("span",{className:"text-text-secondary",children:r.length})]}),o.jsx("div",{className:"space-y-1",children:i.map(c=>{const u=WC[c];return o.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[o.jsx("span",{className:`${u.color} ${u.animate?"animate-pulse":""} text-sm leading-tight`,children:u.icon}),o.jsxs("span",{className:"text-text-muted",children:[u.label,":"]}),o.jsx("span",{className:"text-text-primary font-medium",children:s[c]})]},c)})})]})});function GC({isOpen:e,onClose:r}){const s=gr(C=>C.config),i=gr(C=>C.saveConfig),[c,u]=P.useState(""),[h,l]=P.useState(""),[d,f]=P.useState(!1),[g,m]=P.useState(!1),[v,S]=P.useState(!1);P.useEffect(()=>{e&&(u((s==null?void 0:s.command)??""),l((s==null?void 0:s.url)??""),f((s==null?void 0:s.hotReload)??!1),m((s==null?void 0:s.disableInspect)??!1))},[e,s]);const k=async()=>{!c.trim()||!h.trim()||(S(!0),await i({command:c.trim(),url:h.trim(),hotReload:d,disableInspect:g}),S(!1),r())};return o.jsx(At,{isOpen:e,onClose:r,title:"Dev Server Config",size:"sm",children:o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{children:[o.jsx("label",{className:"block text-xs text-text-secondary mb-1",children:"Command"}),o.jsx("input",{className:"input w-full",type:"text",value:c,onChange:C=>u(C.target.value),placeholder:"npm run dev"})]}),o.jsxs("div",{children:[o.jsx("label",{className:"block text-xs text-text-secondary mb-1",children:"Dev URL"}),o.jsx("input",{className:"input w-full",type:"text",value:h,onChange:C=>l(C.target.value),placeholder:"http://localhost:3000"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("input",{type:"checkbox",id:"hotReload",checked:d,onChange:C=>f(C.target.checked),className:"rounded border-border bg-bg-tertiary"}),o.jsx("label",{htmlFor:"hotReload",className:"text-xs text-text-secondary",children:"Hot Reload"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("input",{type:"checkbox",id:"disableInspect",checked:g,onChange:C=>m(C.target.checked),className:"rounded border-border bg-bg-tertiary"}),o.jsx("label",{htmlFor:"disableInspect",className:"text-xs text-text-secondary",children:"Disable inspect feedback"})]}),o.jsxs("div",{className:"flex justify-end gap-2 pt-2",children:[o.jsx("button",{className:"btn btn-secondary",onClick:r,children:"Cancel"}),o.jsx("button",{className:"btn btn-primary",onClick:k,disabled:v||!c.trim()||!h.trim(),children:v?"Saving...":"Save"})]})]})})}const hb={30:"text-black",31:"text-red-400",32:"text-accent-success",33:"text-accent-warning",34:"text-blue-400",35:"text-purple-400",36:"text-cyan-400",37:"text-gray-300",90:"text-gray-500",91:"text-red-500",92:"text-green-500",93:"text-yellow-400",94:"text-blue-500",95:"text-pink-400",96:"text-cyan-500",97:"text-white"},KC={40:"bg-black",41:"bg-red-900",42:"bg-green-900",43:"bg-yellow-900",44:"bg-blue-900",45:"bg-purple-900",46:"bg-cyan-900",47:"bg-gray-700"},fb={1:"font-bold",2:"opacity-75",4:"underline",7:"bg-bg-secondary"},YC="text-text-primary";function XC(e){const r=[],s=/\x1b\[([0-9;]+)m/g;let i=0,c="text-text-primary",u;try{for(;(u=s.exec(e))!==null;){if(u.index>i){const f=e.slice(i,u.index);f&&r.push({text:f,className:c})}const h=u[1];if(!h)continue;const l=h.split(";").map(Number);if(l.length===0||l[0]===0){c="text-text-primary";continue}const d=[];for(const f of l)if(f>=30&&f<=37){const g=hb[f];g&&d.push(g)}else if(f>=40&&f<=47){const g=KC[f];g&&d.push(g)}else if(f>=90&&f<=97){const g=hb[f];g&&d.push(g)}else if(f in fb){const g=fb[f];g&&d.push(g)}else f===39?d.push(YC):f===49&&(c=c.split(" ").filter(g=>!g.startsWith("bg-")).join(" "));d.length>0&&(c=d.join(" ")),i=s.lastIndex}if(i<e.length){const h=e.slice(i);h&&r.push({text:h,className:c})}return r}catch(h){return console.warn("ANSI parsing failed, stripping codes:",h),[{text:ZC(e),className:"text-text-primary"}]}}function ZC(e){return e.replace(/\x1b\[([0-9;]+)m/g,"")}function co(e){const r=XC(e),s=[];return r.forEach((i,c)=>{const u=i.text.split(`
|
|
85
85
|
`);u.forEach((h,l)=>{s.push(gn.createElement("span",{key:`${c}-${l}`,className:i.className,style:{display:"inline-block",whiteSpace:"pre-wrap"}},h)),l<u.length-1&&s.push(gn.createElement("br",{key:`${c}-${l}-br`}))})}),s.length===1?s[0]:s}const cy=P.memo(function({title:r,logs:s,onClose:i,preClassName:c}){const u=P.useRef(null);return P.useEffect(()=>{u.current&&(u.current.scrollTop=u.current.scrollHeight)},[s]),o.jsx(At,{isOpen:!0,onClose:i,title:r,size:"full",children:o.jsx("pre",{ref:u,className:c,children:s.length===0?o.jsx("span",{className:"text-text-muted",children:"No output yet"}):s.map((h,l)=>o.jsx("span",{className:h.stream==="stderr"?"text-accent-warning":"",children:co(h.content)},l))})})}),QC=P.memo(function({logs:r,anchorRef:s,isHiding:i,onExpand:c,onClose:u}){const[h,l]=P.useState(null),d=P.useRef(null);return P.useEffect(()=>{var g;const f=(g=s.current)==null?void 0:g.getBoundingClientRect();f&&l({bottom:window.innerHeight-f.bottom,right:window.innerWidth-f.right,width:f.width,height:f.height})},[s]),P.useEffect(()=>{d.current&&(d.current.scrollTop=d.current.scrollHeight)},[r]),h?o.jsxs("div",{className:"relative",children:[o.jsx("pre",{ref:d,className:"fixed z-50 text-sm font-mono text-text-primary bg-bg-primary p-2 rounded border border-border overflow-auto transition-all duration-150 ease-out select-text",style:{bottom:h.bottom,right:h.right,width:h.width*2,maxHeight:h.height*3,transformOrigin:"bottom right",transform:i?"scale(0.01)":"scale(1)",opacity:i?0:1},children:r.map((f,g)=>o.jsx("span",{className:f.stream==="stderr"?"text-accent-warning":"",children:co(f.content)},g))}),o.jsx("button",{onClick:()=>{u(),c()},className:"fixed z-50 px-2 py-1 rounded text-xs font-medium bg-accent-primary/30 text-text-primary hover:bg-accent-primary/50 transition-colors duration-150",style:{bottom:h.bottom+8,right:h.right+8},children:"Expand"})]}):null}),JC=P.memo(function({workdir:r}){const s=gr(V=>V.setWorkdir),i=gr(V=>V.status),c=gr(V=>V.config),u=gr(V=>V.logs),h=gr(V=>V.start),l=gr(V=>V.stop),d=gr(V=>V.fetchLogs),f=Ce(V=>V.currentSession),[g,m]=P.useState(!1),[v,S]=P.useState(!1),[k,C]=P.useState(!1),[y,b]=P.useState(!1),x=P.useRef(null),_=P.useRef(null),j=P.useRef(null),A=P.useRef(null),N=P.useRef(null),D=()=>{const V=i==null?void 0:i.inspectProxyPort;if(!V){i!=null&&i.url&&window.open(i.url,"_blank");return}const W=`${window.location.protocol}//${window.location.hostname}:${V}`,I=window.open(W,"_blank");if(I){N.current=I;const $=()=>{var X;!N.current||N.current.closed||(N.current.postMessage({type:"setFoxSessionId",sessionId:(f==null?void 0:f.id)??null},"*"),N.current.postMessage({type:"setFoxSessionTitle",sessionTitle:((X=f==null?void 0:f.metadata)==null?void 0:X.title)??null},"*"),N.current.postMessage({type:"setFoxInspectEnabled",enabled:!(c!=null&&c.disableInspect)},"*"))},B=setInterval(()=>{$(),(!N.current||N.current.closed)&&clearInterval(B)},500);setTimeout(()=>clearInterval(B),5e3)}},T=(i==null?void 0:i.state)??"off",z=c!==null,O=T==="running"||T==="warning";P.useEffect(()=>{s(r??null)},[r,s]),P.useEffect(()=>{O&&d()},[O,d]),P.useEffect(()=>{j.current&&O&&(j.current.scrollTop=j.current.scrollHeight)},[u,O]);const q=()=>{O?l():h()};return o.jsxs("div",{className:"mt-2 pt-3 border-t border-border space-y-3",children:[o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("span",{className:`inline-block w-2.5 h-2.5 rounded-full flex-shrink-0 ${T==="running"?"bg-accent-success":T==="warning"?"bg-accent-warning":T==="error"?"bg-accent-error":"bg-text-muted"}`}),o.jsx("h3",{className:"text-sm font-semibold text-text-primary",children:"Dev Server"})]}),o.jsx("button",{onClick:()=>m(!0),className:"p-1.5 rounded hover:bg-bg-tertiary transition-colors text-text-muted",title:"Configure dev server",children:o.jsx(yw,{})})]}),z?o.jsxs(o.Fragment,{children:[T==="running"||T==="warning"?o.jsxs("div",{className:"flex gap-2",children:[o.jsxs("button",{onClick:q,className:"flex-1 flex items-center justify-center gap-1.5 rounded font-medium text-sm px-3 py-1.5 bg-bg-tertiary text-text-primary hover:bg-border transition-colors",children:[o.jsx(Tw,{}),"Stop"]}),(i==null?void 0:i.url)&&o.jsxs("button",{onClick:()=>D(),className:"flex-1 flex items-center justify-center gap-1.5 rounded font-medium text-sm px-3 py-1.5 bg-accent-primary/25 text-text-primary hover:bg-accent-primary/40 transition-colors",title:i.url,children:[o.jsx(ww,{}),"Open"]})]}):o.jsx("button",{onClick:q,className:"w-full rounded font-medium text-sm px-3 py-1.5 bg-accent-primary/25 text-text-primary hover:bg-accent-primary/40 transition-colors",children:"Start"}),O&&o.jsxs("div",{ref:A,className:"relative",onMouseEnter:()=>{_.current&&clearTimeout(_.current),x.current=setTimeout(()=>{C(!0),b(!1)},500)},onMouseLeave:()=>{x.current&&clearTimeout(x.current),b(!0),_.current=setTimeout(()=>C(!1),150)},children:[o.jsx("pre",{ref:j,className:"text-sm bg-bg-primary p-2 rounded overflow-auto max-h-[200px] border border-border",children:u.length===0?o.jsx("span",{className:"text-text-muted",children:"No output yet"}):u.map((V,W)=>o.jsx("span",{className:V.stream==="stderr"?"text-accent-warning":"",children:co(V.content)},W))}),(k||y)&&A.current&&Ki.createPortal(o.jsx(QC,{logs:u,anchorRef:A,isHiding:y,onExpand:()=>S(!0),onClose:()=>C(!1)}),document.body)]})]}):o.jsx("button",{onClick:()=>m(!0),className:"w-full rounded font-medium text-sm px-3 py-1.5 bg-bg-tertiary text-text-muted hover:bg-border transition-colors",children:"Configure"}),o.jsx(GC,{isOpen:g,onClose:()=>m(!1)}),v&&o.jsx(cy,{title:"Dev Server Logs",logs:u,onClose:()=>S(!1)})]})}),e2=P.memo(function({sessionId:r}){var S;const s=no(k=>k.processes),i=no(k=>k.stopProcess),[c,u]=P.useState(null),[h,l]=P.useState([]),d=s.filter(k=>k.status!=="exited"),f=d.filter(k=>k.status==="running").length;if(s.length===0)return null;const g=k=>{switch(k){case"running":return"bg-accent-success";case"starting":return"bg-accent-warning";case"stopping":return"bg-accent-warning";case"exited":return"bg-text-muted";default:return"bg-text-muted"}},m=k=>{const C=no.getState().logs[k]??[];l(C.map(y=>({content:y.content,stream:y.stream}))),u(k)},v=k=>{r&&i(k,r)};return o.jsxs("div",{className:"mt-2 pt-3 border-t border-border space-y-3",children:[o.jsx("div",{className:"flex items-center justify-between",children:o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("span",{className:"inline-block w-2.5 h-2.5 rounded-full flex-shrink-0 bg-accent-primary"}),o.jsx("h3",{className:"text-sm font-semibold text-text-primary",children:"Background"}),o.jsxs("span",{className:"text-xs text-text-muted",children:["(",f," running)"]})]})}),o.jsx("div",{className:"space-y-2",children:d.map(k=>o.jsx("div",{className:"border border-border rounded p-2",children:o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsxs("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[o.jsx("span",{className:`inline-block w-2 h-2 rounded-full flex-shrink-0 ${g(k.status)}`}),o.jsx("span",{className:"text-sm text-text-primary truncate",title:k.name,children:k.name}),o.jsxs("span",{className:"text-xs text-text-muted",children:["[",k.status,"]"]})]}),o.jsxs("div",{className:"flex gap-1 ml-2",children:[o.jsx("button",{onClick:()=>m(k.id),className:"px-2 py-1 text-xs rounded bg-bg-tertiary hover:bg-border text-text-secondary transition-colors",title:"View logs",children:"Logs"}),o.jsx("button",{onClick:()=>v(k.id),className:"px-2 py-1 text-xs rounded bg-bg-tertiary hover:bg-accent-error/20 text-text-secondary hover:text-accent-error transition-colors",title:"Stop process",children:"Stop"})]})]})},k.id))}),c&&o.jsx(cy,{title:((S=d.find(k=>k.id===c))==null?void 0:S.name)??"",logs:h,onClose:()=>{u(null),l([])}})]})});function pb({summary:e,messages:r,workdir:s}){const[i,c]=P.useState(!1),u=TC(r),{branch:h}=AC(s),l=Rt(f=>f.version),d=Ce(f=>f.currentSession);return o.jsxs("div",{className:"flex flex-col h-full",children:[u&&o.jsxs("div",{className:"mb-4",children:[o.jsx("button",{onClick:()=>c(!0),className:"w-full flex items-center justify-center px-3 py-2 rounded bg-bg-tertiary hover:bg-bg-secondary transition-colors",title:"View detailed response and call-level stats",children:o.jsxs("div",{className:"flex items-center gap-2 text-sm text-text-muted",children:[o.jsx("span",{className:"text-text-secondary",children:DC(u.aiTime)}),o.jsx("span",{className:"w-px h-3 bg-border"}),o.jsx("span",{className:"text-text-secondary",children:lb(u.avgPrefillSpeed)}),o.jsx("span",{children:"pp"}),o.jsx("span",{className:"w-px h-3 bg-border"}),o.jsx("span",{className:"text-text-secondary",children:lb(u.avgGenerationSpeed)}),o.jsx("span",{children:"tg"})]})}),o.jsx(UC,{isOpen:i,onClose:()=>c(!1),stats:u})]}),o.jsxs("div",{className:"flex flex-col flex-1 overflow-y-auto",children:[o.jsx("div",{className:"flex items-center justify-between mb-2",children:o.jsx("h3",{className:"text-sm font-semibold text-text-primary",children:"Summary"})}),e?o.jsx("p",{className:"text-sm text-text-primary leading-relaxed",children:e}):o.jsx("div",{className:"text-text-muted text-sm text-center py-2",children:"No summary yet"}),o.jsxs("div",{className:"mt-4",children:[o.jsx("h3",{className:"text-sm font-semibold text-text-primary mb-2",children:"Progress"}),o.jsx(VC,{criteria:(d==null?void 0:d.criteria)??[]})]})]}),h&&o.jsxs("div",{className:"mt-4 flex items-center gap-2 text-sm",children:[o.jsx(mw,{}),o.jsx("span",{className:"truncate text-text-secondary",title:h,children:h})]}),o.jsx(JC,{workdir:s}),o.jsx(e2,{sessionId:d==null?void 0:d.id}),l&&o.jsxs("div",{className:"mt-4 pt-4 border-t border-border text-center text-xs text-text-muted",children:[o.jsx("a",{href:"https://github.com/co-l/openfox",target:"_blank",rel:"noopener noreferrer",className:"hover:text-accent-primary transition-colors",children:"OpenFox"})," - ",o.jsxs("span",{children:["v",l]})]})]})}function t2({children:e,criteriaSidebarOpen:r=!0,onCriteriaSidebarToggle:s,messages:i}){const c=Ce(u=>u.currentSession);return o.jsxs("div",{className:"relative h-full overflow-hidden",children:[r&&o.jsx("div",{className:"fixed md:hidden inset-0 bg-secondary/50 z-40",onClick:s}),o.jsxs("div",{className:"flex h-full",children:[o.jsx("div",{className:"flex-1 min-w-0 flex flex-col overflow-hidden bg-secondary",children:e}),r?o.jsx("aside",{className:"hidden md:block w-[320px] shrink-0 border-l border-border p-4 overflow-y-auto bg-secondary",children:o.jsx(pb,{summary:(c==null?void 0:c.summary)??null,messages:i,workdir:c==null?void 0:c.workdir})}):o.jsx("aside",{className:"hidden md:block w-0 shrink-0 overflow-hidden border-l-0"}),o.jsx("aside",{className:`
|
|
86
86
|
md:hidden
|
|
87
87
|
p-4 overflow-y-auto bg-secondary
|
package/dist/web/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/png" href="/assets/openfox.png" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, height=device-height" />
|
|
7
7
|
<title>OpenFox</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CWdKiSP8.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-D4Si0Pmc.css">
|
|
10
10
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
|
11
11
|
<body class="bg-bg-primary text-text-primary font-mono">
|
package/dist/web/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let o={};const
|
|
1
|
+
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let o={};const l=e=>i(e,t),c={module:{uri:t},exports:o,require:l};s[t]=Promise.all(n.map(e=>c[e]||l(e))).then(e=>(r(...e),o))}}define(["./workbox-8c29f6e4"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"index.html",revision:"f959c738a2773b1407a9f20b04cd1a2a"},{url:"__inspect__.js",revision:"3232040b9bade73418bcfae3cb11c117"},{url:"assets/index-D4Si0Pmc.css",revision:null},{url:"assets/index-CWdKiSP8.js",revision:null},{url:"assets/html2canvas.esm-QH1iLAAe.js",revision:null},{url:"assets/openfox-192.png",revision:"79feeb86d692c274854e37959a7dae67"},{url:"assets/openfox-512.png",revision:"fee24b214220594b4f595a467e73036e"},{url:"manifest.webmanifest",revision:"c25f372c782e623ab1e768a8dfe350ca"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
|