@kryvenaiofficial/kryven 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +18120 -14030
- package/dist/dashboard/assets/AgentsPage-CAvremYr.js +11 -0
- package/dist/dashboard/assets/ApiKeysPage-DYJj5Pg2.js +11 -0
- package/dist/dashboard/assets/ApprovalsPage-CUUFWGAN.js +21 -0
- package/dist/dashboard/assets/ConfigPage-BY8S7kDh.js +1 -0
- package/dist/dashboard/assets/ConfirmDialog-DiXA7YmQ.js +1 -0
- package/dist/dashboard/assets/CronPage-DiwowD0x.js +6 -0
- package/dist/dashboard/assets/EmptyState-BZSWUG-H.js +6 -0
- package/dist/dashboard/assets/LogTail-DH7rJjV9.js +6 -0
- package/dist/dashboard/assets/LogsPage-mZnLKfZe.js +1 -0
- package/dist/dashboard/assets/McpPage-CKP_f9um.js +16 -0
- package/dist/dashboard/assets/OverviewPage-UJZm2ern.js +6 -0
- package/dist/dashboard/assets/SessionsPage-QHGMC_HR.js +6 -0
- package/dist/dashboard/assets/SkillsPage-B-Tmfueb.js +16 -0
- package/dist/dashboard/assets/StatCard-Bl4JiW8I.js +1 -0
- package/dist/dashboard/assets/StatusBadge-C1IqqKfb.js +1 -0
- package/dist/dashboard/assets/Toast-CFoZ2eqS.js +11 -0
- package/dist/dashboard/assets/UsagePage-Cg2QncR4.js +6 -0
- package/dist/dashboard/assets/WorkflowsPage-DZOfpYyA.js +6 -0
- package/dist/dashboard/assets/circle-check-m7S2YKDA.js +6 -0
- package/dist/dashboard/assets/dollar-sign-CyqQR2qm.js +11 -0
- package/dist/dashboard/assets/format-ChobNBtf.js +1 -0
- package/dist/dashboard/assets/index-BqQfjpT8.css +1 -0
- package/dist/dashboard/assets/index-C-MAoMUW.js +168 -0
- package/dist/dashboard/assets/pages-DBjxqPsI.js +1 -0
- package/dist/dashboard/assets/pages-Dg1jM9JA.css +1 -0
- package/dist/dashboard/assets/pages-group2-BhbgCBuB.js +6 -0
- package/dist/dashboard/assets/pages-group2-RIUWEvL_.css +1 -0
- package/dist/dashboard/assets/refresh-cw-CVNMUM98.js +6 -0
- package/dist/dashboard/assets/save-DMb9oA3j.js +11 -0
- package/dist/dashboard/assets/trash-2-CfEaDneW.js +6 -0
- package/dist/dashboard/assets/triangle-alert-p58-WCLo.js +6 -0
- package/dist/dashboard/index.html +21 -0
- package/package.json +9 -3
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{c as L,u as E,a as B,e as O,f as R,r as d,j as s,B as F,R as $,S as H}from"./index-C-MAoMUW.js";import{S as q}from"./StatusBadge-C1IqqKfb.js";import{E as W}from"./EmptyState-BZSWUG-H.js";import{L as G}from"./LogTail-DH7rJjV9.js";import{C as J}from"./ConfirmDialog-DiXA7YmQ.js";import{u as z}from"./pages-DBjxqPsI.js";import{t as C,s as f,d as S,e as Q}from"./format-ChobNBtf.js";import{R as U}from"./refresh-cw-CVNMUM98.js";import"./triangle-alert-p58-WCLo.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const V=L("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);/**
|
|
7
|
+
* @license lucide-react v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const X=L("Skull",[["path",{d:"m12.5 17-.5-1-.5 1h1z",key:"3me087"}],["path",{d:"M15 22a1 1 0 0 0 1-1v-1a2 2 0 0 0 1.56-3.25 8 8 0 1 0-11.12 0A2 2 0 0 0 8 20v1a1 1 0 0 0 1 1z",key:"1o5pge"}],["circle",{cx:"15",cy:"12",r:"1",key:"1tmaij"}],["circle",{cx:"9",cy:"12",r:"1",key:"1vctgf"}]]);function Y(a,t){var c,i,l,h;return{id:a.id,status:(t==null?void 0:t.status)??a.status,pid:a.pid,startedAt:a.startedAt||(t==null?void 0:t.startedAt)||0,finishedAt:a.finishedAt??(t==null?void 0:t.finishedAt)??null,exitCode:a.exitCode,signal:a.signal,lastLine:(t==null?void 0:t.lastText)||a.lastLine||"",prompt:((c=a.spec)==null?void 0:c.prompt)??a.prompt??(t==null?void 0:t.promptPreview),model:((i=a.spec)==null?void 0:i.model)??a.model??(t==null?void 0:t.model),mood:((l=a.spec)==null?void 0:l.mood)??a.mood??(t==null?void 0:t.mood),cwd:((h=a.spec)==null?void 0:h.cwd)??a.cwd??(t==null?void 0:t.cwd)}}function Z({id:a,running:t}){var g;const c=E(),i=R(),{data:l,loading:h,error:u,reload:x}=z(o=>c.agentLog(a,400,o),[a]),p=(g=i[a])==null?void 0:g.updatedAt;return d.useEffect(()=>{t&&p&&x()},[p,t]),h&&!l?s.jsx("div",{className:"kv-wf-loglabel",children:"loading log..."}):u?s.jsx("div",{className:"kv-banner-error",children:u}):s.jsx(G,{lines:(l==null?void 0:l.lines)??[],maxHeight:320,emptyText:"no log output yet..."})}function cs(){const a=E(),t=B(),{id:c}=O(),i=R(),{data:l,loading:h,error:u,reload:x}=z(e=>a.agents(e),[]),[p,g]=d.useState(c??null),[o,j]=d.useState(null),[K,N]=d.useState(!1),[A,k]=d.useState(void 0);d.useEffect(()=>{c&&g(c)},[c]);const T=d.useMemo(()=>Object.keys(i).sort().join(","),[i]),P=d.useMemo(()=>Object.values(i).map(e=>e.status).join(","),[i]);d.useEffect(()=>{l&&x()},[T,P]);const v=d.useMemo(()=>{const m=(l??[]).map(n=>Y(n,i[n.id])),r=new Set(m.map(n=>n.id));for(const n of Object.values(i))r.has(n.id)||m.push({id:n.id,status:n.status,pid:null,startedAt:n.startedAt,finishedAt:n.finishedAt??null,exitCode:null,signal:null,lastLine:n.lastText||"",prompt:n.promptPreview,model:n.model,mood:n.mood,cwd:n.cwd});return m.sort((n,w)=>{const y=n.status==="running"?1:0,b=w.status==="running"?1:0;return y!==b?b-y:w.startedAt-n.startedAt})},[l,i]),I=d.useCallback(e=>{g(m=>{const r=m===e?null:e;return t(r?`/agents/${r}`:"/agents",{replace:!0}),r})},[t]),D=d.useCallback(async()=>{if(o){N(!0),k(void 0);try{const e=await a.killAgent(o);e.ok||k(e.reason||"kill failed"),x()}catch(e){k(e instanceof Error?e.message:"kill failed")}finally{N(!1),j(null)}}},[a,o,x]),M=v.filter(e=>e.status==="running").length;return h&&!l?s.jsxs("div",{className:"kv-loading",children:[s.jsx("span",{className:"kv-spinner"})," loading agents..."]}):s.jsxs("div",{children:[s.jsxs("div",{className:"kv-page-head",children:[s.jsxs("div",{children:[s.jsx("h1",{className:"kv-page-title",children:"Agents"}),s.jsxs("p",{className:"kv-page-sub",children:["Background agents spawned with ",s.jsx("code",{children:"kryven --bg"})," - ",M," running."]})]}),s.jsx("div",{className:"kv-head-actions",children:s.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:x,title:"Refresh",children:[s.jsx(U,{size:14})," Refresh"]})})]}),u?s.jsx("div",{className:"kv-banner-error",children:u}):null,A?s.jsx("div",{className:"kv-banner-error",children:A}):null,v.length===0?s.jsx("div",{className:"kv-card",children:s.jsx(W,{icon:F,title:"No background agents",description:s.jsxs(s.Fragment,{children:["Spawn one from the CLI with ",s.jsx("code",{children:'kryven --bg "your task"'})," and it will appear here with live status and logs."]})})}):s.jsx("div",{className:"kv-card",style:{padding:0,overflow:"hidden"},children:s.jsxs("table",{className:"kv-table",children:[s.jsx("thead",{children:s.jsxs("tr",{children:[s.jsx("th",{style:{width:28}}),s.jsx("th",{children:"Status"}),s.jsx("th",{children:"Prompt"}),s.jsx("th",{children:"Model"}),s.jsx("th",{children:"Elapsed"}),s.jsx("th",{children:"Last line"}),s.jsx("th",{style:{width:80}})]})}),s.jsx("tbody",{children:v.map(e=>{const m=p===e.id,r=e.status==="running";return s.jsxs($.Fragment,{children:[s.jsxs("tr",{className:"kv-agent-row",onClick:()=>I(e.id),children:[s.jsx("td",{children:s.jsx("span",{className:`kv-chevron${m?" open":""}`,children:s.jsx(V,{size:15})})}),s.jsx("td",{children:s.jsx(q,{status:e.status,size:"sm"})}),s.jsx("td",{className:"kv-cell-prompt",title:e.prompt||f(e.id),children:e.prompt?C(e.prompt,60):s.jsx("span",{className:"kv-mono",children:f(e.id)})}),s.jsx("td",{className:"kv-mono",style:{fontSize:12},children:e.model||"-"}),s.jsx("td",{className:"kv-mono",style:{fontSize:12},children:r?S(e.startedAt):S(e.startedAt,e.finishedAt)}),s.jsx("td",{className:"kv-cell-last",title:e.lastLine,children:e.lastLine?C(e.lastLine,50):"-"}),s.jsx("td",{onClick:n=>n.stopPropagation(),children:r?s.jsxs("button",{className:"kv-btn kv-btn-sm kv-btn-danger",onClick:()=>j(e.id),title:"Kill agent",children:[s.jsx(X,{size:13})," Kill"]}):null})]}),m?s.jsx("tr",{className:"kv-row-detail",children:s.jsx("td",{colSpan:7,children:s.jsxs("div",{className:"kv-detail-inner",children:[s.jsxs("div",{className:"kv-detail-grid",children:[s.jsxs("div",{className:"kv-detail-item",children:[s.jsx("div",{className:"kv-detail-k",children:"Agent ID"}),s.jsx("div",{className:"kv-detail-v",children:e.id})]}),s.jsxs("div",{className:"kv-detail-item",children:[s.jsx("div",{className:"kv-detail-k",children:"PID"}),s.jsx("div",{className:"kv-detail-v",children:e.pid??"-"})]}),s.jsxs("div",{className:"kv-detail-item",children:[s.jsx("div",{className:"kv-detail-k",children:"Mood"}),s.jsx("div",{className:"kv-detail-v",children:e.mood||"-"})]}),s.jsxs("div",{className:"kv-detail-item",children:[s.jsx("div",{className:"kv-detail-k",children:"Started"}),s.jsx("div",{className:"kv-detail-v",children:Q(e.startedAt)})]}),s.jsxs("div",{className:"kv-detail-item",children:[s.jsx("div",{className:"kv-detail-k",children:"Exit"}),s.jsx("div",{className:"kv-detail-v",children:e.exitCode!=null?`code ${e.exitCode}`:e.signal?e.signal:"-"})]}),s.jsxs("div",{className:"kv-detail-item",children:[s.jsx("div",{className:"kv-detail-k",children:"CWD"}),s.jsx("div",{className:"kv-detail-v",children:e.cwd||"-"})]})]}),e.prompt?s.jsxs("div",{className:"kv-detail-item",style:{marginBottom:14},children:[s.jsx("div",{className:"kv-detail-k",children:"Prompt"}),s.jsx("div",{className:"kv-detail-v",children:e.prompt})]}):null,s.jsxs("div",{className:"kv-wf-loglabel",children:[s.jsx(H,{size:12,style:{verticalAlign:"-2px",marginRight:5}}),"Output log"]}),s.jsx(Z,{id:e.id,running:r})]})})}):null]},e.id)})})]})}),s.jsx(J,{open:o!=null,title:"Kill this agent?",message:s.jsxs(s.Fragment,{children:["This sends a termination signal to agent"," ",s.jsx("code",{children:o?f(o):""}),". Any in-progress work is lost."]}),confirmLabel:K?"Killing...":"Kill agent",tone:"danger",onConfirm:D,onCancel:()=>j(null)})]})}export{cs as default};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{c as h,u as y,r as n,A as x,j as e,i as u,T as j}from"./index-C-MAoMUW.js";import{X as N}from"./pages-group2-BhbgCBuB.js";import{R as g}from"./refresh-cw-CVNMUM98.js";import{C as f}from"./circle-check-m7S2YKDA.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const b=h("CircleAlert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);/**
|
|
7
|
+
* @license lucide-react v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const C=h("ExternalLink",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]]),w="https://kryven.cc/cli-login";function R(){const l=y(),[a,p]=n.useState(null),[o,d]=n.useState(null),[c,k]=n.useState(!0),t=n.useCallback(async i=>{k(!0),d(null);try{p(await l.config(i))}catch(r){if(r instanceof x&&r.status===401)return;d(r instanceof Error?r.message:"failed to load key status")}finally{k(!1)}},[l]);n.useEffect(()=>{const i=new AbortController;return t(i.signal),()=>i.abort()},[t]);const s=!!(a!=null&&a.hasApiKey),v=(typeof(a==null?void 0:a.apiKeyHelper)=="string"?a.apiKeyHelper:"")?"helper command":s?"stored in config":"not set",m=n.useCallback(()=>{window.open(w,"_blank","noopener,noreferrer")},[]);return e.jsxs("div",{children:[e.jsxs("div",{className:"kv-page-head",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"kv-page-title",children:"API Keys"}),e.jsx("p",{className:"kv-page-sub",children:"Connect this CLI to your Kryven account. The key is redacted from the dashboard and can only be set from the trusted CLI process."})]}),e.jsx("div",{className:"kv-head-actions",children:e.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:()=>void t(),disabled:c,title:"Re-check key status",children:[e.jsx(g,{size:14,className:c?"kv-spin-icon":""}),"Refresh"]})})]}),o?e.jsxs("div",{className:"kv-banner-error",children:[e.jsx(N,{size:15})," ",o]}):null,c&&!a?e.jsxs("div",{className:"kv-loading",children:[e.jsx("span",{className:"kv-spinner"})," checking key status…"]}):e.jsxs("div",{className:"kv-apikey-grid",children:[e.jsxs("div",{className:`kv-card kv-card-accent kv-apikey-status${s?" ok":" warn"}`,children:[e.jsxs("div",{className:"kv-apikey-status-head",children:[e.jsx("span",{className:`kv-apikey-badge ${s?"ok":"warn"}`,"aria-hidden":!0,children:s?e.jsx(f,{size:20}):e.jsx(b,{size:20})}),e.jsxs("div",{children:[e.jsx("div",{className:"kv-apikey-status-title",children:s?"API key configured":"No API key configured"}),e.jsx("div",{className:"kv-apikey-status-sub",children:s?"This CLI is connected to your Kryven account.":"Connect to start running agents against your account."})]})]}),e.jsxs("dl",{className:"kv-apikey-meta",children:[e.jsxs("div",{className:"kv-apikey-meta-row",children:[e.jsx("dt",{children:"Key"}),e.jsx("dd",{className:"kv-mono",children:s?"kry_sk_••••••••••••••••":"—"})]}),e.jsxs("div",{className:"kv-apikey-meta-row",children:[e.jsx("dt",{children:"Source"}),e.jsx("dd",{className:"kv-mono",children:v})]}),e.jsxs("div",{className:"kv-apikey-meta-row",children:[e.jsx("dt",{children:"Status"}),e.jsx("dd",{children:e.jsx("span",{className:`kv-pill ${s?"running":"neutral"} kv-pill-sm`,children:s?"connected":"disconnected"})})]})]})]}),e.jsxs("div",{className:"kv-card",children:[e.jsx("div",{className:"kv-card-title",children:"Connect via browser"}),e.jsxs("p",{className:"kv-apikey-copy",children:["Start the device-flow login: a browser tab opens at"," ",e.jsx("span",{className:"kv-mono",children:"kryven.cc/cli-login"})," where you approve this device while signed in to your account. Once approved, the CLI stores the key locally — refresh this page to see it."]}),e.jsxs("button",{className:"kv-btn kv-btn-primary",onClick:m,children:[e.jsx(C,{size:15}),s?"Reconnect via browser":"Connect via browser"]}),e.jsxs("p",{className:"kv-apikey-hint",children:[e.jsx(u,{size:13})," The approval happens on kryven.cc — your key is never typed into or stored by this dashboard."]})]}),e.jsxs("div",{className:"kv-card",children:[e.jsx("div",{className:"kv-card-title",children:"Connect via terminal"}),e.jsx("p",{className:"kv-apikey-copy",children:"Prefer the terminal? Run the login command in your shell and follow the prompts:"}),e.jsxs("div",{className:"kv-codeblock kv-mono",children:[e.jsx(j,{size:14,className:"kv-codeblock-icon"}),e.jsx("span",{children:"kryven login"})]}),e.jsxs("p",{className:"kv-apikey-hint",children:["You can also export ",e.jsx("span",{className:"kv-mono",children:"KRYVEN_API_KEY"})," ","in your environment, or point an"," ",e.jsx("span",{className:"kv-mono",children:"apiKeyHelper"})," command at a secrets manager."]})]})]})]})}export{R as default};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import{c as d,j as s,m as u,n as x,r as c,k as f,A as g,i as j,W as b}from"./index-C-MAoMUW.js";import{S as w}from"./StatusBadge-C1IqqKfb.js";import{E as y}from"./EmptyState-BZSWUG-H.js";import{T as N,u as A}from"./Toast-CFoZ2eqS.js";import{s as I,c as S}from"./format-ChobNBtf.js";import{X as C}from"./pages-group2-BhbgCBuB.js";import"./triangle-alert-p58-WCLo.js";import"./circle-check-m7S2YKDA.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const E=d("Ban",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m4.9 4.9 14.2 14.2",key:"1m5liu"}]]);/**
|
|
7
|
+
* @license lucide-react v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const R=d("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);/**
|
|
12
|
+
* @license lucide-react v0.468.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const z=d("ShieldAlert",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"M12 8v4",key:"1got3b"}],["path",{d:"M12 16h.01",key:"1drbdi"}]]);/**
|
|
17
|
+
* @license lucide-react v0.468.0 - ISC
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the ISC license.
|
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/const M=d("Wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",key:"cbrjhi"}]]),$=/\b(rm|del|delete|drop|format|kill|shutdown|sudo|chmod|chown|push|deploy|publish|wipe|truncate)\b/i,W=/\b(write|edit|move|mv|install|npm|pip|exec|spawn|fetch|post|put)\b/i;function B(o){const r=`${o.tool??""} ${o.reason??""}`;return o.kind==="workflow.gate"?"medium":$.test(r)?"high":W.test(r)?"medium":"low"}const T={low:"Low risk",medium:"Medium risk",high:"High risk",critical:"Critical"};function _(){const o=u(),r=x(),{toast:p}=A(),[n,m]=c.useState({}),v=c.useCallback(async(e,t)=>{try{return await f(`/api/approvals/${encodeURIComponent(e.id)}`,{method:"POST",body:{decision:t}}),!0}catch(a){if(a instanceof g&&(a.status===404||a.status===0||a.status===405))return!1;throw a}},[]),h=c.useCallback(async(e,t)=>{if(!n[e.id]){m(a=>({...a,[e.id]:!0}));try{const a=await v(e,t);r(e.id),p({intent:t==="approve"?"success":"warning",title:t==="approve"?"Approved":"Denied",message:a?`${e.tool??"action"} ${t==="approve"?"approved":"denied"}.`:"Acknowledged locally — resolve the gate in the running session."})}catch(a){p({intent:"error",title:"Action failed",message:a instanceof Error?a.message:"request failed"})}finally{m(a=>{const l={...a};return delete l[e.id],l})}}},[n,v,r,p]),i=c.useMemo(()=>[...o].sort((e,t)=>t.ts-e.ts),[o]);return s.jsxs("div",{children:[s.jsxs("div",{className:"kv-page-head",children:[s.jsxs("div",{children:[s.jsx("h1",{className:"kv-page-title",children:"Approvals"}),s.jsx("p",{className:"kv-page-sub",children:"Human-in-the-loop queue — blocked tool calls and workflow gates that need a decision."})]}),i.length>0?s.jsx("div",{className:"kv-head-actions",children:s.jsxs("span",{className:"kv-pill killed",children:[i.length," pending"]})}):null]}),i.length===0?s.jsx(y,{icon:j,title:"No pending approvals",description:"When you run agents in manual-approval mode, blocked tool calls and workflow gates appear here for you to approve or deny in real time."}):s.jsx("div",{className:"kv-approval-list",children:i.map(e=>{const t=B(e),a=e.kind==="workflow.gate",l=a?b:M,k=e.agentId||e.wfId||e.sessionId;return s.jsxs("div",{className:`kv-card kv-approval-card risk-${t}`,children:[s.jsxs("div",{className:"kv-approval-main",children:[s.jsx("span",{className:`kv-approval-icon risk-${t}`,"aria-hidden":!0,children:t==="high"||t==="critical"?s.jsx(z,{size:18}):s.jsx(l,{size:18})}),s.jsxs("div",{className:"kv-approval-body",children:[s.jsxs("div",{className:"kv-approval-title-row",children:[s.jsx("span",{className:"kv-approval-tool kv-mono",children:e.tool||(a?"workflow gate":"blocked tool")}),s.jsx(w,{status:t,label:T[t],size:"sm"}),s.jsx("span",{className:"kv-tag",children:a?"gate":"tool"})]}),s.jsx("div",{className:"kv-approval-reason",children:e.reason||"Awaiting your decision before this action runs."}),s.jsxs("div",{className:"kv-approval-meta kv-mono",children:[s.jsx("span",{className:`kv-src-${e.source}`,children:e.source}),k?s.jsxs("span",{children:["· ",I(k)]}):null,s.jsxs("span",{children:["· ",S(e.ts)]})]})]})]}),s.jsxs("div",{className:"kv-approval-actions",children:[s.jsxs("button",{className:"kv-btn kv-btn-danger kv-btn-sm",onClick:()=>void h(e,"deny"),disabled:!!n[e.id],children:[n[e.id]?s.jsx("span",{className:"kv-spinner kv-spinner-sm"}):s.jsx(E,{size:14}),"Deny"]}),s.jsxs("button",{className:"kv-btn kv-btn-primary kv-btn-sm",onClick:()=>void h(e,"approve"),disabled:!!n[e.id],children:[n[e.id]?s.jsx("span",{className:"kv-spinner kv-spinner-sm"}):s.jsx(R,{size:14}),"Approve"]})]})]},e.id)})}),s.jsxs("p",{className:"kv-approval-foot",children:[s.jsx(C,{size:12})," Approvals stream live from the event bus. Resolving an item here acknowledges it; the running session enforces the gate."]})]})}function J(){return s.jsx(N,{children:s.jsx(_,{})})}export{J as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e,u as A,r as l,A as N,K as I,i as F}from"./index-C-MAoMUW.js";import{T as L,u as P}from"./Toast-CFoZ2eqS.js";import{X as R}from"./pages-group2-BhbgCBuB.js";import{R as T,S as z}from"./save-DMb9oA3j.js";import"./triangle-alert-p58-WCLo.js";import"./circle-check-m7S2YKDA.js";const S=[{key:"apiBaseUrl",label:"API base URL",hint:"Endpoint the CLI talks to.",placeholder:"https://kryven.cc"},{key:"defaultModel",label:"Default model",placeholder:"kryven-coder"},{key:"defaultMood",label:"Default mood",placeholder:"guide"},{key:"lastSessionId",label:"Last session id",hint:"Resumed on next launch."}],D=["low","medium","high","ultra","self-improve","forge"],C=[{key:"telemetry",label:"Telemetry",hint:"Anonymous usage metrics."},{key:"shareFingerprint",label:"Share fingerprint",hint:"Help with free-tier abuse prevention."},{key:"vim",label:"Vim keybindings",hint:"Use vi-style editing in the REPL."},{key:"setupComplete",label:"Setup complete",hint:"First-run wizard already ran."}],M=new Set(["hasApiKey","apiKey","apiKeyHelper","theme","effort",...S.map(n=>String(n.key)),...C.map(n=>String(n.key))]);function _(){const n=A(),{toast:d}=P(),[t,k]=l.useState(null),[i,o]=l.useState({}),[g,u]=l.useState(null),[w,p]=l.useState(!0),[r,f]=l.useState(!1),j=l.useCallback(async s=>{p(!0),u(null);try{const a=await n.config(s);k(a),o({...a})}catch(a){if(a instanceof N&&a.status===401)return;u(a instanceof Error?a.message:"failed to load config")}finally{p(!1)}},[n]);l.useEffect(()=>{const s=new AbortController;return j(s.signal),()=>s.abort()},[j]);const h=l.useCallback((s,a)=>{o(v=>({...v,[s]:a}))},[]),m=l.useMemo(()=>{if(!t)return{};const s={};for(const a of Object.keys(i)){if(a==="hasApiKey"||a==="apiKey"||a==="apiKeyHelper")continue;const v=i[a],y=t[a],b=v===""?void 0:v,O=y===""?void 0:y;JSON.stringify(b)!==JSON.stringify(O)&&(s[a]=b)}return s},[i,t]),c=Object.keys(m).length>0,E=l.useCallback(async()=>{if(!(!c||r)){f(!0);try{const s=await n.saveConfig(m);s.ok&&s.config?(k(s.config),o({...s.config}),d({intent:"success",title:"Config saved",message:"Changes written to disk."})):d({intent:"error",title:"Save rejected",message:s.error||"the server rejected the config"})}catch(s){const a=s instanceof N||s instanceof Error?s.message:"save failed";d({intent:"error",title:"Save failed",message:a})}finally{f(!1)}}},[n,m,c,r,d]),K=l.useCallback(()=>{t&&o({...t})},[t]),x=l.useMemo(()=>t?Object.keys(t).filter(s=>!M.has(s)):[],[t]);return e.jsxs("div",{children:[e.jsxs("div",{className:"kv-page-head",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"kv-page-title",children:"Config"}),e.jsx("p",{className:"kv-page-sub",children:"Edit the CLI user config. Changes write to disk immediately; the API key is managed separately and never editable here."})]}),e.jsxs("div",{className:"kv-head-actions",children:[e.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:K,disabled:!c||r,title:"Discard unsaved changes",children:[e.jsx(T,{size:14})," Reset"]}),e.jsxs("button",{className:"kv-btn kv-btn-primary kv-btn-sm",onClick:()=>void E(),disabled:!c||r,children:[r?e.jsx("span",{className:"kv-spinner kv-spinner-sm"}):e.jsx(z,{size:14}),c?`Save (${Object.keys(m).length})`:"Saved"]})]})]}),g?e.jsxs("div",{className:"kv-banner-error",children:[e.jsx(R,{size:15})," ",g]}):null,w&&!t?e.jsxs("div",{className:"kv-loading",children:[e.jsx("span",{className:"kv-spinner"})," loading config…"]}):t?e.jsxs("div",{className:"kv-config-cols",children:[e.jsxs("div",{className:"kv-card kv-card-accent",children:[e.jsx("div",{className:"kv-card-title",children:"Credentials"}),e.jsxs("div",{className:"kv-cred-row",children:[e.jsx("span",{className:"kv-cred-icon","aria-hidden":!0,children:e.jsx(I,{size:16})}),e.jsxs("div",{className:"kv-cred-body",children:[e.jsx("div",{className:"kv-cred-label",children:"API key"}),e.jsx("div",{className:"kv-cred-value kv-mono",children:t.hasApiKey?"•••••••••••••••• set":"not set"})]}),e.jsx("span",{className:`kv-pill ${t.hasApiKey?"running":"neutral"} kv-pill-sm`,children:t.hasApiKey?"configured":"missing"})]}),e.jsxs("p",{className:"kv-cred-hint",children:[e.jsx(F,{size:13})," Set the key from the CLI (`kryven login`) or the API Keys tab — it is redacted from the dashboard."]})]}),e.jsxs("div",{className:"kv-card",children:[e.jsx("div",{className:"kv-card-title",children:"General"}),S.map(s=>e.jsxs("div",{className:"kv-field",children:[e.jsx("label",{className:"kv-label",htmlFor:`cfg-${String(s.key)}`,children:s.label}),e.jsx("input",{id:`cfg-${String(s.key)}`,className:"kv-input",type:"text",value:i[s.key]??"",placeholder:s.placeholder,onChange:a=>h(s.key,a.target.value)}),s.hint?e.jsx("div",{className:"kv-field-hint",children:s.hint}):null]},String(s.key))),e.jsxs("div",{className:"kv-field",children:[e.jsx("label",{className:"kv-label",htmlFor:"cfg-effort",children:"Effort"}),e.jsx("select",{id:"cfg-effort",className:"kv-select",value:i.effort??"low",onChange:s=>h("effort",s.target.value),children:D.map(s=>e.jsx("option",{value:s,children:s},s))}),e.jsx("div",{className:"kv-field-hint",children:"Orchestrator depth — higher means more multi-stage planning."})]}),e.jsxs("div",{className:"kv-field",children:[e.jsx("label",{className:"kv-label",htmlFor:"cfg-theme",children:"Theme"}),e.jsx("input",{id:"cfg-theme",className:"kv-input",type:"text",value:i.theme??"",placeholder:"dark",onChange:s=>h("theme",s.target.value)})]})]}),e.jsxs("div",{className:"kv-card",children:[e.jsx("div",{className:"kv-card-title",children:"Preferences"}),C.map(s=>e.jsxs("label",{className:"kv-toggle-row",children:[e.jsxs("span",{className:"kv-switch",children:[e.jsx("input",{type:"checkbox",checked:!!i[s.key],onChange:a=>h(s.key,a.target.checked)}),e.jsx("span",{className:"kv-switch-track"}),e.jsx("span",{className:"kv-switch-thumb"})]}),e.jsxs("span",{className:"kv-toggle-body",children:[e.jsx("span",{className:"kv-toggle-label",children:s.label}),s.hint?e.jsx("span",{className:"kv-toggle-hint",children:s.hint}):null]})]},String(s.key)))]}),x.length>0?e.jsxs("div",{className:"kv-card",children:[e.jsx("div",{className:"kv-card-title",children:"Other (read-only)"}),e.jsx("table",{className:"kv-table",children:e.jsx("tbody",{children:x.map(s=>e.jsxs("tr",{children:[e.jsx("td",{className:"kv-mono",children:s}),e.jsx("td",{className:"kv-mono kv-raw-val",children:JSON.stringify(t[s])})]},s))})})]}):null]}):null]})}function G(){return e.jsx(L,{children:e.jsx(_,{})})}export{G as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as a,j as e}from"./index-C-MAoMUW.js";import{T as b}from"./triangle-alert-p58-WCLo.js";function j({open:t,title:u,message:o,confirmLabel:v="Confirm",cancelLabel:k="Cancel",tone:c="danger",icon:p=b,onConfirm:d,onCancel:s}){const[n,m]=a.useState(!1),f=a.useRef(null),l=a.useCallback(async()=>{if(!n)try{const i=d();i&&typeof i.then=="function"&&(m(!0),await i)}finally{m(!1)}},[n,d]);return a.useEffect(()=>{if(!t)return;const i=r=>{r.key==="Escape"&&!n?(r.preventDefault(),s()):r.key==="Enter"&&!n&&(r.preventDefault(),l())};window.addEventListener("keydown",i);const x=requestAnimationFrame(()=>{var r;return(r=f.current)==null?void 0:r.focus()});return()=>{window.removeEventListener("keydown",i),cancelAnimationFrame(x)}},[t,n,s,l]),t?e.jsx("div",{className:"kv-modal-backdrop",onClick:()=>{n||s()},role:"presentation",children:e.jsxs("div",{className:"kv-modal kv-confirm",role:"alertdialog","aria-modal":"true","aria-labelledby":"kv-confirm-title",onClick:i=>i.stopPropagation(),children:[e.jsxs("div",{className:`kv-confirm-head kv-confirm-${c}`,children:[e.jsx("span",{className:"kv-confirm-icon","aria-hidden":!0,children:e.jsx(p,{size:20})}),e.jsx("h3",{id:"kv-confirm-title",className:"kv-confirm-title",children:u})]}),o!=null?e.jsx("div",{className:"kv-confirm-body",children:o}):null,e.jsxs("div",{className:"kv-confirm-actions",children:[e.jsx("button",{className:"kv-btn",onClick:s,disabled:n,children:k}),e.jsxs("button",{ref:f,className:`kv-btn ${c==="danger"?"kv-btn-danger":"kv-btn-primary"}`,onClick:()=>void l(),disabled:n,children:[n?e.jsx("span",{className:"kv-spinner kv-spinner-sm"}):null,v]})]})]})}):null}export{j as C};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as j,u as p,r as d,k as g,A as k,j as e,l as u}from"./index-C-MAoMUW.js";import{E as l}from"./EmptyState-BZSWUG-H.js";import{S as f}from"./StatusBadge-C1IqqKfb.js";import{h as v,e as y}from"./format-ChobNBtf.js";import{X as b}from"./pages-group2-BhbgCBuB.js";import{R as N}from"./refresh-cw-CVNMUM98.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const C=j("CalendarClock",[["path",{d:"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5",key:"1osxxc"}],["path",{d:"M16 2v4",key:"4m81vk"}],["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M3 10h5",key:"r794hk"}],["path",{d:"M17.5 17.5 16 16.3V14",key:"akvzfd"}],["circle",{cx:"16",cy:"16",r:"6",key:"qoo3c4"}]]);function m(a){const r=typeof a=="number"?a:typeof a=="string"?Date.parse(a):NaN;return Number.isFinite(r)?r:void 0}function z(){p();const[a,r]=d.useState({state:"loading"}),i=d.useCallback(async s=>{r({state:"loading"});try{const t=await g("/api/cron",{signal:s});let c=[];if(Array.isArray(t))c=t;else if(t&&typeof t=="object"){const n=t;c=Array.isArray(n.jobs)&&n.jobs||Array.isArray(n.schedules)&&n.schedules||Array.isArray(n.crons)&&n.crons||[]}r({state:"ready",rows:c})}catch(t){if(t instanceof k){if(t.status===401)return;if(t.status===404){r({state:"unavailable"});return}r({state:"error",message:t.message});return}r({state:"error",message:t instanceof Error?t.message:"request failed"})}},[]);return d.useEffect(()=>{const s=new AbortController;return i(s.signal),()=>s.abort()},[i]),e.jsxs("div",{children:[e.jsxs("div",{className:"kv-page-head",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"kv-page-title",children:"Cron"}),e.jsx("p",{className:"kv-page-sub",children:"Scheduled agents that run on a recurring cadence."})]}),a.state==="ready"||a.state==="error"?e.jsx("div",{className:"kv-head-actions",children:e.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:()=>void i(),children:[e.jsx(N,{size:14}),"Refresh"]})}):null]}),a.state==="loading"?e.jsxs("div",{className:"kv-loading",children:[e.jsx("span",{className:"kv-spinner"})," checking for scheduled agents…"]}):a.state==="unavailable"?e.jsx(l,{icon:C,title:"Scheduled agents — coming soon",description:"This build of the CLI doesn't expose a cron scheduler yet. When it lands, your recurring agents will appear here with their next run times."}):a.state==="error"?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"kv-banner-error",children:[e.jsx(b,{size:15})," ",a.message]}),e.jsx(l,{icon:u,title:"Couldn't load schedules",description:"The cron endpoint returned an error.",action:{label:"Retry",onClick:()=>void i()}})]}):a.rows.length===0?e.jsx(l,{icon:u,title:"No scheduled agents",description:"You haven't scheduled any recurring agents yet."}):e.jsx("div",{className:"kv-card",style:{padding:0},children:e.jsxs("table",{className:"kv-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Name"}),e.jsx("th",{children:"Schedule"}),e.jsx("th",{children:"Next run"}),e.jsx("th",{children:"Last run"}),e.jsx("th",{children:"Status"})]})}),e.jsx("tbody",{children:a.rows.map((s,t)=>{const c=s.name||s.task||s.id||`job ${t+1}`,n=s.schedule||s.cron||"—",o=m(s.nextRun),h=m(s.lastRun),x=s.status||(s.enabled===!1?"idle":s.enabled?"active":"neutral");return e.jsxs("tr",{children:[e.jsx("td",{children:c}),e.jsx("td",{className:"kv-mono",children:n}),e.jsx("td",{className:"kv-mono",children:o?v(o):"—"}),e.jsx("td",{className:"kv-mono",children:h?y(h):"—"}),e.jsx("td",{children:e.jsx(f,{status:String(x),size:"sm"})})]},s.id||`${c}-${t}`)})})]})})]})}export{z as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as o,j as e}from"./index-C-MAoMUW.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const r=o("Inbox",[["polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12",key:"o97t9d"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}]]);function d({title:s,description:l,icon:i=r,action:t,children:a,className:n=""}){return e.jsxs("div",{className:`kv-empty${n?` ${n}`:""}`,children:[e.jsx(i,{size:40,strokeWidth:1.5,"aria-hidden":!0}),e.jsx("div",{className:"kv-empty-title",children:s}),l!=null?e.jsx("div",{className:"kv-empty-desc",children:l}):null,t?e.jsx("button",{className:"kv-btn kv-btn-primary",style:{marginTop:14},onClick:t.onClick,children:t.label}):null,a]})}export{d as E};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as h,r as e,j as o,R as v}from"./index-C-MAoMUW.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const b=h("ArrowDownToLine",[["path",{d:"M12 17V3",key:"1cwfxf"}],["path",{d:"m6 11 6 6 6-6",key:"12ii2o"}],["path",{d:"M19 21H5",key:"150jfl"}]]);function R({lines:l,renderLine:a,stickThreshold:u=40,maxHeight:i,emptyText:x="no output yet…",className:p=""}){const c=e.useRef(null),[f,m]=e.useState(!0),n=e.useRef(!0);n.current=f;const d=e.useCallback(()=>{const t=c.current;return t?t.scrollHeight-t.scrollTop-t.clientHeight<=u:!0},[u]),s=e.useCallback(()=>{const t=c.current;t&&(t.scrollTop=t.scrollHeight)},[]);e.useLayoutEffect(()=>{n.current&&s()},[l.length,s]);const j=e.useCallback(()=>{const t=d();t!==n.current&&m(t)},[d]);e.useEffect(()=>{s()},[]);const k=e.useCallback(()=>{m(!0),s()},[s]),g=i!=null?{maxHeight:i}:void 0;return o.jsxs("div",{className:`kv-logtail${p?` ${p}`:""}`,children:[o.jsx("div",{className:"kv-logbox",ref:c,onScroll:j,style:g,children:l.length===0?o.jsx("span",{className:"kv-logtail-empty",children:x}):l.map((t,r)=>a?o.jsx(v.Fragment,{children:a(t,r)},r):o.jsx("div",{className:"kv-logtail-line",children:t||" "},r))}),f?null:o.jsxs("button",{className:"kv-logtail-jump",onClick:k,title:"Jump to latest",children:[o.jsx(b,{size:13}),"Jump to latest"]})]})}export{R as L};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{u as w,d as L,r as t,A as C,j as e}from"./index-C-MAoMUW.js";import{L as S}from"./LogTail-DH7rJjV9.js";import{c as E}from"./format-ChobNBtf.js";import{X as A}from"./pages-group2-BhbgCBuB.js";import{R as I}from"./refresh-cw-CVNMUM98.js";import{T as R}from"./trash-2-CfEaDneW.js";const T=[{key:"all",label:"All"},{key:"foreground",label:"Foreground"},{key:"background",label:"Background"},{key:"workflow",label:"Workflow"}];function F(a){const n=a.agentId||a.wfId||a.sessionId||"";return e.jsxs("div",{className:"kv-logtail-line kv-logline",children:[e.jsx("span",{className:"kv-logline-ts",children:E(a.ts)}),e.jsx("span",{className:`kv-logline-src kv-src-${a.source}`,children:a.source}),n?e.jsx("span",{className:"kv-logline-who kv-mono",children:n.slice(0,8)}):null,e.jsxs("span",{className:"kv-logline-text",children:[e.jsx("span",{className:"kv-logline-type",children:a.type})," ",a.text]})]},`live-${a.seq}`)}function _(){const a=w(),n=L(),[u,k]=t.useState([]),[g,f]=t.useState(null),[v,x]=t.useState(!0),[h,p]=t.useState(""),[o,N]=t.useState("all"),[d,y]=t.useState(!1),m=t.useCallback(async s=>{x(!0),f(null);try{const l=await a.logs(1e3,s);k(Array.isArray(l)?l:[])}catch(l){if(l instanceof C&&l.status===401)return;f(l instanceof Error?l.message:"failed to load logs"),k([])}finally{x(!1)}},[a]);t.useEffect(()=>{const s=new AbortController;return m(s.signal),()=>s.abort()},[m]);const i=h.trim().toLowerCase(),r=t.useMemo(()=>d?[]:i?u.filter(s=>s.toLowerCase().includes(i)):u,[u,i,d]),c=t.useMemo(()=>n.filter(s=>o!=="all"&&s.source!==o?!1:i?s.text.toLowerCase().includes(i)||s.type.toLowerCase().includes(i)||(s.agentId||"").toLowerCase().includes(i)||(s.wfId||"").toLowerCase().includes(i):!0),[n,o,i]),j=t.useMemo(()=>{const s=[];if(r.length){s.push(e.jsxs("div",{className:"kv-log-divider",children:["── on-disk log (",r.length,") ──"]},"div-file"));for(let l=0;l<r.length;l++)s.push(e.jsx("div",{className:"kv-logtail-line",children:r[l]||" "},`file-${l}`))}if(c.length){s.push(e.jsxs("div",{className:"kv-log-divider",children:["── live activity (",c.length,") ──"]},"div-live"));for(const l of c)s.push(F(l))}return s},[r,c]),b=r.length+c.length;return e.jsxs("div",{children:[e.jsxs("div",{className:"kv-page-head",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"kv-page-title",children:"Logs"}),e.jsx("p",{className:"kv-page-sub",children:"Live activity from the event bus plus the on-disk CLI log — tails automatically."})]}),e.jsx("div",{className:"kv-head-actions",children:e.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:()=>void m(),disabled:v,title:"Re-read the log file",children:[e.jsx(I,{size:14,className:v?"kv-spin-icon":""}),"Refresh"]})})]}),g?e.jsxs("div",{className:"kv-banner-error",children:[e.jsx(A,{size:15})," ",g]}):null,e.jsxs("div",{className:"kv-log-toolbar",children:[e.jsxs("div",{className:"kv-search-row kv-log-search",children:[e.jsx("input",{className:"kv-input kv-search-input",placeholder:"Filter log lines…",value:h,onChange:s=>p(s.target.value)}),h?e.jsx("button",{className:"kv-toast-close kv-search-clear",onClick:()=>p(""),"aria-label":"Clear filter",children:e.jsx(R,{size:14})}):null]}),e.jsx("div",{className:"kv-seg",role:"tablist","aria-label":"Source filter",children:T.map(s=>e.jsx("button",{className:`kv-seg-btn${o===s.key?" active":""}`,onClick:()=>N(s.key),role:"tab","aria-selected":o===s.key,children:s.label},s.key))}),e.jsxs("label",{className:"kv-switch-row",title:"Hide the on-disk file tail",children:[e.jsxs("span",{className:"kv-switch",children:[e.jsx("input",{type:"checkbox",checked:d,onChange:s=>y(s.target.checked)}),e.jsx("span",{className:"kv-switch-track"}),e.jsx("span",{className:"kv-switch-thumb"})]}),e.jsx("span",{className:"kv-switch-label",children:"Live only"})]})]}),e.jsxs("div",{className:"kv-log-meta kv-mono",children:[b," line",b===1?"":"s"," shown",d?" · file tail hidden":""]}),e.jsx(S,{lines:j.map(()=>""),renderLine:(s,l)=>j[l],emptyText:v?"loading logs…":"no log lines match the current filters",maxHeight:"64vh"})]})}export{_ as default};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{c as b,j as e,u as H,r as n,A as L,P as S}from"./index-C-MAoMUW.js";import{E as T}from"./EmptyState-BZSWUG-H.js";import{C as E}from"./ConfirmDialog-DiXA7YmQ.js";import{T as I,u as $}from"./Toast-CFoZ2eqS.js";import{X as D}from"./pages-group2-BhbgCBuB.js";import{R as U,S as _}from"./save-DMb9oA3j.js";import{T as B}from"./trash-2-CfEaDneW.js";import"./triangle-alert-p58-WCLo.js";import"./circle-check-m7S2YKDA.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const F=b("Lock",[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]]);/**
|
|
7
|
+
* @license lucide-react v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const J=b("Pencil",[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]]);/**
|
|
12
|
+
* @license lucide-react v0.468.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const O=b("Plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);function V(){return{id:"",url:"",label:"",enabled:!0,_new:!0}}function X(){var M;const p=H(),{toast:d}=$(),[c,k]=n.useState(null),[i,o]=n.useState([]),[f,j]=n.useState(null),[A,g]=n.useState(!0),[m,N]=n.useState(!1),[u,x]=n.useState(null),y=n.useCallback(async s=>{g(!0),j(null);try{const a=await p.mcp(s),r=Array.isArray(a.servers)?a.servers:[];k(r),o(r.map(l=>({...l})))}catch(a){if(a instanceof L&&a.status===401)return;j(a instanceof Error?a.message:"failed to load MCP servers"),k([]),o([])}finally{g(!1)}},[p]);n.useEffect(()=>{const s=new AbortController;return y(s.signal),()=>s.abort()},[y]);const v=n.useCallback((s,a)=>{o(r=>r.map((l,t)=>t===s?{...l,...a}:l))},[]),C=n.useCallback(()=>{o(s=>[...s,V()])},[]),P=n.useCallback(s=>{o(a=>a.filter((r,l)=>l!==s)),x(null)},[]),w=n.useMemo(()=>{if(!c)return!1;if(i.some(l=>l.authHeader))return!0;const s=l=>({id:l.id,url:l.url,label:l.label??"",maxTools:l.maxTools,enabled:l.enabled??!0,hasAuthHeader:l.hasAuthHeader??!1}),a=i.map(s),r=c.map(s);return JSON.stringify(a)!==JSON.stringify(r)},[i,c]),R=n.useCallback(async()=>{if(m)return;const s=new Set;for(const a of i){const r=(a.id||"").trim(),l=(a.url||"").trim();if(!r){d({intent:"error",title:"Missing id",message:"Every server needs an id."});return}if(!l){d({intent:"error",title:"Missing URL",message:`Server "${r}" needs a URL.`});return}if(s.has(r)){d({intent:"error",title:"Duplicate id",message:`"${r}" is used more than once.`});return}s.add(r)}N(!0);try{const a=i.map(t=>{const h={id:t.id.trim(),url:t.url.trim()};return t.label&&(h.label=t.label),typeof t.maxTools=="number"&&(h.maxTools=t.maxTools),typeof t.enabled=="boolean"&&(h.enabled=t.enabled),t.authHeader&&t.authHeader.length>0&&(h.authHeader=t.authHeader),h}),r=await p.saveMcp(a),l=Array.isArray(r.servers)?r.servers:[];k(l),o(l.map(t=>({...t}))),d({intent:"success",title:"MCP servers saved",message:`${l.length} server(s) written.`})}catch(a){const r=a instanceof Error?a.message:"save failed";d({intent:"error",title:"Save failed",message:r})}finally{N(!1)}},[p,i,m,d]),z=n.useCallback(()=>{c&&o(c.map(s=>({...s})))},[c]);return e.jsxs("div",{children:[e.jsxs("div",{className:"kv-page-head",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"kv-page-title",children:"MCP Servers"}),e.jsx("p",{className:"kv-page-sub",children:"Model Context Protocol tool providers the CLI can call. Auth headers are redacted — leave blank to keep the stored value."})]}),e.jsxs("div",{className:"kv-head-actions",children:[e.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:C,disabled:m,children:[e.jsx(O,{size:14})," Add server"]}),e.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:z,disabled:!w||m,title:"Discard unsaved changes",children:[e.jsx(U,{size:14})," Reset"]}),e.jsxs("button",{className:"kv-btn kv-btn-primary kv-btn-sm",onClick:()=>void R(),disabled:!w||m,children:[m?e.jsx("span",{className:"kv-spinner kv-spinner-sm"}):e.jsx(_,{size:14}),"Save changes"]})]})]}),f?e.jsxs("div",{className:"kv-banner-error",children:[e.jsx(D,{size:15})," ",f]}):null,A&&!c?e.jsxs("div",{className:"kv-loading",children:[e.jsx("span",{className:"kv-spinner"})," loading MCP registry…"]}):i.length===0?e.jsx(T,{icon:S,title:"No MCP servers configured",description:"Connect an MCP server to give the CLI extra tools (databases, search, browsers, …).",action:{label:"Add your first server",onClick:C}}):e.jsx("div",{className:"kv-mcp-list",children:i.map((s,a)=>e.jsxs("div",{className:"kv-card kv-mcp-card",children:[e.jsxs("div",{className:"kv-mcp-card-head",children:[e.jsx("span",{className:"kv-mcp-icon","aria-hidden":!0,children:e.jsx(S,{size:15})}),e.jsx("span",{className:"kv-mcp-card-id kv-mono",children:s.id||e.jsx("span",{className:"kv-muted-inline",children:"new server"})}),e.jsxs("label",{className:"kv-switch-row kv-mcp-enable",title:"Enable this server",children:[e.jsxs("span",{className:"kv-switch",children:[e.jsx("input",{type:"checkbox",checked:s.enabled??!0,onChange:r=>v(a,{enabled:r.target.checked})}),e.jsx("span",{className:"kv-switch-track"}),e.jsx("span",{className:"kv-switch-thumb"})]}),e.jsx("span",{className:"kv-switch-label",children:s.enabled??!0?"enabled":"disabled"})]}),e.jsx("button",{className:"kv-btn kv-btn-danger kv-btn-sm kv-mcp-remove",onClick:()=>x(a),title:"Remove server","aria-label":`Remove ${s.id||"server"}`,children:e.jsx(B,{size:14})})]}),e.jsxs("div",{className:"kv-mcp-grid",children:[e.jsxs("div",{className:"kv-field",children:[e.jsx("label",{className:"kv-label",children:"ID"}),e.jsx("input",{className:"kv-input",value:s.id,placeholder:"my-server",onChange:r=>v(a,{id:r.target.value})})]}),e.jsxs("div",{className:"kv-field",children:[e.jsx("label",{className:"kv-label",children:"Label"}),e.jsx("input",{className:"kv-input",value:s.label??"",placeholder:"Friendly name",onChange:r=>v(a,{label:r.target.value})})]}),e.jsxs("div",{className:"kv-field kv-mcp-url",children:[e.jsx("label",{className:"kv-label",children:"URL"}),e.jsx("input",{className:"kv-input",value:s.url,placeholder:"https://mcp.example.com/sse",onChange:r=>v(a,{url:r.target.value})})]}),e.jsxs("div",{className:"kv-field",children:[e.jsx("label",{className:"kv-label",children:"Max tools"}),e.jsx("input",{className:"kv-input",type:"number",min:0,value:s.maxTools??"",placeholder:"auto",onChange:r=>v(a,{maxTools:r.target.value===""?void 0:Number(r.target.value)})})]}),e.jsxs("div",{className:"kv-field kv-mcp-url",children:[e.jsxs("label",{className:"kv-label",children:[e.jsx(F,{size:12})," Auth header"," ",s.hasAuthHeader?e.jsx("span",{className:"kv-tag",children:"stored"}):null]}),e.jsx("input",{className:"kv-input",type:"password",value:s.authHeader??"",placeholder:s.hasAuthHeader?"•••• stored — leave blank to keep":"Authorization: Bearer …",onChange:r=>v(a,{authHeader:r.target.value})}),s.authHeader?e.jsxs("div",{className:"kv-field-hint",children:[e.jsx(J,{size:11})," will overwrite the stored header on save"]}):null]})]})]},s._new?`new-${a}`:`${s.id}-${a}`))}),e.jsx(E,{open:u!==null,title:"Remove MCP server",message:u!==null?e.jsxs(e.Fragment,{children:["Remove ",e.jsx("code",{children:((M=i[u])==null?void 0:M.id)||"this server"})," from the registry? It will be deleted when you save changes."]}):null,confirmLabel:"Remove",onConfirm:()=>{u!==null&&P(u)},onCancel:()=>x(null)})]})}function ae(){return e.jsx(I,{children:e.jsx(X,{})})}export{ae as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as N,u as w,a as y,b as C,d as b,r as h,j as s,B as A,M as R}from"./index-C-MAoMUW.js";import{S as o}from"./StatCard-Bl4JiW8I.js";import{E as $}from"./EmptyState-BZSWUG-H.js";import{u as S}from"./pages-DBjxqPsI.js";import{f as a,a as l,b as T,c as I,t as L,s as M}from"./format-ChobNBtf.js";import{R as z}from"./refresh-cw-CVNMUM98.js";import{C as D,D as E}from"./dollar-sign-CyqQR2qm.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const v=N("Activity",[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]]),V=1440*60*1e3;function _(){const r=w(),i=y(),c=C(),u=b(),{data:e,loading:f,error:d,reload:x}=S(async t=>{const[n,p,j]=await Promise.all([r.status(t),r.usage(t),r.sessions(t)]);return{status:n,usage:p,sessions:j}},[]),k=h.useMemo(()=>{if(!e)return 0;const t=Date.now()-V;return e.sessions.filter(n=>n.createdAt>=t).length},[e]),m=h.useMemo(()=>u.slice(-40).reverse(),[u]),g=c.agentsRunning||(e==null?void 0:e.status.runningAgents)||0;return f&&!e?s.jsxs("div",{className:"kv-loading",children:[s.jsx("span",{className:"kv-spinner"})," loading overview..."]}):s.jsxs("div",{children:[s.jsxs("div",{className:"kv-page-head",children:[s.jsxs("div",{children:[s.jsx("h1",{className:"kv-page-title",children:"Overview"}),s.jsx("p",{className:"kv-page-sub",children:"Local agent activity, sessions and spend - live from your machine."})]}),s.jsx("div",{className:"kv-head-actions",children:s.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:x,title:"Refresh",children:[s.jsx(z,{size:14})," Refresh"]})})]}),d?s.jsxs("div",{className:"kv-banner-error",children:[s.jsx(v,{size:15})," ",d]}):null,s.jsxs("div",{className:"kv-grid kv-grid-4",children:[s.jsx(o,{label:"Running Agents",value:a(g),icon:A,accent:g>0,foot:`${a((e==null?void 0:e.status.totalAgents)??0)} total tracked`,onClick:()=>i("/agents"),title:"View agents"}),s.jsx(o,{label:"Sessions (24h)",value:a(k),icon:R,foot:`${a((e==null?void 0:e.usage.totals.sessions)??0)} all-time`,onClick:()=>i("/sessions"),title:"View sessions"}),s.jsx(o,{label:"Tokens Charged",value:l((e==null?void 0:e.usage.totals.kryvenTokens)??0),icon:D,foot:`${l((e==null?void 0:e.usage.totals.promptTokens)??0)} in / ${l((e==null?void 0:e.usage.totals.completionTokens)??0)} out`,onClick:()=>i("/usage"),title:"View usage"}),s.jsx(o,{label:"Total Spend",value:T((e==null?void 0:e.usage.totals.costUsd)??0),icon:E,accent:!0,foot:`${a((e==null?void 0:e.usage.totals.messages)??0)} messages`,onClick:()=>i("/usage"),title:"View usage"})]}),s.jsxs("div",{className:"kv-section-head",children:[s.jsxs("h2",{className:"kv-section-title",children:[s.jsx(v,{size:16})," Recent Activity"]}),s.jsx("span",{className:"kv-refresh",children:c.events?`${a(c.events)} events`:"waiting for events"})]}),s.jsx("div",{className:"kv-card",children:m.length===0?s.jsx($,{icon:v,title:"No activity yet",description:"Run an agent, start a workflow, or chat in the CLI - live events will stream here."}):s.jsx("div",{className:"kv-feed",children:m.map(t=>{const n=t.agentId||t.wfId||t.sessionId;return s.jsxs("div",{className:"kv-feed-row",children:[s.jsx("span",{className:"kv-feed-ts",children:I(t.ts)}),s.jsx("span",{className:`kv-feed-src ${t.source}`,children:t.source.slice(0,4)}),s.jsx("span",{className:"kv-feed-text",title:t.text,children:L(t.text||t.type,120)}),n?s.jsx("span",{className:"kv-feed-id",children:M(n)}):null]},`${t.seq}-${t.ts}`)})})})]})}export{_ as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as C,u as y,a as _,e as w,b as A,r as h,j as s,M as E}from"./index-C-MAoMUW.js";import{E as p}from"./EmptyState-BZSWUG-H.js";import{u as g}from"./pages-DBjxqPsI.js";import{f as u,s as N,e as R,b,a as j,t as z}from"./format-ChobNBtf.js";import{R as I}from"./refresh-cw-CVNMUM98.js";import{C as M,D as $}from"./dollar-sign-CyqQR2qm.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const T=C("Hash",[["line",{x1:"4",x2:"20",y1:"9",y2:"9",key:"4lhtct"}],["line",{x1:"4",x2:"20",y1:"15",y2:"15",key:"vyu0kd"}],["line",{x1:"10",x2:"8",y1:"3",y2:"21",key:"1ggp8o"}],["line",{x1:"16",x2:"14",y1:"3",y2:"21",key:"weycgp"}]]);function D(a){switch(a){case"user":return"user";case"assistant":return"assistant";case"tool":return"tool";case"system":return"system";default:return"system"}}function f(a){if(typeof a.content=="string")return a.content;if(a.content==null){if(a.tool_calls)try{return`[tool call] ${z(JSON.stringify(a.tool_calls),240)}`}catch{return"[tool call]"}return""}try{return JSON.stringify(a.content)}catch{return String(a.content)}}function H({id:a,usage:c}){const d=y(),{data:r,loading:n,error:m}=g(e=>d.session(a,e),[a]);if(n&&!r)return s.jsxs("div",{className:"kv-loading",children:[s.jsx("span",{className:"kv-spinner"})," loading transcript..."]});if(m)return s.jsx("div",{className:"kv-banner-error",children:m});if(!r)return s.jsx("div",{className:"kv-wf-loglabel",children:"no session loaded."});const i=r.messages.filter(e=>!e.ephemeral&&(f(e).trim()||e.tool_calls));return s.jsxs("div",{className:"kv-detail",children:[s.jsxs("div",{className:"kv-detail-head",children:[s.jsx("h2",{className:"kv-page-title",style:{fontSize:18},children:N(r.meta.id)}),s.jsx("span",{className:"kv-tag",children:r.meta.model}),s.jsx("span",{className:"kv-tag",children:r.meta.mood}),s.jsxs("div",{className:"kv-detail-stats",children:[s.jsxs("span",{children:[s.jsx(T,{size:12,style:{verticalAlign:"-2px",marginRight:4}}),s.jsx("b",{children:u(i.length)})," msgs"]}),s.jsxs("span",{children:[s.jsx(M,{size:12,style:{verticalAlign:"-2px",marginRight:4}}),s.jsx("b",{children:j((c==null?void 0:c.kryvenTokens)??0)})," tokens"]}),s.jsxs("span",{children:[s.jsx($,{size:12,style:{verticalAlign:"-2px",marginRight:4}}),s.jsx("b",{children:b((c==null?void 0:c.costUsd)??0)})]})]})]}),s.jsx("div",{className:"kv-detail-v",style:{marginBottom:12,fontSize:11},children:r.meta.cwd}),i.length===0?s.jsx(p,{title:"Empty transcript",description:"This session has no displayable messages."}):s.jsx("div",{className:"kv-transcript",children:i.map((e,x)=>{var v;const l=D(e.role);return s.jsxs("div",{className:`kv-msg ${l}`,children:[s.jsxs("div",{className:"kv-msg-role",children:[s.jsx("span",{children:e.role||"system"}),(v=e.usage)!=null&&v.kryven_tokens_charged?s.jsxs("span",{style:{color:"var(--kv-muted-2)"},children:[j(e.usage.kryven_tokens_charged)," tok"]}):null]}),s.jsx("div",{className:"kv-msg-content",children:f(e)||"-"}),e.usage?s.jsxs("div",{className:"kv-msg-usage",children:[u(e.usage.prompt_tokens||0)," in / ",u(e.usage.completion_tokens||0)," ","out",e.usage.tier?` / ${e.usage.tier}`:""]}):null]},x)})})]})}function q(){const a=y(),c=_(),{id:d}=w(),r=A(),n=g(t=>a.sessions(t),[]),m=g(t=>a.usage(t),[]),[i,e]=h.useState(d??null);h.useEffect(()=>{d&&e(d)},[d]);const x=r.events;h.useEffect(()=>{n.data&&n.reload()},[x]);const l=h.useMemo(()=>[...n.data??[]].sort((t,o)=>o.createdAt-t.createdAt),[n.data]);h.useEffect(()=>{!i&&l.length&&e(l[0].id)},[l,i]);const v=h.useMemo(()=>{var o;const t=new Map;for(const k of((o=m.data)==null?void 0:o.sessions)??[])t.set(k.id,k);return t},[m.data]),S=t=>{e(t),c(`/sessions/${t}`,{replace:!0})};return n.loading&&!n.data?s.jsxs("div",{className:"kv-loading",children:[s.jsx("span",{className:"kv-spinner"})," loading sessions..."]}):s.jsxs("div",{children:[s.jsxs("div",{className:"kv-page-head",children:[s.jsxs("div",{children:[s.jsx("h1",{className:"kv-page-title",children:"Sessions"}),s.jsxs("p",{className:"kv-page-sub",children:[u(l.length)," saved ",l.length===1?"session":"sessions"," - transcripts, tokens and cost."]})]}),s.jsx("div",{className:"kv-head-actions",children:s.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:()=>{n.reload(),m.reload()},title:"Refresh",children:[s.jsx(I,{size:14})," Refresh"]})})]}),n.error?s.jsx("div",{className:"kv-banner-error",children:n.error}):null,l.length===0?s.jsx("div",{className:"kv-card",children:s.jsx(p,{icon:E,title:"No sessions yet",description:"Chat in the CLI and your sessions - with full transcripts, token usage and cost - appear here."})}):s.jsxs("div",{className:"kv-split",children:[s.jsx("div",{className:"kv-master",children:l.map(t=>{const o=v.get(t.id);return s.jsxs("button",{className:`kv-master-item${i===t.id?" active":""}`,onClick:()=>S(t.id),children:[s.jsxs("div",{className:"kv-master-top",children:[s.jsx("span",{className:"kv-master-id",children:N(t.id)}),s.jsx("span",{className:"kv-mono",style:{fontSize:10.5,color:"var(--kv-muted-2)"},children:R(t.createdAt)})]}),s.jsxs("div",{className:"kv-master-sub",children:[s.jsx("span",{className:"kv-tag",children:t.model}),s.jsx("span",{children:t.mood}),o?s.jsx("span",{children:b(o.costUsd)}):null]})]},t.id)})}),i?s.jsx(H,{id:i,usage:v.get(i)}):s.jsx("div",{className:"kv-detail",children:s.jsx(p,{title:"Select a session",description:"Pick a session on the left to view its transcript."})})]})]})}export{q as default};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{c as g,j as s,u as L,a as $,r as l,A as q,h as A}from"./index-C-MAoMUW.js";import{E as P}from"./EmptyState-BZSWUG-H.js";import{T as F,u as M}from"./Toast-CFoZ2eqS.js";import{X as R}from"./pages-group2-BhbgCBuB.js";import{R as T}from"./refresh-cw-CVNMUM98.js";import"./triangle-alert-p58-WCLo.js";import"./circle-check-m7S2YKDA.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const I=g("ArrowUpRight",[["path",{d:"M7 7h10v10",key:"1tivn9"}],["path",{d:"M7 17 17 7",key:"1vkiza"}]]);/**
|
|
7
|
+
* @license lucide-react v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const K=g("Play",[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]]);/**
|
|
12
|
+
* @license lucide-react v0.468.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const D=g("Search",[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["path",{d:"m21 21-4.3-4.3",key:"1qie3q"}]]);function U(i){return i||"skill"}function O(){const i=L(),x=$(),{toast:c}=M(),[t,j]=l.useState(null),[f,N]=l.useState(null),[d,b]=l.useState(!0),[u,E]=l.useState(""),[k,y]=l.useState({}),[r,o]=l.useState(null),[m,C]=l.useState(""),v=l.useCallback(async e=>{b(!0),N(null);try{const a=await i.skills(e);j(a)}catch(a){if(a instanceof q&&a.status===401)return;N(a instanceof Error?a.message:"failed to load skills"),j([])}finally{b(!1)}},[i]);l.useEffect(()=>{const e=new AbortController;return v(e.signal),()=>e.abort()},[v]);const h=l.useCallback(async(e,a)=>{y(n=>({...n,[e.name]:!0}));try{const n=await i.runSkill(e.name,a);if(n.ok){const p=n.id;c({intent:"success",title:`Running /${e.name}`,message:p?"Spawned a background agent — opening it on Agents…":"Skill started."}),p&&window.setTimeout(()=>x(`/agents/${p}`),650)}else c({intent:"error",title:`Could not start /${e.name}`,message:n.reason||"the runner refused the request"})}catch(n){c({intent:"error",title:`Failed to run /${e.name}`,message:n instanceof Error?n.message:"request failed"})}finally{y(n=>({...n,[e.name]:!1}))}},[i,x,c]),z=l.useCallback(e=>{C(""),o({skill:e})},[]),S=l.useCallback(()=>{if(!r)return;const e=r.skill,a=m.trim();o(null),h(e,a||void 0)},[r,m,h]),w=l.useMemo(()=>{const e=t??[],a=u.trim().toLowerCase();return a?e.filter(n=>n.name.toLowerCase().includes(a)||(n.description||"").toLowerCase().includes(a)||(n.scope||"").toLowerCase().includes(a)):e},[t,u]);return s.jsxs("div",{children:[s.jsxs("div",{className:"kv-page-head",children:[s.jsxs("div",{children:[s.jsx("h1",{className:"kv-page-title",children:"Skills"}),s.jsx("p",{className:"kv-page-sub",children:"One-click skills — each launches a background agent that runs the command for you."})]}),s.jsx("div",{className:"kv-head-actions",children:s.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:()=>void v(),disabled:d,title:"Reload skills",children:[s.jsx(T,{size:14,className:d?"kv-spin-icon":""}),"Refresh"]})})]}),f?s.jsxs("div",{className:"kv-banner-error",children:[s.jsx(R,{size:15})," ",f]}):null,t&&t.length>0?s.jsxs("div",{className:"kv-search-row",children:[s.jsx("span",{className:"kv-search-icon","aria-hidden":!0,children:s.jsx(D,{size:15})}),s.jsx("input",{className:"kv-input kv-search-input",placeholder:"Filter skills…",value:u,onChange:e=>E(e.target.value)})]}):null,d&&!t?s.jsxs("div",{className:"kv-loading",children:[s.jsx("span",{className:"kv-spinner"})," loading skills…"]}):w.length===0?s.jsx(P,{icon:A,title:t&&t.length>0?"No matching skills":"No skills found",description:t&&t.length>0?"Try a different search term.":"Skills are markdown files in your project or home .kryven/skills directory. Add one and refresh."}):s.jsx("div",{className:"kv-grid kv-grid-3 kv-skill-grid",children:w.map(e=>s.jsxs("div",{className:"kv-card kv-skill-card",children:[s.jsxs("div",{className:"kv-skill-card-head",children:[s.jsx("span",{className:"kv-skill-icon","aria-hidden":!0,children:s.jsx(A,{size:16})}),s.jsx("span",{className:"kv-tag",children:U(e.scope)})]}),s.jsxs("div",{className:"kv-skill-name kv-mono",children:["/",e.name]}),s.jsx("p",{className:"kv-skill-desc",children:e.description||"No description provided."}),s.jsxs("div",{className:"kv-skill-actions",children:[s.jsxs("button",{className:"kv-btn kv-btn-primary kv-btn-sm",onClick:()=>void h(e),disabled:!!k[e.name],children:[k[e.name]?s.jsx("span",{className:"kv-spinner kv-spinner-sm"}):s.jsx(K,{size:13}),"Run"]}),s.jsx("button",{className:"kv-btn kv-btn-sm",onClick:()=>z(e),disabled:!!k[e.name],title:"Run with arguments",children:"With args…"})]})]},`${e.scope}:${e.name}`))}),r?s.jsx("div",{className:"kv-modal-backdrop",role:"presentation",onClick:()=>o(null),children:s.jsxs("div",{className:"kv-modal",role:"dialog","aria-modal":"true","aria-label":`Run ${r.skill.name} with arguments`,onClick:e=>e.stopPropagation(),children:[s.jsxs("div",{className:"kv-modal-head",children:[s.jsxs("h3",{className:"kv-modal-title kv-mono",children:["/",r.skill.name]}),s.jsx("button",{className:"kv-toast-close",onClick:()=>o(null),"aria-label":"Close",children:s.jsx(R,{size:15})})]}),s.jsx("p",{className:"kv-modal-sub",children:r.skill.description||"Provide optional input for this skill."}),s.jsxs("div",{className:"kv-field",children:[s.jsx("label",{className:"kv-label",htmlFor:"kv-skill-args",children:"Arguments (optional)"}),s.jsx("textarea",{id:"kv-skill-args",className:"kv-textarea",placeholder:"e.g. a topic, file path, or question…",value:m,autoFocus:!0,onChange:e=>C(e.target.value),onKeyDown:e=>{(e.metaKey||e.ctrlKey)&&e.key==="Enter"&&(e.preventDefault(),S())}})]}),s.jsxs("div",{className:"kv-confirm-actions",children:[s.jsx("button",{className:"kv-btn",onClick:()=>o(null),children:"Cancel"}),s.jsxs("button",{className:"kv-btn kv-btn-primary",onClick:S,children:[s.jsx(I,{size:14})," Run skill"]})]})]})}):null]})}function V(){return s.jsx(F,{children:s.jsx(O,{})})}export{V as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as h,j as s}from"./index-C-MAoMUW.js";import{g as y}from"./format-ChobNBtf.js";function m({data:n,dataKey:p,width:r=400,height:e=56,from:o="#8b5cf6",to:t="#ec4899",fill:a=!0,showLast:d=!0,className:c="",ariaLabel:l}){const v=h.useId().replace(/[^a-zA-Z0-9_-]/g,""),k=`kvSpark-stroke-${v}`,u=`kvSpark-fill-${v}`,i=n&&n.length?y(n,p,r,e,6,8):{path:"",fill:"",circles:[]},f=i.circles[i.circles.length-1],j=!i.path;return s.jsxs("svg",{className:`kv-spark${c?` ${c}`:""}`,viewBox:`0 0 ${r} ${e}`,preserveAspectRatio:"none",role:"img","aria-label":l??"trend sparkline",children:[s.jsxs("defs",{children:[s.jsxs("linearGradient",{id:k,x1:"0",y1:"0",x2:"1",y2:"0",children:[s.jsx("stop",{offset:"0%",stopColor:o}),s.jsx("stop",{offset:"100%",stopColor:t})]}),s.jsxs("linearGradient",{id:u,x1:"0",y1:"0",x2:"0",y2:"1",children:[s.jsx("stop",{offset:"0%",stopColor:o,stopOpacity:"0.32"}),s.jsx("stop",{offset:"100%",stopColor:t,stopOpacity:"0"})]})]}),j?s.jsx("line",{x1:"0",y1:e-8,x2:r,y2:e-8,stroke:"rgba(255,255,255,0.12)",strokeWidth:"2",strokeDasharray:"4 5"}):s.jsxs(s.Fragment,{children:[a&&i.fill?s.jsx("path",{d:i.fill,fill:`url(#${u})`,stroke:"none"}):null,s.jsx("path",{d:i.path,fill:"none",stroke:`url(#${k})`,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),d&&f?s.jsx("circle",{cx:f.x,cy:f.y,r:"3",fill:t,stroke:"#0a0a0f",strokeWidth:"1.5"}):null]})]})}function g({label:n,value:p,foot:r,icon:e,accent:o=!1,spark:t,onClick:a,className:d="",title:c}){const l=typeof a=="function";return s.jsxs("div",{className:`kv-stat kv-statcard${l?" kv-statcard-click":""}${d?` ${d}`:""}`,onClick:a,role:l?"button":void 0,tabIndex:l?0:void 0,onKeyDown:l?x=>{(x.key==="Enter"||x.key===" ")&&(x.preventDefault(),a==null||a())}:void 0,title:c,children:[s.jsxs("div",{className:"kv-statcard-head",children:[s.jsx("div",{className:"kv-stat-label",children:n}),e?s.jsx("span",{className:"kv-statcard-icon","aria-hidden":!0,children:s.jsx(e,{size:16})}):null]}),s.jsx("div",{className:`kv-stat-value${o?" kv-grad-text":""}`,children:p}),r!=null?s.jsx("div",{className:"kv-stat-foot",children:r}):null,t&&t.data.length?s.jsx("div",{className:"kv-statcard-spark",children:s.jsx(m,{data:t.data,dataKey:t.dataKey,width:260,height:36})}):null]})}export{g as S,m as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as l}from"./index-C-MAoMUW.js";function u(e){switch(e){case"running":case"active":case"low":return"running";case"completed":case"done":case"applied":return"completed";case"error":case"failed":case"high":case"critical":return"error";case"timeout":return"timeout";case"killed":case"medium":case"pending":case"gate":return"killed";case"idle":case"neutral":return"neutral";default:return"neutral"}}function o(e){return e?e.charAt(0).toUpperCase()+e.slice(1):""}function d({status:e,label:a,size:n="md",className:t="",title:s}){const i=u(String(e)),r=a??o(String(e)),c=n==="sm"?" kv-pill-sm":"";return l.jsx("span",{className:`kv-pill ${i}${c}${t?` ${t}`:""}`,title:s??r,children:r})}export{d as S};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{c as f,r,j as e}from"./index-C-MAoMUW.js";import{T as x}from"./triangle-alert-p58-WCLo.js";import{C as k}from"./circle-check-m7S2YKDA.js";import{X as p}from"./pages-group2-BhbgCBuB.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const T=f("CircleX",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);/**
|
|
7
|
+
* @license lucide-react v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const j=f("Info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]]),v=r.createContext(null),C={success:k,error:T,warning:x,info:j};let g=1;function E({children:s}){const[u,c]=r.useState([]),l=r.useRef(new Map),i=r.useCallback(t=>{c(a=>a.filter(n=>n.id!==t));const o=l.current.get(t);o&&(clearTimeout(o),l.current.delete(t))},[]),d=r.useCallback(t=>{const o=typeof t=="string"?{message:t}:t,a=g++,n={id:a,message:o.message,title:o.title,intent:o.intent??"info",ttl:o.ttl??4200};if(c(m=>[...m,n]),n.ttl>0){const m=setTimeout(()=>i(a),n.ttl);l.current.set(a,m)}return a},[i]);r.useEffect(()=>{const t=l.current;return()=>{for(const o of t.values())clearTimeout(o);t.clear()}},[]);const h=r.useMemo(()=>({toast:d,dismiss:i}),[d,i]);return e.jsxs(v.Provider,{value:h,children:[s,e.jsx("div",{className:"kv-toast-stack",role:"region","aria-live":"polite","aria-label":"Notifications",children:u.map(t=>e.jsx(y,{toast:t,onClose:()=>i(t.id)},t.id))})]})}function z(){const s=r.useContext(v);if(!s)throw new Error("useToast must be used within <ToastProvider>");return s}function y({toast:s,onClose:u}){const c=C[s.intent];return e.jsxs("div",{className:`kv-toast kv-toast-${s.intent}`,role:"status",children:[e.jsx("span",{className:"kv-toast-icon","aria-hidden":!0,children:e.jsx(c,{size:17})}),e.jsxs("div",{className:"kv-toast-body",children:[s.title?e.jsx("div",{className:"kv-toast-title",children:s.title}):null,e.jsx("div",{className:"kv-toast-msg",children:s.message})]}),e.jsx("button",{className:"kv-toast-close",onClick:u,"aria-label":"Dismiss",children:e.jsx(p,{size:14})})]})}export{E as T,z as u};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as b,u as M,r as d,j as s,C as x,M as C}from"./index-C-MAoMUW.js";import{S as i,a as j}from"./StatCard-Bl4JiW8I.js";import{E as w}from"./EmptyState-BZSWUG-H.js";import{u as U}from"./pages-DBjxqPsI.js";import{f as r,a as o,b as h,s as S,e as A}from"./format-ChobNBtf.js";import{R as z}from"./refresh-cw-CVNMUM98.js";import{C as R,D as L}from"./dollar-sign-CyqQR2qm.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const p=b("Layers",[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]]);function K(){const u=M(),{data:a,loading:N,error:k,reload:g}=U(e=>u.usage(e),[]),v=d.useMemo(()=>[...(a==null?void 0:a.sessions)??[]].sort((n,c)=>n.createdAt-c.createdAt).map(n=>{var c;return{tokens:n.kryvenTokens||0,cost:Number((c=n.costUsd)==null?void 0:c.toFixed(4))||0}}),[a]),m=d.useMemo(()=>{const e=new Map;for(const n of(a==null?void 0:a.sessions)??[]){const c=n.model||"unknown";let l=e.get(c);l||(l={model:c,sessions:0,messages:0,promptTokens:0,completionTokens:0,kryvenTokens:0,costUsd:0},e.set(c,l)),l.sessions+=1,l.messages+=n.messages||0,l.promptTokens+=n.promptTokens||0,l.completionTokens+=n.completionTokens||0,l.kryvenTokens+=n.kryvenTokens||0,l.costUsd+=n.costUsd||0}return[...e.values()].sort((n,c)=>c.costUsd-n.costUsd)},[a]),y=d.useMemo(()=>Math.max(...m.map(e=>e.costUsd),1e-4),[m]),f=d.useMemo(()=>[...(a==null?void 0:a.sessions)??[]].sort((e,n)=>n.createdAt-e.createdAt).slice(0,40),[a]),t=a==null?void 0:a.totals;if(N&&!a)return s.jsxs("div",{className:"kv-loading",children:[s.jsx("span",{className:"kv-spinner"})," loading usage..."]});const T=!t||t.sessions===0;return s.jsxs("div",{children:[s.jsxs("div",{className:"kv-page-head",children:[s.jsxs("div",{children:[s.jsx("h1",{className:"kv-page-title",children:"Usage"}),s.jsx("p",{className:"kv-page-sub",children:"Tokens charged and spend across all local sessions."})]}),s.jsx("div",{className:"kv-head-actions",children:s.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:g,title:"Refresh",children:[s.jsx(z,{size:14})," Refresh"]})})]}),k?s.jsx("div",{className:"kv-banner-error",children:k}):null,T?s.jsx("div",{className:"kv-card",children:s.jsx(w,{icon:x,title:"No usage recorded",description:"Once you run chats or agents, token and cost analytics show up here."})}):s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"kv-grid kv-grid-4",children:[s.jsx(i,{label:"Sessions",value:r(t.sessions),icon:p}),s.jsx(i,{label:"Messages",value:r(t.messages),icon:C}),s.jsx(i,{label:"Tokens Charged",value:o(t.kryvenTokens),icon:R,foot:`${o(t.promptTokens)} in / ${o(t.completionTokens)} out`}),s.jsx(i,{label:"Total Spend",value:h(t.costUsd),icon:L,accent:!0})]}),s.jsxs("div",{className:"kv-usage-charts",children:[s.jsxs("div",{className:"kv-chart-card",children:[s.jsxs("div",{className:"kv-chart-head",children:[s.jsx("span",{className:"kv-chart-title",children:"Tokens / session"}),s.jsx("span",{className:"kv-chart-val",children:o(t.kryvenTokens)})]}),s.jsx(j,{className:"kv-chart-svg",data:v,dataKey:"tokens",width:420,height:92,ariaLabel:"Tokens charged per session"})]}),s.jsxs("div",{className:"kv-chart-card",children:[s.jsxs("div",{className:"kv-chart-head",children:[s.jsx("span",{className:"kv-chart-title",children:"Cost / session"}),s.jsx("span",{className:"kv-chart-val",children:h(t.costUsd)})]}),s.jsx(j,{className:"kv-chart-svg",data:v,dataKey:"cost",width:420,height:92,from:"#ec4899",to:"#8b5cf6",ariaLabel:"Cost per session"})]})]}),s.jsx("div",{className:"kv-section-head",children:s.jsxs("h2",{className:"kv-section-title",children:[s.jsx(p,{size:16})," By model"]})}),s.jsx("div",{className:"kv-card",style:{padding:0,overflow:"hidden",marginBottom:26},children:s.jsxs("table",{className:"kv-table",children:[s.jsx("thead",{children:s.jsxs("tr",{children:[s.jsx("th",{children:"Model"}),s.jsx("th",{className:"kv-num",children:"Sessions"}),s.jsx("th",{className:"kv-num",children:"Messages"}),s.jsx("th",{className:"kv-num",children:"In"}),s.jsx("th",{className:"kv-num",children:"Out"}),s.jsx("th",{className:"kv-num",children:"Charged"}),s.jsx("th",{className:"kv-num",children:"Cost"}),s.jsx("th",{style:{width:120},children:"Spend"})]})}),s.jsx("tbody",{children:m.map(e=>s.jsxs("tr",{children:[s.jsx("td",{className:"kv-mono",children:e.model}),s.jsx("td",{className:"kv-num",children:r(e.sessions)}),s.jsx("td",{className:"kv-num",children:r(e.messages)}),s.jsx("td",{className:"kv-num",children:o(e.promptTokens)}),s.jsx("td",{className:"kv-num",children:o(e.completionTokens)}),s.jsx("td",{className:"kv-num",children:o(e.kryvenTokens)}),s.jsx("td",{className:"kv-num",children:h(e.costUsd)}),s.jsx("td",{children:s.jsx("span",{className:"kv-bar",style:{width:`${Math.max(4,e.costUsd/y*100)}%`}})})]},e.model))})]})}),s.jsx("div",{className:"kv-section-head",children:s.jsxs("h2",{className:"kv-section-title",children:[s.jsx(x,{size:16})," Recent sessions"]})}),s.jsx("div",{className:"kv-card",style:{padding:0,overflow:"hidden"},children:s.jsxs("table",{className:"kv-table",children:[s.jsx("thead",{children:s.jsxs("tr",{children:[s.jsx("th",{children:"Session"}),s.jsx("th",{children:"Model"}),s.jsx("th",{children:"When"}),s.jsx("th",{className:"kv-num",children:"Messages"}),s.jsx("th",{className:"kv-num",children:"Charged"}),s.jsx("th",{className:"kv-num",children:"Cost"})]})}),s.jsx("tbody",{children:f.map(e=>s.jsxs("tr",{children:[s.jsx("td",{className:"kv-mono",children:S(e.id)}),s.jsx("td",{className:"kv-mono",style:{fontSize:12},children:e.model}),s.jsx("td",{className:"kv-mono",style:{fontSize:12,color:"var(--kv-muted)"},children:A(e.createdAt)}),s.jsx("td",{className:"kv-num",children:r(e.messages)}),s.jsx("td",{className:"kv-num",children:o(e.kryvenTokens)}),s.jsx("td",{className:"kv-num",children:h(e.costUsd)})]},e.id))})]})})]})]})}export{K as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as I,u as R,a as M,e as D,g as G,r as v,j as e,W as z,R as P,S as W}from"./index-C-MAoMUW.js";import{S as w}from"./StatusBadge-C1IqqKfb.js";import{E as _}from"./EmptyState-BZSWUG-H.js";import{L as B}from"./LogTail-DH7rJjV9.js";import{u as E}from"./pages-DBjxqPsI.js";import{t as F,s as A,f as S,a as q,d as L,e as K}from"./format-ChobNBtf.js";import{R as O}from"./refresh-cw-CVNMUM98.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const H=I("GitBranch",[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]]),V=["plan","code","review","gate","apply","synthesize"],b={plan:"Plan",code:"Implement",review:"Review",gate:"Gate",apply:"Apply",synthesize:"Refine"},N=new Set(["review","gate"]);function j(s,t){const i=s==null?void 0:s[t];return typeof i=="number"?i:void 0}function p(s,t){const i=s==null?void 0:s[t];return typeof i=="string"?i:void 0}function J(s,t){const n=(Array.isArray(t==null?void 0:t.stages)?t.stages:[]).map(d=>{const u=p(d,"name")??"stage";return{name:u,label:b[u]??u,status:p(d,"status")??"pending",detail:p(d,"detail"),gateLike:N.has(u)}}),h=(Array.isArray(t==null?void 0:t.agents)?t.agents:[]).map(d=>({id:p(d,"id")??"agent",role:p(d,"role")??"agent",status:p(d,"status")??"pending",ok:typeof d.ok=="boolean"?d.ok:void 0,hasDiff:typeof d.hasDiff=="boolean"?d.hasDiff:void 0}));return{id:s,task:p(t,"task")??s,state:p(t,"state")??"running",startedAt:j(t,"startedAt"),finishedAt:j(t,"finishedAt")??null,stages:n,agents:h,tokensCharged:j(t,"tokensCharged"),applied:Array.isArray(t==null?void 0:t.applied)?t.applied.length:void 0,source:"persisted",updatedAt:j(t,"finishedAt")||j(t,"startedAt")||Date.now()}}function Q(s){const t=new Map;for(const n of s.stages??[]){const l=p(n.data,"stage")??p(n.data,"name");l&&(n.type==="workflow.stage_done"?t.set(l,"done"):n.type==="workflow.stage_started"&&t.get(l)!=="done"&&t.set(l,"running"))}const i=[...t.entries()].map(([n,l])=>({name:n,label:b[n]??n,status:l,gateLike:N.has(n)}));return{id:s.id,task:s.task??s.id,state:s.status??"running",startedAt:void 0,finishedAt:null,stages:i,agents:[],source:"live",updatedAt:s.updatedAt}}function U(s){const t=new Map(s.map(n=>[n.name,n])),i=[];for(const n of V){const l=t.get(n);l&&(i.push(l),t.delete(n))}for(const n of t.values())i.push(n);return i}function X({id:s}){const t=R(),{data:i,loading:n,error:l}=E(h=>t.agentLog(s,300,h),[s]);return n&&!i?e.jsxs("div",{className:"kv-wf-loglabel",children:["loading ",A(s)," log..."]}):l?e.jsxs("div",{className:"kv-wf-loglabel",children:["no separate log for ",A(s),"."]}):e.jsx(B,{lines:(i==null?void 0:i.lines)??[],maxHeight:260,emptyText:"no output captured..."})}function Y({wf:s,selected:t,onSelect:i}){const[n,l]=v.useState(null),h=v.useMemo(()=>U(s.stages),[s.stages]),d=s.state==="running"||s.state==="planning"||s.state==="reviewing",u=s.state==="completed"?"done":s.state==="killed"?"killed":s.state;return e.jsxs("div",{className:`kv-wf${t?" selected":""}`,onClick:i,role:"button",tabIndex:0,onKeyDown:a=>{a.key==="Enter"&&i()},children:[e.jsxs("div",{className:"kv-wf-head",children:[e.jsx(w,{status:u,size:"sm"}),e.jsx("span",{className:"kv-wf-task",title:s.task,children:F(s.task,90)}),e.jsx("span",{className:"kv-wf-id",children:A(s.id)})]}),h.length?e.jsx("div",{className:"kv-stages",children:h.map(a=>e.jsxs("span",{className:`kv-stage ${a.status}${a.gateLike?" gate":""}`,title:a.detail?`${a.label}: ${a.detail}`:`${a.label} - ${a.status}`,children:[e.jsx("span",{className:"kv-stage-dot"}),e.jsx("span",{className:"kv-stage-label",children:a.label}),a.gateLike?e.jsx("span",{className:"kv-stage-kind",children:a.name==="gate"?"gate":"rev"}):null]},a.name))}):e.jsx("div",{className:"kv-wf-loglabel",children:"waiting for first stage..."}),s.agents.length?e.jsx("div",{className:"kv-lanes",onClick:a=>a.stopPropagation(),children:s.agents.map(a=>{const f=n===a.id;return e.jsxs(P.Fragment,{children:[e.jsxs("div",{className:`kv-lane${f?" active":""}`,onClick:()=>l(f?null:a.id),title:"View sub-agent log",children:[e.jsx("span",{className:"kv-lane-role",children:a.role}),e.jsx("span",{className:"kv-lane-id",children:a.id}),a.hasDiff?e.jsx("span",{className:"kv-tag",children:"diff"}):null,e.jsx(w,{status:a.status==="done"?"completed":a.status,size:"sm"}),e.jsx(W,{size:13,style:{color:"var(--kv-muted-2)"}})]}),f?e.jsx(X,{id:a.id}):null]},a.id)})}):null,e.jsxs("div",{className:"kv-wf-meta",children:[e.jsxs("span",{children:[e.jsx("b",{children:S(s.agents.length)})," sub-agents"]}),s.applied!=null?e.jsxs("span",{children:[e.jsx("b",{children:S(s.applied)})," applied"]}):null,s.tokensCharged!=null?e.jsxs("span",{children:[e.jsx("b",{children:q(s.tokensCharged)})," tokens"]}):null,s.startedAt?e.jsx("span",{children:d?e.jsxs(e.Fragment,{children:["running ",e.jsx("b",{children:L(s.startedAt)})]}):e.jsxs(e.Fragment,{children:["took ",e.jsx("b",{children:L(s.startedAt,s.finishedAt)})]})}):e.jsxs("span",{children:["updated ",K(s.updatedAt)]}),e.jsx("span",{className:"kv-tag",style:{marginLeft:"auto"},children:s.source})]})]})}function le(){const s=R(),t=M(),{id:i}=D(),n=G(),{data:l,loading:h,error:d,reload:u}=E(r=>s.workflows(r),[]),[a,f]=v.useState(i??null);v.useEffect(()=>{i&&f(i)},[i]);const C=v.useMemo(()=>n.map(r=>`${r.id}:${r.lastType??""}`).join(","),[n]);v.useEffect(()=>{l&&u()},[C]);const y=v.useMemo(()=>{const r=new Map;for(const o of(l==null?void 0:l.runs)??[])r.set(o.id,J(o.id,o.status));for(const o of(l==null?void 0:l.live)??[]){const c=o.sessionId;if(r.has(c))continue;const g=[],x=new Set;for(const m of o.stages){const k=p(m.data,"stage")??p(m.data,"name");!k||x.has(k)||(x.add(k),g.push({name:k,label:b[k]??k,status:m.type==="workflow.stage_done"?"done":"running",gateLike:N.has(k)}))}r.set(c,{id:c,task:c,state:o.lastType==="workflow.done"?"done":"running",stages:g,agents:[],source:"live",updatedAt:o.lastTs})}for(const o of n){const c=Q(o),g=r.get(o.id);if(!g)r.set(o.id,c);else if(g.source!=="persisted"||c.updatedAt>g.updatedAt){const x=new Map(g.stages.map(m=>[m.name,m]));for(const m of c.stages)x.set(m.name,m);g.stages=[...x.values()],g.state=c.state||g.state,g.updatedAt=Math.max(g.updatedAt,c.updatedAt)}}return[...r.values()].sort((o,c)=>c.updatedAt-o.updatedAt)},[l,n]),T=v.useCallback(r=>{const o=a===r?null:r;f(o),t(o?`/workflows/${o}`:"/workflows",{replace:!0})},[t,a]),$=y.filter(r=>r.state==="running"||r.state==="planning"||r.state==="reviewing").length;return h&&!l?e.jsxs("div",{className:"kv-loading",children:[e.jsx("span",{className:"kv-spinner"})," loading workflows..."]}):e.jsxs("div",{children:[e.jsxs("div",{className:"kv-page-head",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"kv-page-title",children:"Workflows"}),e.jsxs("p",{className:"kv-page-sub",children:["Multi-agent pipelines - ",$," active. Plan -> Implement -> Review -> Gate -> Apply -> Refine."]})]}),e.jsx("div",{className:"kv-head-actions",children:e.jsxs("button",{className:"kv-btn kv-btn-sm",onClick:u,title:"Refresh",children:[e.jsx(O,{size:14})," Refresh"]})})]}),d?e.jsx("div",{className:"kv-banner-error",children:d}):null,y.length===0?e.jsx("div",{className:"kv-card",children:e.jsx(_,{icon:z,title:"No workflow runs",description:e.jsxs(e.Fragment,{children:["Kick off a multi-agent run with ",e.jsx("code",{children:'kryven workflow "your task"'})," - its DAG, stages and sub-agents will stream here live."]}),children:e.jsxs("div",{className:"kv-wf-loglabel",style:{marginTop:14},children:[e.jsx(H,{size:13,style:{verticalAlign:"-2px",marginRight:5}}),"parallel coders / reviewer gate / auto-apply"]})})}):e.jsx("div",{className:"kv-wf-list",children:y.map(r=>e.jsx(Y,{wf:r,selected:a===r.id,onSelect:()=>T(r.id)},r.id))})]})}export{le as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c}from"./index-C-MAoMUW.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const r=c("CircleCheck",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);export{r as C};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{c as e}from"./index-C-MAoMUW.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const y=e("Coins",[["circle",{cx:"8",cy:"8",r:"6",key:"3yglwk"}],["path",{d:"M18.09 10.37A6 6 0 1 1 10.34 18",key:"t5s6rm"}],["path",{d:"M7 6h1v4",key:"1obek4"}],["path",{d:"m16.71 13.88.7.71-2.82 2.82",key:"1rbuyh"}]]);/**
|
|
7
|
+
* @license lucide-react v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const o=e("DollarSign",[["line",{x1:"12",x2:"12",y1:"2",y2:"22",key:"7eqyqh"}],["path",{d:"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6",key:"1b0p4s"}]]);export{y as C,o as D};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function N(t,n,u=400,o=110,s=10,i=20){if(!t||t.length===0)return{path:"",fill:"",circles:[]};const c=t.map(r=>r[n]),f=Math.max(...c,1),e=t.map((r,a)=>{const g=t.length===1?u/2:a/(t.length-1)*u,x=s+(1-r[n]/f)*(o-s-i);return{x:g,y:x,val:r[n]}});let l=`M${e[0].x},${e[0].y}`;for(let r=1;r<e.length;r++){const a=(e[r-1].x+e[r].x)/2;l+=` C${a},${e[r-1].y} ${a},${e[r].y} ${e[r].x},${e[r].y}`}const $=e[e.length-1],h=`${l} L${$.x},${o} L${e[0].x},${o} Z`;return{path:l,fill:h,circles:e}}const m="—";function M(t){return t==null||Number.isNaN(t)?"$0.00":t>=1e3?`$${(t/1e3).toFixed(1)}k`:`$${t.toFixed(2)}`}function d(t){return t==null||Number.isNaN(t)?"0":t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(0)}K`:`${t}`}function S(t){const n=new Date(t);return Number.isNaN(n.getTime())?m:n.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",second:"2-digit"})}function b(t){const n=new Date(t);return Number.isNaN(n.getTime())?m:n.toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})}function D(t,n=Date.now()){const u=Math.max(0,n-t),o=Math.floor(u/1e3);if(o<5)return"just now";if(o<60)return`${o}s ago`;const s=Math.floor(o/60);if(s<60)return`${s}m ago`;const i=Math.floor(s/60);return i<24?`${i}h ago`:`${Math.floor(i/24)}d ago`}function L(t,n){const u=n??Date.now(),o=Math.max(0,u-t);if(o<1e3)return`${o}ms`;const s=Math.floor(o/1e3);if(s<60)return`${s}s`;const i=Math.floor(s/60),c=s%60;if(i<60)return c?`${i}m ${c}s`:`${i}m`;const f=Math.floor(i/60),e=i%60;return e?`${f}h ${e}m`:`${f}h`}function T(t,n=80){return t?t.length>n?t.slice(0,n-1)+"…":t:""}function p(t){return t&&t.length>8?t.slice(0,8):t}function y(t){return t==null||Number.isNaN(t)?"0":Math.round(t).toLocaleString("en-US")}export{d as a,M as b,S as c,L as d,D as e,y as f,N as g,b as h,p as s,T as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.kv-pill.kv-pill-sm{font-size:10px;padding:1px 7px;gap:4px}.kv-pill.kv-pill-sm:before{width:5px;height:5px}.kv-statcard{display:flex;flex-direction:column;position:relative;overflow:hidden}.kv-statcard-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.kv-statcard-head .kv-stat-label{margin-bottom:6px}.kv-statcard-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:8px;flex:0 0 auto;color:var(--kv-purple-soft);background:#8b5cf61f;border:1px solid rgba(139,92,246,.22)}.kv-statcard-spark{margin-top:12px;margin-bottom:-4px;height:36px}.kv-statcard-click{cursor:pointer;transition:border-color .13s,background .13s,transform .08s}.kv-statcard-click:hover{border-color:var(--kv-border);background:var(--kv-surface-hover)}.kv-statcard-click:active{transform:translateY(1px)}.kv-statcard-click:focus-visible{outline:none;border-color:var(--kv-purple);box-shadow:0 0 0 3px #8b5cf62e}.kv-empty-desc{color:var(--kv-muted);font-size:13px;max-width:380px;margin:0 auto}.kv-spin-icon{animation:kv-spin .9s linear infinite}.kv-sidebar-loopback{font-size:10px;color:var(--kv-muted-2)}.kv-toast-stack{position:fixed;bottom:20px;right:20px;z-index:60;display:flex;flex-direction:column;gap:10px;width:min(360px,calc(100vw - 32px));pointer-events:none}.kv-toast{pointer-events:auto;display:flex;align-items:flex-start;gap:11px;padding:12px 13px;border-radius:var(--kv-radius);background:#101019f5;border:1px solid var(--kv-border-soft);box-shadow:var(--kv-shadow);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);animation:kv-toast-in .22s cubic-bezier(.21,1.02,.73,1)}.kv-toast-icon{flex:0 0 auto;display:inline-flex;margin-top:1px}.kv-toast-body{flex:1 1 auto;min-width:0}.kv-toast-title{font-weight:600;font-size:13px;color:var(--kv-text);margin-bottom:2px}.kv-toast-msg{font-size:12.5px;color:var(--kv-text-dim);line-height:1.45;word-break:break-word}.kv-toast-close{flex:0 0 auto;background:none;border:none;color:var(--kv-muted-2);cursor:pointer;padding:2px;border-radius:5px;display:inline-flex;transition:color .13s,background .13s}.kv-toast-close:hover{color:var(--kv-text);background:var(--kv-surface-2)}.kv-toast-success{border-color:#34d39966}.kv-toast-success .kv-toast-icon{color:var(--kv-green)}.kv-toast-error{border-color:#f8717166}.kv-toast-error .kv-toast-icon{color:var(--kv-red)}.kv-toast-warning{border-color:#fbbf2466}.kv-toast-warning .kv-toast-icon{color:var(--kv-amber)}.kv-toast-info{border-color:#38bdf866}.kv-toast-info .kv-toast-icon{color:var(--kv-blue)}@keyframes kv-toast-in{0%{opacity:0;transform:translate(16px) scale(.98)}to{opacity:1;transform:translate(0) scale(1)}}.kv-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:70;background:#0202089e;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);display:flex;align-items:center;justify-content:center;padding:24px;animation:kv-fade-in .14s ease-out}.kv-modal{width:100%;max-width:440px;background:var(--kv-bg-3);border:1px solid var(--kv-border);border-radius:var(--kv-radius-lg);box-shadow:var(--kv-shadow);padding:20px 20px 18px;animation:kv-modal-in .18s cubic-bezier(.21,1.02,.73,1)}.kv-confirm-head{display:flex;align-items:center;gap:11px;margin-bottom:12px}.kv-confirm-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:10px;flex:0 0 auto}.kv-confirm-danger .kv-confirm-icon{color:var(--kv-red);background:#f871711f;border:1px solid rgba(248,113,113,.28)}.kv-confirm-primary .kv-confirm-icon{color:var(--kv-purple-soft);background:#8b5cf61f;border:1px solid rgba(139,92,246,.28)}.kv-confirm-title{font-size:16px;font-weight:700;margin:0;color:var(--kv-text)}.kv-confirm-body{font-size:13.5px;color:var(--kv-text-dim);line-height:1.55;margin-bottom:18px}.kv-confirm-body code{font-family:var(--kv-mono);font-size:12.5px;color:var(--kv-purple-soft)}.kv-confirm-actions{display:flex;justify-content:flex-end;gap:10px}.kv-spinner-sm{width:13px;height:13px;border-width:2px}@keyframes kv-fade-in{0%{opacity:0}to{opacity:1}}@keyframes kv-modal-in{0%{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.kv-logtail{position:relative}.kv-logtail-empty{color:var(--kv-muted-2);font-style:italic}.kv-logtail-line{white-space:pre-wrap;word-break:break-word}.kv-logtail-jump{position:absolute;bottom:12px;right:16px;display:inline-flex;align-items:center;gap:6px;font-family:var(--kv-sans);font-size:11.5px;font-weight:600;padding:5px 11px;border-radius:999px;border:1px solid transparent;color:#fff;background:var(--kv-grad);box-shadow:0 4px 14px #8b5cf659;cursor:pointer;transition:filter .13s,transform .08s}.kv-logtail-jump:hover{filter:brightness(1.08)}.kv-logtail-jump:active{transform:translateY(1px)}:root{--kv-purple: #8b5cf6;--kv-purple-bright: #a78bfa;--kv-purple-soft: #c4b5fd;--kv-pink: #ec4899;--kv-grad: linear-gradient(90deg, #8b5cf6, #ec4899);--kv-grad-135: linear-gradient(135deg, #8b5cf6, #ec4899);--kv-bg: #06060d;--kv-bg-2: #0a0a0f;--kv-bg-3: #101019;--kv-surface: rgba(255, 255, 255, .03);--kv-surface-2: rgba(255, 255, 255, .05);--kv-surface-hover: rgba(139, 92, 246, .08);--kv-border: rgba(139, 92, 246, .35);--kv-border-soft: rgba(255, 255, 255, .08);--kv-border-faint: rgba(255, 255, 255, .05);--kv-text: #f5f5f7;--kv-text-dim: #d4d4d8;--kv-muted: #a1a1aa;--kv-muted-2: #71717a;--kv-green: #34d399;--kv-amber: #fbbf24;--kv-red: #f87171;--kv-blue: #38bdf8;--kv-radius: 12px;--kv-radius-sm: 8px;--kv-radius-lg: 16px;--kv-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;--kv-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--kv-sidebar-w: 232px;--kv-shadow: 0 8px 30px rgba(0, 0, 0, .45)}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{background:var(--kv-bg);color:var(--kv-text);font-family:var(--kv-sans);font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}a{color:var(--kv-purple-bright);text-decoration:none}a:hover{color:var(--kv-purple-soft)}code,.kv-mono{font-family:var(--kv-mono)}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#8b5cf640;border-radius:8px;border:2px solid transparent;background-clip:padding-box}::-webkit-scrollbar-thumb:hover{background:#8b5cf666;background-clip:padding-box}.kv-app{display:flex;min-height:100vh;background:radial-gradient(900px 500px at 0% 0%,rgba(139,92,246,.08),transparent 60%),radial-gradient(900px 600px at 100% 100%,rgba(236,72,153,.06),transparent 55%),var(--kv-bg)}.kv-sidebar{width:var(--kv-sidebar-w);flex:0 0 var(--kv-sidebar-w);position:sticky;top:0;height:100vh;display:flex;flex-direction:column;background:#080810b3;border-right:1px solid var(--kv-border-soft);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);padding:18px 12px;gap:4px;overflow-y:auto}.kv-brand{display:flex;align-items:center;gap:10px;padding:4px 8px 14px}.kv-brand-logo{width:30px;height:30px;border-radius:9px;background:var(--kv-grad-135);display:flex;align-items:center;justify-content:center;color:#fff;flex:0 0 auto;box-shadow:0 4px 14px #8b5cf666}.kv-brand-name{font-weight:700;font-size:15px;color:var(--kv-text);line-height:1.1}.kv-brand-sub{font-size:10.5px;color:var(--kv-muted);font-family:var(--kv-mono);letter-spacing:.04em}.kv-nav{display:flex;flex-direction:column;gap:2px}.kv-nav-link{display:flex;align-items:center;gap:11px;padding:8px 11px;border-radius:var(--kv-radius-sm);color:var(--kv-muted);font-size:13.5px;font-weight:500;cursor:pointer;border:1px solid transparent;transition:background .13s,color .13s,border-color .13s;position:relative}.kv-nav-link:hover{background:var(--kv-surface-hover);color:var(--kv-text-dim)}.kv-nav-link.active{background:#8b5cf624;color:var(--kv-text);border-color:var(--kv-border)}.kv-nav-link.active:before{content:"";position:absolute;left:-12px;top:8px;bottom:8px;width:3px;border-radius:3px;background:var(--kv-grad)}.kv-nav-link svg{flex:0 0 auto}.kv-nav-badge{margin-left:auto;font-family:var(--kv-mono);font-size:10.5px;min-width:18px;height:18px;padding:0 5px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;background:#ec489933;color:#fbbcdd;border:1px solid rgba(236,72,153,.35)}.kv-nav-badge.kv-badge-dot{background:#34d3992e;color:var(--kv-green);border-color:#34d39959}.kv-sidebar-footer{margin-top:auto;padding:12px 10px 2px;border-top:1px solid var(--kv-border-faint);display:flex;flex-direction:column;gap:6px}.kv-conn{display:flex;align-items:center;gap:8px;font-family:var(--kv-mono);font-size:11px;color:var(--kv-muted)}.kv-conn-dot{width:8px;height:8px;border-radius:50%;background:var(--kv-muted-2);flex:0 0 auto}.kv-conn.open .kv-conn-dot{background:var(--kv-green);box-shadow:0 0 8px #34d39999}.kv-conn.connecting .kv-conn-dot,.kv-conn.reconnecting .kv-conn-dot{background:var(--kv-amber);animation:kv-pulse 1.1s ease-in-out infinite}.kv-conn.closed .kv-conn-dot{background:var(--kv-red)}.kv-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column}.kv-content{flex:1 1 auto;padding:26px 32px 60px;max-width:1180px;width:100%;margin:0 auto}.kv-page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:22px;flex-wrap:wrap}.kv-page-title{font-size:23px;font-weight:700;margin:0;color:var(--kv-text)}.kv-page-sub{color:var(--kv-muted);font-size:13px;margin:4px 0 0}.kv-card{background:var(--kv-surface);border:1px solid var(--kv-border-soft);border-radius:var(--kv-radius);padding:16px 18px}.kv-card.kv-card-accent{border-color:var(--kv-border)}.kv-card-title{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--kv-muted);margin:0 0 10px}.kv-grid{display:grid;gap:14px}.kv-grid-2{grid-template-columns:repeat(2,1fr)}.kv-grid-3{grid-template-columns:repeat(3,1fr)}.kv-grid-4{grid-template-columns:repeat(4,1fr)}.kv-stat{background:var(--kv-surface);border:1px solid var(--kv-border-soft);border-radius:var(--kv-radius);padding:15px 16px}.kv-stat-label{font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--kv-muted);margin-bottom:6px}.kv-stat-value{font-family:var(--kv-mono);font-size:24px;font-weight:700;color:var(--kv-text);line-height:1.1}.kv-stat-value.kv-grad-text{background:var(--kv-grad);-webkit-background-clip:text;background-clip:text;color:transparent}.kv-stat-foot{font-size:11px;color:var(--kv-muted-2);margin-top:5px}.kv-table{width:100%;border-collapse:collapse;font-size:13px}.kv-table th{text-align:left;font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--kv-muted);padding:9px 12px;border-bottom:1px solid var(--kv-border-soft);white-space:nowrap}.kv-table td{padding:10px 12px;border-bottom:1px solid var(--kv-border-faint);color:var(--kv-text-dim);vertical-align:middle}.kv-table tr:hover td{background:var(--kv-surface-hover)}.kv-table .kv-mono,.kv-table td.kv-num{font-family:var(--kv-mono)}.kv-table td.kv-num{text-align:right}.kv-pill{display:inline-flex;align-items:center;gap:6px;font-family:var(--kv-mono);font-size:11px;font-weight:600;padding:2px 9px;border-radius:999px;border:1px solid transparent;white-space:nowrap}.kv-pill:before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}.kv-pill.running{color:var(--kv-green);background:#34d3991f;border-color:#34d3994d}.kv-pill.completed,.kv-pill.done{color:var(--kv-purple-soft);background:#8b5cf61f;border-color:#8b5cf64d}.kv-pill.error,.kv-pill.failed,.kv-pill.timeout{color:var(--kv-red);background:#f871711f;border-color:#f871714d}.kv-pill.killed{color:var(--kv-amber);background:#fbbf241f;border-color:#fbbf244d}.kv-pill.idle,.kv-pill.neutral{color:var(--kv-muted);background:var(--kv-surface-2);border-color:var(--kv-border-soft)}.kv-tag{display:inline-block;font-family:var(--kv-mono);font-size:11px;padding:1px 7px;border-radius:6px;background:#8b5cf61f;color:var(--kv-purple-soft);border:1px solid rgba(139,92,246,.25)}.kv-btn{font-family:var(--kv-sans);font-size:13px;font-weight:600;padding:8px 15px;border-radius:var(--kv-radius-sm);border:1px solid var(--kv-border-soft);background:var(--kv-surface-2);color:var(--kv-text-dim);cursor:pointer;display:inline-flex;align-items:center;gap:7px;transition:background .13s,border-color .13s,transform .08s,color .13s}.kv-btn:hover{background:var(--kv-surface-hover);border-color:var(--kv-border);color:var(--kv-text)}.kv-btn:active{transform:translateY(1px)}.kv-btn:disabled{opacity:.45;cursor:not-allowed}.kv-btn.kv-btn-primary{background:var(--kv-grad);border-color:transparent;color:#fff;box-shadow:0 4px 16px #8b5cf64d}.kv-btn.kv-btn-primary:hover{filter:brightness(1.08);color:#fff}.kv-btn.kv-btn-danger{color:var(--kv-red);border-color:#f871714d}.kv-btn.kv-btn-danger:hover{background:#f871711f}.kv-btn.kv-btn-sm{font-size:12px;padding:5px 11px}.kv-input,.kv-textarea,.kv-select{font-family:var(--kv-mono);font-size:13px;width:100%;padding:8px 11px;border-radius:var(--kv-radius-sm);background:var(--kv-bg-2);border:1px solid var(--kv-border-soft);color:var(--kv-text);outline:none;transition:border-color .13s,box-shadow .13s}.kv-input:focus,.kv-textarea:focus,.kv-select:focus{border-color:var(--kv-purple);box-shadow:0 0 0 3px #8b5cf62e}.kv-textarea{resize:vertical;min-height:80px}.kv-label{display:block;font-size:12px;font-weight:600;color:var(--kv-muted);margin-bottom:6px}.kv-field{margin-bottom:16px}.kv-switch{position:relative;display:inline-flex;width:40px;height:22px;flex:0 0 auto;cursor:pointer}.kv-switch input{position:absolute;opacity:0;width:0;height:0}.kv-switch-track{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:999px;background:var(--kv-surface-2);border:1px solid var(--kv-border-soft);transition:background .15s,border-color .15s}.kv-switch-thumb{position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:var(--kv-muted);transition:transform .15s,background .15s}.kv-switch input:checked~.kv-switch-track{background:#8b5cf666;border-color:var(--kv-purple)}.kv-switch input:checked~.kv-switch-thumb{transform:translate(18px);background:#fff}.kv-logbox{font-family:var(--kv-mono);font-size:12px;line-height:1.55;background:#04040a;border:1px solid var(--kv-border-soft);border-radius:var(--kv-radius-sm);padding:12px 14px;overflow:auto;white-space:pre-wrap;word-break:break-word;color:var(--kv-text-dim);max-height:60vh}.kv-logline{display:flex;gap:10px;padding:1px 0}.kv-logline-ts{color:var(--kv-muted-2);flex:0 0 auto}.kv-logline-src{flex:0 0 auto;width:70px;color:var(--kv-purple-soft)}.kv-logline-text{flex:1 1 auto;min-width:0;color:var(--kv-text-dim)}.kv-spark{width:100%;height:auto;display:block}.kv-spark-line{fill:none;stroke:url(#kvSparkStroke);stroke-width:2}.kv-spark-fill{fill:url(#kvSparkFill);opacity:.6}.kv-empty{text-align:center;padding:48px 20px;color:var(--kv-muted);font-size:13.5px}.kv-empty svg{color:var(--kv-muted-2);margin-bottom:12px;opacity:.7}.kv-empty-title{color:var(--kv-text-dim);font-weight:600;font-size:15px;margin-bottom:6px}.kv-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:48px;color:var(--kv-muted);font-size:13px}.kv-spinner{width:18px;height:18px;border:2px solid rgba(139,92,246,.25);border-top-color:var(--kv-purple);border-radius:50%;animation:kv-spin .7s linear infinite}.kv-banner-error{background:#f871711a;border:1px solid rgba(248,113,113,.3);color:#fca5a5;border-radius:var(--kv-radius-sm);padding:10px 14px;font-size:13px;margin-bottom:16px;display:flex;align-items:center;gap:8px}@keyframes kv-spin{to{transform:rotate(360deg)}}@keyframes kv-pulse{0%,to{opacity:1}50%{opacity:.35}}@media(max-width:1100px){.kv-grid-4{grid-template-columns:repeat(2,1fr)}}@media(max-width:860px){.kv-sidebar{position:fixed;z-index:40;transform:translate(-100%);transition:transform .2s}.kv-sidebar.open{transform:translate(0)}.kv-content{padding:20px 16px 48px}.kv-grid-2,.kv-grid-3,.kv-grid-4{grid-template-columns:1fr}}.kv-topbar{display:none;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--kv-border-soft);background:#080810b3;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);position:sticky;top:0;z-index:30}.kv-topbar-burger{background:none;border:1px solid var(--kv-border-soft);border-radius:8px;color:var(--kv-text-dim);padding:6px;cursor:pointer;display:inline-flex}@media(max-width:860px){.kv-topbar{display:flex}}.kv-scrim{display:none}@media(max-width:860px){.kv-scrim.show{display:block;position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:35}}
|