openfox 1.6.68 → 1.6.69

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.
@@ -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-HU4QSO5Q.js");
182
+ const { runServe } = await import("./serve-ZAN7QVCE.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-4SJOSEAL.js.map
195
+ //# sourceMappingURL=chunk-2INV2J2S.js.map
@@ -5058,7 +5058,7 @@ function createTerminalRoutes() {
5058
5058
  }
5059
5059
 
5060
5060
  // src/constants.ts
5061
- var VERSION = "1.6.68";
5061
+ var VERSION = "1.6.69";
5062
5062
 
5063
5063
  // src/server/index.ts
5064
5064
  var __dirname2 = dirname5(fileURLToPath4(import.meta.url));
@@ -5972,4 +5972,4 @@ export {
5972
5972
  createServerHandle,
5973
5973
  createServer
5974
5974
  };
5975
- //# sourceMappingURL=chunk-6GHEJITS.js.map
5975
+ //# sourceMappingURL=chunk-TCVV7VOX.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-4SJOSEAL.js";
4
+ } from "../chunk-2INV2J2S.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-4SJOSEAL.js";
4
+ } from "../chunk-2INV2J2S.js";
5
5
  import {
6
6
  logger
7
7
  } from "../chunk-PNBH3RAX.js";
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openfox",
3
- "version": "1.6.68",
3
+ "version": "1.6.69",
4
4
  "description": "Local-LLM-first agentic coding assistant",
5
5
  "type": "module",
6
6
  "bin": {
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  VERSION,
8
8
  createServer
9
- } from "./chunk-6GHEJITS.js";
9
+ } from "./chunk-TCVV7VOX.js";
10
10
  import "./chunk-K6NHXJM3.js";
11
11
  import "./chunk-KVZIYCT4.js";
12
12
  import "./chunk-RBPOAAIZ.js";
@@ -188,4 +188,4 @@ async function runServe(options) {
188
188
  export {
189
189
  runServe
190
190
  };
191
- //# sourceMappingURL=serve-HU4QSO5Q.js.map
191
+ //# sourceMappingURL=serve-ZAN7QVCE.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createServer,
3
3
  createServerHandle
4
- } from "../chunk-6GHEJITS.js";
4
+ } from "../chunk-TCVV7VOX.js";
5
5
  import "../chunk-K6NHXJM3.js";
6
6
  import "../chunk-KVZIYCT4.js";
7
7
  import "../chunk-RBPOAAIZ.js";
