openfox 1.6.54 → 1.6.56

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.
@@ -2,13 +2,13 @@ import {
2
2
  maybeAutoCompactContext,
3
3
  performManualContextCompaction,
4
4
  resolveCompactionStatsIdentity
5
- } from "./chunk-Y4UE4ZRG.js";
5
+ } from "./chunk-NJLOJ5JQ.js";
6
6
  import "./chunk-NBU6KIOD.js";
7
7
  import "./chunk-574HZVLE.js";
8
8
  import "./chunk-7JPKRM6M.js";
9
9
  import "./chunk-WNZIUQ2L.js";
10
- import "./chunk-UQGY56XJ.js";
11
- import "./chunk-LIMBYVO4.js";
10
+ import "./chunk-XDPSXKYP.js";
11
+ import "./chunk-L5RGGVMA.js";
12
12
  import "./chunk-KFBIHS3S.js";
13
13
  import "./chunk-22CTURMH.js";
14
14
  import "./chunk-GQZGIMJO.js";
@@ -23,4 +23,4 @@ export {
23
23
  performManualContextCompaction,
24
24
  resolveCompactionStatsIdentity
25
25
  };
26
- //# sourceMappingURL=auto-compaction-JJEWRJWV.js.map
26
+ //# sourceMappingURL=auto-compaction-WR4LBUXX.js.map
@@ -5,19 +5,19 @@ import {
5
5
  generateSessionName,
6
6
  getSessionMessageCount,
7
7
  needsNameGenerationCheck
8
- } from "./chunk-GIPCUPTT.js";
8
+ } from "./chunk-5FCZWJS7.js";
9
9
  import {
10
10
  runChatTurn
11
- } from "./chunk-RRNFFFN4.js";
12
- import "./chunk-Y4UE4ZRG.js";
11
+ } from "./chunk-3SRJOMW2.js";
12
+ import "./chunk-NJLOJ5JQ.js";
13
13
  import "./chunk-NBU6KIOD.js";
14
14
  import "./chunk-574HZVLE.js";
15
15
  import "./chunk-7JPKRM6M.js";
16
16
  import "./chunk-WNZIUQ2L.js";
