loki-mode 6.37.7 → 6.37.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: Multi-agent autonomous startup system. Triggers on "Loki Mode". Takes PRD to deployed product with minimal human intervention. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v6.37.7
6
+ # Loki Mode v6.37.9
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -267,4 +267,4 @@ The following features are documented in skill modules but not yet fully automat
267
267
  | Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
268
268
  | Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
269
269
 
270
- **v6.37.7 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
270
+ **v6.37.9 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 6.37.7
1
+ 6.37.9
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "6.37.7"
10
+ __version__ = "6.37.9"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -94,8 +94,8 @@ class Project(Base):
94
94
  description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
95
95
  prd_path: Mapped[Optional[str]] = mapped_column(String(512), nullable=True)
96
96
  status: Mapped[str] = mapped_column(String(50), default="active")
97
- tenant_id: Mapped[Optional[int]] = mapped_column(
98
- Integer, ForeignKey("tenants.id", ondelete="CASCADE"), nullable=True
97
+ tenant_id: Mapped[int] = mapped_column(
98
+ Integer, ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False
99
99
  )
100
100
  created_at: Mapped[datetime] = mapped_column(
101
101
  DateTime, server_default=func.now(), nullable=False
@@ -105,7 +105,7 @@ class Project(Base):
105
105
  )
106
106
 
107
107
  # Relationships
108
- tenant: Mapped[Optional["Tenant"]] = relationship(
108
+ tenant: Mapped["Tenant"] = relationship(
109
109
  "Tenant", back_populates="projects"
110
110
  )
111
111
  tasks: Mapped[list["Task"]] = relationship(
@@ -162,6 +162,7 @@ class ProjectCreate(BaseModel):
162
162
  name: str = Field(..., min_length=1, max_length=255)
163
163
  description: Optional[str] = None
164
164
  prd_path: Optional[str] = None
165
+ tenant_id: int = Field(..., gt=0, description="Tenant ID (required, must be positive)")
165
166
 
166
167
  @field_validator("name")
167
168
  @classmethod
@@ -778,6 +779,7 @@ async def create_project(
778
779
  name=project.name,
779
780
  description=project.description,
780
781
  prd_path=project.prd_path,
782
+ tenant_id=project.tenant_id,
781
783
  )
782
784
  db.add(db_project)
783
785
  await db.flush()
@@ -2852,7 +2854,7 @@ def _calculate_model_cost(model: str, input_tokens: int, output_tokens: int) ->
2852
2854
  pricing = pricing_table.get(model.lower(), pricing_table.get("sonnet", {}))
2853
2855
  input_cost = (input_tokens / 1_000_000) * pricing.get("input", 3.00)
2854
2856
  output_cost = (output_tokens / 1_000_000) * pricing.get("output", 15.00)
2855
- return input_cost + output_cost
2857
+ return round(input_cost + output_cost, 6)
2856
2858
 
2857
2859
 
2858
2860
  @app.get("/api/cost")
@@ -2945,16 +2947,20 @@ async def get_cost():
2945
2947
  return {
2946
2948
  "total_input_tokens": total_input,
2947
2949
  "total_output_tokens": total_output,
2948
- "estimated_cost_usd": round(estimated_cost, 4),
2949
- "by_phase": by_phase,
2950
+ "estimated_cost_usd": round(estimated_cost, 6),
2951
+ "by_phase": {k: {
2952
+ "input_tokens": v["input_tokens"],
2953
+ "output_tokens": v["output_tokens"],
2954
+ "cost_usd": round(v["cost_usd"], 6),
2955
+ } for k, v in by_phase.items()},
2950
2956
  "by_model": {k: {
2951
2957
  "input_tokens": v["input_tokens"],
2952
2958
  "output_tokens": v["output_tokens"],
2953
- "cost_usd": round(v["cost_usd"], 4),
2959
+ "cost_usd": round(v["cost_usd"], 6),
2954
2960
  } for k, v in by_model.items()},
2955
2961
  "budget_limit": budget_limit,
2956
- "budget_used": round(budget_used, 4) if budget_limit is not None else None,
2957
- "budget_remaining": round(budget_remaining, 4) if budget_remaining is not None else None,
2962
+ "budget_used": round(budget_used, 6) if budget_limit is not None else None,
2963
+ "budget_remaining": round(budget_remaining, 6) if budget_remaining is not None else None,
2958
2964
  }
2959
2965
 
2960
2966
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  The flagship product of [Autonomi](https://www.autonomi.dev/). Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v6.37.7
5
+ **Version:** v6.37.9
6
6
 
7
7
  ---
8
8
 
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '6.37.7'
60
+ __version__ = '6.37.9'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loki-mode",
3
- "version": "6.37.7",
3
+ "version": "6.37.9",
4
4
  "description": "Loki Mode by Autonomi - Multi-agent autonomous startup system for Claude Code, Codex CLI, and Gemini CLI",
5
5
  "keywords": [
6
6
  "agent",
@@ -62,5 +62,5 @@ Describe your project here...
62
62
 
63
63
  - Requirement 1
64
64
  - Requirement 2
65
- `)}},[]),Pl=async()=>{if(!(!M.trim()||tt)){Ql(!0),wl(null),ft(!0);try{const _=await ql.planSession(M,ll);wl(_)}catch{wl({complexity:"unknown",cost_estimate:"N/A",iterations:0,phases:[],output_text:"Failed to run loki plan. The CLI may not be available.",returncode:1})}finally{Ql(!1)}}},S=async()=>{if(!(!M.trim()||g||jl)){ft(!1),Ol(!0);try{await f(M,ll,O.trim()||void 0,Al?"quick":void 0)}finally{Ol(!1)}}};return i.jsxs(i.Fragment,{children:[Xl&&i.jsx(z0,{plan:Yl,loading:tt,onConfirm:S,onCancel:()=>ft(!1)}),i.jsxs("div",{className:"glass p-6 flex flex-col",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Product Requirements"}),i.jsx("div",{className:"flex items-center gap-2",children:i.jsxs("div",{className:"relative",children:[i.jsx("button",{onClick:()=>F(!al),className:"text-xs font-medium px-3 py-1.5 rounded-xl border border-primary/20 text-primary hover:bg-primary/5 transition-colors",children:L||"Templates"}),al&&i.jsx("div",{className:"absolute right-0 top-full mt-1 w-56 glass-subtle rounded-xl overflow-hidden z-20 shadow-glass",children:i.jsxs("div",{className:"py-1 max-h-64 overflow-y-auto terminal-scroll",children:[gl&&i.jsx("div",{className:"px-3 py-2 text-xs text-warning border-b border-warning/10",children:"Could not load templates from server. Check that the backend is running."}),!gl&&Nl.length===0&&i.jsx("div",{className:"px-3 py-2 text-xs text-slate",children:"Loading..."}),Nl.map(_=>i.jsx("button",{onClick:()=>Vl(_.filename,_.name),className:"w-full text-left px-3 py-2 text-sm text-charcoal hover:bg-primary/5 transition-colors",children:_.name},_.filename))]})})]})})]}),i.jsx("textarea",{value:M,onChange:_=>R(_.target.value),placeholder:"Paste your PRD here, or select a template above to get started...",className:"flex-1 min-h-[280px] w-full bg-white/40 rounded-xl border border-white/30 px-4 py-3 text-sm font-mono text-charcoal placeholder:text-primary-wash resize-none focus:outline-none focus:ring-2 focus:ring-accent-product/20 focus:border-accent-product/30 transition-all",spellCheck:!1}),i.jsxs("div",{className:"mt-3",children:[i.jsx("label",{className:"block text-xs text-slate font-medium mb-1 uppercase tracking-wider",children:"Project Directory"}),i.jsx("input",{type:"text",value:O,onChange:_=>Q(_.target.value),placeholder:"Leave blank to auto-create, or type a path (e.g. /Users/you/my-project)",className:"w-full bg-white/40 rounded-xl border border-white/30 px-4 py-2 text-sm font-mono text-charcoal placeholder:text-primary-wash/70 focus:outline-none focus:ring-2 focus:ring-accent-product/20 focus:border-accent-product/30 transition-all",spellCheck:!1}),i.jsx("p",{className:"text-[10px] text-slate mt-1",children:"Type a path or leave blank to auto-create under ~/purple-lab-projects/"})]}),p&&i.jsx("div",{className:"mt-3 px-3 py-2 rounded-lg bg-danger/10 border border-danger/20 text-danger text-xs font-medium",children:p}),i.jsxs("div",{className:"flex items-center gap-3 mt-4",children:[i.jsxs("button",{onClick:()=>k(!Al),title:"Quick Mode: 3 iterations max, faster builds",className:`flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-xs font-semibold border transition-all ${Al?"bg-accent-product/10 border-accent-product/30 text-accent-product":"border-white/30 text-slate hover:text-charcoal hover:bg-white/20"}`,children:[i.jsx("span",{className:`w-1.5 h-1.5 rounded-full ${Al?"bg-accent-product":"bg-slate/40"}`}),"Quick"]}),i.jsx("div",{className:"flex-1"}),i.jsxs("span",{className:"text-xs text-slate font-mono",children:[M.length.toLocaleString()," chars"]}),i.jsx("button",{onClick:Pl,disabled:!M.trim()||g||tt,className:`px-4 py-2.5 rounded-xl text-sm font-semibold border transition-all ${!M.trim()||g||tt?"border-white/20 text-slate/40 cursor-not-allowed":"border-accent-product/30 text-accent-product hover:bg-accent-product/5"}`,children:tt?"Analyzing...":"Estimate"}),i.jsx("button",{onClick:S,disabled:!M.trim()||g||jl,className:`px-6 py-2.5 rounded-xl text-sm font-semibold transition-all ${!M.trim()||g||jl?"bg-surface/50 text-slate cursor-not-allowed":"bg-accent-product text-white hover:bg-accent-product/90 shadow-glass-subtle"}`,children:jl?"Starting...":g?"Building...":"Start Build"})]})]})]})}const Cn=[{key:"reason",label:"Reason",description:"Analyzing task, planning approach"},{key:"act",label:"Act",description:"Implementing changes, writing code"},{key:"reflect",label:"Reflect",description:"Reviewing output, self-critique"},{key:"verify",label:"Verify",description:"Testing, validation, quality gates"}];function _0(f){const g=f.toLowerCase();return g.includes("reason")||g.includes("plan")?"reason":g.includes("act")||g.includes("implement")||g.includes("code")?"act":g.includes("reflect")||g.includes("review")?"reflect":g.includes("verify")||g.includes("test")||g.includes("check")?"verify":"idle"}function M0({currentPhase:f,iteration:g}){const p=_0(f);return i.jsxs("div",{className:"glass p-6",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"RARV Cycle"}),i.jsxs("span",{className:"font-mono text-xs text-slate",children:["Iteration ",g]})]}),i.jsx("div",{className:"flex items-center justify-center mb-5",children:i.jsxs("svg",{viewBox:"0 0 120 120",className:"w-28 h-28",children:[Cn.map((o,T)=>{const M=o.key===p,R=p!=="idle"&&Cn.findIndex(q=>q.key===p)>T,L=(T*90-90)*(Math.PI/180),D=60+40*Math.cos(L),N=60+40*Math.sin(L);return i.jsxs("g",{children:[T<Cn.length-1&&i.jsx("line",{x1:D,y1:N,x2:60+40*Math.cos(((T+1)*90-90)*(Math.PI/180)),y2:60+40*Math.sin(((T+1)*90-90)*(Math.PI/180)),stroke:R?"#3D52A0":"#ADBBDA",strokeWidth:R?2:1,strokeDasharray:R?"none":"4 3"}),T===Cn.length-1&&i.jsx("line",{x1:D,y1:N,x2:60+40*Math.cos(-90*(Math.PI/180)),y2:60+40*Math.sin(-90*(Math.PI/180)),stroke:"#ADBBDA",strokeWidth:1,strokeDasharray:"4 3"}),i.jsx("circle",{cx:D,cy:N,r:M?14:10,fill:M?"#3D52A0":R?"#7091E6":"#EDE8F5",stroke:M?"#6C63FF":R?"#3D52A0":"#ADBBDA",strokeWidth:M?3:1.5,className:M?"phase-active":""}),i.jsx("text",{x:D,y:N+(T===0?-20:T===2?24:0),textAnchor:"middle",className:"text-[9px] font-semibold fill-charcoal",dx:T===1?22:T===3?-22:0,children:o.label[0]})]},o.key)}),i.jsx("text",{x:"60",y:"64",textAnchor:"middle",className:"text-lg font-bold font-mono fill-primary",children:g})]})}),i.jsx("div",{className:"space-y-2",children:Cn.map(o=>{const T=o.key===p;return i.jsxs("div",{className:`flex items-center gap-3 px-3 py-2 rounded-xl transition-all duration-200 ${T?"bg-primary/8 border border-primary/20":"opacity-50"}`,children:[i.jsx("div",{className:`w-2.5 h-2.5 rounded-full flex-shrink-0 ${T?"bg-primary phase-active":"bg-surface"}`}),i.jsxs("div",{children:[i.jsx("span",{className:`text-sm font-semibold ${T?"text-primary":"text-slate"}`,children:o.label}),T&&i.jsx("p",{className:"text-xs text-slate mt-0.5",children:o.description})]})]},o.key)})})]})}const Od={architect:"bg-accent-product/10 text-accent-product border-accent-product/20",developer:"bg-primary/10 text-primary border-primary/20",tester:"bg-success/10 text-success border-success/20",reviewer:"bg-warning/10 text-warning border-warning/20",planner:"bg-primary-wash/20 text-charcoal border-primary-wash/30",default:"bg-surface/30 text-slate border-surface/50"};function O0(f){const g=f.toLowerCase();for(const[p,o]of Object.entries(Od))if(g.includes(p))return o;return Od.default}function D0({agents:f,loading:g}){const p=(f==null?void 0:f.filter(T=>T.alive))||[],o=(f==null?void 0:f.filter(T=>!T.alive))||[];return i.jsxs("div",{className:"glass p-6",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Agents"}),i.jsxs("span",{className:"font-mono text-xs text-slate",children:[p.length," active"]})]}),g&&!f&&i.jsx("div",{className:"text-center py-8 text-slate text-sm",children:"Loading agents..."}),!g&&(f==null?void 0:f.length)===0&&i.jsxs("div",{className:"text-center py-8",children:[i.jsx("p",{className:"text-slate text-sm",children:"No agents running"}),i.jsx("p",{className:"text-primary-wash text-xs mt-1",children:"Start a build to spawn agents"})]}),p.length>0&&i.jsx("div",{className:"space-y-2 mb-4",children:p.map(T=>i.jsx(Dd,{agent:T},T.id))}),o.length>0&&i.jsxs("details",{className:"mt-3",children:[i.jsxs("summary",{className:"text-xs text-slate cursor-pointer hover:text-charcoal transition-colors",children:[o.length," completed"]}),i.jsx("div",{className:"space-y-1.5 mt-2",children:o.slice(0,10).map(T=>i.jsx(Dd,{agent:T,compact:!0},T.id))})]})]})}function Dd({agent:f,compact:g}){const p=O0(f.type||f.name);return g?i.jsxs("div",{className:"flex items-center gap-2 px-2 py-1 rounded-lg bg-white/30 text-xs",children:[i.jsx("div",{className:"w-1.5 h-1.5 rounded-full bg-slate/30"}),i.jsx("span",{className:"font-medium text-slate truncate",children:f.name||f.id}),i.jsx("span",{className:"text-primary-wash ml-auto",children:f.type})]}):i.jsxs("div",{className:`flex items-start gap-3 px-3 py-2.5 rounded-xl border ${p}`,children:[i.jsx("div",{className:"flex-shrink-0 mt-0.5",children:i.jsx("div",{className:`w-2.5 h-2.5 rounded-full ${f.alive?"bg-success phase-active":"bg-slate/30"}`})}),i.jsxs("div",{className:"flex-1 min-w-0",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("span",{className:"text-sm font-semibold truncate",children:f.name||f.id}),f.type&&i.jsx("span",{className:"text-[10px] font-mono font-medium opacity-70",children:f.type})]}),f.task&&i.jsx("p",{className:"text-xs opacity-70 mt-0.5 truncate",children:f.task}),f.status&&f.status!=="unknown"&&i.jsx("span",{className:"inline-block text-[10px] font-mono mt-1 opacity-60",children:f.status})]}),f.pid&&i.jsxs("span",{className:"text-[10px] font-mono text-slate/50 flex-shrink-0",children:["PID ",f.pid]})]})}const U0={info:"text-primary-light",error:"text-danger",warning:"text-warning",debug:"text-slate",critical:"text-danger font-bold"};function C0(f){if(!f)return"";if(f.includes("T")||f.includes("-"))try{return new Date(f).toLocaleTimeString("en-US",{hour12:!1})}catch{return f}return f}function R0({logs:f,loading:g,subscribe:p}){const o=U.useRef(null),[T,M]=U.useState(!1),[R,L]=U.useState([]);U.useEffect(()=>p?p("log",Q=>{const ll=Q;ll!=null&&ll.line&&L(al=>{const F=[...al,{message:ll.line,timestamp:ll.timestamp||""}];return F.length>500?F.slice(-500):F})}):void 0,[p]);const D=(()=>{const O=R.map(F=>{let Nl="info";const xl=F.message.toLowerCase();return xl.includes("error")||xl.includes("fail")?Nl="error":xl.includes("warn")?Nl="warning":xl.includes("debug")&&(Nl="debug"),{timestamp:F.timestamp,level:Nl,message:F.message,source:"ws"}}),Q=f||[];if(O.length===0)return Q;if(Q.length===0)return O;const ll=new Set(O.map(F=>F.message));return[...Q.filter(F=>!ll.has(F.message)),...O]})();U.useEffect(()=>{!T&&o.current&&(o.current.scrollTop=o.current.scrollHeight)},[D,T]);const N=()=>{if(!o.current)return;const{scrollTop:O,scrollHeight:Q,clientHeight:ll}=o.current,al=Q-O-ll<50;M(!al)},q=()=>{var O;M(!1),(O=o.current)==null||O.scrollTo({top:o.current.scrollHeight,behavior:"smooth"})};return i.jsxs("div",{className:"glass p-0 overflow-hidden flex flex-col h-full",children:[i.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-white/10",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Terminal"}),i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsxs("span",{className:"font-mono text-xs text-slate",children:[D.length," lines"]}),i.jsx("button",{onClick:T?q:()=>M(!0),className:`text-xs font-medium px-2.5 py-1 rounded-lg border transition-colors ${T?"border-warning/40 text-warning bg-warning/5 hover:bg-warning/10":"border-primary/20 text-primary hover:bg-primary/5"}`,title:T?"Scroll locked -- click to resume auto-scroll":"Auto-scrolling -- click to lock",children:T?"Locked":"Live"}),T&&i.jsx("button",{onClick:q,className:"text-xs text-primary hover:text-primary-light transition-colors font-medium",children:"Jump to bottom"})]})]}),i.jsxs("div",{ref:o,onScroll:N,className:"flex-1 overflow-y-auto terminal-scroll bg-charcoal/[0.03] p-4 font-mono text-xs leading-relaxed min-h-[300px]",children:[g&&!f&&R.length===0&&i.jsx("div",{className:"text-slate animate-pulse",children:"Connecting to log stream..."}),D.length===0&&!g&&i.jsxs("div",{className:"text-slate/60",children:[i.jsx("p",{children:"No log output yet."}),i.jsx("p",{className:"mt-1",children:"Start a build to see terminal output here."})]}),D.map((O,Q)=>i.jsxs("div",{className:"flex gap-2 hover:bg-white/5 rounded px-1 -mx-1",children:[i.jsx("span",{className:"text-slate/40 flex-shrink-0 select-none w-16 text-right",children:C0(O.timestamp)}),i.jsx("span",{className:`flex-shrink-0 w-12 text-right uppercase text-[10px] font-semibold ${U0[O.level]||"text-slate"}`,children:O.level}),i.jsx("span",{className:`flex-1 break-all ${O.level==="error"||O.level==="critical"?"text-danger":"text-charcoal/80"}`,children:O.message})]},Q)),D.length>0&&i.jsx("div",{className:"terminal-cursor mt-1"})]})]})}const H0={pass:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Pass"},fail:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Fail"},skip:{badge:"bg-slate/10 text-slate border-slate/20",dot:"bg-slate/40",label:"Skip"},pending:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Pending"}};function B0({item:f}){const[g,p]=U.useState(!1),o=H0[f.status];return i.jsxs("div",{className:`border rounded-xl overflow-hidden ${o.badge}`,children:[i.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>f.details&&p(!g),children:[i.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${o.dot}`}),i.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:f.label}),i.jsx("span",{className:"text-[10px] font-mono font-semibold uppercase tracking-wider flex-shrink-0",children:o.label}),f.details&&i.jsx("span",{className:"text-xs text-slate/60 flex-shrink-0",children:g?"v":">"})]}),g&&f.details&&i.jsx("div",{className:"px-3 pb-2.5 pt-0",children:i.jsx("p",{className:"text-xs font-mono opacity-70 leading-relaxed",children:f.details})})]})}function q0({checklist:f,loading:g}){const p=f&&f.total>0?f.passed/f.total*100:0;return i.jsxs("div",{className:"glass p-6",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Quality Gates"}),f&&i.jsxs("span",{className:"font-mono text-xs text-slate",children:[f.passed,"/",f.total," passed"]})]}),g&&!f&&i.jsx("div",{className:"text-center py-8 text-slate text-sm",children:"Loading gates..."}),!g&&!f&&i.jsxs("div",{className:"text-center py-8",children:[i.jsx("p",{className:"text-slate text-sm",children:"No quality gate data"}),i.jsx("p",{className:"text-primary-wash text-xs mt-1",children:"Gates run during verification phase"})]}),f&&i.jsxs(i.Fragment,{children:[i.jsxs("div",{className:"flex items-center gap-4 mb-3 text-xs",children:[i.jsxs("span",{className:"text-success font-medium",children:[f.passed," passed"]}),f.failed>0&&i.jsxs("span",{className:"text-danger font-medium",children:[f.failed," failed"]}),f.skipped>0&&i.jsxs("span",{className:"text-slate",children:[f.skipped," skipped"]}),f.pending>0&&i.jsxs("span",{className:"text-warning",children:[f.pending," pending"]})]}),i.jsx("div",{className:"w-full h-2 bg-charcoal/10 rounded-full overflow-hidden mb-4",children:i.jsx("div",{className:"h-full bg-success rounded-full transition-all duration-500",style:{width:`${p}%`}})}),i.jsx("div",{className:"space-y-2 max-h-[400px] overflow-y-auto terminal-scroll",children:f.items.map(o=>i.jsx(B0,{item:o},o.id))})]})]})}const Y0={".py":"bg-success",".ts":"bg-primary",".tsx":"bg-primary",".md":"bg-warning",".sh":"bg-accent-product"};function G0(f){const g=f.substring(f.lastIndexOf("."));return Y0[g]||"bg-slate"}function w0(f){return f==null?"":f<1024?`${f}B`:f<1024*1024?`${(f/1024).toFixed(1)}KB`:`${(f/(1024*1024)).toFixed(1)}MB`}function Hd({node:f,depth:g,onSelectFile:p,selectedPath:o}){const[T,M]=U.useState(g===0),R=f.type==="directory",L=f.path===o;return i.jsxs("div",{children:[i.jsxs("button",{type:"button",className:`w-full flex items-center gap-2 px-2 py-1 rounded-lg text-left text-sm transition-colors hover:bg-white/30 ${L?"bg-primary/10 text-primary":"text-charcoal"}`,style:{paddingLeft:`${g*16+8}px`},onClick:()=>{R?M(!T):p(f.path)},children:[R?i.jsx("span",{className:"font-mono text-xs text-slate w-3 flex-shrink-0",children:T?"v":">"}):i.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${G0(f.name)}`}),i.jsx("span",{className:`truncate ${R?"font-medium":"font-mono text-xs"}`,children:f.name}),!R&&f.size!==void 0&&i.jsx("span",{className:"ml-auto text-[10px] font-mono text-slate/60 flex-shrink-0",children:w0(f.size)})]}),R&&T&&f.children&&i.jsx("div",{children:f.children.map(D=>i.jsx(Hd,{node:D,depth:g+1,onSelectFile:p,selectedPath:o},D.path))})]})}function Q0({files:f,loading:g}){const[p,o]=U.useState(null),[T,M]=U.useState(null),[R,L]=U.useState(!1),[D,N]=U.useState(null),q=U.useCallback(async Q=>{M(null),o(Q),L(!0),N(null);try{const ll=await ql.getFileContent(Q);M(ll.content)}catch(ll){const al=ll instanceof Error?ll.message:"Unknown error",F=ll instanceof TypeError||al==="Request timeout",Nl=al.includes("404")||al.includes("not found")||al.includes("Not found");N(F?"Network error - server may be unreachable":Nl?"File not found - it may have been deleted or renamed":al),M(null)}finally{L(!1)}},[]),O=U.useCallback(Q=>{q(Q)},[q]);return i.jsxs("div",{className:"glass p-6 flex flex-col",style:{minHeight:"300px"},children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"File Browser"}),i.jsx("span",{className:"font-mono text-xs text-slate",children:".loki/"})]}),g&&!f&&i.jsx("div",{className:"text-center py-8 text-slate text-sm",children:"Loading files..."}),!g&&(!f||f.length===0)&&i.jsxs("div",{className:"text-center py-8",children:[i.jsx("p",{className:"text-slate text-sm",children:"No project files found"}),i.jsx("p",{className:"text-primary-wash text-xs mt-1",children:"Start a session to generate .loki/ state"})]}),f&&f.length>0&&i.jsxs("div",{className:"flex gap-4 flex-1 min-h-0",children:[i.jsx("div",{className:"w-1/2 overflow-y-auto terminal-scroll pr-2",children:f.map(Q=>i.jsx(Hd,{node:Q,depth:0,onSelectFile:O,selectedPath:p},Q.path))}),i.jsxs("div",{className:"w-1/2 bg-charcoal/5 rounded-xl p-3 overflow-hidden flex flex-col",children:[!p&&i.jsx("div",{className:"flex-1 flex items-center justify-center text-slate text-xs",children:"Select a file to preview"}),p&&i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"text-xs font-mono text-primary mb-2 truncate",children:p}),i.jsx("div",{className:"flex-1 overflow-y-auto terminal-scroll",children:R?i.jsx("div",{className:"text-slate text-xs",children:"Loading..."}):D?i.jsxs("div",{className:"flex flex-col items-center justify-center gap-2 py-6",children:[i.jsx("p",{className:"text-danger text-xs font-medium",children:"Failed to load file"}),i.jsx("p",{className:"text-slate text-[10px] text-center max-w-[200px] break-words",children:D}),i.jsx("button",{type:"button",onClick:()=>p&&q(p),className:"mt-1 px-3 py-1 text-[10px] font-semibold rounded-lg border border-primary/20 text-primary hover:bg-primary/5 transition-colors",children:"Retry"})]}):i.jsx("pre",{className:"text-xs font-mono text-charcoal whitespace-pre-wrap break-words leading-relaxed",children:T})})]})]})]})]})}const Ud=5e5;function Cd(f){return f>=1e6?`${(f/1e6).toFixed(1)}M`:f>=1e3?`${(f/1e3).toFixed(1)}K`:f.toString()}function X0(f){if(!f)return"Never";try{const g=new Date(f),o=new Date().getTime()-g.getTime(),T=Math.floor(o/(1e3*60*60));return T<1?"Just now":T<24?`${T}h ago`:`${Math.floor(T/24)}d ago`}catch{return f}}function L0({memory:f,loading:g}){const p=f?[{label:"Episodic",count:f.episodic_count,color:"text-primary",bg:"bg-primary/10",border:"border-primary/20"},{label:"Semantic",count:f.semantic_count,color:"text-success",bg:"bg-success/10",border:"border-success/20"},{label:"Skills",count:f.skill_count,color:"text-warning",bg:"bg-warning/10",border:"border-warning/20"}]:[],o=f?Math.min(f.total_tokens/Ud*100,100):0;return i.jsxs("div",{className:"glass p-6",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Memory System"}),f&&i.jsx("span",{className:"font-mono text-xs text-slate",children:X0(f.last_consolidation)})]}),g&&!f&&i.jsx("div",{className:"text-center py-8 text-slate text-sm",children:"Loading memory..."}),!g&&!f&&i.jsxs("div",{className:"text-center py-8",children:[i.jsx("p",{className:"text-slate text-sm",children:"No memory data available"}),i.jsx("p",{className:"text-primary-wash text-xs mt-1",children:"Memory populates during autonomous runs"})]}),f&&i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"grid grid-cols-3 gap-3 mb-4",children:p.map(T=>i.jsxs("div",{className:`${T.bg} border ${T.border} rounded-xl p-3 text-center`,children:[i.jsx("div",{className:`text-2xl font-bold font-mono ${T.color}`,children:T.count}),i.jsx("div",{className:"text-[10px] text-slate font-medium mt-1 uppercase tracking-wider",children:T.label})]},T.label))}),i.jsxs("div",{className:"mt-3",children:[i.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[i.jsx("span",{className:"text-xs text-slate font-medium",children:"Token Usage"}),i.jsxs("span",{className:"text-xs font-mono text-charcoal",children:[Cd(f.total_tokens)," / ",Cd(Ud)]})]}),i.jsx("div",{className:"w-full h-2 bg-charcoal/10 rounded-full overflow-hidden",children:i.jsx("div",{className:`h-full rounded-full transition-all duration-500 ${o>80?"bg-danger":o>50?"bg-warning":"bg-primary-light"}`,style:{width:`${o}%`}})})]}),i.jsxs("div",{className:"mt-3 flex items-center justify-between text-xs",children:[i.jsx("span",{className:"text-slate",children:"Last Consolidation"}),i.jsx("span",{className:"font-mono text-charcoal",children:f.last_consolidation?new Date(f.last_consolidation).toLocaleString():"Never"})]})]})]})}function Z0({visible:f}){const[g,p]=U.useState("markdown"),[o,T]=U.useState(null),[M,R]=U.useState(null),[L,D]=U.useState(!1),[N,q]=U.useState(!1),[O,Q]=U.useState(null),[ll,al]=U.useState(!1);if(!f)return null;const F=async()=>{D(!0),Q(null),T(null),R(null);try{const J=await ql.generateReport(g);T(J)}catch(J){Q(J instanceof Error?J.message:"Failed to generate report")}finally{D(!1)}},Nl=async()=>{q(!0),Q(null);try{const J=await ql.shareSession();R(J)}catch(J){Q(J instanceof Error?J.message:"Failed to share session")}finally{q(!1)}},xl=async J=>{try{await navigator.clipboard.writeText(J),al(!0),setTimeout(()=>al(!1),2e3)}catch{}},gl=()=>{if(!o)return;const J=new Blob([o.content],{type:g==="html"?"text/html":"text/markdown"}),jl=URL.createObjectURL(J),Ol=document.createElement("a");Ol.href=jl,Ol.download=`loki-report.${g==="html"?"html":"md"}`,Ol.click(),URL.revokeObjectURL(jl)};return i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsxs("div",{className:"flex items-center justify-between mb-3",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Session Report"}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("div",{className:"flex items-center gap-1 glass-subtle rounded-xl p-1",children:["markdown","html"].map(J=>i.jsx("button",{onClick:()=>p(J),className:`px-3 py-1 text-xs font-semibold rounded-lg transition-all ${g===J?"bg-accent-product text-white shadow-sm":"text-slate hover:text-charcoal hover:bg-white/40"}`,children:J.toUpperCase()},J))}),i.jsx("button",{onClick:F,disabled:L,className:"px-4 py-1.5 rounded-xl text-xs font-semibold bg-accent-product text-white hover:bg-accent-product/90 disabled:opacity-50 transition-all",children:L?"Generating...":"Generate Report"})]})]}),O&&i.jsx("div",{className:"mb-3 px-3 py-2 rounded-lg bg-danger/10 border border-danger/20 text-danger text-xs",children:O}),o&&i.jsxs("div",{className:"mt-3",children:[i.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[i.jsxs("span",{className:"text-xs text-slate",children:["Report generated (",o.format,")"]}),i.jsx("div",{className:"flex-1"}),i.jsx("button",{onClick:()=>xl(o.content),className:"px-3 py-1 text-xs font-medium text-slate hover:text-charcoal border border-white/30 rounded-lg hover:bg-white/30 transition-all",children:ll?"Copied":"Copy"}),i.jsx("button",{onClick:gl,className:"px-3 py-1 text-xs font-medium text-slate hover:text-charcoal border border-white/30 rounded-lg hover:bg-white/30 transition-all",children:"Download"}),i.jsx("button",{onClick:Nl,disabled:N,className:"px-3 py-1 text-xs font-medium bg-accent-product/10 text-accent-product border border-accent-product/20 rounded-lg hover:bg-accent-product/20 disabled:opacity-50 transition-all",children:N?"Sharing...":"Share as Gist"})]}),M&&i.jsxs("div",{className:"mb-2 flex items-center gap-2 px-3 py-2 rounded-lg bg-success/10 border border-success/20",children:[i.jsx("span",{className:"text-xs text-success font-medium",children:"Shared:"}),M.url?i.jsx("a",{href:M.url,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-accent-product underline flex-1 truncate",children:M.url}):i.jsx("span",{className:"text-xs text-slate flex-1",children:"No URL returned"}),M.url&&i.jsx("button",{onClick:()=>xl(M.url),className:"text-xs text-slate hover:text-charcoal",children:"Copy URL"})]}),i.jsx("pre",{className:"text-[11px] font-mono text-charcoal bg-black/5 rounded-xl p-3 overflow-auto max-h-64 whitespace-pre-wrap terminal-scroll",children:o.content||"(empty report)"})]})]})}function Rd({visible:f}){const g=U.useCallback(()=>ql.getMetrics(),[]),{data:p,loading:o}=Ra(g,15e3,f);return f?i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsxs("div",{className:"flex items-center justify-between mb-3",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Session Metrics"}),o&&i.jsx("div",{className:"w-4 h-4 border-2 border-accent-product border-t-transparent rounded-full animate-spin"})]}),p?i.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[i.jsxs("div",{className:"glass-subtle rounded-xl p-3",children:[i.jsx("div",{className:"text-[10px] font-semibold text-slate uppercase tracking-wider mb-1",children:"Iterations"}),i.jsx("div",{className:"text-xl font-bold text-charcoal",children:p.iterations??0})]}),i.jsxs("div",{className:"glass-subtle rounded-xl p-3",children:[i.jsx("div",{className:"text-[10px] font-semibold text-slate uppercase tracking-wider mb-1",children:"Gate Pass Rate"}),i.jsx("div",{className:"text-xl font-bold text-charcoal",children:typeof p.quality_gate_pass_rate=="number"?`${p.quality_gate_pass_rate.toFixed(0)}%`:"N/A"})]}),i.jsxs("div",{className:"glass-subtle rounded-xl p-3",children:[i.jsx("div",{className:"text-[10px] font-semibold text-slate uppercase tracking-wider mb-1",children:"Tokens Used"}),i.jsx("div",{className:"text-xl font-bold text-charcoal",children:(p.tokens_used??0).toLocaleString()})]}),i.jsxs("div",{className:"glass-subtle rounded-xl p-3",children:[i.jsx("div",{className:"text-[10px] font-semibold text-slate uppercase tracking-wider mb-1",children:"Time Elapsed"}),i.jsx("div",{className:"text-xl font-bold text-charcoal",children:p.time_elapsed||"N/A"})]})]}):i.jsx("div",{className:"text-sm text-slate py-4 text-center",children:o?"Loading metrics...":"No metrics available"})]}):null}const V0={completed:{bg:"bg-success/10",text:"text-success",label:"Completed"},complete:{bg:"bg-success/10",text:"text-success",label:"Completed"},done:{bg:"bg-success/10",text:"text-success",label:"Completed"},in_progress:{bg:"bg-primary/10",text:"text-primary",label:"In Progress"},started:{bg:"bg-warning/10",text:"text-warning",label:"Started"},error:{bg:"bg-danger/10",text:"text-danger",label:"Failed"},failed:{bg:"bg-danger/10",text:"text-danger",label:"Failed"},empty:{bg:"bg-slate/10",text:"text-slate",label:"Empty"}};function K0(f){return V0[f]||{bg:"bg-slate/10",text:"text-slate",label:f}}function J0({onLoadSession:f}){const g=U.useCallback(()=>ql.getSessionsHistory(),[]),{data:p,loading:o}=Ra(g,6e4,!0);return o&&!p?i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider mb-3",children:"Past Builds"}),i.jsx("div",{className:"text-sm text-slate",children:"Loading..."})]}):!p||p.length===0?null:i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider mb-3",children:"Past Builds"}),i.jsx("div",{className:"flex flex-col gap-2 max-h-64 overflow-y-auto terminal-scroll",children:p.map(T=>{const M=K0(T.status),R=T.file_count;return i.jsxs("button",{onClick:()=>f==null?void 0:f(T),className:"text-left px-4 py-3 rounded-xl glass-subtle hover:bg-white/40 transition-all group cursor-pointer",children:[i.jsxs("div",{className:"flex items-center justify-between mb-1",children:[i.jsx("span",{className:"text-[10px] font-mono text-slate",children:T.date}),i.jsxs("div",{className:"flex items-center gap-2",children:[R!==void 0&&R>0&&i.jsxs("span",{className:"text-[10px] font-mono text-slate",children:[R," files"]}),i.jsx("span",{className:`text-[10px] font-semibold px-2 py-0.5 rounded-full ${M.bg} ${M.text}`,children:M.label})]})]}),i.jsx("div",{className:"text-xs text-charcoal truncate group-hover:text-accent-product transition-colors",children:T.prd_snippet||T.id}),i.jsx("div",{className:"text-[10px] font-mono text-slate/60 mt-0.5 truncate",children:T.path})]},T.id)})})]})}function k0(){const[f,g]=U.useState(null),[p,o]=U.useState(!1),[T,M]=U.useState(!1),[R,L]=U.useState(null),[D,N]=U.useState(!1),[q,O]=U.useState(!1),[Q,ll]=U.useState(!1),[al,F]=U.useState("terminal"),[Nl,xl]=U.useState("claude"),[gl,J]=U.useState(null),[jl,Ol]=U.useState(null),[Al,k]=U.useState(null),[Yl,wl]=U.useState(null),tt=U.useCallback(pl=>{if(!pl){Ol(null),k(null),wl(null);return}Ol(pl.status),k(pl.agents),wl(pl.logs),o(pl.status.running??!1),M(pl.status.paused??!1)},[]),{connected:Ql,subscribe:Xl}=p0(tt),ft=U.useCallback(()=>ql.getStatus(),[]),{data:Vl}=Ra(ft,3e4,!Ql);U.useEffect(()=>{jl===null&&Vl!==null&&(o(Vl.running??!1),M(Vl.paused??!1))},[Vl,jl]),U.useEffect(()=>{p&&N(!0)},[p]);const Pl=U.useCallback(()=>ql.getMemorySummary(),[]),S=U.useCallback(()=>ql.getChecklist(),[]),_=U.useCallback(()=>ql.getFiles(),[]),{data:G,loading:ul}=Ra(Pl,3e4,p),{data:ol,loading:m}=Ra(S,3e4,p),{data:A,loading:C}=Ra(_,3e4,p),H=jl??Vl,Z=Al,W=Yl,cl=Al===null,Kl=Yl===null,El=U.useCallback(async(pl,Yt,Hn,Ba)=>{g(null),N(!1),O(!1),F("terminal");try{await ql.startSession({prd:pl,provider:Yt,projectDir:Hn,mode:Ba}),L(pl)}catch($e){g($e instanceof Error?$e.message:"Failed to start session")}},[]),_e=U.useCallback(async()=>{try{(await ql.stopSession()).stopped&&(o(!1),M(!1),L(null),Ol(null),k(null),wl(null))}catch{o(!1),M(!1),L(null)}},[]),Je=U.useCallback(async pl=>{try{const Yt=await ql.getSessionDetail(pl.id);J(Yt)}catch{}},[]),ke=U.useCallback(pl=>{xl(pl)},[]),Rn=U.useCallback(async()=>{try{await ql.pauseSession(),M(!0)}catch{}},[]),qt=U.useCallback(async()=>{try{await ql.resumeSession(),M(!1)}catch{}},[]),Ha=R&&R.replace(/^#+\s*/gm,"").split(`
65
+ `)}},[]),Pl=async()=>{if(!(!M.trim()||tt)){Ql(!0),wl(null),ft(!0);try{const _=await ql.planSession(M,ll);wl(_)}catch{wl({complexity:"unknown",cost_estimate:"N/A",iterations:0,phases:[],output_text:"Failed to run loki plan. The CLI may not be available.",returncode:1})}finally{Ql(!1)}}},S=async()=>{if(!(!M.trim()||g||jl)){ft(!1),Ol(!0);try{await f(M,ll,O.trim()||void 0,Al?"quick":void 0)}finally{Ol(!1)}}};return i.jsxs(i.Fragment,{children:[Xl&&i.jsx(z0,{plan:Yl,loading:tt,onConfirm:S,onCancel:()=>ft(!1)}),i.jsxs("div",{className:"glass p-6 flex flex-col",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Product Requirements"}),i.jsx("div",{className:"flex items-center gap-2",children:i.jsxs("div",{className:"relative",children:[i.jsx("button",{onClick:()=>F(!al),className:"text-xs font-medium px-3 py-1.5 rounded-xl border border-primary/20 text-primary hover:bg-primary/5 transition-colors",children:L||"Templates"}),al&&i.jsx("div",{className:"absolute right-0 top-full mt-1 w-56 glass-subtle rounded-xl overflow-hidden z-20 shadow-glass",children:i.jsxs("div",{className:"py-1 max-h-64 overflow-y-auto terminal-scroll",children:[gl&&i.jsx("div",{className:"px-3 py-2 text-xs text-warning border-b border-warning/10",children:"Could not load templates from server. Check that the backend is running."}),!gl&&Nl.length===0&&i.jsx("div",{className:"px-3 py-2 text-xs text-slate",children:"Loading..."}),Nl.map(_=>i.jsx("button",{onClick:()=>Vl(_.filename,_.name),className:"w-full text-left px-3 py-2 text-sm text-charcoal hover:bg-primary/5 transition-colors",children:_.name},_.filename))]})})]})})]}),i.jsx("textarea",{value:M,onChange:_=>R(_.target.value),placeholder:"Paste your PRD here, or select a template above to get started...",className:"flex-1 min-h-[280px] w-full bg-white/40 rounded-xl border border-white/30 px-4 py-3 text-sm font-mono text-charcoal placeholder:text-primary-wash resize-none focus:outline-none focus:ring-2 focus:ring-accent-product/20 focus:border-accent-product/30 transition-all",spellCheck:!1}),i.jsxs("div",{className:"mt-3",children:[i.jsx("label",{className:"block text-xs text-slate font-medium mb-1 uppercase tracking-wider",children:"Project Directory"}),i.jsx("input",{type:"text",value:O,onChange:_=>Q(_.target.value),placeholder:"Leave blank to auto-create, or type a path (e.g. /Users/you/my-project)",className:"w-full bg-white/40 rounded-xl border border-white/30 px-4 py-2 text-sm font-mono text-charcoal placeholder:text-primary-wash/70 focus:outline-none focus:ring-2 focus:ring-accent-product/20 focus:border-accent-product/30 transition-all",spellCheck:!1}),i.jsx("p",{className:"text-[10px] text-slate mt-1",children:"Type a path or leave blank to auto-create under ~/purple-lab-projects/"})]}),p&&i.jsx("div",{className:"mt-3 px-3 py-2 rounded-lg bg-danger/10 border border-danger/20 text-danger text-xs font-medium",children:p}),i.jsxs("div",{className:"flex items-center gap-3 mt-4",children:[i.jsxs("button",{onClick:()=>k(!Al),title:"Quick Mode: 3 iterations max, faster builds",className:`flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-xs font-semibold border transition-all ${Al?"bg-accent-product/10 border-accent-product/30 text-accent-product":"border-white/30 text-slate hover:text-charcoal hover:bg-white/20"}`,children:[i.jsx("span",{className:`w-1.5 h-1.5 rounded-full ${Al?"bg-accent-product":"bg-slate/40"}`}),"Quick"]}),i.jsx("div",{className:"flex-1"}),i.jsxs("span",{className:"text-xs text-slate font-mono",children:[M.length.toLocaleString()," chars"]}),i.jsx("button",{onClick:Pl,disabled:!M.trim()||g||tt,className:`px-4 py-2.5 rounded-xl text-sm font-semibold border transition-all ${!M.trim()||g||tt?"border-white/20 text-slate/40 cursor-not-allowed":"border-accent-product/30 text-accent-product hover:bg-accent-product/5"}`,children:tt?"Analyzing...":"Estimate"}),i.jsx("button",{onClick:S,disabled:!M.trim()||g||jl,className:`px-6 py-2.5 rounded-xl text-sm font-semibold transition-all ${!M.trim()||g||jl?"bg-surface/50 text-slate cursor-not-allowed":"bg-accent-product text-white hover:bg-accent-product/90 shadow-glass-subtle"}`,children:jl?"Starting...":g?"Building...":"Start Build"})]})]})]})}const Cn=[{key:"reason",label:"Reason",description:"Analyzing task, planning approach"},{key:"act",label:"Act",description:"Implementing changes, writing code"},{key:"reflect",label:"Reflect",description:"Reviewing output, self-critique"},{key:"verify",label:"Verify",description:"Testing, validation, quality gates"}];function _0(f){const g=f.toLowerCase();return g.includes("reason")||g.includes("plan")?"reason":g.includes("act")||g.includes("implement")||g.includes("code")?"act":g.includes("reflect")||g.includes("review")?"reflect":g.includes("verify")||g.includes("test")||g.includes("check")?"verify":"idle"}function M0({currentPhase:f,iteration:g}){const p=_0(f);return i.jsxs("div",{className:"glass p-6",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"RARV Cycle"}),i.jsxs("span",{className:"font-mono text-xs text-slate",children:["Iteration ",g]})]}),i.jsx("div",{className:"flex items-center justify-center mb-5",children:i.jsxs("svg",{viewBox:"0 0 120 120",className:"w-28 h-28",children:[Cn.map((o,T)=>{const M=o.key===p,R=p!=="idle"&&Cn.findIndex(q=>q.key===p)>T,L=(T*90-90)*(Math.PI/180),D=60+40*Math.cos(L),N=60+40*Math.sin(L);return i.jsxs("g",{children:[T<Cn.length-1&&i.jsx("line",{x1:D,y1:N,x2:60+40*Math.cos(((T+1)*90-90)*(Math.PI/180)),y2:60+40*Math.sin(((T+1)*90-90)*(Math.PI/180)),stroke:R?"#3D52A0":"#ADBBDA",strokeWidth:R?2:1,strokeDasharray:R?"none":"4 3"}),T===Cn.length-1&&i.jsx("line",{x1:D,y1:N,x2:60+40*Math.cos(-90*(Math.PI/180)),y2:60+40*Math.sin(-90*(Math.PI/180)),stroke:"#ADBBDA",strokeWidth:1,strokeDasharray:"4 3"}),i.jsx("circle",{cx:D,cy:N,r:M?14:10,fill:M?"#3D52A0":R?"#7091E6":"#EDE8F5",stroke:M?"#6C63FF":R?"#3D52A0":"#ADBBDA",strokeWidth:M?3:1.5,className:M?"phase-active":""}),i.jsx("text",{x:D,y:N+(T===0?-20:T===2?24:0),textAnchor:"middle",className:"text-[9px] font-semibold fill-charcoal",dx:T===1?22:T===3?-22:0,children:o.label[0]})]},o.key)}),i.jsx("text",{x:"60",y:"64",textAnchor:"middle",className:"text-lg font-bold font-mono fill-primary",children:g})]})}),i.jsx("div",{className:"space-y-2",children:Cn.map(o=>{const T=o.key===p;return i.jsxs("div",{className:`flex items-center gap-3 px-3 py-2 rounded-xl transition-all duration-200 ${T?"bg-primary/8 border border-primary/20":"opacity-50"}`,children:[i.jsx("div",{className:`w-2.5 h-2.5 rounded-full flex-shrink-0 ${T?"bg-primary phase-active":"bg-surface"}`}),i.jsxs("div",{children:[i.jsx("span",{className:`text-sm font-semibold ${T?"text-primary":"text-slate"}`,children:o.label}),T&&i.jsx("p",{className:"text-xs text-slate mt-0.5",children:o.description})]})]},o.key)})})]})}const Od={architect:"bg-accent-product/10 text-accent-product border-accent-product/20",developer:"bg-primary/10 text-primary border-primary/20",tester:"bg-success/10 text-success border-success/20",reviewer:"bg-warning/10 text-warning border-warning/20",planner:"bg-primary-wash/20 text-charcoal border-primary-wash/30",default:"bg-surface/30 text-slate border-surface/50"};function O0(f){const g=f.toLowerCase();for(const[p,o]of Object.entries(Od))if(g.includes(p))return o;return Od.default}function D0({agents:f,loading:g}){const p=(f==null?void 0:f.filter(T=>T.alive))||[],o=(f==null?void 0:f.filter(T=>!T.alive))||[];return i.jsxs("div",{className:"glass p-6",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Agents"}),i.jsxs("span",{className:"font-mono text-xs text-slate",children:[p.length," active"]})]}),g&&!f&&i.jsx("div",{className:"text-center py-8 text-slate text-sm",children:"Loading agents..."}),!g&&(f==null?void 0:f.length)===0&&i.jsxs("div",{className:"text-center py-8",children:[i.jsx("p",{className:"text-slate text-sm",children:"No agents running"}),i.jsx("p",{className:"text-primary-wash text-xs mt-1",children:"Start a build to spawn agents"})]}),p.length>0&&i.jsx("div",{className:"space-y-2 mb-4",children:p.map(T=>i.jsx(Dd,{agent:T},T.id))}),o.length>0&&i.jsxs("details",{className:"mt-3",children:[i.jsxs("summary",{className:"text-xs text-slate cursor-pointer hover:text-charcoal transition-colors",children:[o.length," completed"]}),i.jsx("div",{className:"space-y-1.5 mt-2",children:o.slice(0,10).map(T=>i.jsx(Dd,{agent:T,compact:!0},T.id))})]})]})}function Dd({agent:f,compact:g}){const p=O0(f.type||f.name);return g?i.jsxs("div",{className:"flex items-center gap-2 px-2 py-1 rounded-lg bg-white/30 text-xs",children:[i.jsx("div",{className:"w-1.5 h-1.5 rounded-full bg-slate/30"}),i.jsx("span",{className:"font-medium text-slate truncate",children:f.name||f.id}),i.jsx("span",{className:"text-primary-wash ml-auto",children:f.type})]}):i.jsxs("div",{className:`flex items-start gap-3 px-3 py-2.5 rounded-xl border ${p}`,children:[i.jsx("div",{className:"flex-shrink-0 mt-0.5",children:i.jsx("div",{className:`w-2.5 h-2.5 rounded-full ${f.alive?"bg-success phase-active":"bg-slate/30"}`})}),i.jsxs("div",{className:"flex-1 min-w-0",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("span",{className:"text-sm font-semibold truncate",children:f.name||f.id}),f.type&&i.jsx("span",{className:"text-[10px] font-mono font-medium opacity-70",children:f.type})]}),f.task&&i.jsx("p",{className:"text-xs opacity-70 mt-0.5 truncate",children:f.task}),f.status&&f.status!=="unknown"&&i.jsx("span",{className:"inline-block text-[10px] font-mono mt-1 opacity-60",children:f.status})]}),f.pid&&i.jsxs("span",{className:"text-[10px] font-mono text-slate/50 flex-shrink-0",children:["PID ",f.pid]})]})}const U0={info:"text-primary-light",error:"text-danger",warning:"text-warning",debug:"text-slate",critical:"text-danger font-bold"};function C0(f){if(!f)return"";if(f.includes("T")||f.includes("-"))try{return new Date(f).toLocaleTimeString("en-US",{hour12:!1})}catch{return f}return f}function R0({logs:f,loading:g,subscribe:p}){const o=U.useRef(null),[T,M]=U.useState(!1),[R,L]=U.useState([]);U.useEffect(()=>p?p("log",Q=>{const ll=Q;ll!=null&&ll.line&&L(al=>{const F=[...al,{message:ll.line,timestamp:ll.timestamp||""}];return F.length>500?F.slice(-500):F})}):void 0,[p]);const D=(()=>{const O=R.map(F=>{let Nl="info";const xl=F.message.toLowerCase();return xl.includes("error")||xl.includes("fail")?Nl="error":xl.includes("warn")?Nl="warning":xl.includes("debug")&&(Nl="debug"),{timestamp:F.timestamp,level:Nl,message:F.message,source:"ws"}}),Q=f||[];if(O.length===0)return Q;if(Q.length===0)return O;const ll=new Set(O.map(F=>F.message));return[...Q.filter(F=>!ll.has(F.message)),...O]})();U.useEffect(()=>{!T&&o.current&&(o.current.scrollTop=o.current.scrollHeight)},[D,T]);const N=()=>{if(!o.current)return;const{scrollTop:O,scrollHeight:Q,clientHeight:ll}=o.current,al=Q-O-ll<50;M(!al)},q=()=>{var O;M(!1),(O=o.current)==null||O.scrollTo({top:o.current.scrollHeight,behavior:"smooth"})};return i.jsxs("div",{className:"glass p-0 overflow-hidden flex flex-col h-full",children:[i.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-white/10",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Terminal"}),i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsxs("span",{className:"font-mono text-xs text-slate",children:[D.length," lines"]}),i.jsx("button",{onClick:T?q:()=>M(!0),className:`text-xs font-medium px-2.5 py-1 rounded-lg border transition-colors ${T?"border-warning/40 text-warning bg-warning/5 hover:bg-warning/10":"border-primary/20 text-primary hover:bg-primary/5"}`,title:T?"Scroll locked -- click to resume auto-scroll":"Auto-scrolling -- click to lock",children:T?"Locked":"Live"}),T&&i.jsx("button",{onClick:q,className:"text-xs text-primary hover:text-primary-light transition-colors font-medium",children:"Jump to bottom"})]})]}),i.jsxs("div",{ref:o,onScroll:N,className:"flex-1 overflow-y-auto terminal-scroll bg-charcoal/[0.03] p-4 font-mono text-xs leading-relaxed min-h-[300px]",children:[g&&!f&&R.length===0&&i.jsx("div",{className:"text-slate animate-pulse",children:"Connecting to log stream..."}),D.length===0&&!g&&i.jsxs("div",{className:"text-slate/60",children:[i.jsx("p",{children:"No log output yet."}),i.jsx("p",{className:"mt-1",children:"Start a build to see terminal output here."})]}),D.map((O,Q)=>i.jsxs("div",{className:"flex gap-2 hover:bg-white/5 rounded px-1 -mx-1",children:[i.jsx("span",{className:"text-slate/40 flex-shrink-0 select-none w-16 text-right",children:C0(O.timestamp)}),i.jsx("span",{className:`flex-shrink-0 w-12 text-right uppercase text-[10px] font-semibold ${U0[O.level]||"text-slate"}`,children:O.level}),i.jsx("span",{className:`flex-1 break-all ${O.level==="error"||O.level==="critical"?"text-danger":"text-charcoal/80"}`,children:O.message})]},Q)),D.length>0&&i.jsx("div",{className:"terminal-cursor mt-1"})]})]})}const H0={pass:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Pass"},fail:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Fail"},skip:{badge:"bg-slate/10 text-slate border-slate/20",dot:"bg-slate/40",label:"Skip"},pending:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Pending"}};function B0({item:f}){const[g,p]=U.useState(!1),o=H0[f.status];return i.jsxs("div",{className:`border rounded-xl overflow-hidden ${o.badge}`,children:[i.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>f.details&&p(!g),children:[i.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${o.dot}`}),i.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:f.label}),i.jsx("span",{className:"text-[10px] font-mono font-semibold uppercase tracking-wider flex-shrink-0",children:o.label}),f.details&&i.jsx("span",{className:"text-xs text-slate/60 flex-shrink-0",children:g?"v":">"})]}),g&&f.details&&i.jsx("div",{className:"px-3 pb-2.5 pt-0",children:i.jsx("p",{className:"text-xs font-mono opacity-70 leading-relaxed",children:f.details})})]})}function q0({checklist:f,loading:g}){const p=f&&f.total>0?f.passed/f.total*100:0;return i.jsxs("div",{className:"glass p-6",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Quality Gates"}),f&&i.jsxs("span",{className:"font-mono text-xs text-slate",children:[f.passed,"/",f.total," passed"]})]}),g&&!f&&i.jsx("div",{className:"text-center py-8 text-slate text-sm",children:"Loading gates..."}),!g&&!f&&i.jsxs("div",{className:"text-center py-8",children:[i.jsx("p",{className:"text-slate text-sm",children:"No quality gate data"}),i.jsx("p",{className:"text-primary-wash text-xs mt-1",children:"Gates run during verification phase"})]}),f&&i.jsxs(i.Fragment,{children:[i.jsxs("div",{className:"flex items-center gap-4 mb-3 text-xs",children:[i.jsxs("span",{className:"text-success font-medium",children:[f.passed," passed"]}),f.failed>0&&i.jsxs("span",{className:"text-danger font-medium",children:[f.failed," failed"]}),f.skipped>0&&i.jsxs("span",{className:"text-slate",children:[f.skipped," skipped"]}),f.pending>0&&i.jsxs("span",{className:"text-warning",children:[f.pending," pending"]})]}),i.jsx("div",{className:"w-full h-2 bg-charcoal/10 rounded-full overflow-hidden mb-4",children:i.jsx("div",{className:"h-full bg-success rounded-full transition-all duration-500",style:{width:`${p}%`}})}),i.jsx("div",{className:"space-y-2 max-h-[400px] overflow-y-auto terminal-scroll",children:f.items.map(o=>i.jsx(B0,{item:o},o.id))})]})]})}const Y0={".py":"bg-success",".ts":"bg-primary",".tsx":"bg-primary",".md":"bg-warning",".sh":"bg-accent-product"};function G0(f){const g=f.substring(f.lastIndexOf("."));return Y0[g]||"bg-slate"}function w0(f){return f==null?"":f<1024?`${f}B`:f<1024*1024?`${(f/1024).toFixed(1)}KB`:`${(f/(1024*1024)).toFixed(1)}MB`}function Hd({node:f,depth:g,onSelectFile:p,selectedPath:o}){const[T,M]=U.useState(!1),R=f.type==="directory",L=f.path===o;return i.jsxs("div",{children:[i.jsxs("button",{type:"button",className:`w-full flex items-center gap-2 px-2 py-1 rounded-lg text-left text-sm transition-colors hover:bg-white/30 ${L?"bg-primary/10 text-primary":"text-charcoal"}`,style:{paddingLeft:`${g*16+8}px`},onClick:()=>{R?M(!T):p(f.path)},children:[R?i.jsx("span",{className:"font-mono text-xs text-slate w-3 flex-shrink-0",children:T?"v":">"}):i.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${G0(f.name)}`}),i.jsx("span",{className:`truncate ${R?"font-medium":"font-mono text-xs"}`,children:f.name}),!R&&f.size!==void 0&&i.jsx("span",{className:"ml-auto text-[10px] font-mono text-slate/60 flex-shrink-0",children:w0(f.size)})]}),R&&T&&f.children&&f.children.length>0&&i.jsx("div",{children:f.children.map(D=>i.jsx(Hd,{node:D,depth:g+1,onSelectFile:p,selectedPath:o},D.path))})]})}function Q0({files:f,loading:g}){const[p,o]=U.useState(null),[T,M]=U.useState(null),[R,L]=U.useState(!1),[D,N]=U.useState(null),q=U.useCallback(async Q=>{M(null),o(Q),L(!0),N(null);try{const ll=await ql.getFileContent(Q);M(ll.content)}catch(ll){const al=ll instanceof Error?ll.message:"Unknown error",F=ll instanceof TypeError||al==="Request timeout",Nl=al.includes("404")||al.includes("not found")||al.includes("Not found");N(F?"Network error - server may be unreachable":Nl?"File not found - it may have been deleted or renamed":al),M(null)}finally{L(!1)}},[]),O=U.useCallback(Q=>{q(Q)},[q]);return i.jsxs("div",{className:"glass p-6 flex flex-col",style:{minHeight:"300px"},children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"File Browser"}),i.jsx("span",{className:"font-mono text-xs text-slate",children:".loki/"})]}),g&&!f&&i.jsx("div",{className:"text-center py-8 text-slate text-sm",children:"Loading files..."}),!g&&(!f||f.length===0)&&i.jsxs("div",{className:"text-center py-8",children:[i.jsx("p",{className:"text-slate text-sm",children:"No project files found"}),i.jsx("p",{className:"text-primary-wash text-xs mt-1",children:"Start a session to generate .loki/ state"})]}),f&&f.length>0&&i.jsxs("div",{className:"flex gap-4 flex-1 min-h-0",children:[i.jsx("div",{className:"w-1/2 overflow-y-auto terminal-scroll pr-2",children:f.map(Q=>i.jsx(Hd,{node:Q,depth:0,onSelectFile:O,selectedPath:p},Q.path))}),i.jsxs("div",{className:"w-1/2 bg-charcoal/5 rounded-xl p-3 overflow-hidden flex flex-col",children:[!p&&i.jsx("div",{className:"flex-1 flex items-center justify-center text-slate text-xs",children:"Select a file to preview"}),p&&i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"text-xs font-mono text-primary mb-2 truncate",children:p}),i.jsx("div",{className:"flex-1 overflow-y-auto terminal-scroll",children:R?i.jsx("div",{className:"text-slate text-xs",children:"Loading..."}):D?i.jsxs("div",{className:"flex flex-col items-center justify-center gap-2 py-6",children:[i.jsx("p",{className:"text-danger text-xs font-medium",children:"Failed to load file"}),i.jsx("p",{className:"text-slate text-[10px] text-center max-w-[200px] break-words",children:D}),i.jsx("button",{type:"button",onClick:()=>p&&q(p),className:"mt-1 px-3 py-1 text-[10px] font-semibold rounded-lg border border-primary/20 text-primary hover:bg-primary/5 transition-colors",children:"Retry"})]}):i.jsx("pre",{className:"text-xs font-mono text-charcoal whitespace-pre-wrap break-words leading-relaxed",children:T})})]})]})]})]})}const Ud=5e5;function Cd(f){return f>=1e6?`${(f/1e6).toFixed(1)}M`:f>=1e3?`${(f/1e3).toFixed(1)}K`:f.toString()}function X0(f){if(!f)return"Never";try{const g=new Date(f),o=new Date().getTime()-g.getTime(),T=Math.floor(o/(1e3*60*60));return T<1?"Just now":T<24?`${T}h ago`:`${Math.floor(T/24)}d ago`}catch{return f}}function L0({memory:f,loading:g}){const p=f?[{label:"Episodic",count:f.episodic_count,color:"text-primary",bg:"bg-primary/10",border:"border-primary/20"},{label:"Semantic",count:f.semantic_count,color:"text-success",bg:"bg-success/10",border:"border-success/20"},{label:"Skills",count:f.skill_count,color:"text-warning",bg:"bg-warning/10",border:"border-warning/20"}]:[],o=f?Math.min(f.total_tokens/Ud*100,100):0;return i.jsxs("div",{className:"glass p-6",children:[i.jsxs("div",{className:"flex items-center justify-between mb-4",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Memory System"}),f&&i.jsx("span",{className:"font-mono text-xs text-slate",children:X0(f.last_consolidation)})]}),g&&!f&&i.jsx("div",{className:"text-center py-8 text-slate text-sm",children:"Loading memory..."}),!g&&!f&&i.jsxs("div",{className:"text-center py-8",children:[i.jsx("p",{className:"text-slate text-sm",children:"No memory data available"}),i.jsx("p",{className:"text-primary-wash text-xs mt-1",children:"Memory populates during autonomous runs"})]}),f&&i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"grid grid-cols-3 gap-3 mb-4",children:p.map(T=>i.jsxs("div",{className:`${T.bg} border ${T.border} rounded-xl p-3 text-center`,children:[i.jsx("div",{className:`text-2xl font-bold font-mono ${T.color}`,children:T.count}),i.jsx("div",{className:"text-[10px] text-slate font-medium mt-1 uppercase tracking-wider",children:T.label})]},T.label))}),i.jsxs("div",{className:"mt-3",children:[i.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[i.jsx("span",{className:"text-xs text-slate font-medium",children:"Token Usage"}),i.jsxs("span",{className:"text-xs font-mono text-charcoal",children:[Cd(f.total_tokens)," / ",Cd(Ud)]})]}),i.jsx("div",{className:"w-full h-2 bg-charcoal/10 rounded-full overflow-hidden",children:i.jsx("div",{className:`h-full rounded-full transition-all duration-500 ${o>80?"bg-danger":o>50?"bg-warning":"bg-primary-light"}`,style:{width:`${o}%`}})})]}),i.jsxs("div",{className:"mt-3 flex items-center justify-between text-xs",children:[i.jsx("span",{className:"text-slate",children:"Last Consolidation"}),i.jsx("span",{className:"font-mono text-charcoal",children:f.last_consolidation?new Date(f.last_consolidation).toLocaleString():"Never"})]})]})]})}function Z0({visible:f}){const[g,p]=U.useState("markdown"),[o,T]=U.useState(null),[M,R]=U.useState(null),[L,D]=U.useState(!1),[N,q]=U.useState(!1),[O,Q]=U.useState(null),[ll,al]=U.useState(!1);if(!f)return null;const F=async()=>{D(!0),Q(null),T(null),R(null);try{const J=await ql.generateReport(g);T(J)}catch(J){Q(J instanceof Error?J.message:"Failed to generate report")}finally{D(!1)}},Nl=async()=>{q(!0),Q(null);try{const J=await ql.shareSession();R(J)}catch(J){Q(J instanceof Error?J.message:"Failed to share session")}finally{q(!1)}},xl=async J=>{try{await navigator.clipboard.writeText(J),al(!0),setTimeout(()=>al(!1),2e3)}catch{}},gl=()=>{if(!o)return;const J=new Blob([o.content],{type:g==="html"?"text/html":"text/markdown"}),jl=URL.createObjectURL(J),Ol=document.createElement("a");Ol.href=jl,Ol.download=`loki-report.${g==="html"?"html":"md"}`,Ol.click(),URL.revokeObjectURL(jl)};return i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsxs("div",{className:"flex items-center justify-between mb-3",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Session Report"}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("div",{className:"flex items-center gap-1 glass-subtle rounded-xl p-1",children:["markdown","html"].map(J=>i.jsx("button",{onClick:()=>p(J),className:`px-3 py-1 text-xs font-semibold rounded-lg transition-all ${g===J?"bg-accent-product text-white shadow-sm":"text-slate hover:text-charcoal hover:bg-white/40"}`,children:J.toUpperCase()},J))}),i.jsx("button",{onClick:F,disabled:L,className:"px-4 py-1.5 rounded-xl text-xs font-semibold bg-accent-product text-white hover:bg-accent-product/90 disabled:opacity-50 transition-all",children:L?"Generating...":"Generate Report"})]})]}),O&&i.jsx("div",{className:"mb-3 px-3 py-2 rounded-lg bg-danger/10 border border-danger/20 text-danger text-xs",children:O}),o&&i.jsxs("div",{className:"mt-3",children:[i.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[i.jsxs("span",{className:"text-xs text-slate",children:["Report generated (",o.format,")"]}),i.jsx("div",{className:"flex-1"}),i.jsx("button",{onClick:()=>xl(o.content),className:"px-3 py-1 text-xs font-medium text-slate hover:text-charcoal border border-white/30 rounded-lg hover:bg-white/30 transition-all",children:ll?"Copied":"Copy"}),i.jsx("button",{onClick:gl,className:"px-3 py-1 text-xs font-medium text-slate hover:text-charcoal border border-white/30 rounded-lg hover:bg-white/30 transition-all",children:"Download"}),i.jsx("button",{onClick:Nl,disabled:N,className:"px-3 py-1 text-xs font-medium bg-accent-product/10 text-accent-product border border-accent-product/20 rounded-lg hover:bg-accent-product/20 disabled:opacity-50 transition-all",children:N?"Sharing...":"Share as Gist"})]}),M&&i.jsxs("div",{className:"mb-2 flex items-center gap-2 px-3 py-2 rounded-lg bg-success/10 border border-success/20",children:[i.jsx("span",{className:"text-xs text-success font-medium",children:"Shared:"}),M.url?i.jsx("a",{href:M.url,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-accent-product underline flex-1 truncate",children:M.url}):i.jsx("span",{className:"text-xs text-slate flex-1",children:"No URL returned"}),M.url&&i.jsx("button",{onClick:()=>xl(M.url),className:"text-xs text-slate hover:text-charcoal",children:"Copy URL"})]}),i.jsx("pre",{className:"text-[11px] font-mono text-charcoal bg-black/5 rounded-xl p-3 overflow-auto max-h-64 whitespace-pre-wrap terminal-scroll",children:o.content||"(empty report)"})]})]})}function Rd({visible:f}){const g=U.useCallback(()=>ql.getMetrics(),[]),{data:p,loading:o}=Ra(g,15e3,f);return f?i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsxs("div",{className:"flex items-center justify-between mb-3",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:"Session Metrics"}),o&&i.jsx("div",{className:"w-4 h-4 border-2 border-accent-product border-t-transparent rounded-full animate-spin"})]}),p?i.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[i.jsxs("div",{className:"glass-subtle rounded-xl p-3",children:[i.jsx("div",{className:"text-[10px] font-semibold text-slate uppercase tracking-wider mb-1",children:"Iterations"}),i.jsx("div",{className:"text-xl font-bold text-charcoal",children:p.iterations??0})]}),i.jsxs("div",{className:"glass-subtle rounded-xl p-3",children:[i.jsx("div",{className:"text-[10px] font-semibold text-slate uppercase tracking-wider mb-1",children:"Gate Pass Rate"}),i.jsx("div",{className:"text-xl font-bold text-charcoal",children:typeof p.quality_gate_pass_rate=="number"?`${p.quality_gate_pass_rate.toFixed(0)}%`:"N/A"})]}),i.jsxs("div",{className:"glass-subtle rounded-xl p-3",children:[i.jsx("div",{className:"text-[10px] font-semibold text-slate uppercase tracking-wider mb-1",children:"Tokens Used"}),i.jsx("div",{className:"text-xl font-bold text-charcoal",children:(p.tokens_used??0).toLocaleString()})]}),i.jsxs("div",{className:"glass-subtle rounded-xl p-3",children:[i.jsx("div",{className:"text-[10px] font-semibold text-slate uppercase tracking-wider mb-1",children:"Time Elapsed"}),i.jsx("div",{className:"text-xl font-bold text-charcoal",children:p.time_elapsed||"N/A"})]})]}):i.jsx("div",{className:"text-sm text-slate py-4 text-center",children:o?"Loading metrics...":"No metrics available"})]}):null}const V0={completed:{bg:"bg-success/10",text:"text-success",label:"Completed"},complete:{bg:"bg-success/10",text:"text-success",label:"Completed"},done:{bg:"bg-success/10",text:"text-success",label:"Completed"},in_progress:{bg:"bg-primary/10",text:"text-primary",label:"In Progress"},started:{bg:"bg-warning/10",text:"text-warning",label:"Started"},error:{bg:"bg-danger/10",text:"text-danger",label:"Failed"},failed:{bg:"bg-danger/10",text:"text-danger",label:"Failed"},empty:{bg:"bg-slate/10",text:"text-slate",label:"Empty"}};function K0(f){return V0[f]||{bg:"bg-slate/10",text:"text-slate",label:f}}function J0({onLoadSession:f}){const g=U.useCallback(()=>ql.getSessionsHistory(),[]),{data:p,loading:o}=Ra(g,6e4,!0);return o&&!p?i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider mb-3",children:"Past Builds"}),i.jsx("div",{className:"text-sm text-slate",children:"Loading..."})]}):!p||p.length===0?null:i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsx("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider mb-3",children:"Past Builds"}),i.jsx("div",{className:"flex flex-col gap-2 max-h-64 overflow-y-auto terminal-scroll",children:p.map(T=>{const M=K0(T.status),R=T.file_count;return i.jsxs("button",{onClick:()=>f==null?void 0:f(T),className:"text-left px-4 py-3 rounded-xl glass-subtle hover:bg-white/40 transition-all group cursor-pointer",children:[i.jsxs("div",{className:"flex items-center justify-between mb-1",children:[i.jsx("span",{className:"text-[10px] font-mono text-slate",children:T.date}),i.jsxs("div",{className:"flex items-center gap-2",children:[R!==void 0&&R>0&&i.jsxs("span",{className:"text-[10px] font-mono text-slate",children:[R," files"]}),i.jsx("span",{className:`text-[10px] font-semibold px-2 py-0.5 rounded-full ${M.bg} ${M.text}`,children:M.label})]})]}),i.jsx("div",{className:"text-xs text-charcoal truncate group-hover:text-accent-product transition-colors",children:T.prd_snippet||T.id}),i.jsx("div",{className:"text-[10px] font-mono text-slate/60 mt-0.5 truncate",children:T.path})]},T.id)})})]})}function k0(){const[f,g]=U.useState(null),[p,o]=U.useState(!1),[T,M]=U.useState(!1),[R,L]=U.useState(null),[D,N]=U.useState(!1),[q,O]=U.useState(!1),[Q,ll]=U.useState(!1),[al,F]=U.useState("terminal"),[Nl,xl]=U.useState("claude"),[gl,J]=U.useState(null),[jl,Ol]=U.useState(null),[Al,k]=U.useState(null),[Yl,wl]=U.useState(null),tt=U.useCallback(pl=>{if(!pl){Ol(null),k(null),wl(null);return}Ol(pl.status),k(pl.agents),wl(pl.logs),o(pl.status.running??!1),M(pl.status.paused??!1)},[]),{connected:Ql,subscribe:Xl}=p0(tt),ft=U.useCallback(()=>ql.getStatus(),[]),{data:Vl}=Ra(ft,3e4,!Ql);U.useEffect(()=>{jl===null&&Vl!==null&&(o(Vl.running??!1),M(Vl.paused??!1))},[Vl,jl]),U.useEffect(()=>{p&&N(!0)},[p]);const Pl=U.useCallback(()=>ql.getMemorySummary(),[]),S=U.useCallback(()=>ql.getChecklist(),[]),_=U.useCallback(()=>ql.getFiles(),[]),{data:G,loading:ul}=Ra(Pl,3e4,p),{data:ol,loading:m}=Ra(S,3e4,p),{data:A,loading:C}=Ra(_,3e4,p),H=jl??Vl,Z=Al,W=Yl,cl=Al===null,Kl=Yl===null,El=U.useCallback(async(pl,Yt,Hn,Ba)=>{g(null),N(!1),O(!1),F("terminal");try{await ql.startSession({prd:pl,provider:Yt,projectDir:Hn,mode:Ba}),L(pl)}catch($e){g($e instanceof Error?$e.message:"Failed to start session")}},[]),_e=U.useCallback(async()=>{try{(await ql.stopSession()).stopped&&(o(!1),M(!1),L(null),Ol(null),k(null),wl(null))}catch{o(!1),M(!1),L(null)}},[]),Je=U.useCallback(async pl=>{try{const Yt=await ql.getSessionDetail(pl.id);J(Yt)}catch{}},[]),ke=U.useCallback(pl=>{xl(pl)},[]),Rn=U.useCallback(async()=>{try{await ql.pauseSession(),M(!0)}catch{}},[]),qt=U.useCallback(async()=>{try{await ql.resumeSession(),M(!1)}catch{}},[]),Ha=R&&R.replace(/^#+\s*/gm,"").split(`
66
66
  `).find(pl=>pl.trim().length>0)||null;return i.jsxs("div",{className:"min-h-screen bg-background relative",children:[i.jsx("div",{className:"pattern-circles"}),i.jsx(S0,{status:H,wsConnected:Ql,onProviderChange:ke,selectedProvider:Nl}),i.jsx("main",{className:"max-w-[1920px] mx-auto px-6 py-6 relative z-10",children:p?i.jsxs(i.Fragment,{children:[i.jsx(T0,{status:H,prdSummary:Ha,onStop:_e,onPause:Rn,onResume:qt,isPaused:T}),i.jsx("div",{className:"mt-4",children:i.jsx(E0,{status:H})}),i.jsxs("div",{className:"mt-4 grid grid-cols-12 gap-6",style:{minHeight:"calc(100vh - 340px)"},children:[i.jsx("div",{className:"col-span-3 flex flex-col gap-6",children:i.jsx(M0,{currentPhase:(H==null?void 0:H.phase)||"idle",iteration:(H==null?void 0:H.iteration)||0})}),i.jsxs("div",{className:"col-span-5 flex flex-col gap-0",children:[i.jsxs("div",{className:"flex items-center gap-1 mb-2",children:[i.jsx("button",{onClick:()=>F("terminal"),className:`px-3 py-1.5 text-xs font-semibold rounded-lg transition-all ${al==="terminal"?"bg-accent-product text-white":"text-slate hover:text-charcoal hover:bg-white/30"}`,children:"Terminal"}),i.jsx("button",{onClick:()=>F("metrics"),className:`px-3 py-1.5 text-xs font-semibold rounded-lg transition-all ${al==="metrics"?"bg-accent-product text-white":"text-slate hover:text-charcoal hover:bg-white/30"}`,children:"Metrics"})]}),al==="terminal"?i.jsx(R0,{logs:W,loading:Kl,subscribe:Xl}):i.jsx(Rd,{visible:!0})]}),i.jsxs("div",{className:"col-span-4 flex flex-col gap-6",children:[i.jsx(D0,{agents:Z,loading:cl}),i.jsx(q0,{checklist:ol,loading:m})]})]}),i.jsxs("div",{className:"mt-6 grid grid-cols-12 gap-6",children:[i.jsx("div",{className:"col-span-6",children:i.jsx(Q0,{files:A,loading:C})}),i.jsx("div",{className:"col-span-6",children:i.jsx(L0,{memory:G,loading:ul})})]})]}):i.jsxs("div",{className:"flex flex-col items-center",children:[i.jsxs("div",{className:"text-center mt-8 mb-8",children:[i.jsx("h2",{className:"text-3xl font-bold text-charcoal tracking-tight",children:"Describe it. Build it. Ship it."}),i.jsx("p",{className:"text-slate mt-2 text-base max-w-lg mx-auto",children:"Paste a PRD or pick a template. Purple Lab spins up autonomous agents to build your project from scratch."})]}),i.jsx("div",{className:"w-full max-w-3xl",children:i.jsx(A0,{onSubmit:El,running:p,error:f,provider:Nl,onProviderChange:ke})}),D&&!p&&i.jsxs("div",{className:"w-full max-w-3xl mt-4 flex flex-col gap-4",children:[i.jsxs("div",{className:"flex items-center gap-3",children:[i.jsx("button",{onClick:()=>O(!q),className:"px-4 py-2 rounded-xl text-sm font-semibold border border-accent-product/30 text-accent-product hover:bg-accent-product/5 transition-all",children:q?"Hide Report Panel":"Report"}),i.jsx("button",{onClick:()=>ll(!Q),className:"px-4 py-2 rounded-xl text-sm font-semibold border border-white/30 text-slate hover:text-charcoal hover:bg-white/30 transition-all",children:Q?"Hide Metrics":"View Metrics"})]}),i.jsx(Z0,{visible:q}),i.jsx(Rd,{visible:Q})]}),gl&&i.jsx("div",{className:"w-full max-w-3xl mt-4",children:i.jsxs("div",{className:"glass p-4 rounded-2xl",children:[i.jsxs("div",{className:"flex items-center justify-between mb-3",children:[i.jsxs("h3",{className:"text-sm font-semibold text-charcoal uppercase tracking-wider",children:["Session: ",gl.id]}),i.jsx("button",{onClick:()=>J(null),className:"text-xs text-slate hover:text-charcoal transition-colors px-2 py-1 rounded-lg hover:bg-white/30",children:"Close"})]}),i.jsx("div",{className:"text-[10px] font-mono text-slate mb-3",children:gl.path}),gl.prd&&i.jsxs("div",{className:"mb-3",children:[i.jsx("div",{className:"text-[10px] text-slate uppercase tracking-wider font-semibold mb-1",children:"PRD"}),i.jsxs("div",{className:"bg-charcoal/[0.03] rounded-lg p-3 font-mono text-xs text-charcoal/80 max-h-32 overflow-y-auto terminal-scroll whitespace-pre-wrap",children:[gl.prd.slice(0,500),gl.prd.length>500?"...":""]})]}),gl.files.length>0&&i.jsxs("div",{className:"mb-3",children:[i.jsxs("div",{className:"text-[10px] text-slate uppercase tracking-wider font-semibold mb-1",children:["Files (",gl.files.length,")"]}),i.jsx("div",{className:"bg-charcoal/[0.03] rounded-lg p-3 font-mono text-xs max-h-40 overflow-y-auto terminal-scroll",children:gl.files.map((pl,Yt)=>i.jsx("div",{className:"text-charcoal/70",children:pl.type==="directory"?`${pl.name}/`:pl.name},Yt))})]}),gl.logs.length>0&&i.jsxs("div",{children:[i.jsxs("div",{className:"text-[10px] text-slate uppercase tracking-wider font-semibold mb-1",children:["Logs (",gl.logs.length," lines)"]}),i.jsx("div",{className:"bg-charcoal/[0.03] rounded-lg p-3 font-mono text-[10px] max-h-40 overflow-y-auto terminal-scroll",children:gl.logs.map((pl,Yt)=>i.jsx("div",{className:"text-charcoal/70",children:pl},Yt))})]})]})}),i.jsx("div",{className:"w-full max-w-3xl mt-4",children:i.jsx(J0,{onLoadSession:Je})}),i.jsxs("div",{className:"mt-6 text-xs text-slate flex items-center gap-2",children:[i.jsx("div",{className:`w-2 h-2 rounded-full ${Ql?"bg-success":"bg-danger"}`}),Ql?"Connected to Purple Lab backend":"Waiting for backend connection..."]})]})})]})}v0.createRoot(document.getElementById("root")).render(i.jsx(U.StrictMode,{children:i.jsx(k0,{})}));
@@ -8,7 +8,7 @@
8
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
10
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
11
- <script type="module" crossorigin src="/assets/index-BVw_Fxig.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-Bwj6Ubaa.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-CDiM5Vh4.css">
13
13
  </head>
14
14
  <body class="bg-background text-charcoal font-sans antialiased">