@@ -73,7 +73,7 @@ WARNING: This link could potentially be dangerous`)){const b=window.open();if(b)
73
73
  * Fabrice Bellard's javascript vt100 for jslinux:
74
74
  * http://bellard.org/jslinux/
75
75
  * Copyright (c) 2011 Fabrice Bellard
76
- */var Zw=2,Qw=1,Jw=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let r=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(r._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){var m;if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(e.css.cell.width===0||e.css.cell.height===0)return;let r=this._terminal.options.scrollback===0?0:((m=this._terminal.options.overviewRuler)==null?void 0:m.width)||14,s=window.getComputedStyle(this._terminal.element.parentElement),i=parseInt(s.getPropertyValue("height")),c=Math.max(0,parseInt(s.getPropertyValue("width"))),u=window.getComputedStyle(this._terminal.element),h={top:parseInt(u.getPropertyValue("padding-top")),bottom:parseInt(u.getPropertyValue("padding-bottom")),right:parseInt(u.getPropertyValue("padding-right")),left:parseInt(u.getPropertyValue("padding-left"))},l=h.top+h.bottom,d=h.right+h.left,f=i-l,g=c-d-r;return{cols:Math.max(Zw,Math.floor(g/e.css.cell.width)),rows:Math.max(Qw,Math.floor(f/e.css.cell.height))}}};function eC({sessionId:e,onClose:r,onEscape:s,autoFocus:i}){const c=P.useRef(null),u=P.useRef(e),h=P.useRef(null),l=P.useRef(null),d=ir(g=>g.writeSession),f=ir(g=>g.resizeSession);return P.useEffect(()=>{u.current=e},[e]),P.useEffect(()=>{if(!s)return;const g=m=>{m.key==="Escape"&&(m.preventDefault(),m.stopPropagation(),s())};return window.addEventListener("keydown",g),()=>window.removeEventListener("keydown",g)},[s]),P.useEffect(()=>{if(!c.current)return;const g=new Xw.Terminal({fontFamily:'"JetBrains Mono", monospace',fontSize:13,theme:{background:"#1a1a1a",foreground:"#e0e0e0",cursor:"#ffffff",cursorAccent:"#1a1a1a"},cursorBlink:!0,cursorStyle:"bar",convertEol:!0}),m=new Jw;g.loadAddon(m),h.current={term:g,fitAddon:m},c.current.addEventListener("keydown",C=>{C.key==="Escape"&&s&&(C.preventDefault(),C.stopPropagation(),s())}),g.open(c.current);const v=c.current.querySelector(".xterm");v&&(v.style.padding="8px"),m.fit(),i&&setTimeout(()=>{g.focus()},150);const S=new ResizeObserver(()=>{l.current&&clearTimeout(l.current),l.current=setTimeout(()=>{requestAnimationFrame(()=>{var y;m.fit&&m.fit();const C=(y=h.current)==null?void 0:y.term;C&&C.cols>0&&C.rows>0&&f(u.current,C.cols,C.rows)})},100)});S.observe(c.current),g.onData(C=>{if(C==="\x1B"&&s){s();return}d(u.current,C)}),g.onKey(C=>{C.key==="\x1B"&&s&&(C.domEvent.stopPropagation(),s())});const k=Gt.subscribe(C=>{var y,b;if(C.type==="terminal.output"&&((y=C.payload)==null?void 0:y.sessionId)===u.current){const x=(b=C.payload)==null?void 0:b.data;x&&g.write(x)}});return()=>{k(),S.disconnect(),l.current&&clearTimeout(l.current),g.dispose(),h.current=null}},[e,d,f]),o.jsxs("div",{className:"flex flex-col h-full bg-[#1a1a1a]",children:[o.jsxs("div",{className:"flex-shrink-0 flex items-center justify-between px-2 py-1 bg-[#252525] border-b border-[#333]",children:[o.jsx("div",{}),o.jsx("button",{onClick:r,className:"p-1 rounded hover:bg-[#333] text-[#888] hover:text-[#ccc] transition-colors",title:"Close terminal",children:o.jsx(Rw,{})})]}),o.jsx("div",{ref:c,className:"flex-1 relative overflow-hidden",tabIndex:0,onKeyDown:g=>{g.key==="Escape"&&s&&(g.preventDefault(),g.stopPropagation(),s())}})]})}const ty="openfox-chat-textarea";function ny(){const e=document.getElementById(ty);e&&e.focus()}function tC(e){return e===1?"grid-cols-1":e===2?"grid-cols-1 lg:grid-cols-2":"grid-cols-1 lg:grid-cols-2 xl:grid-cols-3"}function nC({isOpen:e,onClose:r}){const s=ir(k=>k.createSession),i=ir(k=>k.killSession),c=ir(k=>k.sessions),u=ir(k=>k.setWorkdir),h=ir(k=>k.fetchSessions),l=Ft(k=>k.currentProject),[d,f]=P.useState(!0),g=P.useRef(null),m=P.useRef(!1),v=P.useRef(!1),S=P.useCallback(()=>{r()},[r]);return P.useEffect(()=>{l!=null&&l.workdir&&u(l.workdir)},[l==null?void 0:l.workdir,u]),P.useEffect(()=>{e?(f(!0),h(l==null?void 0:l.id).finally(()=>f(!1))):ny()},[e,h,l==null?void 0:l.id]),P.useEffect(()=>{e&&c.length===0&&!d&&!v.current&&(v.current=!0,s(void 0,l==null?void 0:l.id))},[e,c.length,d,s,l==null?void 0:l.id]),P.useEffect(()=>{e?(m.current=!0,setTimeout(()=>{var k;(k=g.current)==null||k.focus(),setTimeout(()=>{m.current=!1},200)},100)):v.current=!1},[e]),P.useEffect(()=>{if(!e)return;const k=C=>{m.current||C.key==="Escape"&&(C.preventDefault(),r())};return window.addEventListener("keydown",k),()=>window.removeEventListener("keydown",k)},[e,r]),e?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"fixed inset-x-0 top-[50vh] bottom-0 z-[100] bg-black/40",style:{pointerEvents:"auto"},onClick:S}),o.jsxs("div",{ref:g,tabIndex:-1,className:"fixed inset-x-0 top-0 z-[100] h-[50vh] bg-bg-primary border-b border-border flex flex-col animate-slide-down outline-none",onClick:k=>k.stopPropagation(),onKeyDown:k=>{k.key==="Escape"&&(k.preventDefault(),S())},children:[o.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-border",children:[o.jsx("h3",{className:"text-sm font-semibold text-text-primary",children:"Terminal"}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("button",{onClick:()=>s(void 0,l==null?void 0:l.id),className:"p-2 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"New terminal",children:o.jsx(Cw,{})}),o.jsx("button",{onClick:r,className:"p-2 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Close (Esc)",children:o.jsx(Fh,{})})]})]}),o.jsx("div",{className:"flex-1 min-h-0 p-2 overflow-auto",children:d?o.jsx("div",{className:"flex items-center justify-center h-full text-text-muted",children:"Loading..."}):c.length===0?o.jsx("div",{className:"flex items-center justify-center h-full text-text-muted",children:o.jsxs("div",{className:"text-center",children:[o.jsx("p",{className:"mb-4",children:"No terminal sessions"}),o.jsx("button",{onClick:()=>s(void 0,l==null?void 0:l.id),className:"px-4 py-2 bg-accent-primary/25 text-text-primary rounded hover:bg-accent-primary/40 transition-colors",children:"Create Terminal"})]})}):o.jsx("div",{className:`grid ${tC(c.length)} gap-2 h-full auto-rows-fr`,children:c.map(k=>o.jsx(eC,{sessionId:k.id,onClose:()=>i(k.id),onEscape:S,autoFocus:c.length===1},k.id))})})]})]}):null}function bo({items:e,trigger:r,minWidth:s="120px",isOpen:i,onOpenChange:c}){const[u,h]=P.useState(!1),l=i!==void 0,d=l?i:u,f=O=>{if(l){const q=typeof O=="function"?O(u):O;c==null||c(q)}else h(O)},[g,m]=P.useState(null),v=P.useRef(null),S=P.useRef(null),[k,C]=P.useState(0),y=P.useRef(0),b=P.useRef(e),x=P.useCallback(()=>{if(!v.current)return;const O=v.current.getBoundingClientRect(),q=200,W=window.innerHeight-O.bottom<q;m({top:W?O.top-q-4:O.bottom+4,left:O.left,alignToTop:W})},[]);P.useEffect(()=>{b.current=e},[e]),P.useEffect(()=>{function O(q){S.current&&!S.current.contains(q.target)&&f(!1)}return d&&document.addEventListener("mousedown",O),()=>{document.removeEventListener("mousedown",O)}},[d]),P.useEffect(()=>{d&&x()},[d,x]),P.useEffect(()=>{if(!d)return;setTimeout(()=>{var q;(q=S.current)==null||q.focus()},0);function O(q){const G=b.current,W=G.filter($=>!_($)),I=j(y.current,G);switch(q.key){case"ArrowDown":if(q.preventDefault(),q.stopPropagation(),I<W.length-1){const $=A(y.current+1,G);y.current=$,C($)}break;case"ArrowUp":if(q.preventDefault(),q.stopPropagation(),I>0){const $=N(y.current-1,G);y.current=$,C($)}break;case"Enter":q.preventDefault(),q.stopPropagation(),D(y.current,G);break;case"Escape":q.preventDefault(),q.stopPropagation(),f(!1);break}}return window.addEventListener("keydown",O,!0),()=>window.removeEventListener("keydown",O,!0)},[d,e]);function _(O){var W;const q=O.label;return q?String(((W=q.props)==null?void 0:W.className)??"").includes("cursor-default"):!1}function j(O,q){let G=0;for(let W=0;W<O;W++){const I=q[W];I&&!_(I)&&G++}return G}function A(O,q){for(let G=O;G<q.length;G++){const W=q[G];if(W&&!_(W))return G}return O}function N(O,q){for(let G=O;G>=0;G--){const W=q[G];if(W&&!_(W))return G}return O}function D(O,q){var W;const G=q[O];!G||_(G)||((W=G.onClick)==null||W.call(G),G.href&&(window.history.pushState(null,"",G.href),window.dispatchEvent(new PopStateEvent("popstate"))),f(!1))}P.useEffect(()=>{d&&(C(e.findIndex(O=>!_(O))),y.current=e.findIndex(O=>!_(O)))},[d,e]);const T=O=>{O.stopPropagation(),d||x(),f(!d)},z=g&&o.jsx("div",{ref:S,"data-testid":"session-dropdown-menu",className:`fixed bg-bg-secondary border border-border rounded shadow-lg z-50 ${g.alignToTop?"mb-1":"mt-1"}`,style:{top:g.top,left:g.left,minWidth:s},tabIndex:-1,children:e.map((O,q)=>{const W=!_(O)&&q===k,I=o.jsxs(o.Fragment,{children:[O.icon&&o.jsx("span",{className:"w-4 h-4 flex-shrink-0",children:O.icon}),O.label]});return O.href?o.jsx(Fn,{href:O.href,onClick:$=>{var B;(B=O.onClick)==null||B.call(O,$),f(!1)},className:`w-full px-3 py-2 text-left text-sm flex items-center gap-2 transition-colors ${O.danger?"text-accent-error hover:bg-accent-error/10":W?"bg-accent-primary/20 text-text-primary":"hover:bg-bg-tertiary text-text-primary"} ${q!==e.length-1?"border-b border-border":""}`,children:I},q):o.jsx("button",{onClick:$=>{var B;(B=O.onClick)==null||B.call(O,$),O.closeOnClick!==!1&&f(!1)},className:`w-full px-3 py-2 text-left text-sm flex items-center gap-2 transition-colors ${O.danger?"text-accent-error hover:bg-accent-error/10":W?"bg-accent-primary/20 text-text-primary":"hover:bg-bg-tertiary text-text-primary"} ${q!==e.length-1?"border-b border-border":""}`,children:I},q)})});return o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"relative",children:o.jsx("div",{ref:v,onClick:T,children:r})}),d&&xo.createPortal(z,document.body)]})}function ry(e){const r=new Date(e),i=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][r.getDay()],c=r.getFullYear(),u=String(r.getMonth()+1).padStart(2,"0"),h=String(r.getDate()).padStart(2,"0");return`${i} ${c}/${u}/${h}`}function uc(e){const r=new Date(e),s=String(r.getHours()).padStart(2,"0"),i=String(r.getMinutes()).padStart(2,"0");return`${s}:${i}`}function rC(e){const r=new Date(e),s=new Date,i=new Date(s.getFullYear(),s.getMonth(),s.getDate()),c=new Date(r.getFullYear(),r.getMonth(),r.getDate()),u=Math.floor((i.getTime()-c.getTime())/(1e3*60*60*24)),h=uc(e);if(u===0)return`today ${h}`;if(u===1)return`yesterday ${h}`;if(u<7)return`${u} days ago ${h}`;{const l=r.getFullYear(),d=String(r.getMonth()+1).padStart(2,"0"),f=String(r.getDate()).padStart(2,"0");return`${l}/${d}/${f} ${h}`}}function sy(e){const r=new Date(e);return{year:r.getFullYear(),month:String(r.getMonth()+1).padStart(2,"0"),day:String(r.getDate()).padStart(2,"0")}}function sC(e){const{year:r,month:s,day:i}=sy(e);return`${r}-${s}-${i}`}function iy(e){const r=new Map;for(const c of e){const u=sC(c.updatedAt);r.has(u)||r.set(u,[]),r.get(u).push(c)}for(const[c,u]of r)u.sort((h,l)=>{const d=new Date(h.updatedAt).getTime();return new Date(l.updatedAt).getTime()-d});const s=Array.from(r.keys()).sort((c,u)=>u.localeCompare(c)),i=new Map;for(const c of s)i.set(c,r.get(c));return i}function iC({items:e,trigger:r,isActive:s=!1}){const[i,c]=P.useState(!1),u=P.useRef(null);return P.useEffect(()=>{function h(l){u.current&&!u.current.contains(l.target)&&c(!1)}if(i)return document.addEventListener("mousedown",h),()=>document.removeEventListener("mousedown",h)},[i]),o.jsxs("div",{className:"relative",ref:u,children:[o.jsxs("button",{type:"button",onClick:()=>c(!i),className:`flex items-center gap-1 px-1.5 py-0.5 rounded transition-colors ${s?"bg-bg-tertiary":"hover:bg-bg-tertiary"}`,children:[typeof r=="string"?o.jsx("span",{className:"text-sm text-text-secondary font-medium",children:r}):r,o.jsx(br,{className:"w-3 h-3 text-text-muted flex-shrink-0 transition-transform",rotate:i?180:0})]}),i&&e.length>0&&o.jsx("div",{className:"absolute top-full left-0 mt-1 w-56 bg-bg-secondary border border-border rounded-lg shadow-lg overflow-hidden z-50",children:e.map((h,l)=>{const d=h.label&&typeof h.label=="object"&&h.label.type===Fn?h.label:null;if(d){const f=d.props.href||"";return o.jsxs(Fn,{href:f,className:"flex items-center gap-2 px-3 py-2 text-sm border-b border-border hover:bg-bg-tertiary transition-colors",children:[h.icon,d.props.children]},l)}return h.href?o.jsxs("a",{href:h.href,className:"flex items-center gap-2 px-3 py-2 text-sm border-b border-border hover:bg-bg-tertiary transition-colors",children:[h.icon,h.label]},l):o.jsxs("button",{type:"button",onClick:()=>{var f;(f=h.onClick)==null||f.call(h),c(!1)},className:"flex items-center gap-2 px-3 py-2 text-sm w-full text-left border-b border-border hover:bg-bg-tertiary transition-colors",children:[h.icon,h.label]},l)})})]})}function aC({projects:e,currentProject:r}){const s=Ft(u=>u.loadProject),c=[...e].sort((u,h)=>u.name.localeCompare(h.name)).map(u=>({label:u.name,icon:u.id===r.id?o.jsx(Ur,{}):void 0,href:`/p/${u.id}`,onClick:()=>{s(u.id)}}));return o.jsx(bo,{items:c,trigger:o.jsxs("button",{className:"text-text-secondary hover:text-text-primary hover:underline text-sm truncate flex items-center gap-1",title:r.name,children:[r.name,o.jsx(br,{})]}),minWidth:"250px"})}function oC({currentProject:e,sessions:r,currentSession:s,projectIdFromUrl:i}){if(!(e!=null&&e.id)||e.id!==i)return null;const c=r.filter(h=>h.projectId===e.id).sort((h,l)=>new Date(l.updatedAt).getTime()-new Date(h.updatedAt).getTime()).slice(0,5),u=[{label:o.jsxs(Fn,{href:`/p/${e.id}/new`,className:"flex items-center gap-2",children:[o.jsx(qi,{className:"w-3 h-3 text-accent-primary"}),o.jsx("span",{className:"text-sm",children:"New Session"})]})},...c.map(h=>({label:o.jsx(Fn,{href:`/p/${e.id}/s/${h.id}`,className:"flex items-center gap-2 truncate text-sm",children:o.jsx("span",{children:h.title??h.id.slice(0,8)})}),icon:h.id===(s==null?void 0:s.id)?o.jsx(Ur,{className:"w-3 h-3"}):void 0})),{label:o.jsxs(Fn,{href:"/",className:"flex items-center gap-2 text-text-muted hover:text-text-primary",children:[o.jsx(fw,{className:"w-3 h-3"}),o.jsx("span",{className:"text-sm",children:"Projects"})]})}];return o.jsx(iC,{items:u,trigger:o.jsx("span",{className:"text-sm text-text-secondary font-medium",children:e.name})})}function lC({sessions:e,currentProject:r,currentSession:s,isOpen:i,onOpenChange:c}){var g;const u=Ce(m=>m.loadSession),h=e.filter(m=>m.projectId===r.id).slice(0,15),l=iy(h),d=P.useMemo(()=>{const m=[];m.push({label:o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(qi,{className:"w-4 h-4 text-accent-primary"}),o.jsx("span",{className:"text-sm",children:"New session"})]}),href:`/p/${r.id}/new`,onClick:()=>{}});for(const[v,S]of l){const k=S[0];if(k){m.push({label:o.jsx("div",{className:"px-3 py-2 text-text-muted text-xs font-medium cursor-default",children:ry(k.updatedAt)}),onClick:()=>{}});for(const C of S)m.push({label:o.jsxs("div",{className:"min-w-[160px]",children:[o.jsx("div",{className:"truncate text-sm",children:C.title??C.id.slice(0,8)}),o.jsx("div",{className:"text-text-muted text-xs",children:uc(C.updatedAt)})]}),icon:C.id===(s==null?void 0:s.id)?o.jsx(Ur,{}):void 0,href:`/p/${r.id}/s/${C.id}`,onClick:()=>{u(C.id)}})}}return m},[r.id,l,s==null?void 0:s.id]),f=s?((g=s.metadata)==null?void 0:g.title)??s.id.slice(0,8):"No session selected";return o.jsx(bo,{items:d,isOpen:i,onOpenChange:c,trigger:o.jsxs("button",{className:"text-text-secondary hover:text-text-primary hover:underline text-sm truncate flex items-center gap-1",title:f,"data-testid":"header-session-dropdown",children:[f,o.jsx(br,{})]}),minWidth:"280px"})}function cC({onMenuClick:e,onCriteriaToggle:r}){const[s,i]=P.useState(!1),[c,u]=P.useState(!1),[h,l]=P.useState(!!document.fullscreenElement);P.useEffect(()=>{const j=()=>l(!!document.fullscreenElement);return document.addEventListener("fullscreenchange",j),()=>document.removeEventListener("fullscreenchange",j)},[]);const[d]=lr(),f=d.startsWith("/p/"),g=/^\/p\/[^/]+\/s\/[^/]+$/.test(d),m=Ce(j=>j.currentSession),v=Ce(j=>j.sessions),S=Ft(j=>j.currentProject),k=Ft(j=>j.projects),C=Rt(j=>j.startAutoRefresh),y=Rt(j=>j.stopAutoRefresh),b=ir(j=>j.setOpen),x=ir(j=>j.isOpen);P.useEffect(()=>{const j=()=>u(!0);return window.addEventListener("open-session-dropdown",j),()=>window.removeEventListener("open-session-dropdown",j)},[]);const _=P.useRef(0);return P.useEffect(()=>{const j=A=>{if(A.key==="Control"&&!A.shiftKey&&!A.metaKey&&!A.altKey){const N=Date.now();N-_.current<300?(A.preventDefault(),A.stopPropagation(),ir.getState().toggleOpen(),_.current=0):_.current=N}};return window.addEventListener("keydown",j,!0),()=>window.removeEventListener("keydown",j,!0)},[]),P.useEffect(()=>(C(),()=>y()),[C,y]),o.jsxs("header",{className:"h-8 bg-secondary border-b border-border flex items-center justify-between px-2",children:[o.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[e&&f&&o.jsx("button",{onClick:e,className:"flex-shrink-0 p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Toggle session list",children:o.jsx(eb,{})}),o.jsx(Fn,{href:"/",className:"text-accent-primary font-semibold text-base hover:underline flex-shrink-0 hidden md:inline",children:"OpenFox"}),S&&o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"hidden md:inline text-text-muted flex-shrink-0",children:"/"}),o.jsx("span",{className:"hidden md:inline",children:o.jsx(aC,{projects:k,currentProject:S})}),o.jsx("span",{className:"md:hidden",children:o.jsx(oC,{currentProject:S,sessions:v,currentSession:m,projectIdFromUrl:f&&d.split("/")[2]||null},S==null?void 0:S.id)}),o.jsx("span",{className:"hidden md:inline text-text-muted flex-shrink-0",children:"/"}),o.jsx("span",{className:"hidden md:inline",children:o.jsx(lC,{sessions:v,currentProject:S,currentSession:m,isOpen:c,onOpenChange:u})})]})]}),o.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[g&&o.jsx("button",{onClick:()=>{var j,A,N;document.fullscreenElement?(j=document.exitFullscreen)==null||j.call(document):(N=(A=document.documentElement).requestFullscreen)==null||N.call(A)},className:"max-sm:block hidden p-2 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:h?"Exit fullscreen":"Enter fullscreen",children:h?o.jsx(xw,{}):o.jsx(bw,{})}),f&&o.jsx("button",{onClick:()=>b(!x),className:`p-2.5 rounded hover:bg-bg-tertiary transition-colors ${x?"text-accent-primary":"text-text-muted hover:text-text-primary"}`,title:"Toggle terminal (double Ctrl)",children:o.jsx(Aw,{})}),o.jsx("button",{onClick:()=>i(!0),className:"p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Settings",children:o.jsx(Ew,{})}),o.jsx("button",{onClick:()=>{localStorage.removeItem("openfox_token"),window.location.reload()},className:"p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Logout",children:o.jsx(_w,{})}),r&&g&&o.jsx("button",{onClick:r,className:"p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Toggle summary sidebar",children:o.jsx(eb,{})})]}),o.jsx(qw,{isOpen:s,onClose:()=>i(!1)}),o.jsx(nC,{isOpen:x,onClose:()=>b(!1)})]})}function uC({isOpen:e,onClose:r,title:s,label:i,description:c,placeholder:u,value:h,isLoading:l=!1,onSave:d}){const[f,g]=P.useState(h),[m,v]=P.useState(!1),[S,k]=P.useState(!1);P.useEffect(()=>{g(h),v(!1)},[h]);const C=_=>{g(_.target.value),v(!0)},y=async()=>{k(!0),await d(f),k(!1),v(!1),r()},b=()=>{g(h),v(!1),r()},x=l||S;return o.jsx(jt,{isOpen:e,onClose:b,title:s,size:"lg",children:o.jsxs("div",{className:"flex flex-col h-full -mt-1",children:[o.jsx("label",{className:"block text-sm font-medium text-text-primary mb-1 flex-shrink-0",children:i}),o.jsx("p",{className:"text-sm text-text-muted mb-3 flex-shrink-0",children:c}),o.jsx("div",{className:"flex-1 min-h-[150px]",children:o.jsx("textarea",{value:f,onChange:C,placeholder:u,className:"w-full h-full px-3 py-2 bg-bg-tertiary border border-border rounded text-sm font-mono resize-none focus:outline-none focus:ring-1 focus:ring-accent-primary",disabled:x})}),m&&o.jsx(Kh,{}),o.jsxs("div",{className:"flex justify-end gap-2 pt-2 border-t border-border flex-shrink-0",children:[o.jsx(nt,{variant:"secondary",onClick:b,children:"Cancel"}),o.jsx(nt,{variant:"primary",onClick:y,disabled:!m||x,children:S?"Saving...":"Save"})]})]})})}function dC({isOpen:e,onClose:r,project:s}){const i=Ft(u=>u.updateProject),c=async u=>{i(s.id,{customInstructions:u||null}),await new Promise(h=>setTimeout(h,100))};return o.jsx(uC,{isOpen:e,onClose:r,title:`${s.name} Settings`,label:"Project Instructions",description:"These instructions are injected into prompts when working in this project. They are applied after global instructions but before AGENTS.md files.",placeholder:"Enter project-specific instructions...",value:s.customInstructions??"",onSave:c})}const hC={sm:"w-3 h-3",md:"w-4 h-4",lg:"w-5 h-5",xl:"w-6 h-6"},fC="M6 18L18 6M6 6l12 12";function oo({onClick:e,className:r="",size:s="md",variant:i="default"}){const c=i==="overlay"?"bg-accent-error text-white rounded-full flex items-center justify-center hover:bg-accent-error/80 transition-colors":i==="sidebar"?"flex-shrink-0 p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors":i==="modal"?"text-text-muted hover:text-text-primary transition-colors":"hover:text-white transition-colors";return o.jsx(cc,{onClick:e,icon:fC,iconSize:hC[s],className:`${c} ${r}`,title:"Close"})}function ay({projectId:e,isOpen:r=!0,onClose:s}){const[,i]=lr(),[c,u]=P.useState(!1),h=Ce(j=>j.sessions),l=Ce(j=>j.currentSession),d=Ce(j=>j.unreadSessionIds),f=Ce(j=>j.deleteSession),g=Ce(j=>j.deleteAllSessions),m=Ce(j=>j.loadMoreSessions),v=Ce(j=>j.sessionsHasMore),S=Ce(j=>j.sessionsPaginationLoading),k=Ft(j=>j.currentProject),C=P.useRef(null),y=P.useCallback(()=>{v&&!S&&k&&m(k.id)},[v,S,k,m]);P.useEffect(()=>{if(!C.current||!v)return;const j=new IntersectionObserver(A=>{const N=A[0];N&&N.isIntersecting&&y()},{threshold:.1});return j.observe(C.current),()=>j.disconnect()},[v,y]);const b=h.filter(j=>j.projectId===(k==null?void 0:k.id)),x=(j,A)=>{A==null||A.stopPropagation(),confirm("Delete this session?")&&(f(j),(l==null?void 0:l.id)===j&&i(`/p/${e}`))},_=()=>{confirm("Delete all sessions in this project? This cannot be undone.")&&(g(e),i(`/p/${e}`))};return o.jsxs(o.Fragment,{children:[r&&s&&o.jsx("div",{className:"md:hidden fixed inset-0 bg-black/50 z-40",onClick:s}),o.jsxs("aside",{className:`
76
+ */var Zw=2,Qw=1,Jw=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let r=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(r._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){var m;if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(e.css.cell.width===0||e.css.cell.height===0)return;let r=this._terminal.options.scrollback===0?0:((m=this._terminal.options.overviewRuler)==null?void 0:m.width)||14,s=window.getComputedStyle(this._terminal.element.parentElement),i=parseInt(s.getPropertyValue("height")),c=Math.max(0,parseInt(s.getPropertyValue("width"))),u=window.getComputedStyle(this._terminal.element),h={top:parseInt(u.getPropertyValue("padding-top")),bottom:parseInt(u.getPropertyValue("padding-bottom")),right:parseInt(u.getPropertyValue("padding-right")),left:parseInt(u.getPropertyValue("padding-left"))},l=h.top+h.bottom,d=h.right+h.left,f=i-l,g=c-d-r;return{cols:Math.max(Zw,Math.floor(g/e.css.cell.width)),rows:Math.max(Qw,Math.floor(f/e.css.cell.height))}}};function eC({sessionId:e,onClose:r,onEscape:s,autoFocus:i}){const c=P.useRef(null),u=P.useRef(e),h=P.useRef(null),l=P.useRef(null),d=ir(g=>g.writeSession),f=ir(g=>g.resizeSession);return P.useEffect(()=>{u.current=e},[e]),P.useEffect(()=>{if(!s)return;const g=m=>{m.key==="Escape"&&(m.preventDefault(),m.stopPropagation(),s())};return window.addEventListener("keydown",g),()=>window.removeEventListener("keydown",g)},[s]),P.useEffect(()=>{if(!c.current)return;const g=new Xw.Terminal({fontFamily:'"JetBrains Mono", monospace',fontSize:13,theme:{background:"#1a1a1a",foreground:"#e0e0e0",cursor:"#ffffff",cursorAccent:"#1a1a1a"},cursorBlink:!0,cursorStyle:"bar",convertEol:!0}),m=new Jw;g.loadAddon(m),h.current={term:g,fitAddon:m},c.current.addEventListener("keydown",C=>{C.key==="Escape"&&s&&(C.preventDefault(),C.stopPropagation(),s())}),g.open(c.current);const v=c.current.querySelector(".xterm");v&&(v.style.padding="8px"),m.fit(),i&&setTimeout(()=>{g.focus()},150);const S=new ResizeObserver(()=>{l.current&&clearTimeout(l.current),l.current=setTimeout(()=>{requestAnimationFrame(()=>{var y;m.fit&&m.fit();const C=(y=h.current)==null?void 0:y.term;C&&C.cols>0&&C.rows>0&&f(u.current,C.cols,C.rows)})},100)});S.observe(c.current),g.onData(C=>{if(C==="\x1B"&&s){s();return}d(u.current,C)}),g.onKey(C=>{C.key==="\x1B"&&s&&(C.domEvent.stopPropagation(),s())});const k=Gt.subscribe(C=>{var y,b;if(C.type==="terminal.output"&&((y=C.payload)==null?void 0:y.sessionId)===u.current){const x=(b=C.payload)==null?void 0:b.data;x&&g.write(x)}});return()=>{k(),S.disconnect(),l.current&&clearTimeout(l.current),g.dispose(),h.current=null}},[e,d,f]),o.jsxs("div",{className:"flex flex-col h-full bg-[#1a1a1a]",children:[o.jsxs("div",{className:"flex-shrink-0 flex items-center justify-between px-2 py-1 bg-[#252525] border-b border-[#333]",children:[o.jsx("div",{}),o.jsx("button",{onClick:r,className:"p-1 rounded hover:bg-[#333] text-[#888] hover:text-[#ccc] transition-colors",title:"Close terminal",children:o.jsx(Rw,{})})]}),o.jsx("div",{ref:c,className:"flex-1 relative overflow-hidden",tabIndex:0,onKeyDown:g=>{g.key==="Escape"&&s&&(g.preventDefault(),g.stopPropagation(),s())}})]})}const ty="openfox-chat-textarea";function ny(){const e=document.getElementById(ty);e&&e.focus()}function tC(e){return e===1?"grid-cols-1":e===2?"grid-cols-1 lg:grid-cols-2":"grid-cols-1 lg:grid-cols-2 xl:grid-cols-3"}function nC({isOpen:e,onClose:r}){const s=ir(k=>k.createSession),i=ir(k=>k.killSession),c=ir(k=>k.sessions),u=ir(k=>k.setWorkdir),h=ir(k=>k.fetchSessions),l=Ft(k=>k.currentProject),[d,f]=P.useState(!0),g=P.useRef(null),m=P.useRef(!1),v=P.useRef(!1),S=P.useCallback(()=>{r()},[r]);return P.useEffect(()=>{l!=null&&l.workdir&&u(l.workdir)},[l==null?void 0:l.workdir,u]),P.useEffect(()=>{e?(f(!0),h(l==null?void 0:l.id).finally(()=>f(!1))):ny()},[e,h,l==null?void 0:l.id]),P.useEffect(()=>{e&&c.length===0&&!d&&!v.current&&(v.current=!0,s(void 0,l==null?void 0:l.id))},[e,c.length,d,s,l==null?void 0:l.id]),P.useEffect(()=>{e?(m.current=!0,setTimeout(()=>{var k;(k=g.current)==null||k.focus(),setTimeout(()=>{m.current=!1},200)},100)):v.current=!1},[e]),P.useEffect(()=>{if(!e)return;const k=C=>{m.current||C.key==="Escape"&&(C.preventDefault(),r())};return window.addEventListener("keydown",k),()=>window.removeEventListener("keydown",k)},[e,r]),e?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"fixed inset-x-0 top-[50vh] bottom-0 z-[100] bg-black/40",style:{pointerEvents:"auto"},onClick:S}),o.jsxs("div",{ref:g,tabIndex:-1,className:"fixed inset-x-0 top-0 z-[100] h-[50vh] bg-bg-primary border-b border-border flex flex-col animate-slide-down outline-none",onClick:k=>k.stopPropagation(),onKeyDown:k=>{k.key==="Escape"&&(k.preventDefault(),S())},children:[o.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-border",children:[o.jsx("h3",{className:"text-sm font-semibold text-text-primary",children:"Terminal"}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("button",{onClick:()=>s(void 0,l==null?void 0:l.id),className:"p-2 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"New terminal",children:o.jsx(Cw,{})}),o.jsx("button",{onClick:r,className:"p-2 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Close (Esc)",children:o.jsx(Fh,{})})]})]}),o.jsx("div",{className:"flex-1 min-h-0 p-2 overflow-auto",children:d?o.jsx("div",{className:"flex items-center justify-center h-full text-text-muted",children:"Loading..."}):c.length===0?o.jsx("div",{className:"flex items-center justify-center h-full text-text-muted",children:o.jsxs("div",{className:"text-center",children:[o.jsx("p",{className:"mb-4",children:"No terminal sessions"}),o.jsx("button",{onClick:()=>s(void 0,l==null?void 0:l.id),className:"px-4 py-2 bg-accent-primary/25 text-text-primary rounded hover:bg-accent-primary/40 transition-colors",children:"Create Terminal"})]})}):o.jsx("div",{className:`grid ${tC(c.length)} gap-2 h-full auto-rows-fr`,children:c.map(k=>o.jsx(eC,{sessionId:k.id,onClose:()=>i(k.id),onEscape:S,autoFocus:c.length===1},k.id))})})]})]}):null}function bo({items:e,trigger:r,minWidth:s="120px",isOpen:i,onOpenChange:c}){const[u,h]=P.useState(!1),l=i!==void 0,d=l?i:u,f=O=>{if(l){const q=typeof O=="function"?O(u):O;c==null||c(q)}else h(O)},[g,m]=P.useState(null),v=P.useRef(null),S=P.useRef(null),[k,C]=P.useState(0),y=P.useRef(0),b=P.useRef(e),x=P.useCallback(()=>{if(!v.current)return;const O=v.current.getBoundingClientRect(),q=200,W=window.innerHeight-O.bottom<q;m({top:W?O.top-q-4:O.bottom+4,left:O.left,alignToTop:W})},[]);P.useEffect(()=>{b.current=e},[e]),P.useEffect(()=>{function O(q){S.current&&!S.current.contains(q.target)&&f(!1)}return d&&document.addEventListener("mousedown",O),()=>{document.removeEventListener("mousedown",O)}},[d]),P.useEffect(()=>{d&&x()},[d,x]),P.useEffect(()=>{if(!d)return;setTimeout(()=>{var q;(q=S.current)==null||q.focus()},0);function O(q){const G=b.current,W=G.filter($=>!_($)),I=j(y.current,G);switch(q.key){case"ArrowDown":if(q.preventDefault(),q.stopPropagation(),I<W.length-1){const $=A(y.current+1,G);y.current=$,C($)}break;case"ArrowUp":if(q.preventDefault(),q.stopPropagation(),I>0){const $=N(y.current-1,G);y.current=$,C($)}break;case"Enter":q.preventDefault(),q.stopPropagation(),D(y.current,G);break;case"Escape":q.preventDefault(),q.stopPropagation(),f(!1);break}}return window.addEventListener("keydown",O,!0),()=>window.removeEventListener("keydown",O,!0)},[d,e]);function _(O){var W;const q=O.label;return q?String(((W=q.props)==null?void 0:W.className)??"").includes("cursor-default"):!1}function j(O,q){let G=0;for(let W=0;W<O;W++){const I=q[W];I&&!_(I)&&G++}return G}function A(O,q){for(let G=O;G<q.length;G++){const W=q[G];if(W&&!_(W))return G}return O}function N(O,q){for(let G=O;G>=0;G--){const W=q[G];if(W&&!_(W))return G}return O}function D(O,q){var W;const G=q[O];!G||_(G)||((W=G.onClick)==null||W.call(G),G.href&&(window.history.pushState(null,"",G.href),window.dispatchEvent(new PopStateEvent("popstate"))),f(!1))}P.useEffect(()=>{d&&(C(e.findIndex(O=>!_(O))),y.current=e.findIndex(O=>!_(O)))},[d,e]);const T=O=>{O.stopPropagation(),d||x(),f(!d)},z=g&&o.jsx("div",{ref:S,"data-testid":"session-dropdown-menu",className:`fixed bg-bg-secondary border border-border rounded shadow-lg z-50 ${g.alignToTop?"mb-1":"mt-1"}`,style:{top:g.top,left:g.left,minWidth:s},tabIndex:-1,children:e.map((O,q)=>{const W=!_(O)&&q===k,I=o.jsxs(o.Fragment,{children:[O.icon&&o.jsx("span",{className:"w-4 h-4 flex-shrink-0",children:O.icon}),O.label]});return O.href?o.jsx(Fn,{href:O.href,onMouseDown:$=>{var B;(B=O.onClick)==null||B.call(O,$),f(!1)},className:`w-full px-3 py-2 text-left text-sm flex items-center gap-2 transition-colors ${O.danger?"text-accent-error hover:bg-accent-error/10":W?"bg-accent-primary/20 text-text-primary":"hover:bg-bg-tertiary text-text-primary"} ${q!==e.length-1?"border-b border-border":""}`,children:I},q):o.jsx("button",{onClick:$=>{var B;(B=O.onClick)==null||B.call(O,$),O.closeOnClick!==!1&&f(!1)},className:`w-full px-3 py-2 text-left text-sm flex items-center gap-2 transition-colors ${O.danger?"text-accent-error hover:bg-accent-error/10":W?"bg-accent-primary/20 text-text-primary":"hover:bg-bg-tertiary text-text-primary"} ${q!==e.length-1?"border-b border-border":""}`,children:I},q)})});return o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"relative",children:o.jsx("div",{ref:v,onClick:T,children:r})}),d&&xo.createPortal(z,document.body)]})}function ry(e){const r=new Date(e),i=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][r.getDay()],c=r.getFullYear(),u=String(r.getMonth()+1).padStart(2,"0"),h=String(r.getDate()).padStart(2,"0");return`${i} ${c}/${u}/${h}`}function uc(e){const r=new Date(e),s=String(r.getHours()).padStart(2,"0"),i=String(r.getMinutes()).padStart(2,"0");return`${s}:${i}`}function rC(e){const r=new Date(e),s=new Date,i=new Date(s.getFullYear(),s.getMonth(),s.getDate()),c=new Date(r.getFullYear(),r.getMonth(),r.getDate()),u=Math.floor((i.getTime()-c.getTime())/(1e3*60*60*24)),h=uc(e);if(u===0)return`today ${h}`;if(u===1)return`yesterday ${h}`;if(u<7)return`${u} days ago ${h}`;{const l=r.getFullYear(),d=String(r.getMonth()+1).padStart(2,"0"),f=String(r.getDate()).padStart(2,"0");return`${l}/${d}/${f} ${h}`}}function sy(e){const r=new Date(e);return{year:r.getFullYear(),month:String(r.getMonth()+1).padStart(2,"0"),day:String(r.getDate()).padStart(2,"0")}}function sC(e){const{year:r,month:s,day:i}=sy(e);return`${r}-${s}-${i}`}function iy(e){const r=new Map;for(const c of e){const u=sC(c.updatedAt);r.has(u)||r.set(u,[]),r.get(u).push(c)}for(const[c,u]of r)u.sort((h,l)=>{const d=new Date(h.updatedAt).getTime();return new Date(l.updatedAt).getTime()-d});const s=Array.from(r.keys()).sort((c,u)=>u.localeCompare(c)),i=new Map;for(const c of s)i.set(c,r.get(c));return i}function iC({items:e,trigger:r,isActive:s=!1}){const[i,c]=P.useState(!1),u=P.useRef(null);return P.useEffect(()=>{function h(l){u.current&&!u.current.contains(l.target)&&c(!1)}if(i)return document.addEventListener("mousedown",h),()=>document.removeEventListener("mousedown",h)},[i]),o.jsxs("div",{className:"relative",ref:u,children:[o.jsxs("button",{type:"button",onClick:()=>c(!i),className:`flex items-center gap-1 px-1.5 py-0.5 rounded transition-colors ${s?"bg-bg-tertiary":"hover:bg-bg-tertiary"}`,children:[typeof r=="string"?o.jsx("span",{className:"text-sm text-text-secondary font-medium",children:r}):r,o.jsx(br,{className:"w-3 h-3 text-text-muted flex-shrink-0 transition-transform",rotate:i?180:0})]}),i&&e.length>0&&o.jsx("div",{className:"absolute top-full left-0 mt-1 w-56 bg-bg-secondary border border-border rounded-lg shadow-lg overflow-hidden z-50",children:e.map((h,l)=>{const d=h.label&&typeof h.label=="object"&&h.label.type===Fn?h.label:null;if(d){const f=d.props.href||"";return o.jsxs(Fn,{href:f,className:"flex items-center gap-2 px-3 py-2 text-sm border-b border-border hover:bg-bg-tertiary transition-colors",children:[h.icon,d.props.children]},l)}return h.href?o.jsxs("a",{href:h.href,className:"flex items-center gap-2 px-3 py-2 text-sm border-b border-border hover:bg-bg-tertiary transition-colors",children:[h.icon,h.label]},l):o.jsxs("button",{type:"button",onClick:()=>{var f;(f=h.onClick)==null||f.call(h),c(!1)},className:"flex items-center gap-2 px-3 py-2 text-sm w-full text-left border-b border-border hover:bg-bg-tertiary transition-colors",children:[h.icon,h.label]},l)})})]})}function aC({projects:e,currentProject:r}){const s=Ft(u=>u.loadProject),c=[...e].sort((u,h)=>u.name.localeCompare(h.name)).map(u=>({label:u.name,icon:u.id===r.id?o.jsx(Ur,{}):void 0,href:`/p/${u.id}`,onClick:()=>{s(u.id)}}));return o.jsx(bo,{items:c,trigger:o.jsxs("button",{className:"text-text-secondary hover:text-text-primary hover:underline text-sm truncate flex items-center gap-1",title:r.name,children:[r.name,o.jsx(br,{})]}),minWidth:"250px"})}function oC({currentProject:e,sessions:r,currentSession:s,projectIdFromUrl:i}){if(!(e!=null&&e.id)||e.id!==i)return null;const c=r.filter(h=>h.projectId===e.id).sort((h,l)=>new Date(l.updatedAt).getTime()-new Date(h.updatedAt).getTime()).slice(0,5),u=[{label:o.jsxs(Fn,{href:`/p/${e.id}/new`,className:"flex items-center gap-2",children:[o.jsx(qi,{className:"w-3 h-3 text-accent-primary"}),o.jsx("span",{className:"text-sm",children:"New Session"})]})},...c.map(h=>({label:o.jsx(Fn,{href:`/p/${e.id}/s/${h.id}`,className:"flex items-center gap-2 truncate text-sm",children:o.jsx("span",{children:h.title??h.id.slice(0,8)})}),icon:h.id===(s==null?void 0:s.id)?o.jsx(Ur,{className:"w-3 h-3"}):void 0})),{label:o.jsxs(Fn,{href:"/",className:"flex items-center gap-2 text-text-muted hover:text-text-primary",children:[o.jsx(fw,{className:"w-3 h-3"}),o.jsx("span",{className:"text-sm",children:"Projects"})]})}];return o.jsx(iC,{items:u,trigger:o.jsx("span",{className:"text-sm text-text-secondary font-medium",children:e.name})})}function lC({sessions:e,currentProject:r,currentSession:s,isOpen:i,onOpenChange:c}){var g;const u=Ce(m=>m.loadSession),h=e.filter(m=>m.projectId===r.id).slice(0,15),l=iy(h),d=P.useMemo(()=>{const m=[];m.push({label:o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(qi,{className:"w-4 h-4 text-accent-primary"}),o.jsx("span",{className:"text-sm",children:"New session"})]}),href:`/p/${r.id}/new`,onClick:()=>{}});for(const[v,S]of l){const k=S[0];if(k){m.push({label:o.jsx("div",{className:"px-3 py-2 text-text-muted text-xs font-medium cursor-default",children:ry(k.updatedAt)}),onClick:()=>{}});for(const C of S)m.push({label:o.jsxs("div",{className:"min-w-[160px]",children:[o.jsx("div",{className:"truncate text-sm",children:C.title??C.id.slice(0,8)}),o.jsx("div",{className:"text-text-muted text-xs",children:uc(C.updatedAt)})]}),icon:C.id===(s==null?void 0:s.id)?o.jsx(Ur,{}):void 0,href:`/p/${r.id}/s/${C.id}`,onClick:()=>{u(C.id)}})}}return m},[r.id,l,s==null?void 0:s.id]),f=s?((g=s.metadata)==null?void 0:g.title)??s.id.slice(0,8):"No session selected";return o.jsx(bo,{items:d,isOpen:i,onOpenChange:c,trigger:o.jsxs("button",{className:"text-text-secondary hover:text-text-primary hover:underline text-sm truncate flex items-center gap-1",title:f,"data-testid":"header-session-dropdown",children:[f,o.jsx(br,{})]}),minWidth:"280px"})}function cC({onMenuClick:e,onCriteriaToggle:r}){const[s,i]=P.useState(!1),[c,u]=P.useState(!1),[h,l]=P.useState(!!document.fullscreenElement);P.useEffect(()=>{const j=()=>l(!!document.fullscreenElement);return document.addEventListener("fullscreenchange",j),()=>document.removeEventListener("fullscreenchange",j)},[]);const[d]=lr(),f=d.startsWith("/p/"),g=/^\/p\/[^/]+\/s\/[^/]+$/.test(d),m=Ce(j=>j.currentSession),v=Ce(j=>j.sessions),S=Ft(j=>j.currentProject),k=Ft(j=>j.projects),C=Rt(j=>j.startAutoRefresh),y=Rt(j=>j.stopAutoRefresh),b=ir(j=>j.setOpen),x=ir(j=>j.isOpen);P.useEffect(()=>{const j=()=>u(!0);return window.addEventListener("open-session-dropdown",j),()=>window.removeEventListener("open-session-dropdown",j)},[]);const _=P.useRef(0);return P.useEffect(()=>{const j=A=>{if(A.key==="Control"&&!A.shiftKey&&!A.metaKey&&!A.altKey){const N=Date.now();N-_.current<300?(A.preventDefault(),A.stopPropagation(),ir.getState().toggleOpen(),_.current=0):_.current=N}};return window.addEventListener("keydown",j,!0),()=>window.removeEventListener("keydown",j,!0)},[]),P.useEffect(()=>(C(),()=>y()),[C,y]),o.jsxs("header",{className:"h-8 bg-secondary border-b border-border flex items-center justify-between px-2",children:[o.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[e&&f&&o.jsx("button",{onClick:e,className:"flex-shrink-0 p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Toggle session list",children:o.jsx(eb,{})}),o.jsx(Fn,{href:"/",className:"text-accent-primary font-semibold text-base hover:underline flex-shrink-0 hidden md:inline",children:"OpenFox"}),S&&o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"hidden md:inline text-text-muted flex-shrink-0",children:"/"}),o.jsx("span",{className:"hidden md:inline",children:o.jsx(aC,{projects:k,currentProject:S})}),o.jsx("span",{className:"md:hidden",children:o.jsx(oC,{currentProject:S,sessions:v,currentSession:m,projectIdFromUrl:f&&d.split("/")[2]||null},S==null?void 0:S.id)}),o.jsx("span",{className:"hidden md:inline text-text-muted flex-shrink-0",children:"/"}),o.jsx("span",{className:"hidden md:inline",children:o.jsx(lC,{sessions:v,currentProject:S,currentSession:m,isOpen:c,onOpenChange:u})})]})]}),o.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[g&&o.jsx("button",{onClick:()=>{var j,A,N;document.fullscreenElement?(j=document.exitFullscreen)==null||j.call(document):(N=(A=document.documentElement).requestFullscreen)==null||N.call(A)},className:"max-sm:block hidden p-2 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:h?"Exit fullscreen":"Enter fullscreen",children:h?o.jsx(xw,{}):o.jsx(bw,{})}),f&&o.jsx("button",{onClick:()=>b(!x),className:`p-2.5 rounded hover:bg-bg-tertiary transition-colors ${x?"text-accent-primary":"text-text-muted hover:text-text-primary"}`,title:"Toggle terminal (double Ctrl)",children:o.jsx(Aw,{})}),o.jsx("button",{onClick:()=>i(!0),className:"p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Settings",children:o.jsx(Ew,{})}),o.jsx("button",{onClick:()=>{localStorage.removeItem("openfox_token"),window.location.reload()},className:"p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Logout",children:o.jsx(_w,{})}),r&&g&&o.jsx("button",{onClick:r,className:"p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors",title:"Toggle summary sidebar",children:o.jsx(eb,{})})]}),o.jsx(qw,{isOpen:s,onClose:()=>i(!1)}),o.jsx(nC,{isOpen:x,onClose:()=>b(!1)})]})}function uC({isOpen:e,onClose:r,title:s,label:i,description:c,placeholder:u,value:h,isLoading:l=!1,onSave:d}){const[f,g]=P.useState(h),[m,v]=P.useState(!1),[S,k]=P.useState(!1);P.useEffect(()=>{g(h),v(!1)},[h]);const C=_=>{g(_.target.value),v(!0)},y=async()=>{k(!0),await d(f),k(!1),v(!1),r()},b=()=>{g(h),v(!1),r()},x=l||S;return o.jsx(jt,{isOpen:e,onClose:b,title:s,size:"lg",children:o.jsxs("div",{className:"flex flex-col h-full -mt-1",children:[o.jsx("label",{className:"block text-sm font-medium text-text-primary mb-1 flex-shrink-0",children:i}),o.jsx("p",{className:"text-sm text-text-muted mb-3 flex-shrink-0",children:c}),o.jsx("div",{className:"flex-1 min-h-[150px]",children:o.jsx("textarea",{value:f,onChange:C,placeholder:u,className:"w-full h-full px-3 py-2 bg-bg-tertiary border border-border rounded text-sm font-mono resize-none focus:outline-none focus:ring-1 focus:ring-accent-primary",disabled:x})}),m&&o.jsx(Kh,{}),o.jsxs("div",{className:"flex justify-end gap-2 pt-2 border-t border-border flex-shrink-0",children:[o.jsx(nt,{variant:"secondary",onClick:b,children:"Cancel"}),o.jsx(nt,{variant:"primary",onClick:y,disabled:!m||x,children:S?"Saving...":"Save"})]})]})})}function dC({isOpen:e,onClose:r,project:s}){const i=Ft(u=>u.updateProject),c=async u=>{i(s.id,{customInstructions:u||null}),await new Promise(h=>setTimeout(h,100))};return o.jsx(uC,{isOpen:e,onClose:r,title:`${s.name} Settings`,label:"Project Instructions",description:"These instructions are injected into prompts when working in this project. They are applied after global instructions but before AGENTS.md files.",placeholder:"Enter project-specific instructions...",value:s.customInstructions??"",onSave:c})}const hC={sm:"w-3 h-3",md:"w-4 h-4",lg:"w-5 h-5",xl:"w-6 h-6"},fC="M6 18L18 6M6 6l12 12";function oo({onClick:e,className:r="",size:s="md",variant:i="default"}){const c=i==="overlay"?"bg-accent-error text-white rounded-full flex items-center justify-center hover:bg-accent-error/80 transition-colors":i==="sidebar"?"flex-shrink-0 p-2.5 rounded hover:bg-bg-tertiary text-text-muted hover:text-text-primary transition-colors":i==="modal"?"text-text-muted hover:text-text-primary transition-colors":"hover:text-white transition-colors";return o.jsx(cc,{onClick:e,icon:fC,iconSize:hC[s],className:`${c} ${r}`,title:"Close"})}function ay({projectId:e,isOpen:r=!0,onClose:s}){const[,i]=lr(),[c,u]=P.useState(!1),h=Ce(j=>j.sessions),l=Ce(j=>j.currentSession),d=Ce(j=>j.unreadSessionIds),f=Ce(j=>j.deleteSession),g=Ce(j=>j.deleteAllSessions),m=Ce(j=>j.loadMoreSessions),v=Ce(j=>j.sessionsHasMore),S=Ce(j=>j.sessionsPaginationLoading),k=Ft(j=>j.currentProject),C=P.useRef(null),y=P.useCallback(()=>{v&&!S&&k&&m(k.id)},[v,S,k,m]);P.useEffect(()=>{if(!C.current||!v)return;const j=new IntersectionObserver(A=>{const N=A[0];N&&N.isIntersecting&&y()},{threshold:.1});return j.observe(C.current),()=>j.disconnect()},[v,y]);const b=h.filter(j=>j.projectId===(k==null?void 0:k.id)),x=(j,A)=>{A==null||A.stopPropagation(),confirm("Delete this session?")&&(f(j),(l==null?void 0:l.id)===j&&i(`/p/${e}`))},_=()=>{confirm("Delete all sessions in this project? This cannot be undone.")&&(g(e),i(`/p/${e}`))};return o.jsxs(o.Fragment,{children:[r&&s&&o.jsx("div",{className:"md:hidden fixed inset-0 bg-black/50 z-40",onClick:s}),o.jsxs("aside",{className:`
77
77
  ${r?"md:w-[300px] md:shrink-0":"md:w-0 md:shrink-0 md:overflow-hidden"}
78
78
  md:relative md:h-auto md:translate-x-0
79
79
 
@@ -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-KbZgYzd8.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-DcfuP6Ep.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-CRQDugUa.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),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:"d756f8b43030c25aaa97db8413d17b59"},{url:"__inspect__.js",revision:"dcb0a7b70a0153a18cdc0794e39ee0d6"},{url:"assets/index-KbZgYzd8.js",revision:null},{url:"assets/index-CRQDugUa.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:"1832a67e994a77f34bf026122a0d9200"},{url:"__inspect__.js",revision:"dcb0a7b70a0153a18cdc0794e39ee0d6"},{url:"assets/index-DcfuP6Ep.js",revision:null},{url:"assets/index-CRQDugUa.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.68",
3
+ "version": "1.6.69",
4
4
  "description": "Local-LLM-first agentic coding assistant",
5
5
  "type": "module",
6
6
  "bin": {