17
17
  import {
18
18
  getEventStore
19
- } from "./chunk-UQGY56XJ.js";
20
- import "./chunk-LIMBYVO4.js";
19
+ } from "./chunk-XDPSXKYP.js";
20
+ import "./chunk-L5RGGVMA.js";
21
21
  import {
22
22
  createChatMessageMessage,
23
23
  createPhaseChangedMessage,
@@ -60,7 +60,7 @@ async function startChatSession(sessionId, content, deps, options) {
60
60
  sessionManager.setRunning(sessionId, true);
61
61
  broadcastForSession(sessionId, createSessionRunningMessage(true));
62
62
  try {
63
- const { maybeAutoCompactContext } = await import("./auto-compaction-JJEWRJWV.js");
63
+ const { maybeAutoCompactContext } = await import("./auto-compaction-WR4LBUXX.js");
64
64
  await maybeAutoCompactContext({
65
65
  sessionManager,
66
66
  sessionId,
@@ -169,4 +169,4 @@ export {
169
169
  startChatSession,
170
170
  stopSessionExecution
171
171
  };
172
- //# sourceMappingURL=chat-handler-KVS36WQL.js.map
172
+ //# sourceMappingURL=chat-handler-6O63Q5XV.js.map
@@ -13,14 +13,14 @@ import {
13
13
  getToolRegistryForAgent,
14
14
  loadAllAgentsDefault,
15
15
  runTopLevelAgentLoop
16
- } from "./chunk-Y4UE4ZRG.js";
16
+ } from "./chunk-NJLOJ5JQ.js";
17
17
  import {
18
18
  getCurrentContextWindowId,
19
19
  getEventStore
20
- } from "./chunk-UQGY56XJ.js";
20
+ } from "./chunk-XDPSXKYP.js";
21
21
  import {
22
22
  buildSnapshotFromSessionState
23
- } from "./chunk-LIMBYVO4.js";
23
+ } from "./chunk-L5RGGVMA.js";
24
24
  import {
25
25
  logger
26
26
  } from "./chunk-PNBH3RAX.js";
@@ -293,4 +293,4 @@ export {
293
293
  runBuilderTurn,
294
294
  runVerifierTurn
295
295
  };
296
- //# sourceMappingURL=chunk-RRNFFFN4.js.map
296
+ //# sourceMappingURL=chunk-3SRJOMW2.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getEventStore,
3
3
  updateSessionMetadata
4
- } from "./chunk-UQGY56XJ.js";
4
+ } from "./chunk-XDPSXKYP.js";
5
5
  import {
6
6
  buildMessagesFromStoredEvents,
7
7
  foldPendingConfirmations
8
- } from "./chunk-LIMBYVO4.js";
8
+ } from "./chunk-L5RGGVMA.js";
9
9
  import {
10
10
  createContextStateMessage,
11
11
  createSessionStateMessage
@@ -143,4 +143,4 @@ export {
143
143
  needsNameGenerationCheck,
144
144
  applyGeneratedSessionName
145
145
  };
146
- //# sourceMappingURL=chunk-GIPCUPTT.js.map
146
+ //# sourceMappingURL=chunk-5FCZWJS7.js.map
@@ -2,7 +2,7 @@ import {
2
2
  createVerifierNudgeConfig,
3
3
  runBuilderTurn,
4
4
  runChatTurn
5
- } from "./chunk-RRNFFFN4.js";
5
+ } from "./chunk-3SRJOMW2.js";
6
6
  import {
7
7
  TurnMetrics,
8
8
  agentExists,
@@ -38,7 +38,7 @@ import {
38
38
  setSkillEnabled,
39
39
  skillExists,
40
40
  spawnShellProcess
41
- } from "./chunk-Y4UE4ZRG.js";
41
+ } from "./chunk-NJLOJ5JQ.js";
42
42
  import {
43
43
  getPathSeparator,
44
44
  getPlatformShell,
@@ -88,11 +88,11 @@ import {
88
88
  updateSessionProvider,
89
89
  updateSessionRunning,
90
90
  updateSessionSummary
91
- } from "./chunk-UQGY56XJ.js";
91
+ } from "./chunk-XDPSXKYP.js";
92
92
  import {
93
93
  buildMessagesFromStoredEvents,
94
94
  foldPendingConfirmations
95
- } from "./chunk-LIMBYVO4.js";
95
+ } from "./chunk-L5RGGVMA.js";
96
96
  import {
97
97
  createChatErrorMessage,
98
98
  createChatMessageMessage,
@@ -5001,12 +5001,12 @@ function createDevServerRoutes() {
5001
5001
  router.post("/config", async (req, res) => {
5002
5002
  const workdir = req.query["workdir"];
5003
5003
  if (!workdir) return res.status(400).json({ error: "workdir required" });
5004
- const { command, url, hotReload } = req.body;
5004
+ const { command, url, hotReload, disableInspect } = req.body;
5005
5005
  if (!command || !url) {
5006
5006
  return res.status(400).json({ error: "command and url are required" });
5007
5007
  }
5008
5008
  try {
5009
- const config = { command, url, hotReload: hotReload ?? false };
5009
+ const config = { command, url, hotReload: hotReload ?? false, disableInspect: disableInspect ?? false };
5010
5010
  await devServerManager.saveConfig(workdir, config);
5011
5011
  res.json({ config });
5012
5012
  } catch (err) {
@@ -5058,7 +5058,7 @@ function createTerminalRoutes() {
5058
5058
  }
5059
5059
 
5060
5060
  // src/constants.ts
5061
- var VERSION = "1.6.54";
5061
+ var VERSION = "1.6.56";
5062
5062
 
5063
5063
  // src/server/index.ts
5064
5064
  var __dirname2 = dirname5(fileURLToPath4(import.meta.url));
@@ -5220,7 +5220,7 @@ async function createServerHandle(config) {
5220
5220
  res.json({ success: true });
5221
5221
  });
5222
5222
  app.get("/api/sessions", async (req, res) => {
5223
- const { getRecentUserPromptsForSession } = await import("./events-UCHHTT6X.js");
5223
+ const { getRecentUserPromptsForSession } = await import("./events-4NDTE3KM.js");
5224
5224
  const projectId = req.query["projectId"];
5225
5225
  const limit = Math.min(parseInt(req.query["limit"]) || 20, 100);
5226
5226
  const offset = parseInt(req.query["offset"]) || 0;
@@ -5253,8 +5253,8 @@ async function createServerHandle(config) {
5253
5253
  res.status(201).json({ session });
5254
5254
  });
5255
5255
  app.get("/api/sessions/:id", async (req, res) => {
5256
- const { getEventStore: getEventStore2 } = await import("./events-UCHHTT6X.js");
5257
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-NEZWWL7K.js");
5256
+ const { getEventStore: getEventStore2 } = await import("./events-4NDTE3KM.js");
5257
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-2XZRSTU5.js");
5258
5258
  const session = sessionManager.getSession(req.params.id);
5259
5259
  if (!session) {
5260
5260
  return res.status(404).json({ error: "Session not found" });
@@ -5284,8 +5284,8 @@ async function createServerHandle(config) {
5284
5284
  res.json({ success: true });
5285
5285
  });
5286
5286
  app.post("/api/sessions/:id/provider", async (req, res) => {
5287
- const { getEventStore: getEventStore2 } = await import("./events-UCHHTT6X.js");
5288
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-NEZWWL7K.js");
5287
+ const { getEventStore: getEventStore2 } = await import("./events-4NDTE3KM.js");
5288
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-2XZRSTU5.js");
5289
5289
  const sessionId = req.params.id;
5290
5290
  const session = sessionManager.getSession(sessionId);
5291
5291
  if (!session) {
@@ -5322,8 +5322,8 @@ async function createServerHandle(config) {
5322
5322
  res.json({ success: true });
5323
5323
  });
5324
5324
  app.put("/api/sessions/:id/mode", async (req, res) => {
5325
- const { getEventStore: getEventStore2 } = await import("./events-UCHHTT6X.js");
5326
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-NEZWWL7K.js");
5325
+ const { getEventStore: getEventStore2 } = await import("./events-4NDTE3KM.js");
5326
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-2XZRSTU5.js");
5327
5327
  const sessionId = req.params.id;
5328
5328
  const session = sessionManager.getSession(sessionId);
5329
5329
  if (!session) {
@@ -5361,13 +5361,13 @@ async function createServerHandle(config) {
5361
5361
  if (!callId || approved === void 0) {
5362
5362
  return res.status(400).json({ error: "callId and approved are required" });
5363
5363
  }
5364
- const { providePathConfirmation: providePathConfirmation2 } = await import("./tools-T2FCQ5FE.js");
5364
+ const { providePathConfirmation: providePathConfirmation2 } = await import("./tools-UTC5L4SN.js");
5365
5365
  const result = providePathConfirmation2(callId, approved, alwaysAllow);
5366
5366
  if (!result.found) {
5367
5367
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
5368
5368
  }
5369
- const { getEventStore: getEventStore2 } = await import("./events-UCHHTT6X.js");
5370
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-NEZWWL7K.js");
5369
+ const { getEventStore: getEventStore2 } = await import("./events-4NDTE3KM.js");
5370
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-2XZRSTU5.js");
5371
5371
  const { createSessionStateMessage: createSessionStateMessage2 } = await import("./protocol-5AWNGFLH.js");
5372
5372
  const eventStore = getEventStore2();
5373
5373
  const events = eventStore.getEvents(sessionId);
@@ -5386,7 +5386,7 @@ async function createServerHandle(config) {
5386
5386
  if (!callId || !answer) {
5387
5387
  return res.status(400).json({ error: "callId and answer are required" });
5388
5388
  }
5389
- const { provideAnswer: provideAnswer2 } = await import("./tools-T2FCQ5FE.js");
5389
+ const { provideAnswer: provideAnswer2 } = await import("./tools-UTC5L4SN.js");
5390
5390
  const found = provideAnswer2(callId, answer);
5391
5391
  if (!found) {
5392
5392
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -5422,14 +5422,14 @@ async function createServerHandle(config) {
5422
5422
  if (!session) {
5423
5423
  return res.status(404).json({ error: "Session not found" });
5424
5424
  }
5425
- const { stopSessionExecution } = await import("./chat-handler-KVS36WQL.js");
5426
- const { cancelQuestionsForSession: cancelQuestionsForSession2, cancelPathConfirmationsForSession: cancelPathConfirmationsForSession2 } = await import("./tools-T2FCQ5FE.js");
5425
+ const { stopSessionExecution } = await import("./chat-handler-6O63Q5XV.js");
5426
+ const { cancelQuestionsForSession: cancelQuestionsForSession2, cancelPathConfirmationsForSession: cancelPathConfirmationsForSession2 } = await import("./tools-UTC5L4SN.js");
5427
5427
  stopSessionExecution(sessionId, sessionManager);
5428
5428
  abortSession(sessionId);
5429
5429
  cancelQuestionsForSession2(sessionId, "Session stopped by user");
5430
5430
  cancelPathConfirmationsForSession2(sessionId, "Session stopped by user");
5431
5431
  sessionManager.clearMessageQueue(sessionId);
5432
- const eventStore = (await import("./events-UCHHTT6X.js")).getEventStore();
5432
+ const eventStore = (await import("./events-4NDTE3KM.js")).getEventStore();
5433
5433
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
5434
5434
  res.json({ success: true });
5435
5435
  });
@@ -5882,7 +5882,7 @@ async function createServerHandle(config) {
5882
5882
  providerManager
5883
5883
  );
5884
5884
  const wss = wssExports.wss;
5885
- const { QueueProcessor } = await import("./processor-R3FG6O6H.js");
5885
+ const { QueueProcessor } = await import("./processor-REYSIEHR.js");
5886
5886
  const queueProcessor = new QueueProcessor({
5887
5887
  sessionManager,
5888
5888
  providerManager,
@@ -5955,4 +5955,4 @@ export {
5955
5955
  createServerHandle,
5956
5956
  createServer
5957
5957
  };
5958
- //# sourceMappingURL=chunk-2W3U4KL3.js.map
5958
+ //# sourceMappingURL=chunk-AKTAFYRR.js.map
@@ -179,7 +179,7 @@ async function runCli(options) {
179
179
  if (!configExists) {
180
180
  await runNetworkSetup(mode);
181
181
  }
182
- const { runServe } = await import("./serve-HJQ7FZ3R.js");
182
+ const { runServe } = await import("./serve-PA6IILYU.js");
183
183
  await runServe({
184
184
  mode,
185
185
  port: values.port ? parseInt(values.port) : void 0,
@@ -192,4 +192,4 @@ async function runCli(options) {
192
192
  export {
193
193
  runCli
194
194
  };
195
- //# sourceMappingURL=chunk-ERSDTWU2.js.map
195
+ //# sourceMappingURL=chunk-EZASKT6F.js.map
@@ -778,7 +778,9 @@ function buildSnapshotFromSessionState(input) {
778
778
  todos: foldedState.todos,
779
779
  readFiles: foldedState.readFiles,
780
780
  snapshotSeq: latestSeq,
781
- snapshotAt
781
+ snapshotAt,
782
+ ...foldedState.sessionInit !== void 0 && { sessionInit: foldedState.sessionInit },
783
+ ...foldedState.lastModeWithReminder !== void 0 && { lastModeWithReminder: foldedState.lastModeWithReminder }
782
784
  };
783
785
  }
784
786
  function getMessagesForWindow(messages, windowId) {
@@ -815,4 +817,4 @@ export {
815
817
  getMessagesForWindow,
816
818
  buildContextMessagesFromMessages
817
819
  };
818
- //# sourceMappingURL=chunk-LIMBYVO4.js.map
820
+ //# sourceMappingURL=chunk-L5RGGVMA.js.map
@@ -24,7 +24,7 @@ import {
24
24
  getContextMessages,
25
25
  getCurrentContextWindowId,
26
26
  getEventStore
27
- } from "./chunk-UQGY56XJ.js";
27
+ } from "./chunk-XDPSXKYP.js";
28
28
  import {
29
29
  createChatDoneMessage,
30
30
  createChatMessageMessage,
@@ -3380,7 +3380,7 @@ var callSubAgentTool = {
3380
3380
  };
3381
3381
  }
3382
3382
  try {
3383
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-T2FCQ5FE.js");
3383
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-UTC5L4SN.js");
3384
3384
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3385
3385
  const turnMetrics = new TurnMetrics();
3386
3386
  const result = await executeSubAgent({
@@ -3639,25 +3639,11 @@ import { readFile as readFile7, writeFile as writeFile5, mkdir as mkdir4 } from
3639
3639
  import { resolve as resolve5, join as join6 } from "path";
3640
3640
 
3641
3641
  // src/server/dev-server/inspect-proxy.ts
3642
- import httpProxy from "http-proxy";
3643
- import { createServer as createHttpServer } from "http";
3644
- var proxyCache = /* @__PURE__ */ new Map();
3645
- function getProxy(target) {
3646
- if (!proxyCache.has(target)) {
3647
- const proxy = httpProxy.createProxyServer({
3648
- changeOrigin: true,
3649
- selfHandleResponse: true
3650
- });
3651
- proxy.on("error", (err, _req, res) => {
3652
- if (res && !res.writableEnded) {
3653
- res.writeHead(502, { "content-type": "text/plain" });
3654
- res.end("Proxy error: " + err.message);
3655
- }
3656
- });
3657
- proxyCache.set(target, proxy);
3658
- }
3659
- return proxyCache.get(target);
3660
- }
3642
+ import net from "net";
3643
+ import zlib from "zlib";
3644
+ import fs from "fs";
3645
+ import "http";
3646
+ var INJECT_SCRIPT = '<script src="/__inspect__.js"></script>';
3661
3647
  var proxyPool = /* @__PURE__ */ new Map();
3662
3648
  var nextOffset = 0;
3663
3649
  function getAvailablePort() {
@@ -3672,28 +3658,121 @@ function getAvailablePort() {
3672
3658
  }
3673
3659
  return base + (nextOffset++ % 200 + 1);
3674
3660
  }
3661
+ function parseReqHeaders(str) {
3662
+ const lines = str.split("\r\n");
3663
+ const method = lines[0].split(" ")[0];
3664
+ const url = lines[0].split(" ")[1];
3665
+ const headers = parseHeaderLines(lines);
3666
+ return { method, url, headers };
3667
+ }
3668
+ function parseResHeaders(str) {
3669
+ const lines = str.split("\r\n");
3670
+ const status = parseInt(lines[0].split(" ")[1] || "200");
3671
+ const headers = parseHeaderLines(lines);
3672
+ return { status, headers };
3673
+ }
3674
+ function parseHeaderLines(lines) {
3675
+ const headers = {};
3676
+ for (let i = 1; i < lines.length; i++) {
3677
+ const line = lines[i];
3678
+ if (!line) break;
3679
+ const ci = line.indexOf(":");
3680
+ if (ci < 0) continue;
3681
+ headers[line.slice(0, ci).toLowerCase()] = line.slice(ci + 1).trim();
3682
+ }
3683
+ return headers;
3684
+ }
3685
+ function buildResponse(status, headers, body) {
3686
+ const statusLine = `HTTP/1.1 ${status} ${status === 200 ? "OK" : status === 404 ? "Not Found" : "Error"}`;
3687
+ const headerLines = Object.entries(headers).map(([k, v]) => `${k}: ${v}`).join("\r\n");
3688
+ const head = Buffer.from(`${statusLine}\r
3689
+ ${headerLines}\r
3690
+ \r
3691
+ `, "utf8");
3692
+ return Buffer.concat([head, body]);
3693
+ }
3694
+ function forwardHtml(client, body, resHeaders, status) {
3695
+ const bi = body.indexOf("</body>");
3696
+ const hi = body.indexOf("</head>");
3697
+ let modified;
3698
+ if (bi >= 0) {
3699
+ modified = Buffer.concat([body.slice(0, bi), Buffer.from(INJECT_SCRIPT, "utf8"), body.slice(bi)]);
3700
+ } else if (hi >= 0) {
3701
+ modified = Buffer.concat([body.slice(0, hi), Buffer.from(INJECT_SCRIPT, "utf8"), body.slice(hi)]);
3702
+ } else {
3703
+ client.write(body);
3704
+ return;
3705
+ }
3706
+ const newH = { ...resHeaders };
3707
+ delete newH["content-length"];
3708
+ delete newH["transfer-encoding"];
3709
+ newH["content-length"] = Buffer.byteLength(modified).toString();
3710
+ const newHead = `HTTP/1.1 ${status} OK\r
3711
+ ` + Object.entries(newH).map(([k, v]) => `${k}: ${v}`).join("\r\n") + "\r\n\r\n";
3712
+ client.write(Buffer.from(newHead, "utf8"));
3713
+ client.write(modified);
3714
+ }
3715
+ function forwardHtmlChunk(client, chunk) {
3716
+ const str = chunk.toString("utf8");
3717
+ const bi = str.indexOf("</body>");
3718
+ const hi = str.indexOf("</head>");
3719
+ if (bi >= 0) {
3720
+ const modified = Buffer.from(str.slice(0, bi) + INJECT_SCRIPT + str.slice(bi), "utf8");
3721
+ client.write(modified);
3722
+ } else if (hi >= 0) {
3723
+ const modified = Buffer.from(str.slice(0, hi) + INJECT_SCRIPT + str.slice(hi), "utf8");
3724
+ client.write(modified);
3725
+ } else {
3726
+ client.write(chunk);
3727
+ }
3728
+ }
3675
3729
  function startInspectProxy(target, sessionManager) {
3676
3730
  const port = getAvailablePort();
3677
- const proxy = getProxy(target);
3678
- const server = createHttpServer();
3679
- server.on("request", (req, res) => {
3680
- if (req.url === "/__openfox_feedback" && req.method === "POST") {
3681
- let body = "";
3682
- req.on("data", (chunk) => {
3683
- body += chunk;
3684
- });
3685
- req.on("end", () => {
3731
+ const server = net.createServer((client) => {
3732
+ let clientHead = "";
3733
+ let clientParsed = false;
3734
+ client.on("data", (chunk) => {
3735
+ if (clientParsed) return;
3736
+ clientHead += chunk.toString("utf8");
3737
+ const he = clientHead.indexOf("\r\n\r\n");
3738
+ if (he < 0) return;
3739
+ const { method, url, headers } = parseReqHeaders(clientHead);
3740
+ const isWS = headers["upgrade"] === "websocket";
3741
+ clientParsed = true;
3742
+ if (url === "/__inspect__.js") {
3743
+ const possiblePaths = [
3744
+ `${import.meta.dirname}/../public/__inspect__.js`,
3745
+ `${import.meta.dirname}/../../src/server/public/__inspect__.js`,
3746
+ `${process.cwd()}/dist/server/public/__inspect__.js`
3747
+ ];
3748
+ let inspectJs = null;
3749
+ for (const p of possiblePaths) {
3750
+ try {
3751
+ inspectJs = fs.readFileSync(p);
3752
+ break;
3753
+ } catch {
3754
+ }
3755
+ }
3756
+ if (!inspectJs) {
3757
+ const resp2 = buildResponse(404, { "Content-Type": "text/plain" }, Buffer.from("Not found"));
3758
+ client.write(resp2);
3759
+ client.end();
3760
+ return;
3761
+ }
3762
+ const resp = buildResponse(200, { "Content-Type": "application/javascript", "Content-Length": inspectJs.length.toString() }, inspectJs);
3763
+ client.write(resp);
3764
+ client.end();
3765
+ return;
3766
+ }
3767
+ if (url === "/__openfox_feedback" && method === "POST") {
3768
+ const body = chunk.slice(he + 4).toString("utf8");
3686
3769
  try {
3687
3770
  const { sessionId, element, annotation, pageUrl } = JSON.parse(body);
3688
- if (!sessionId) {
3689
- res.writeHead(400, { "content-type": "application/json" });
3690
- res.end(JSON.stringify({ error: "sessionId required" }));
3691
- return;
3692
- }
3693
- const elementDesc = element ? `${element.tag}${element.id ? "#" + element.id : ""}` : "unknown";
3694
- const htmlSnippet = element?.outerHTML ? `
3771
+ if (sessionId) {
3772
+ const elementDesc = element ? `${element.tag}${element.id ? "#" + element.id : ""}` : "unknown";
3773
+ const htmlSnippet = element?.outerHTML ? `
3695
3774
  Html: ${element.outerHTML.slice(0, 300)}` : "";
3696
- const content = `# User feedback from page inspection on dev_server
3775
+ const content = `# User feedback from page inspection on dev_server
3697
3776
 
3698
3777
  ## Context
3699
3778
 
@@ -3704,63 +3783,114 @@ xPath: ${element?.xpath || ""}${htmlSnippet}
3704
3783
  ## Feedback
3705
3784
 
3706
3785
  ${annotation || "(none)"}`;
3707
- sessionManager.queueMessage(sessionId, "asap", content, [], "ui_feedback");
3708
- res.writeHead(200, { "content-type": "application/json" });
3709
- res.end(JSON.stringify({ success: true }));
3710
- } catch (err) {
3711
- res.writeHead(400, { "content-type": "application/json" });
3712
- res.end(JSON.stringify({ error: err instanceof Error ? err.message : "Invalid request" }));
3713
- }
3714
- });
3715
- return;
3716
- }
3717
- if (req.url === "/__inspect__.js") {
3718
- import("fs/promises").then(async ({ readFile: readFile8 }) => {
3719
- const dir = import.meta.dirname ?? __dirname;
3720
- try {
3721
- const content = await readFile8(`${dir}/../public/__inspect__.js`, "utf-8");
3722
- res.writeHead(200, { "Content-Type": "application/javascript" });
3723
- res.end(content);
3786
+ sessionManager.queueMessage(sessionId, "asap", content, [], "ui_feedback");
3787
+ }
3788
+ client.write(buildResponse(200, { "Content-Type": "application/json" }, Buffer.from('{"success":true}')));
3724
3789
  } catch {
3725
- res.writeHead(404);
3726
- res.end("Not found");
3790
+ client.write(buildResponse(400, { "Content-Type": "application/json" }, Buffer.from('{"error":"Invalid request"}')));
3727
3791
  }
3728
- });
3729
- return;
3730
- }
3731
- ;
3732
- proxy.web(req, res, { target }, (err) => {
3733
- if (err && !res.headersSent) {
3734
- res.writeHead(502, { "content-type": "text/plain" });
3735
- res.end("Proxy error: " + err.message);
3792
+ client.end();
3793
+ return;
3736
3794
  }
3737
- });
3738
- proxy.on("proxyRes", (proxyRes) => {
3739
- const contentType = proxyRes.headers?.["content-type"] ?? "";
3740
- const isHtml = contentType.includes("text/html") || contentType.includes("application/xhtml+xml");
3741
- if (!isHtml) {
3742
- if (res.headersSent) return;
3743
- res.writeHead(proxyRes.statusCode ?? 200, proxyRes.headers);
3744
- proxyRes.pipe(res);
3795
+ const targetParts = target.replace(/^https?:\/\//, "").split(":");
3796
+ const targetHost = targetParts[0] ?? "127.0.0.1";
3797
+ const targetPort = parseInt(targetParts[1] ?? "80");
3798
+ if (isWS) {
3799
+ const server3 = net.connect(targetPort, targetHost);
3800
+ server3.on("error", () => client.destroy());
3801
+ client.on("error", () => server3.destroy());
3802
+ server3.write(clientHead);
3803
+ server3.pipe(client);
3804
+ client.pipe(server3);
3745
3805
  return;
3746
3806
  }
3747
- const chunks = [];
3748
- proxyRes.on("data", (chunk) => chunks.push(chunk));
3749
- proxyRes.on("end", () => {
3750
- try {
3751
- const html = Buffer.concat(chunks).toString("utf8");
3752
- const snippet = `<script src="/__inspect__.js"></script>`;
3753
- const injected = html.replace("</head>", snippet + "</head>");
3754
- res.writeHead(proxyRes.statusCode ?? 200, {
3755
- ...proxyRes.headers,
3756
- "content-type": "text/html; charset=utf-8"
3757
- });
3758
- res.end(injected);
3759
- } catch {
3760
- res.writeHead(500, { "content-type": "text/plain" });
3761
- res.end("Failed to process response");
3807
+ const server2 = net.connect(targetPort, targetHost);
3808
+ server2.on("error", () => client.destroy());
3809
+ client.on("error", () => server2.destroy());
3810
+ server2.write(clientHead);
3811
+ client.pipe(server2);
3812
+ let serverHeadBuf = "";
3813
+ let serverParsed = false;
3814
+ let isHtml = false;
3815
+ let enc = null;
3816
+ let status = 200;
3817
+ let resHeaders = {};
3818
+ let bodyBuf = [];
3819
+ let headEnd = -1;
3820
+ server2.on("data", (sChunk) => {
3821
+ if (!serverParsed) {
3822
+ serverHeadBuf += sChunk.toString("utf8");
3823
+ const sHe = serverHeadBuf.indexOf("\r\n\r\n");
3824
+ if (sHe < 0) return;
3825
+ headEnd = sHe + 4;
3826
+ const p = parseResHeaders(serverHeadBuf.slice(0, sHe));
3827
+ status = p.status;
3828
+ resHeaders = p.headers;
3829
+ isHtml = (resHeaders["content-type"] || "").includes("text/html");
3830
+ enc = resHeaders["content-encoding"] || null;
3831
+ serverParsed = true;
3832
+ if (isHtml && enc) {
3833
+ bodyBuf.push(sChunk.slice(headEnd));
3834
+ return;
3835
+ }
3836
+ if (isHtml) {
3837
+ const body = sChunk.slice(headEnd);
3838
+ forwardHtml(client, body, resHeaders, status);
3839
+ return;
3840
+ }
3841
+ client.write(sChunk);
3842
+ return;
3843
+ }
3844
+ if (isHtml && enc) {
3845
+ bodyBuf.push(sChunk);
3846
+ return;
3847
+ }
3848
+ if (isHtml) {
3849
+ forwardHtmlChunk(client, sChunk);
3850
+ return;
3762
3851
  }
3852
+ client.write(sChunk);
3763
3853
  });
3854
+ server2.on("end", () => {
3855
+ if (!serverParsed) {
3856
+ client.end();
3857
+ return;
3858
+ }
3859
+ if (isHtml && enc) {
3860
+ const fullBody = Buffer.concat(bodyBuf);
3861
+ let text;
3862
+ try {
3863
+ if (enc === "gzip") text = zlib.gunzipSync(fullBody).toString("utf8");
3864
+ else if (enc === "deflate") text = zlib.inflateSync(fullBody).toString("utf8");
3865
+ else text = fullBody.toString("utf8");
3866
+ } catch {
3867
+ client.end();
3868
+ return;
3869
+ }
3870
+ const bi = text.indexOf("</body>");
3871
+ const hi = text.indexOf("</head>");
3872
+ let modified;
3873
+ if (bi >= 0) modified = text.slice(0, bi) + INJECT_SCRIPT + text.slice(bi);
3874
+ else if (hi >= 0) modified = text.slice(0, hi) + INJECT_SCRIPT + text.slice(hi);
3875
+ else {
3876
+ client.end();
3877
+ return;
3878
+ }
3879
+ let compressed;
3880
+ if (enc === "gzip") compressed = zlib.gzipSync(Buffer.from(modified, "utf8"));
3881
+ else if (enc === "deflate") compressed = zlib.deflateSync(Buffer.from(modified, "utf8"));
3882
+ else compressed = Buffer.from(modified, "utf8");
3883
+ const newH = { ...resHeaders };
3884
+ delete newH["content-length"];
3885
+ const headStr = `HTTP/1.1 ${status} OK\r
3886
+ ` + Object.entries(newH).map(([k, v]) => `${k}: ${v}`).join("\r\n") + "\r\n\r\n";
3887
+ client.write(Buffer.from(headStr, "utf8"));
3888
+ client.write(compressed);
3889
+ }
3890
+ client.end();
3891
+ });
3892
+ });
3893
+ client.on("error", () => {
3764
3894
  });
3765
3895
  });
3766
3896
  server.listen(port, "0.0.0.0", () => {
@@ -3769,7 +3899,6 @@ ${annotation || "(none)"}`;
3769
3899
  proxyPool.set(target, { server, target });
3770
3900
  const cleanup = () => {
3771
3901
  server.close();
3772
- proxyCache.delete(target);
3773
3902
  proxyPool.delete(target);
3774
3903
  logger.debug("Inspect proxy stopped", { port, target });
3775
3904
  };
@@ -4534,7 +4663,8 @@ async function performContextCompaction(options) {
4534
4663
  toolChoice: "none",
4535
4664
  disableThinking: true,
4536
4665
  ...instructions ? { customInstructions: instructions } : {},
4537
- ...skills.length > 0 ? { skills } : {}
4666
+ ...skills.length > 0 ? { skills } : {},
4667
+ modelName: options.llmClient.getModel()
4538
4668
  });
4539
4669
  const compactionReminder = `<system-reminder>
4540
4670
  ${COMPACTION_PROMPT}
@@ -4670,4 +4800,4 @@ export {
4670
4800
  getToolRegistryForAgent,
4671
4801
  createToolRegistry
4672
4802
  };
4673
- //# sourceMappingURL=chunk-Y4UE4ZRG.js.map
4803
+ //# sourceMappingURL=chunk-NJLOJ5JQ.js.map
@@ -6,7 +6,7 @@ import {
6
6
  foldSessionState,
7
7
  spreadOptionalMessageFields,
8
8
  stripPromptContextMessages
9
- } from "./chunk-LIMBYVO4.js";
9
+ } from "./chunk-L5RGGVMA.js";
10
10
  import {
11
11
  getDatabase
12
12
  } from "./chunk-BLNFJ22S.js";
@@ -416,6 +416,7 @@ var EventStore = class {
416
416
  const deleteResult = this.db.prepare(`
417
417
  DELETE FROM events
418
418
  WHERE session_id = ? AND seq <= ?
419
+ AND event_type != 'session.initialized'
419
420
  `).run(sessionId, latestSeq);
420
421
  const snapshotEvent = this.append(sessionId, {
421
422
  type: "turn.snapshot",
@@ -764,9 +765,27 @@ function getSessionState(sessionId, maxTokens) {
764
765
  break;
765
766
  }
766
767
  }
767
- if (!initialWindowId && latestSnapshotEvent) {
768
- const snapshotData = latestSnapshotEvent.data;
769
- initialWindowId = snapshotData.sessionInit?.contextWindowId;
768
+ if (!initialWindowId) {
769
+ for (const event of events) {
770
+ if (event.type === "turn.snapshot") {
771
+ const snapshotData = event.data;
772
+ if (snapshotData.sessionInit?.contextWindowId) {
773
+ initialWindowId = snapshotData.sessionInit.contextWindowId;
774
+ break;
775
+ }
776
+ }
777
+ }
778
+ }
779
+ if (!initialWindowId) {
780
+ for (const event of events) {
781
+ if (event.type === "turn.snapshot") {
782
+ const snapshotData = event.data;
783
+ if (snapshotData.currentContextWindowId) {
784
+ initialWindowId = snapshotData.currentContextWindowId;
785
+ break;
786
+ }
787
+ }
788
+ }
770
789
  }
771
790
  if (!initialWindowId) {
772
791
  return void 0;
@@ -1162,4 +1181,4 @@ export {
1162
1181
  compactContext,
1163
1182
  getRecentUserPromptsForSession
1164
1183
  };
1165
- //# sourceMappingURL=chunk-UQGY56XJ.js.map
1184
+ //# sourceMappingURL=chunk-XDPSXKYP.js.map
package/dist/cli/dev.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "../chunk-ERSDTWU2.js";
4
+ } from "../chunk-EZASKT6F.js";
5
5
  import {
6
6
  logger
7
7
  } from "../chunk-PNBH3RAX.js";
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "../chunk-ERSDTWU2.js";
4
+ } from "../chunk-EZASKT6F.js";
5
5
  import {
6
6
  logger
7
7
  } from "../chunk-PNBH3RAX.js";
@@ -36,7 +36,7 @@ import {
36
36
  isFileInCache,
37
37
  isStoredEvent,
38
38
  isTurnEvent
39
- } from "./chunk-UQGY56XJ.js";
39
+ } from "./chunk-XDPSXKYP.js";
40
40
  import {
41
41
  buildContextMessagesFromEventHistory,
42
42
  buildContextMessagesFromMessages,
@@ -53,7 +53,7 @@ import {
53
53
  foldTodos,
54
54
  foldTurnEventsToSnapshotMessages,
55
55
  getMessagesForWindow
56
- } from "./chunk-LIMBYVO4.js";
56
+ } from "./chunk-L5RGGVMA.js";
57
57
  import "./chunk-BLNFJ22S.js";
58
58
  import "./chunk-TVQOONDR.js";
59
59
  import "./chunk-PNBH3RAX.js";
@@ -111,4 +111,4 @@ export {
111
111
  isStoredEvent,
112
112
  isTurnEvent
113
113
  };
114
- //# sourceMappingURL=events-UCHHTT6X.js.map
114
+ //# sourceMappingURL=events-4NDTE3KM.js.map
@@ -17,7 +17,7 @@ import {
17
17
  foldTurnEventsToSnapshotMessagesFromInitial,
18
18
  getMessagesForWindow,
19
19
  spreadOptionalMessageFields
20
- } from "./chunk-LIMBYVO4.js";
20
+ } from "./chunk-L5RGGVMA.js";
21
21
  export {
22
22
  buildContextMessagesFromEventHistory,
23
23
  buildContextMessagesFromMessages,
@@ -38,4 +38,4 @@ export {
38
38
  getMessagesForWindow,
39
39
  spreadOptionalMessageFields
40
40
  };
41
- //# sourceMappingURL=folding-NEZWWL7K.js.map
41
+ //# sourceMappingURL=folding-2XZRSTU5.js.map
@@ -3,7 +3,7 @@ import {
3
3
  runBuilderTurn,
4
4
  runChatTurn,
5
5
  runVerifierTurn
6
- } from "./chunk-RRNFFFN4.js";
6
+ } from "./chunk-3SRJOMW2.js";
7
7
  import {
8
8
  TurnMetrics,
9
9
  createChatDoneEvent,
@@ -11,13 +11,13 @@ import {
11
11
  createMessageStartEvent,
12
12
  createToolCallEvent,
13
13
  createToolResultEvent
14
- } from "./chunk-Y4UE4ZRG.js";
14
+ } from "./chunk-NJLOJ5JQ.js";
15
15
  import "./chunk-NBU6KIOD.js";
16
16
  import "./chunk-574HZVLE.js";
17
17
  import "./chunk-7JPKRM6M.js";
18
18
  import "./chunk-WNZIUQ2L.js";
19
- import "./chunk-UQGY56XJ.js";
20
- import "./chunk-LIMBYVO4.js";
19
+ import "./chunk-XDPSXKYP.js";
20
+ import "./chunk-L5RGGVMA.js";
21
21
  import "./chunk-KFBIHS3S.js";
22
22
  import "./chunk-22CTURMH.js";
23
23
  import "./chunk-GQZGIMJO.js";
@@ -39,4 +39,4 @@ export {
39
39
  runChatTurn,
40
40
  runVerifierTurn
41
41
  };
42
- //# sourceMappingURL=orchestrator-TA4MAODB.js.map
42
+ //# sourceMappingURL=orchestrator-25JCF7GZ.js.map
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openfox",
3
- "version": "1.6.54",
3
+ "version": "1.6.56",
4
4
  "description": "Local-LLM-first agentic coding assistant",
5
5
  "type": "module",
6
6
  "bin": {
@@ -5,11 +5,11 @@ import {
5
5
  generateSessionName,
6
6
  getSessionMessageCount,
7
7
  needsNameGenerationCheck
8
- } from "./chunk-GIPCUPTT.js";
8
+ } from "./chunk-5FCZWJS7.js";
9
9
  import {
10
10
  getEventStore
11
- } from "./chunk-UQGY56XJ.js";
12
- import "./chunk-LIMBYVO4.js";
11
+ } from "./chunk-XDPSXKYP.js";
12
+ import "./chunk-L5RGGVMA.js";
13
13
  import {
14
14
  createChatMessageMessage,
15
15
  createSessionRunningMessage
@@ -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-TA4MAODB.js");
176
+ const { runChatTurn } = await import("./orchestrator-25JCF7GZ.js");
177
177
  const runChatTurnParams = buildRunChatTurnParams({
178
178
  sessionManager,
179
179
  sessionId,
@@ -190,7 +190,11 @@ var QueueProcessor = class {
190
190
  }).finally(() => {
191
191
  this.activeAgents.delete(sessionId);
192
192
  const session2 = this.deps.sessionManager.getSession(sessionId);
193
- if (!session2) return;
193
+ if (!session2) {
194
+ this.deps.sessionManager.setRunning(sessionId, false);
195
+ this.deps.broadcastForSession(sessionId, createSessionRunningMessage(false));
196
+ return;
197
+ }
194
198
  const hasMore = sessionManager.hasQueuedMessages(sessionId);
195
199
  if (!hasMore) {
196
200
  finalizeTurnCompletion(sessionId, sessionManager, broadcastForSession);
@@ -206,4 +210,4 @@ var QueueProcessor = class {
206
210
  export {
207
211
  QueueProcessor
208
212
  };
209
- //# sourceMappingURL=processor-R3FG6O6H.js.map
213
+ //# sourceMappingURL=processor-REYSIEHR.js.map
@@ -6,17 +6,17 @@ import {
6
6
  import {
7
7
  VERSION,
8
8
  createServer
9
- } from "./chunk-2W3U4KL3.js";
10
- import "./chunk-RRNFFFN4.js";
11
- import "./chunk-Y4UE4ZRG.js";
9
+ } from "./chunk-AKTAFYRR.js";
10
+ import "./chunk-3SRJOMW2.js";
11
+ import "./chunk-NJLOJ5JQ.js";
12
12
  import "./chunk-NBU6KIOD.js";
13
13
  import "./chunk-574HZVLE.js";
14
14
  import "./chunk-7JPKRM6M.js";
15
15
  import "./chunk-HYIQFRYJ.js";
16
16
  import "./chunk-F2VWCCMC.js";
17
17
  import "./chunk-WNZIUQ2L.js";
18
- import "./chunk-UQGY56XJ.js";
19
- import "./chunk-LIMBYVO4.js";
18
+ import "./chunk-XDPSXKYP.js";
19
+ import "./chunk-L5RGGVMA.js";
20
20
  import "./chunk-KFBIHS3S.js";
21
21
  import "./chunk-22CTURMH.js";
22
22
  import "./chunk-GQZGIMJO.js";
@@ -187,4 +187,4 @@ async function runServe(options) {
187
187
  export {
188
188
  runServe
189
189
  };
190
- //# sourceMappingURL=serve-HJQ7FZ3R.js.map
190
+ //# sourceMappingURL=serve-PA6IILYU.js.map
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  createServer,
3
3
  createServerHandle
4
- } from "../chunk-2W3U4KL3.js";
5
- import "../chunk-RRNFFFN4.js";
6
- import "../chunk-Y4UE4ZRG.js";
4
+ } from "../chunk-AKTAFYRR.js";
5
+ import "../chunk-3SRJOMW2.js";
6
+ import "../chunk-NJLOJ5JQ.js";
7
7
  import "../chunk-NBU6KIOD.js";
8
8
  import "../chunk-574HZVLE.js";
9
9
  import "../chunk-7JPKRM6M.js";
10
10
  import "../chunk-HYIQFRYJ.js";
11
11
  import "../chunk-F2VWCCMC.js";
12
12
  import "../chunk-WNZIUQ2L.js";
13
- import "../chunk-UQGY56XJ.js";
14
- import "../chunk-LIMBYVO4.js";
13
+ import "../chunk-XDPSXKYP.js";
14
+ import "../chunk-L5RGGVMA.js";
15
15
  import "../chunk-KFBIHS3S.js";
16
16
  import "../chunk-22CTURMH.js";
17
17
  import "../chunk-GQZGIMJO.js";
@@ -11,13 +11,13 @@ import {
11
11
  requestPathAccess,
12
12
  stepDoneTool,
13
13
  validateToolAction
14
- } from "./chunk-Y4UE4ZRG.js";
14
+ } from "./chunk-NJLOJ5JQ.js";
15
15
  import "./chunk-NBU6KIOD.js";
16
16
  import "./chunk-574HZVLE.js";
17
17
  import "./chunk-7JPKRM6M.js";
18
18
  import "./chunk-WNZIUQ2L.js";
19
- import "./chunk-UQGY56XJ.js";
20
- import "./chunk-LIMBYVO4.js";
19
+ import "./chunk-XDPSXKYP.js";
20
+ import "./chunk-L5RGGVMA.js";
21
21
  import "./chunk-KFBIHS3S.js";
22
22
  import {
23
23
  AskUserInterrupt,
@@ -48,4 +48,4 @@ export {
48
48
  stepDoneTool,
49
49
  validateToolAction
50
50
  };
51
- //# sourceMappingURL=tools-T2FCQ5FE.js.map
51
+ //# sourceMappingURL=tools-UTC5L4SN.js.map
@@ -82,7 +82,7 @@ WARNING: This link could potentially be dangerous`)){const b=window.open();if(b)
82
82
  transition-all duration-300 ease-in-out
83
83
  ${r?"translate-x-0":"-translate-x-full"}
84
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(xo,{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(zh,{})})}),s&&o.jsx(ao,{onClick:s,className:"md:hidden",variant:"sidebar",size:"md"})]}),k&&o.jsx(mC,{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:bC(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 bC(e,r,s,i,c){const u=cy(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:oy(d.updatedAt)}),l.map(p=>{const g=(r==null?void 0:r.id)===p.id,m=s.includes(p.id),v=p.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/${p.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:p.title??p.id.slice(0,6)}),o.jsx(xo,{items:[{label:"Delete session",onClick:S=>i(p.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(zh,{})})})]}),o.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[v?o.jsx(Dw,{}):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:dc(p.updatedAt)}),o.jsxs("span",{className:"text-text-muted text-xs flex-shrink-0",children:[p.messageCount," messages"]})]})]})},p.id)})]},h):null})}const sb=["⠋","⠙","⠹","⠸","⠼","⠴"];function vC(){var l;const e=Ft(d=>d.currentProject),r=Ce(d=>d.currentSession),s=Uv(),i=!1,c=H.useRef(0),u=H.useRef(null);H.useEffect(()=>(s?(u.current=window.setInterval(()=>{c.current=(c.current+1)%sb.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 p=(m=r==null?void 0:r.metadata)==null?void 0:m.title,g=s?`${sb[c.current]} `:"";e&&p?document.title=`${g}${e.name} - ${p} | 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}const hc=H.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}));hc.displayName="Input";function yC({isOpen:e,onClose:r,projectName:s,onConfirm:i}){const c=()=>{i(),r()};return o.jsx(jt,{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(st,{variant:"secondary",onClick:r,children:"Cancel"}),o.jsx(st,{variant:"danger",onClick:c,children:"Delete"})]})]})})}function _C(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 SC({isOpen:e,onClose:r}){const[,s]=lr(),[i,c]=H.useState(""),[u,h]=H.useState(null),[l,d]=H.useState(!1),[p,g]=H.useState(""),m=H.useRef(null);H.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=H.useCallback(async C=>{C.preventDefault();const y=_C(i);if(!y.valid){h(y.error);return}d(!0),h(null);const b=`${p}/${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,p]),S=H.useCallback(()=>{c(""),h(null),r()},[r]),k=i?`${p}/${i}`:"";return o.jsx(jt,{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(hc,{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(st,{type:"button",variant:"secondary",onClick:S,disabled:l,children:"Cancel"}),o.jsx(st,{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(Yv,{className:"h-4 w-4"}),"Creating..."]}):"Create"})]})]})})}const wC={sm:"w-4 h-4",md:"w-8 h-8",lg:"w-12 h-12"};function bo({size:e="md",className:r=""}){return o.jsx("div",{className:`animate-spin border-2 border-accent-primary border-t-transparent rounded-full ${wC[e]} ${r}`})}function CC({text:e,...r}){return o.jsxs("div",{className:"text-center",children:[o.jsx(bo,{...r,className:"mx-auto mb-4"}),e&&o.jsx("div",{className:"text-text-secondary",children:e})]})}function dy({onSelect:e,onClose:r,initialPath:s}){const[i,c]=H.useState(null),[u,h]=H.useState(!0),l=H.useCallback(async p=>{h(!0);try{const g=p?`/api/directories?path=${encodeURIComponent(p)}`:"/api/directories",v=await(await ke(g)).json();c(v)}catch(g){console.error("Failed to load directories:",g)}finally{h(!1)}},[]);H.useEffect(()=>{l(s)},[s,l]);const d=((i==null?void 0:i.current)??"").split("/").filter(Boolean).map((p,g,m)=>({name:p,path:"/"+m.slice(0,g+1).join("/")}));return o.jsxs(jt,{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:[d.map((p,g)=>o.jsxs("span",{className:"flex items-center shrink-0",children:[o.jsx("span",{className:"text-text-muted",children:"/"}),o.jsx("button",{onClick:()=>l(p.path),className:`px-1 ${g===d.length-1?"text-accent-primary font-medium":"text-text-secondary hover:text-accent-primary"}`,children:p.name})]},p.path)),d.length===0&&o.jsx("button",{onClick:()=>l("/"),className:"text-text-muted hover:text-accent-primary",children:"/"})]})}),o.jsx("div",{className:"flex-1 overflow-y-auto -mx-4",children:u?o.jsx("div",{className:"p-8 text-center",children:o.jsx(bo,{size:"sm"})}):o.jsxs("div",{className:"divide-y divide-border",children:[(i==null?void 0:i.parent)&&o.jsxs("button",{onClick:()=>l(i.parent),className:"w-full p-3 flex items-center gap-3 hover:bg-bg-tertiary/50 text-text-muted",children:[o.jsx(mw,{className:"w-5 h-5"}),o.jsx("span",{children:".."})]}),i==null?void 0:i.directories.map(p=>o.jsxs("div",{className:"group flex items-center gap-2 hover:bg-bg-tertiary/50",children:[o.jsxs("button",{onClick:()=>l(p.path),className:"flex-1 p-3 flex items-center gap-3 text-left",children:[o.jsx(Xl,{}),o.jsx("span",{children:p.name})]}),o.jsx("button",{onClick:()=>e(p.path),className:"px-3 py-1 text-xs bg-accent-primary/10 text-accent-primary rounded opacity-0 group-hover:opacity-100 transition-opacity mr-3",children:"Select"})]},p.path)),(i==null?void 0:i.directories.length)===0&&o.jsx("div",{className:"p-8 text-center text-text-muted text-sm",children:"No subdirectories"})]})}),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"})]})]})}async function Wd(e,r){let s="/api/directories";return e?s=`/api/directories?path=${encodeURIComponent(e)}`:r&&(s=`/api/directories?path=${encodeURIComponent(r)}`),(await ke(s)).json()}function kC({isOpen:e,onClose:r}){const[,s]=lr(),[i,c]=H.useState(!1),[u,h]=H.useState(""),[l,d]=H.useState(null),[p,g]=H.useState(!1),[m,v]=H.useState(null),S=Ft(Z=>Z.projects),k=Ft(Z=>Z.createProject),C=Ft(Z=>Z.listProjects),y=Ft(Z=>Z.deleteProject),[b,x]=H.useState(null),[_,j]=H.useState(-1),[A,N]=H.useState(null),[D,T]=H.useState(!1),z=H.useRef([]);H.useEffect(()=>{ke("/api/config").then(Z=>Z.json()).then(Z=>{Z.workdir&&v(Z.workdir)})},[]);const O=H.useCallback(async Z=>{g(!0);try{const P=await Wd(Z,m??void 0);d(P)}catch(P){console.error("Failed to load directories:",P)}finally{g(!1)}},[m]);H.useEffect(()=>{e&&m&&(Wd(m),C())},[e,m,O,C]);const q=(l==null?void 0:l.directories.filter(Z=>u===""||Z.name.toLowerCase().includes(u.toLowerCase())))??[],G=[...l!=null&&l.parent&&!u?[{type:"parent",path:l.parent,name:".."}]:[],...q.map(Z=>({type:"directory",path:Z.path,name:Z.name}))],W=Z=>{s(`/p/${Z}`),r()},I=(Z,P)=>{P.stopPropagation(),N(Z)},$=()=>{A&&(y(A.id),N(null))},B=Z=>{const P=Z.split("/").filter(Boolean).pop()??"";k(P,Z),C(),x(Z)};H.useEffect(()=>{if(b){const Z=S.find(P=>P.workdir===b);Z&&(s(`/p/${Z.id}`),r(),x(null))}},[S,b,s,r]),H.useEffect(()=>{j(G.length>0?0:-1)},[u,G.length]);const X=Z=>{h(""),Wd(Z)};return H.useEffect(()=>{_>=0&&z.current[_]&&z.current[_].scrollIntoView({behavior:"smooth",block:"nearest"})},[_]),e?o.jsxs(jt,{isOpen:e,onClose:r,title:"Open Project",size:"xl",footer:o.jsxs("div",{className:"flex justify-between gap-2",children:[o.jsx(st,{variant:"secondary",onClick:()=>c(!0),"data-testid":"open-project-create-button",children:"Create Project"}),o.jsx(st,{variant:"secondary",onClick:r,children:"Cancel"})]}),children:[o.jsxs("div",{className:"flex flex-1 -m-4",children:[o.jsxs("div",{className:"w-1/2 border-r border-border flex flex-col",children:[o.jsx("div",{className:"p-3 border-b border-border bg-bg-tertiary/30",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:S.length===0?o.jsx("div",{className:"p-4 text-center text-text-muted text-sm",children:"No recent projects"}):o.jsx("div",{className:"divide-y divide-border",children:S.map(Z=>o.jsxs("div",{className:"group flex items-center gap-3 p-3 hover:bg-bg-tertiary/50 transition-colors",children:[o.jsxs("button",{onClick:()=>W(Z.id),className:"flex-1 flex items-center gap-3 text-left",children:[o.jsx(Xl,{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:Z.name}),o.jsx("div",{className:"text-xs text-text-muted truncate",children:Z.workdir})]})]}),o.jsx("button",{onClick:P=>I(Z,P),className:"opacity-0 group-hover:opacity-100 text-accent-error/70 hover:text-accent-error p-1 transition-opacity",title:"Delete project",children:o.jsx(lc,{className:"w-4 h-4"})})]},Z.id))})})]}),o.jsxs("div",{className:"w-1/2 flex flex-col",children:[o.jsxs("div",{className:"p-3 border-b border-border bg-bg-tertiary/30 flex items-center justify-between",children:[o.jsx("h3",{className:"font-medium text-sm text-text-secondary",children:"Browse Projects"}),o.jsx("button",{onClick:()=>T(!0),className:"text-xs text-accent-primary hover:underline",children:"Open in dialog"})]}),o.jsx("div",{className:"p-3 border-b border-border",children:o.jsx(hc,{value:u,onChange:Z=>h(Z.target.value),placeholder:"Filter directories...",className:"w-full"})}),o.jsx("div",{className:"flex-1 overflow-y-auto",children:p?o.jsx("div",{className:"p-8 text-center text-text-muted",children:o.jsx("div",{className:"animate-spin w-5 h-5 border-2 border-accent-primary border-t-transparent rounded-full mx-auto"})}):G.length===0?o.jsx("div",{className:"p-8 text-center text-text-muted text-sm",children:u?"No matching directories":"No subdirectories"}):o.jsx("div",{className:"divide-y divide-border",children:G.map((Z,P)=>o.jsxs("button",{ref:R=>{R&&(z.current[P]=R)},onClick:()=>Z.type==="parent"?X(Z.path):B(Z.path),className:`w-full p-3 flex items-center gap-3 text-left transition-colors ${P===_?"bg-accent-primary/20 text-accent-primary":"hover:bg-bg-tertiary/50"}`,children:[o.jsx(Xl,{className:"w-5 h-5"}),o.jsx("span",{className:"flex-1",children:Z.name})]},Z.path))})})]})]}),i&&o.jsx(SC,{isOpen:i,onClose:()=>c(!1)}),A&&o.jsx(yC,{isOpen:!0,onClose:()=>N(null),projectName:A.name,onConfirm:$}),D&&o.jsx(dy,{initialPath:m??void 0,onSelect:Z=>{B(Z),T(!1)},onClose:()=>T(!1)})]}):null}function EC(){const[e,r]=H.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);H.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}),p=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(st,{variant:"primary",onClick:g,children:"Open Project"})]}),d.map(m=>{const v=p(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(Xl,{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:oC(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(bo,{})})]}),e&&o.jsx(kC,{isOpen:e,onClose:()=>r(!1)})]})}function jC(){const[,e]=Bh("/p/:projectId/new"),[,r]=lr(),s=e==null?void 0:e.projectId,i=Ce(c=>c.createSession);return H.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(bo,{})})}function NC(){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 Wa=e=>Math.round(e*10)/10;function xh(e){return{providerId:e.providerId,providerName:e.providerName,backend:e.backend,model:e.model}}function TC(e){return`${e.providerId}::${e.model}`}function AC(e){return`${e.providerName} > ${e.model}`}function ib(e){let r=0,s=0,i=0,c=0,u=0,h=0;const l=[],d=[];let p=0;for(const[v,S]of e.entries()){const k=S.stats,C=xh(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)p+=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:p,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?Wa(i/u):0,m=h>0?Wa(c/h):0;return{totalTime:Wa(r),aiTime:Wa(r-s),toolTime:Wa(s),prefillTokens:i,generationTokens:c,avgPrefillSpeed:g,avgGenerationSpeed:m,responseCount:e.length,llmCallCount:d.length,dataPoints:l,callDataPoints:d}}function DC(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=TC(xh(c.stats)),h=s.get(u)??[];s.set(u,[...h,c])}const i=Array.from(s.entries()).map(([c,u])=>{const h=xh(u[0].stats),l=ib(u);return{...h,key:c,label:AC(h),...l}});return{...ib(r),modelGroups:i}}function RC(e){return H.useMemo(()=>DC(e),[e])}function LC(e){const[r,s]=H.useState(null),[i,c]=H.useState(!0),[u,h]=H.useState(null),l=e||"";return H.useEffect(()=>{if(!l){c(!1);return}let d=!0,p=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(),p=setInterval(g,3e3),()=>{d=!1,p&&clearInterval(p)}},[l]),{branch:r,loading:i,error:u}}function Zl(e){return e.toLocaleString("en-US").replace(/,/g," ")}function ab(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function OC(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 ob=["▁","▂","▃","▄","▅","▆","▇","█"];function MC(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 IC(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 BC(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}=IC(u,h),p=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);p[m]=ob[MC(S,l,d)]??ob[0]}return{blocks:p.join(""),minX:i,maxX:c,minY:l,maxY:d}}function lb(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function cb({data:e,width:r=60,height:s=78,label:i,xLabel:c,yLabel:u,showAxes:h=!0,formatY:l=lb,formatX:d=lb}){const p=H.useMemo(()=>{const g=BC(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:p.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 ${p.chartWidth} ${s}`,className:"w-full h-[78px] overflow-visible",preserveAspectRatio:"none","aria-hidden":"true",children:[p.gridLines.map(g=>o.jsx("line",{x1:"0",x2:p.chartWidth,y1:g.y,y2:g.y,stroke:"currentColor",strokeDasharray:"3 4",className:"text-border/60"},`grid-${g.y}`)),p.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}`)),p.points.length>1&&o.jsx("path",{d:p.path,fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-accent-primary/45"})]}),p.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(p.minX)}),o.jsx("span",{children:c}),o.jsx("span",{children:d(p.maxX)})]})]}),u&&h&&o.jsx("div",{className:"text-text-muted mt-1 text-center",children:u})]})}function zC({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(cb,{data:u,width:c,label:r,xLabel:i}),o.jsx(cb,{data:h,width:c,label:s,xLabel:i})]})}function PC(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 HC(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 FC(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 UC(e){return e.callDataPoints.length>0?FC(e):HC(e)}function Vd(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 Ja(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:e.toFixed(1)}function $C(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`${Ja(e)} t/s`}function hy(e){try{return new Date(e).toLocaleTimeString("en-US",{hour12:!1})}catch{return e}}function qC(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 WC({isOpen:e,onClose:r,stats:s}){const i=H.useRef(null),[c,u]=H.useState({}),[h,l]=H.useState(()=>{var k;return((k=s.modelGroups[0])==null?void 0:k.key)??""});H.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=H.useMemo(()=>s.modelGroups.find(k=>k.key===h)??s.modelGroups[0],[h,s.modelGroups]),p=H.useMemo(()=>d?PC(d):[],[d]),g=H.useMemo(()=>d?UC(d):{mode:"responses",xLabel:"response",prefillLabel:"",generationLabel:"",points:[]},[d]),m=H.useCallback(k=>{u(C=>({...C,[k]:!C[k]}))},[]),v=H.useCallback(()=>{if(!d)return;const k=qC(d);navigator.clipboard.writeText(JSON.stringify(k,null,2)).catch(C=>console.error("Failed to copy:",C))},[d]),S=H.useCallback(async()=>{if(i.current)try{const k=(await mh(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(jt,{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:Vd(d.aiTime)}),o.jsx(Hr,{label:"Total Time",value:Vd(d.totalTime)}),o.jsx(Hr,{label:"Tool Time",value:Vd(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:`@ ${Ja(d.avgPrefillSpeed)} tok/s`}),o.jsx(Hr,{label:"Gen Tokens",value:$s(d.generationTokens),subValue:`@ ${Ja(d.avgGenerationSpeed)} tok/s`}),o.jsx(Hr,{label:"Avg PP Speed",value:`${Ja(d.avgPrefillSpeed)}`,subValue:"tok/s"}),o.jsx(Hr,{label:"Avg TG Speed",value:`${Ja(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(zC,{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:p.map((k,C)=>o.jsxs(H.Fragment,{children:[o.jsx(VC,{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(GC,{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 VC({row:e,index:r,isExpanded:s,onToggle:i}){const c=e.calls.length>0?$C(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:hy(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 GC({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:hy(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 KC={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"}},YC=H.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=KC[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 XC({isOpen:e,onClose:r}){const s=gr(C=>C.config),i=gr(C=>C.saveConfig),[c,u]=H.useState(""),[h,l]=H.useState(""),[d,p]=H.useState(!1),[g,m]=H.useState(!1),[v,S]=H.useState(!1);H.useEffect(()=>{e&&(u((s==null?void 0:s.command)??""),l((s==null?void 0:s.url)??""),p((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(jt,{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=>p(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 ub={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"},ZC={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"},db={1:"font-bold",2:"opacity-75",4:"underline",7:"bg-bg-secondary"},QC="text-text-primary";function JC(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 p=e.slice(i,u.index);p&&r.push({text:p,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 p of l)if(p>=30&&p<=37){const g=ub[p];g&&d.push(g)}else if(p>=40&&p<=47){const g=ZC[p];g&&d.push(g)}else if(p>=90&&p<=97){const g=ub[p];g&&d.push(g)}else if(p in db){const g=db[p];g&&d.push(g)}else p===39?d.push(QC):p===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:e2(e),className:"text-text-primary"}]}}function e2(e){return e.replace(/\x1b\[([0-9;]+)m/g,"")}function oo(e){const r=JC(e),s=[];return r.forEach((i,c)=>{const u=i.text.split(`
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 t2=H.memo(function({title:r,logs:s,onClose:i,preClassName:c}){const u=H.useRef(null);return H.useEffect(()=>{u.current&&(u.current.scrollTop=u.current.scrollHeight)},[s]),o.jsx(jt,{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:oo(h.content)},l))})})}),n2=H.memo(function({logs:r,anchorRef:s,isHiding:i,onExpand:c,onClose:u}){const[h,l]=H.useState(null),d=H.useRef(null);return H.useEffect(()=>{var g;const p=(g=s.current)==null?void 0:g.getBoundingClientRect();p&&l({bottom:window.innerHeight-p.bottom,right:window.innerWidth-p.right,width:p.width,height:p.height})},[s]),H.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((p,g)=>o.jsx("span",{className:p.stream==="stderr"?"text-accent-warning":"",children:oo(p.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}),r2=H.memo(function({workdir:r}){const s=gr(G=>G.setWorkdir),i=gr(G=>G.status),c=gr(G=>G.config),u=gr(G=>G.logs),h=gr(G=>G.start),l=gr(G=>G.stop),d=gr(G=>G.fetchLogs),p=Ce(G=>G.currentSession),[g,m]=H.useState(!1),[v,S]=H.useState(!1),[k,C]=H.useState(!1),[y,b]=H.useState(!1),x=H.useRef(null),_=H.useRef(null),j=H.useRef(null),A=H.useRef(null),N=H.useRef(null),D=()=>{const G=i==null?void 0:i.inspectProxyPort;if(!G)return;const W=`${window.location.protocol}//${window.location.hostname}:${G}`,I=window.open(W,"openfox-inspect");if(I){N.current=I;const $=()=>{!N.current||N.current.closed||(N.current.postMessage({type:"setFoxSessionId",sessionId:(p==null?void 0:p.id)??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";H.useEffect(()=>{s(r??null)},[r,s]),H.useEffect(()=>{O&&d()},[O,d]),H.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(ww,{})})]}),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(Rw,{}),"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(Ew,{}),"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((G,W)=>o.jsx("span",{className:G.stream==="stderr"?"text-accent-warning":"",children:oo(G.content)},W))}),(k||y)&&A.current&&go.createPortal(o.jsx(n2,{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(XC,{isOpen:g,onClose:()=>m(!1)}),v&&o.jsx(t2,{title:"Dev Server Logs",logs:u,onClose:()=>S(!1)})]})});function s2({isOpen:e,onClose:r,processName:s,logs:i}){return e?o.jsx(jt,{isOpen:e,onClose:r,title:s,size:"lg",children:o.jsx("pre",{className:"flex-1 overflow-auto text-sm font-mono text-text-primary whitespace-pre-wrap",children:i.map((c,u)=>o.jsx("span",{className:c.stream==="stderr"?"text-accent-error":"",children:c.content},u))})}):null}const i2=H.memo(function({sessionId:r}){var S;const s=eo(k=>k.processes),i=eo(k=>k.stopProcess),[c,u]=H.useState(null),[h,l]=H.useState([]),d=s.filter(k=>k.status!=="exited"),p=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=eo.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:["(",p," 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(s2,{isOpen:!!c,onClose:()=>{u(null),l([])},processName:((S=d.find(k=>k.id===c))==null?void 0:S.name)??"",logs:h})]})});function hb({summary:e,messages:r,workdir:s}){const[i,c]=H.useState(!1),u=RC(r),{branch:h}=LC(s),l=Rt(p=>p.version),d=Ce(p=>p.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:OC(u.aiTime)}),o.jsx("span",{className:"w-px h-3 bg-border"}),o.jsx("span",{className:"text-text-secondary",children:ab(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:ab(u.avgGenerationSpeed)}),o.jsx("span",{children:"tg"})]})}),o.jsx(WC,{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(YC,{criteria:(d==null?void 0:d.criteria)??[]})]})]}),h&&o.jsxs("div",{className:"mt-4 flex items-center gap-2 text-sm",children:[o.jsx(bw,{}),o.jsx("span",{className:"truncate text-text-secondary",title:h,children:h})]}),o.jsx(r2,{workdir:s}),o.jsx(i2,{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 a2({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(hb,{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:`
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 t2=H.memo(function({title:r,logs:s,onClose:i,preClassName:c}){const u=H.useRef(null);return H.useEffect(()=>{u.current&&(u.current.scrollTop=u.current.scrollHeight)},[s]),o.jsx(jt,{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:oo(h.content)},l))})})}),n2=H.memo(function({logs:r,anchorRef:s,isHiding:i,onExpand:c,onClose:u}){const[h,l]=H.useState(null),d=H.useRef(null);return H.useEffect(()=>{var g;const p=(g=s.current)==null?void 0:g.getBoundingClientRect();p&&l({bottom:window.innerHeight-p.bottom,right:window.innerWidth-p.right,width:p.width,height:p.height})},[s]),H.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((p,g)=>o.jsx("span",{className:p.stream==="stderr"?"text-accent-warning":"",children:oo(p.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}),r2=H.memo(function({workdir:r}){const s=gr(G=>G.setWorkdir),i=gr(G=>G.status),c=gr(G=>G.config),u=gr(G=>G.logs),h=gr(G=>G.start),l=gr(G=>G.stop),d=gr(G=>G.fetchLogs),p=Ce(G=>G.currentSession),[g,m]=H.useState(!1),[v,S]=H.useState(!1),[k,C]=H.useState(!1),[y,b]=H.useState(!1),x=H.useRef(null),_=H.useRef(null),j=H.useRef(null),A=H.useRef(null),N=H.useRef(null),D=()=>{const G=i==null?void 0:i.inspectProxyPort;if(!G){i!=null&&i.url&&window.open(i.url,"_blank");return}const W=`${window.location.protocol}//${window.location.hostname}:${G}`,I=window.open(W,"openfox-inspect");if(I){N.current=I;const $=()=>{!N.current||N.current.closed||(N.current.postMessage({type:"setFoxSessionId",sessionId:(p==null?void 0:p.id)??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";H.useEffect(()=>{s(r??null)},[r,s]),H.useEffect(()=>{O&&d()},[O,d]),H.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(ww,{})})]}),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(Rw,{}),"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(Ew,{}),"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((G,W)=>o.jsx("span",{className:G.stream==="stderr"?"text-accent-warning":"",children:oo(G.content)},W))}),(k||y)&&A.current&&go.createPortal(o.jsx(n2,{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(XC,{isOpen:g,onClose:()=>m(!1)}),v&&o.jsx(t2,{title:"Dev Server Logs",logs:u,onClose:()=>S(!1)})]})});function s2({isOpen:e,onClose:r,processName:s,logs:i}){return e?o.jsx(jt,{isOpen:e,onClose:r,title:s,size:"lg",children:o.jsx("pre",{className:"flex-1 overflow-auto text-sm font-mono text-text-primary whitespace-pre-wrap",children:i.map((c,u)=>o.jsx("span",{className:c.stream==="stderr"?"text-accent-error":"",children:c.content},u))})}):null}const i2=H.memo(function({sessionId:r}){var S;const s=eo(k=>k.processes),i=eo(k=>k.stopProcess),[c,u]=H.useState(null),[h,l]=H.useState([]),d=s.filter(k=>k.status!=="exited"),p=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=eo.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:["(",p," 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(s2,{isOpen:!!c,onClose:()=>{u(null),l([])},processName:((S=d.find(k=>k.id===c))==null?void 0:S.name)??"",logs:h})]})});function hb({summary:e,messages:r,workdir:s}){const[i,c]=H.useState(!1),u=RC(r),{branch:h}=LC(s),l=Rt(p=>p.version),d=Ce(p=>p.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:OC(u.aiTime)}),o.jsx("span",{className:"w-px h-3 bg-border"}),o.jsx("span",{className:"text-text-secondary",children:ab(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:ab(u.avgGenerationSpeed)}),o.jsx("span",{children:"tg"})]})}),o.jsx(WC,{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(YC,{criteria:(d==null?void 0:d.criteria)??[]})]})]}),h&&o.jsxs("div",{className:"mt-4 flex items-center gap-2 text-sm",children:[o.jsx(bw,{}),o.jsx("span",{className:"truncate text-text-secondary",title:h,children:h})]}),o.jsx(r2,{workdir:s}),o.jsx(i2,{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 a2({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(hb,{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
88
88
  transition-all duration-300 ease-in-out
@@ -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-DICFgGhL.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-GOUOKTPT.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-BKpOPPkC.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 l=e=>i(e,t),u={module:{uri:t},exports:o,require:l};s[t]=Promise.all(n.map(e=>u[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:"5a63b2a4e615e2378ec84f40321e91d2"},{url:"assets/index-DICFgGhL.js",revision:null},{url:"assets/index-BKpOPPkC.css",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")))});
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:"fbdcd1352bd7ad18e30ca6085813fa5b"},{url:"assets/index-GOUOKTPT.js",revision:null},{url:"assets/index-BKpOPPkC.css",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")))});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openfox",
3
- "version": "1.6.54",
3
+ "version": "1.6.56",
4
4
  "description": "Local-LLM-first agentic coding assistant",
5
5
  "type": "module",
6
6
  "bin": {