@sma1lboy/kobe 0.7.44 → 0.7.46

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.
Files changed (30) hide show
  1. package/dist/cli/index.js +206 -206
  2. package/dist/web-ui/assets/{AppShell-CDaOEdi-.js → AppShell-CYm01lx0.js} +1 -1
  3. package/dist/web-ui/assets/{Board-Fbdp8XH6.js → Board-Cb_qgK8p.js} +1 -1
  4. package/dist/web-ui/assets/{BoardPeek-CGlvEzKm.js → BoardPeek-BhMuWjKj.js} +2 -2
  5. package/dist/web-ui/assets/{ChatTerminal-BVTnkMgh.js → ChatTerminal-DtqC7Mxi.js} +1 -1
  6. package/dist/web-ui/assets/{ChatTranscript-GThjCf3G.js → ChatTranscript-DdXMAQZR.js} +1 -1
  7. package/dist/web-ui/assets/{ConfirmDialog-ChauYIZh.js → ConfirmDialog-NPI1j7RW.js} +1 -1
  8. package/dist/web-ui/assets/{IssueIntakePanel-NYS_B5Ja.js → IssueIntakePanel-60iwjJTZ.js} +1 -1
  9. package/dist/web-ui/assets/{IssuePeek-CHxd9Wd2.js → IssuePeek-BbXifAKp.js} +1 -1
  10. package/dist/web-ui/assets/{IssuesPage-DWYtp4SQ.js → IssuesPage-zQbthJwx.js} +1 -1
  11. package/dist/web-ui/assets/{SettingsPage-DrXLFGQC.js → SettingsPage-BT-LGgyI.js} +1 -1
  12. package/dist/web-ui/assets/{SlideOver-Ecw6HOJj.js → SlideOver-CLaRtSQE.js} +1 -1
  13. package/dist/web-ui/assets/{ViewToggle-CugmdlMf.js → ViewToggle-Cok6O_mP.js} +1 -1
  14. package/dist/web-ui/assets/{WorkspaceTabs-BpeeMXZx.js → WorkspaceTabs-DmfAn-hk.js} +3 -3
  15. package/dist/web-ui/assets/board-BEUe7jtL.js +1 -0
  16. package/dist/web-ui/assets/index-C7JcdWbk.css +1 -0
  17. package/dist/web-ui/assets/{index-Dj1p8IG5.js → index-CZ8GNIM9.js} +3 -3
  18. package/dist/web-ui/assets/issues-DkAiF0x1.js +1 -0
  19. package/dist/web-ui/assets/{issues-B7S736HE.js → issues-Dq7AkivK.js} +1 -1
  20. package/dist/web-ui/assets/{lazy-issue-panels-BEMcULAZ.js → lazy-issue-panels-CAA0flSv.js} +3 -3
  21. package/dist/web-ui/assets/routes-DBeL-4xe.js +1 -0
  22. package/dist/web-ui/assets/{store-C4ms6xvg.js → store-BXWXnGds.js} +1 -1
  23. package/dist/web-ui/assets/{task._taskId-CFALCSAr.js → task._taskId-DBT8vG_M.js} +1 -1
  24. package/dist/web-ui/index.html +3 -3
  25. package/dist/web-ui/pty-session-lifecycle.mjs +99 -0
  26. package/package.json +1 -1
  27. package/dist/web-ui/assets/board-Brh_Zq0E.js +0 -1
  28. package/dist/web-ui/assets/index-BxOdeldP.css +0 -1
  29. package/dist/web-ui/assets/issues-DzyXWaNt.js +0 -1
  30. package/dist/web-ui/assets/routes-CaoA3-Vv.js +0 -1
@@ -0,0 +1 @@
1
+ import{IssuesPage as e}from"./IssuesPage-zQbthJwx.js";var t=e;export{t as component};
@@ -1,3 +1,3 @@
1
- import{c as e}from"./tabs-Db1r1FTh.js";import{t}from"./store-C4ms6xvg.js";import{i as n,r}from"./terminal-Ckm9XXat.js";import{t as i}from"./settings-B_VT_pPR.js";import{w as a}from"./index-Dj1p8IG5.js";import{t as o}from"./text-match-C3BRtNXy.js";var s=[{key:`backlog`,title:`Backlog`,accent:`text-subtle`,alwaysVisible:!0},{key:`in_progress`,title:`In progress`,accent:`text-kobe-orange`,alwaysVisible:!0},{key:`done`,title:`Done`,accent:`text-kobe-green`,alwaysVisible:!0}],c=new Set([`done`]);function l(e){return e.status===`done`?`done`:e.taskId!==void 0&&e.taskId!==``?`in_progress`:`backlog`}function u(e){return e.taskId!==void 0&&e.taskId!==``}function d(e,t){return e.issue.created===t.issue.created?t.issue.id-e.issue.id:e.issue.created<t.issue.created?1:-1}function f(e){let t=new Map,n=(e,n)=>{let r=t.get(e);r?r.push(n):t.set(e,[n])};for(let t of e)n(l(t.issue),t);for(let e of t.values())e.sort(d);let r=(e,t)=>!c.has(e)||t.length<=30?{cards:t,hiddenCount:0}:{cards:t.slice(0,30),hiddenCount:t.length-30};return s.map(e=>({...e,...r(e.key,t.get(e.key)??[])})).filter(e=>e.alwaysVisible||e.cards.length+e.hiddenCount>0)}function p(e){return e.reduce((e,t)=>e+t.cards.length,0)}function m(e){let t=new Map;for(let n of e){let e=n.repo,r=t.get(e);r?r.push(n):t.set(e,[n])}let n=[...t.keys()];return n.map(e=>({repo:e,label:g(e,n),columns:f(t.get(e)??[])})).sort((e,t)=>e.label.localeCompare(t.label))}function h(e){let t=e.replace(/\/+$/,``);return t.split(`/`).pop()||t}function g(e,t){let n=h(e);return t.some(t=>t!==e&&h(t)===n)?e.replace(/\/+$/,``).split(`/`).slice(-2).join(`/`):n}function _(e,t,n){let r=[];for(let i of t){let t=e[i];if(!(!t||!t.exists))for(let e of t.issues){let t=n.get(`${i}:${e.id}`);r.push(t&&!e.taskId?{repo:i,issue:{...e,taskId:t.taskId}}:{repo:i,issue:e})}}return r}function v(e){let t=new Map;for(let{repo:n}of e)t.set(n,(t.get(n)??0)+1);let n=[...t.keys()];return n.map(e=>({repo:e,label:g(e,n),count:t.get(e)??0})).sort((e,t)=>e.label.localeCompare(t.label))}function y(e,t,n){return e.filter(({repo:e,issue:r})=>n&&e!==n?!1:o(`#${r.id} ${r.title} ${r.body}`,t))}function b(e){let t=_(e.issueData,e.issueRepos,e.pendingLinks),n=v(t),r=m(y(t,e.query,e.repoFilter));return e.repoFilter&&r.length===0&&e.issueRepos.includes(e.repoFilter)&&r.push({repo:e.repoFilter,label:g(e.repoFilter,e.issueRepos),columns:f([])}),{allIssues:t,repoChips:n,projectBoards:r,shownCount:r.reduce((e,t)=>e+p(t.columns),0),hasAnyCard:t.length>0}}async function x(){let e=await n.get(`/api/projects`,{label:`load projects`});return Array.isArray(e.projects)?e.projects.filter(e=>typeof e==`string`):[]}async function S(e){return n.get(`/api/issues`,{query:{repoRoot:e},label:`load issues`})}async function C(e,t){return n.post(`/api/issues`,{repoRoot:e,op:t},{label:`update issues`})}async function w(e,t){return C(e,{type:`create`,...t})}async function T(e,t,n){return C(e,{type:`update`,id:t,...n})}async function E(e,t,n){return C(e,{type:`link`,id:t,taskId:n})}async function D(e,t){return C(e,{type:`delete`,id:t})}async function O(){let e=await n.getOr(`/api/cli-invocation`,{},{label:`load CLI invocation`});return typeof e.api==`string`&&e.api.trim().length>0?e.api:`kobe api`}var k=[`open`,`doing`,`hold`,`done`],A={open:{title:`Backlog`,accent:`text-kobe-blue`},doing:{title:`In session`,accent:`text-kobe-orange`},hold:{title:`Blocked`,accent:`text-kobe-yellow`},done:{title:`Done`,accent:`text-kobe-green`}};function j(e){return e!==`done`}function M(e,t){let n=(t.query??``).trim().toLowerCase(),r=t.statuses&&t.statuses.length>0?t.statuses:null;return e.filter(e=>r&&!r.includes(e.status)?!1:n?`#${e.id} ${e.title} ${e.body}`.toLowerCase().includes(n):!0)}function N(e){let t={open:[],doing:[],hold:[],done:[]};for(let n of e)t[n.status]?.push(n);let n=(e,t)=>e.created===t.created?t.id-e.id:e.created<t.created?1:-1;return t.open.sort(n),t.doing.sort(n),t.hold.sort(n),t.done.sort((e,t)=>t.id-e.id),t}function P(e,t=[]){let n=new Map;for(let e of t)e.trim().length>0&&n.set(e,0);let r=new Set(e.filter(e=>!e.archived&&e.kind===`main`&&e.repo).map(e=>e.repo));for(let e of r)n.set(e,n.get(e)??0);let i=new Set(n.keys());for(let t of e)t.archived||!t.repo||i.size>0&&!i.has(t.repo)||n.set(t.repo,(n.get(t.repo)??0)+1);let a=[...n.keys()];return a.map(e=>({repo:e,label:g(e,a),count:n.get(e)??0})).sort((e,t)=>e.label.localeCompare(t.label))}function F(e,t){return e.length===0?null:t&&e.some(e=>e.repo===t)?t:e[0]?.repo??null}function I(e,t=`kobe api`){let n=[`Work on user story #${e.id}: ${e.title}`,``],r=e.body.trim();return r&&n.push(r,``),n.push(`Treat this as the story's dedicated kobe task session: work only in this task worktree, and preserve any repo init instructions already delivered to the session.`,`Before finishing, verify the acceptance criteria implied by the story and summarize what changed plus any verification still needed.`,`Then merge the task branch back into the current project's main branch after the worktree is clean and checks pass.`,`When the work lands, run: ${t} issue-set-status --repo . --id ${e.id} --status done`),n.join(`
1
+ import{c as e}from"./tabs-Db1r1FTh.js";import{t}from"./store-BXWXnGds.js";import{i as n,r}from"./terminal-Ckm9XXat.js";import{t as i}from"./settings-B_VT_pPR.js";import{w as a}from"./index-CZ8GNIM9.js";import{t as o}from"./text-match-C3BRtNXy.js";var s=[{key:`backlog`,title:`Backlog`,accent:`text-subtle`,alwaysVisible:!0},{key:`in_progress`,title:`In progress`,accent:`text-kobe-orange`,alwaysVisible:!0},{key:`done`,title:`Done`,accent:`text-kobe-green`,alwaysVisible:!0}],c=new Set([`done`]);function l(e){return e.status===`done`?`done`:e.taskId!==void 0&&e.taskId!==``?`in_progress`:`backlog`}function u(e){return e.taskId!==void 0&&e.taskId!==``}function d(e,t){return e.issue.created===t.issue.created?t.issue.id-e.issue.id:e.issue.created<t.issue.created?1:-1}function f(e){let t=new Map,n=(e,n)=>{let r=t.get(e);r?r.push(n):t.set(e,[n])};for(let t of e)n(l(t.issue),t);for(let e of t.values())e.sort(d);let r=(e,t)=>!c.has(e)||t.length<=30?{cards:t,hiddenCount:0}:{cards:t.slice(0,30),hiddenCount:t.length-30};return s.map(e=>({...e,...r(e.key,t.get(e.key)??[])})).filter(e=>e.alwaysVisible||e.cards.length+e.hiddenCount>0)}function p(e){return e.reduce((e,t)=>e+t.cards.length,0)}function m(e){let t=new Map;for(let n of e){let e=n.repo,r=t.get(e);r?r.push(n):t.set(e,[n])}let n=[...t.keys()];return n.map(e=>({repo:e,label:g(e,n),columns:f(t.get(e)??[])})).sort((e,t)=>e.label.localeCompare(t.label))}function h(e){let t=e.replace(/\/+$/,``);return t.split(`/`).pop()||t}function g(e,t){let n=h(e);return t.some(t=>t!==e&&h(t)===n)?e.replace(/\/+$/,``).split(`/`).slice(-2).join(`/`):n}function _(e,t,n){let r=[];for(let i of t){let t=e[i];if(!(!t||!t.exists))for(let e of t.issues){let t=n.get(`${i}:${e.id}`);r.push(t&&!e.taskId?{repo:i,issue:{...e,taskId:t.taskId}}:{repo:i,issue:e})}}return r}function v(e){let t=new Map;for(let{repo:n}of e)t.set(n,(t.get(n)??0)+1);let n=[...t.keys()];return n.map(e=>({repo:e,label:g(e,n),count:t.get(e)??0})).sort((e,t)=>e.label.localeCompare(t.label))}function y(e,t,n){return e.filter(({repo:e,issue:r})=>n&&e!==n?!1:o(`#${r.id} ${r.title} ${r.body}`,t))}function b(e){let t=_(e.issueData,e.issueRepos,e.pendingLinks),n=v(t),r=m(y(t,e.query,e.repoFilter));return e.repoFilter&&r.length===0&&e.issueRepos.includes(e.repoFilter)&&r.push({repo:e.repoFilter,label:g(e.repoFilter,e.issueRepos),columns:f([])}),{allIssues:t,repoChips:n,projectBoards:r,shownCount:r.reduce((e,t)=>e+p(t.columns),0),hasAnyCard:t.length>0}}async function x(){let e=await n.get(`/api/projects`,{label:`load projects`});return Array.isArray(e.projects)?e.projects.filter(e=>typeof e==`string`):[]}async function S(e){return n.get(`/api/issues`,{query:{repoRoot:e},label:`load issues`})}async function C(e,t){return n.post(`/api/issues`,{repoRoot:e,op:t},{label:`update issues`})}async function w(e,t){return C(e,{type:`create`,...t})}async function T(e,t,n){return C(e,{type:`update`,id:t,...n})}async function E(e,t,n){return C(e,{type:`link`,id:t,taskId:n})}async function D(e,t){return C(e,{type:`delete`,id:t})}async function O(){let e=await n.getOr(`/api/cli-invocation`,{},{label:`load CLI invocation`});return typeof e.api==`string`&&e.api.trim().length>0?e.api:`kobe api`}var k=[`open`,`doing`,`hold`,`done`],A={open:{title:`Backlog`,accent:`text-kobe-blue`},doing:{title:`In session`,accent:`text-kobe-orange`},hold:{title:`Blocked`,accent:`text-kobe-yellow`},done:{title:`Done`,accent:`text-kobe-green`}};function j(e){return e!==`done`}function M(e,t){let n=(t.query??``).trim().toLowerCase(),r=t.statuses&&t.statuses.length>0?t.statuses:null;return e.filter(e=>r&&!r.includes(e.status)?!1:n?`#${e.id} ${e.title} ${e.body}`.toLowerCase().includes(n):!0)}function N(e){let t={open:[],doing:[],hold:[],done:[]};for(let n of e)t[n.status]?.push(n);let n=(e,t)=>e.created===t.created?t.id-e.id:e.created<t.created?1:-1;return t.open.sort(n),t.doing.sort(n),t.hold.sort(n),t.done.sort((e,t)=>t.id-e.id),t}function P(e,t=[]){let n=new Map;for(let e of t)e.trim().length>0&&n.set(e,0);let r=new Set(e.filter(e=>!e.archived&&e.kind===`main`&&e.repo).map(e=>e.repo));for(let e of r)n.set(e,n.get(e)??0);let i=new Set(n.keys());for(let t of e)t.archived||!t.repo||i.size>0&&!i.has(t.repo)||n.set(t.repo,(n.get(t.repo)??0)+1);let a=[...n.keys()];return a.map(e=>({repo:e,label:g(e,a),count:n.get(e)??0})).sort((e,t)=>e.label.localeCompare(t.label))}function F(e,t){return e.length===0?null:t&&e.some(e=>e.repo===t)?t:e[0]?.repo??null}function I(e,t=`kobe api`){let n=[`Work on user story #${e.id}: ${e.title}`,``],r=e.body.trim();return r&&n.push(r,``),n.push(`Treat this as the story's dedicated kobe task session: work only in this task worktree, and preserve any repo init instructions already delivered to the session.`,`Before finishing, verify the acceptance criteria implied by the story and summarize what changed plus any verification still needed.`,`Then merge the task branch back into the current project's main branch after the worktree is clean and checks pass.`,`When the work lands, run: ${t} issue-set-status --repo . --id ${e.id} --status done`),n.join(`
2
2
  `)}function L(e,t=`kobe api`){return[`Finish user story #${e.id}: ${e.title}`,``,`Verify the acceptance criteria implied by the story, then summarize what changed and any verification still needed.`,`Then merge this task branch back into the current project's main branch after the worktree is clean and checks pass. Resolve conflicts if needed.`,`When the work lands, run: ${t} issue-set-status --repo . --id ${e.id} --status done`].join(`
3
3
  `)}async function R(n,o,s,c){let l=s?.trim()||await i(),{taskId:u}=await t(`task.create`,{repo:n,title:`#${o.id} ${o.title}`,...l?{vendor:l}:{},...c?.trim()?{effort:c.trim()}:{}});a(u),await E(n,o.id,u).catch(()=>{});let d=await O().catch(()=>`kobe api`);return await r(e(u),u,I(o,d)),{taskId:u}}async function z(t,n){let i=await O().catch(()=>`kobe api`);await r(e(t),t,L(n,i))}export{D as a,M as c,z as d,R as f,u as g,b as h,w as i,N as l,T as m,A as n,S as o,F as p,j as r,x as s,k as t,P as u};
@@ -1,6 +1,6 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/IssueIntakePanel-NYS_B5Ja.js","assets/tabs-Db1r1FTh.js","assets/terminal-Ckm9XXat.js","assets/SlideOver-Ecw6HOJj.js","assets/index-Dj1p8IG5.js","assets/store-C4ms6xvg.js","assets/createLucideIcon-BoVlWivB.js","assets/toast-CfAxitbT.js","assets/settings-B_VT_pPR.js","assets/index-BxOdeldP.css","assets/SlideOver-B4sEOPyN.css","assets/issues-B7S736HE.js","assets/text-match-C3BRtNXy.js","assets/IssuePeek-CHxd9Wd2.js","assets/external-link-C51-09OW.js"])))=>i.map(i=>d[i]);
2
- import{S as e,y as t}from"./tabs-Db1r1FTh.js";import{d as n,t as r}from"./createLucideIcon-BoVlWivB.js";import{i,n as a,r as o}from"./store-C4ms6xvg.js";import{o as s}from"./ConfirmDialog-ChauYIZh.js";import{o as c}from"./issues-B7S736HE.js";var l=r(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),u=r(`trash-2`,[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]]),d=e(t(),1);function f(e){let{issueSnapshots:t}=a(),[n,r]=(0,d.useState)({}),[i,s]=(0,d.useState)({}),[l,u]=(0,d.useState)(!1),f=(0,d.useRef)(new Map),p=(0,d.useRef)(new Map),m=(0,d.useRef)(new Map),h=(0,d.useRef)(new Map),g=(0,d.useCallback)(e=>{let t=(f.current.get(e)??0)+1;return f.current.set(e,t),t},[]),_=(0,d.useCallback)((e,t,n=e.repoRoot)=>{t<(p.current.get(n)??0)||(p.current.set(n,t),e.repoRoot&&e.repoRoot!==n&&h.current.set(n,e.repoRoot),r(t=>({...t,[n]:{...e,repoRoot:n}})),s(e=>{if(!(n in e))return e;let{[n]:t,...r}=e;return r}))},[]),v=(0,d.useCallback)(e=>{e.length!==0&&(u(!0),Promise.all(e.map(async e=>{let t=g(e);try{_(await c(e),t,e)}catch(t){s(n=>({...n,[e]:t instanceof Error?t.message:String(t)}))}})).finally(()=>u(!1)))},[g,_]),y=(0,d.useMemo)(()=>[...e].join(`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/IssueIntakePanel-60iwjJTZ.js","assets/tabs-Db1r1FTh.js","assets/terminal-Ckm9XXat.js","assets/SlideOver-CLaRtSQE.js","assets/index-CZ8GNIM9.js","assets/store-BXWXnGds.js","assets/createLucideIcon-BoVlWivB.js","assets/toast-CfAxitbT.js","assets/settings-B_VT_pPR.js","assets/index-C7JcdWbk.css","assets/SlideOver-B4sEOPyN.css","assets/issues-Dq7AkivK.js","assets/text-match-C3BRtNXy.js","assets/IssuePeek-BbXifAKp.js","assets/external-link-C51-09OW.js"])))=>i.map(i=>d[i]);
2
+ import{S as e,y as t}from"./tabs-Db1r1FTh.js";import{d as n,t as r}from"./createLucideIcon-BoVlWivB.js";import{i,n as a,r as o}from"./store-BXWXnGds.js";import{o as s}from"./ConfirmDialog-NPI1j7RW.js";import{o as c}from"./issues-Dq7AkivK.js";var l=r(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),u=r(`trash-2`,[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]]),d=e(t(),1);function f(e){let{issueSnapshots:t}=a(),[n,r]=(0,d.useState)({}),[i,s]=(0,d.useState)({}),[l,u]=(0,d.useState)(!1),f=(0,d.useRef)(new Map),p=(0,d.useRef)(new Map),m=(0,d.useRef)(new Map),h=(0,d.useRef)(new Map),g=(0,d.useCallback)(e=>{let t=(f.current.get(e)??0)+1;return f.current.set(e,t),t},[]),_=(0,d.useCallback)((e,t,n=e.repoRoot)=>{t<(p.current.get(n)??0)||(p.current.set(n,t),e.repoRoot&&e.repoRoot!==n&&h.current.set(n,e.repoRoot),r(t=>({...t,[n]:{...e,repoRoot:n}})),s(e=>{if(!(n in e))return e;let{[n]:t,...r}=e;return r}))},[]),v=(0,d.useCallback)(e=>{e.length!==0&&(u(!0),Promise.all(e.map(async e=>{let t=g(e);try{_(await c(e),t,e)}catch(t){s(n=>({...n,[e]:t instanceof Error?t.message:String(t)}))}})).finally(()=>u(!1)))},[g,_]),y=(0,d.useMemo)(()=>[...e].join(`
3
3
  `),[e]);return(0,d.useEffect)(()=>{v(y?y.split(`
4
4
  `):[])},[y]),(0,d.useEffect)(()=>{let e=new Map(Object.values(t).map(e=>[o(e.repoRoot),e]));for(let t of y?y.split(`
5
5
  `):[]){let n=h.current.get(t),r=e.get(o(t))??(n?e.get(o(n)):void 0);r&&m.current.get(t)!==r&&(m.current.set(t,r),_(r,g(t),t))}},[t,y,g,_]),{data:n,failed:i,loading:l,pending:(0,d.useMemo)(()=>(y?y.split(`
6
- `):[]).some(e=>!(e in n)&&!(e in i)),[y,n,i]),refresh:v}}var p=n();function m({issue:e,onOpen:t,onDelete:n}){return(0,p.jsxs)(`div`,{className:`group/card relative`,children:[(0,p.jsxs)(`button`,{type:`button`,onClick:t,className:`flex w-full cursor-pointer flex-col gap-1.5 border border-line bg-surface p-3 text-left transition-colors hover:border-primary hover:bg-inset`,children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsxs)(`span`,{className:`shrink-0 font-mono text-[10px] text-subtle`,children:[`#`,e.id]}),(0,p.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-[13px] text-fg`,children:e.title})]}),(0,p.jsx)(`div`,{className:`flex items-center gap-2 text-[11px] text-subtle`,children:(0,p.jsx)(`span`,{className:`font-mono`,children:e.created})})]}),(0,p.jsxs)(`div`,{className:`absolute right-2 top-2 flex gap-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover/card:opacity-100`,children:[(0,p.jsx)(`button`,{type:`button`,onClick:t,"aria-label":`Open issue #${e.id}`,"data-tip":`Open issue detail`,className:`relative flex h-5 w-5 items-center justify-center border border-line bg-surface text-subtle hover:border-primary hover:text-fg ${s}`,children:(0,p.jsx)(l,{size:11,strokeWidth:1.8})}),(0,p.jsx)(`button`,{type:`button`,onClick:n,"aria-label":`Delete issue #${e.id}`,"data-tip":`Delete issue`,className:`relative flex h-5 w-5 items-center justify-center border border-line bg-surface text-subtle hover:border-kobe-red/50 hover:text-kobe-red ${s}`,children:(0,p.jsx)(u,{size:11,strokeWidth:1.8})})]})]})}var h=(0,d.lazy)(()=>i(()=>import(`./IssueIntakePanel-NYS_B5Ja.js`).then(e=>({default:e.IssueIntakePanel})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12]))),g=(0,d.lazy)(()=>i(()=>import(`./IssuePeek-CHxd9Wd2.js`).then(e=>({default:e.IssuePeek})),__vite__mapDeps([13,1,2,3,4,5,6,7,8,9,10,14,11,12])));function _({children:e}){return(0,p.jsx)(d.Suspense,{fallback:(0,p.jsx)(`div`,{className:`fixed inset-0 z-40 flex justify-end`,children:(0,p.jsx)(`div`,{className:`relative flex h-full w-[640px] max-w-[92vw] items-center justify-center border-l border-line bg-bg text-[12px] text-subtle shadow-2xl`,children:`Loading…`})}),children:e})}export{f as a,m as i,h as n,g as r,_ as t};
6
+ `):[]).some(e=>!(e in n)&&!(e in i)),[y,n,i]),refresh:v}}var p=n();function m({issue:e,onOpen:t,onDelete:n}){return(0,p.jsxs)(`div`,{className:`group/card relative`,children:[(0,p.jsxs)(`button`,{type:`button`,onClick:t,className:`flex w-full cursor-pointer flex-col gap-1.5 border border-line bg-surface p-3 text-left transition-colors hover:border-primary hover:bg-inset`,children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsxs)(`span`,{className:`shrink-0 font-mono text-[10px] text-subtle`,children:[`#`,e.id]}),(0,p.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-[13px] text-fg`,children:e.title})]}),(0,p.jsx)(`div`,{className:`flex items-center gap-2 text-[11px] text-subtle`,children:(0,p.jsx)(`span`,{className:`font-mono`,children:e.created})})]}),(0,p.jsxs)(`div`,{className:`absolute right-2 top-2 flex gap-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover/card:opacity-100`,children:[(0,p.jsx)(`button`,{type:`button`,onClick:t,"aria-label":`Open issue #${e.id}`,"data-tip":`Open issue detail`,className:`relative flex h-5 w-5 items-center justify-center border border-line bg-surface text-subtle hover:border-primary hover:text-fg ${s}`,children:(0,p.jsx)(l,{size:11,strokeWidth:1.8})}),(0,p.jsx)(`button`,{type:`button`,onClick:n,"aria-label":`Delete issue #${e.id}`,"data-tip":`Delete issue`,className:`relative flex h-5 w-5 items-center justify-center border border-line bg-surface text-subtle hover:border-kobe-red/50 hover:text-kobe-red ${s}`,children:(0,p.jsx)(u,{size:11,strokeWidth:1.8})})]})]})}var h=(0,d.lazy)(()=>i(()=>import(`./IssueIntakePanel-60iwjJTZ.js`).then(e=>({default:e.IssueIntakePanel})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12]))),g=(0,d.lazy)(()=>i(()=>import(`./IssuePeek-BbXifAKp.js`).then(e=>({default:e.IssuePeek})),__vite__mapDeps([13,1,2,3,4,5,6,7,8,9,10,14,11,12])));function _({children:e}){return(0,p.jsx)(d.Suspense,{fallback:(0,p.jsx)(`div`,{className:`fixed inset-0 z-40 flex justify-end`,children:(0,p.jsx)(`div`,{className:`relative flex h-full w-[640px] max-w-[92vw] items-center justify-center border-l border-line bg-bg text-[12px] text-subtle shadow-2xl`,children:`Loading…`})}),children:e})}export{f as a,m as i,h as n,g as r,_ as t};
@@ -0,0 +1 @@
1
+ import{AppShell as e}from"./AppShell-CYm01lx0.js";var t=e;export{t as component};
@@ -1,2 +1,2 @@
1
1
  const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tabs-Db1r1FTh.js","assets/terminal-Ckm9XXat.js","assets/terminal-DV9S9xMa.js"])))=>i.map(i=>d[i]);
2
- import{S as e,u as t,y as n}from"./tabs-Db1r1FTh.js";import{n as r,s as i}from"./createLucideIcon-BoVlWivB.js";import{i as a}from"./terminal-Ckm9XXat.js";var o=e(n(),1),s=`modulepreload`,c=function(e){return`/`+e},l={},u=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=c(t,n),t in l)return;l[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:s,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},d=`kobe.dispatch.deliveredAt.`;function f(e){try{let t=localStorage.getItem(d+e),n=t?Number.parseInt(t,10):0;return Number.isFinite(n)?n:0}catch{return 0}}function p(e,t){try{localStorage.setItem(d+e,String(t))}catch{}}function m(e,t){return e.at>t}async function h(e,t){if(!m(e,f(e.taskId)))return!1;p(e.taskId,e.at);let n=t?.ensureTab,r=t?.send;if(!n||!r){let e=await u(()=>import(`./tabs-Db1r1FTh.js`).then(e=>e.g),__vite__mapDeps([0,1])),t=await u(()=>import(`./terminal-DV9S9xMa.js`),__vite__mapDeps([2,1]));n??=e.ensureEngineTab,r??=t.sendPtyText}try{let t=n(e.taskId);return await r(t,e.taskId,e.text),!0}catch(t){return p(e.taskId,e.at-1),console.warn(`[dispatch-delivery] failed to deliver into session`,e.taskId,t),!1}}function g(e){return e.length>1?e.replace(/\/+$/,``):e}function _(e,t){let n=g(t),r=new Set([t]);for(let t of e){let e=g(t.repo),i=g(t.worktreePath);(e===n||i===n)&&(t.repo&&r.add(t.repo),t.worktreePath&&r.add(t.worktreePath))}return[...r]}function v(e={}){let t=e.path??`/api/rpc`,n=e.post??a.post.bind(a);return{async request(e,r){return(await n(t,{name:e,payload:r},{label:`rpc ${e}`})).result}}}var y=v(),b={tasks:[],activeTaskId:null,engineStates:{},update:null,jobs:{},worktreeChanges:{},issueSnapshots:{},deliver:null,uiPrefs:null,hydrated:!1,daemonConnected:!1,streamConnected:!1},x=new Set;function S(e){b={...b,...e};for(let e of x)e()}function C(e,t){let n=Object.entries(e).filter(([e])=>t.has(e));return n.length===Object.keys(e).length?e:Object.fromEntries(n)}function w(e,t){return!e&&t===`idle`}function T(e,t){if(t.phase===`running`)return{...e,[t.taskId]:t};let{[t.taskId]:n,...r}=e;return r}function E(e,t,n){let r={...e};for(let e of _(t,n.repoRoot))r[e]={...n,repoRoot:e};return r}function D(e){let n=new Set(e.map(e=>e.id));S({tasks:e,engineStates:C(b.engineStates,n),jobs:C(b.jobs,n)}),t(n)}function O(e){switch(e.channel){case`task.snapshot`:D(e.payload.tasks);break;case`active-task`:S({activeTaskId:e.payload.taskId});break;case`engine-state`:{let t=b.engineStates[e.payload.taskId]?.state,n=b.tasks.find(t=>t.id===e.payload.taskId);if(w(n,e.payload.state))break;i(e.payload.taskId,n?.title||n?.branch||e.payload.taskId,t,e.payload.state),S({engineStates:{...b.engineStates,[e.payload.taskId]:e.payload}});break}case`update`:S({update:e.payload.info});break;case`task.jobs`:S({jobs:T(b.jobs,e.payload)});break;case`worktree.changes`:S({worktreeChanges:e.payload.changes});break;case`issue.snapshot`:S({issueSnapshots:E(b.issueSnapshots,b.tasks,e.payload)});break;case`session.deliver`:S({deliver:e.payload}),h(e.payload);break;case`ui-prefs`:S({uiPrefs:e.payload}),r(e.payload.theme);break}}var k=null;function A(){k||(k=new EventSource(`/events`),k.addEventListener(`open`,()=>S({streamConnected:!0})),k.addEventListener(`snapshot`,e=>{let n=JSON.parse(e.data);S({tasks:n.tasks,activeTaskId:n.activeTaskId,engineStates:n.engineStates,update:n.update,jobs:n.jobs??{},worktreeChanges:n.worktreeChanges??{},issueSnapshots:n.issueSnapshots??{},deliver:n.deliver??null,uiPrefs:n.uiPrefs??null,hydrated:!0,daemonConnected:n.connected,streamConnected:!0}),n.uiPrefs&&r(n.uiPrefs.theme),n.connected&&n.deliver&&h(n.deliver),n.connected&&t(new Set(n.tasks.map(e=>e.id)))}),k.addEventListener(`channel`,e=>{O(JSON.parse(e.data)),b.daemonConnected||S({daemonConnected:!0})}),k.addEventListener(`error`,()=>S({streamConnected:!1})))}function j(e){return A(),x.add(e),()=>{x.delete(e)}}function M(){return b}function N(){return(0,o.useSyncExternalStore)(j,M,M)}async function P(e,t){return y.request(e,t)}export{u as i,N as n,g as r,P as t};
2
+ import{S as e,u as t,y as n}from"./tabs-Db1r1FTh.js";import{n as r,s as i}from"./createLucideIcon-BoVlWivB.js";import{i as a}from"./terminal-Ckm9XXat.js";var o=e(n(),1),s=`modulepreload`,c=function(e){return`/`+e},l={},u=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=c(t,n),t in l)return;l[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:s,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},d=`kobe.dispatch.deliveredAt.`;function f(e){try{let t=localStorage.getItem(d+e),n=t?Number.parseInt(t,10):0;return Number.isFinite(n)?n:0}catch{return 0}}function p(e,t){try{localStorage.setItem(d+e,String(t))}catch{}}function m(e,t){return e.at>t}async function h(e,t){if(!m(e,f(e.taskId)))return!1;p(e.taskId,e.at);let n=t?.ensureTab,r=t?.send;if(!n||!r){let e=await u(()=>import(`./tabs-Db1r1FTh.js`).then(e=>e.g),__vite__mapDeps([0,1])),t=await u(()=>import(`./terminal-DV9S9xMa.js`),__vite__mapDeps([2,1]));n??=e.ensureEngineTab,r??=t.sendPtyText}try{let t=n(e.taskId);return await r(t,e.taskId,e.text),!0}catch(t){return p(e.taskId,e.at-1),console.warn(`[dispatch-delivery] failed to deliver into session`,e.taskId,t),!1}}function g(e){return e.length>1?e.replace(/\/+$/,``):e}function _(e,t){let n=g(t),r=new Set([t]);for(let t of e){let e=g(t.repo),i=g(t.worktreePath);(e===n||i===n)&&(t.repo&&r.add(t.repo),t.worktreePath&&r.add(t.worktreePath))}return[...r]}function v(e={}){let t=e.path??`/api/rpc`,n=e.post??a.post.bind(a);return{async request(e,r){return(await n(t,{name:e,payload:r},{label:`rpc ${e}`})).result}}}var y=v(),b={tasks:[],activeTaskId:null,engineStates:{},update:null,jobs:{},worktreeChanges:{},issueSnapshots:{},deliver:null,uiPrefs:null,hydrated:!1,daemonConnected:!1,streamConnected:!1},x=new Set;function S(e){b={...b,...e};for(let e of x)e()}function C(e,t){let n=Object.entries(e).filter(([e])=>t.has(e));return n.length===Object.keys(e).length?e:Object.fromEntries(n)}function w(e,t){return!e&&t===`idle`}function T(e,t){if(t.phase===`running`)return{...e,[t.taskId]:t};let{[t.taskId]:n,...r}=e;return r}function E(e,t,n){let r={...e};for(let e of _(t,n.repoRoot))r[e]={...n,repoRoot:e};return r}function D(e){let n=new Set(e.map(e=>e.id));S({tasks:e,engineStates:C(b.engineStates,n),jobs:C(b.jobs,n)}),t(n)}function O(e){switch(e.channel){case`task.snapshot`:D(e.payload.tasks);break;case`active-task`:S({activeTaskId:e.payload.taskId});break;case`engine-state`:{let t=b.engineStates[e.payload.taskId]?.state,n=b.tasks.find(t=>t.id===e.payload.taskId);if(w(n,e.payload.state))break;i(e.payload.taskId,n?.title||n?.branch||e.payload.taskId,t,e.payload.state),S({engineStates:{...b.engineStates,[e.payload.taskId]:e.payload}});break}case`update`:S({update:e.payload.info});break;case`task.jobs`:S({jobs:T(b.jobs,e.payload)});break;case`worktree.changes`:S({worktreeChanges:e.payload.changes});break;case`issue.snapshot`:S({issueSnapshots:E(b.issueSnapshots,b.tasks,e.payload)});break;case`session.deliver`:S({deliver:e.payload}),h(e.payload);break;case`ui-prefs`:S({uiPrefs:e.payload}),r(e.payload.theme);break}}function k(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function A(e){if(!k(e)||!Array.isArray(e.tasks)||typeof e.activeTaskId!=`string`&&e.activeTaskId!==null||!k(e.engineStates)||typeof e.connected!=`boolean`)return null;for(let t of[`jobs`,`worktreeChanges`,`issueSnapshots`])if(e[t]!==void 0&&!k(e[t]))return null;return e.uiPrefs!==void 0&&e.uiPrefs!==null&&!k(e.uiPrefs)?null:e}function j(e){return Math.min(1e4,500*2**Math.max(0,e))}var M=null,N=0,P=null;function F(e){return e!==null&&e.readyState!==EventSource.CLOSED}function I(e){N=0,S({tasks:e.tasks,activeTaskId:e.activeTaskId,engineStates:e.engineStates,update:e.update,jobs:e.jobs??{},worktreeChanges:e.worktreeChanges??{},issueSnapshots:e.issueSnapshots??{},deliver:e.deliver??null,uiPrefs:e.uiPrefs??null,hydrated:!0,daemonConnected:e.connected,streamConnected:!0}),e.uiPrefs&&r(e.uiPrefs.theme),e.connected&&e.deliver&&h(e.deliver),e.connected&&t(new Set(e.tasks.map(e=>e.id)))}function L(){if(P!==null)return;let e=j(N);N+=1,P=setTimeout(()=>{P=null,x.size>0&&R()},e)}function R(){F(M)||(M=new EventSource(`/events`),M.addEventListener(`open`,()=>{N=0,S({streamConnected:!0})}),M.addEventListener(`snapshot`,e=>{let t;try{t=JSON.parse(e.data)}catch{console.warn(`[store] dropped unparseable snapshot frame`);return}let n=A(t);if(!n){console.warn(`[store] dropped malformed snapshot frame`);return}I(n)}),M.addEventListener(`channel`,e=>{let t;try{t=JSON.parse(e.data)}catch{console.warn(`[store] dropped unparseable channel frame`);return}if(!k(t)||typeof t.channel!=`string`){console.warn(`[store] dropped malformed channel frame`);return}O(t),b.daemonConnected||S({daemonConnected:!0})}),M.addEventListener(`error`,()=>{S({streamConnected:!1}),M&&M.readyState===EventSource.CLOSED&&(M.close(),M=null,L())}))}function z(e){return R(),x.add(e),()=>{x.delete(e)}}function B(){return b}function V(){return(0,o.useSyncExternalStore)(z,B,B)}async function H(e,t){return y.request(e,t)}export{u as i,V as n,g as r,H as t};
@@ -1 +1 @@
1
- import{S as e,_ as t,f as n,y as r}from"./tabs-Db1r1FTh.js";import{d as i}from"./createLucideIcon-BoVlWivB.js";import{t as a,w as o}from"./index-Dj1p8IG5.js";import{AppShell as s}from"./AppShell-CDaOEdi-.js";var c=e(r()),l=i();function u(){let{taskId:e}=a.useParams(),{selectedTaskId:r}=t();return(0,c.useEffect)(()=>{!e||e===r||(n(e),o(e))},[e,r]),(0,l.jsx)(s,{})}export{u as component};
1
+ import{S as e,_ as t,f as n,y as r}from"./tabs-Db1r1FTh.js";import{d as i}from"./createLucideIcon-BoVlWivB.js";import{t as a,w as o}from"./index-CZ8GNIM9.js";import{AppShell as s}from"./AppShell-CYm01lx0.js";var c=e(r()),l=i();function u(){let{taskId:e}=a.useParams(),{selectedTaskId:r}=t();return(0,c.useEffect)(()=>{!e||e===r||(n(e),o(e))},[e,r]),(0,l.jsx)(s,{})}export{u as component};
@@ -5,14 +5,14 @@
5
5
  <meta charset="UTF-8" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>kobe-web</title>
8
- <script type="module" crossorigin src="/assets/index-Dj1p8IG5.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-CZ8GNIM9.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/terminal-Ckm9XXat.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/tabs-Db1r1FTh.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BoVlWivB.js">
12
- <link rel="modulepreload" crossorigin href="/assets/store-C4ms6xvg.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/store-BXWXnGds.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/settings-B_VT_pPR.js">
14
14
  <link rel="modulepreload" crossorigin href="/assets/toast-CfAxitbT.js">
15
- <link rel="stylesheet" crossorigin href="/assets/index-BxOdeldP.css">
15
+ <link rel="stylesheet" crossorigin href="/assets/index-C7JcdWbk.css">
16
16
  </head>
17
17
  <body>
18
18
  <div id="app"></div>
@@ -12,6 +12,55 @@ const DEFAULT_SUBMIT_DELAYS = {
12
12
  enterMs: 150,
13
13
  }
14
14
 
15
+ // A browser opening /pty?tab=<id> with ever-new tab ids would otherwise spawn
16
+ // node-pty processes without bound. Cap concurrent sessions; spawning past the
17
+ // cap evicts the oldest session with no attached sockets, and rejects when every
18
+ // session is being actively viewed.
19
+ const DEFAULT_MAX_SESSIONS = 64
20
+
21
+ // PTY→WebSocket backpressure: a flooding pty (`yes`) outruns a slow browser, so
22
+ // node buffers the unsent bytes (ws.bufferedAmount) without bound. Pause the pty
23
+ // once any socket's buffer crosses the high-water mark and resume once every
24
+ // socket has drained back under the low-water mark.
25
+ const DEFAULT_BACKPRESSURE = {
26
+ highWaterBytes: 1 << 20, // 1 MiB queued to a socket → pause the pty
27
+ lowWaterBytes: 1 << 18, // 256 KiB → resume once all sockets are back under
28
+ drainPollMs: 50,
29
+ }
30
+
31
+ /** First session (insertion order) with no attached sockets — the safest to
32
+ * evict under cap pressure since no browser is watching it. Returns null when
33
+ * every session is actively viewed (caller rejects the new spawn). Exported
34
+ * for tests. */
35
+ export function pickEvictableTab(sessions) {
36
+ for (const [tabId, entry] of sessions) {
37
+ if (entry.sockets.size === 0) return tabId
38
+ }
39
+ return null
40
+ }
41
+
42
+ /** Pause the pty when ANY open socket has more than `highWaterBytes` queued —
43
+ * one slow client is enough to grow node memory unbounded. Exported for tests. */
44
+ export function shouldPausePty(sockets, highWaterBytes) {
45
+ for (const ws of sockets) {
46
+ if (ws.readyState === ws.OPEN && ws.bufferedAmount > highWaterBytes) {
47
+ return true
48
+ }
49
+ }
50
+ return false
51
+ }
52
+
53
+ /** Resume only when EVERY open socket has drained back under `lowWaterBytes`
54
+ * (an empty socket set resumes immediately). Exported for tests. */
55
+ export function shouldResumePty(sockets, lowWaterBytes) {
56
+ for (const ws of sockets) {
57
+ if (ws.readyState === ws.OPEN && ws.bufferedAmount > lowWaterBytes) {
58
+ return false
59
+ }
60
+ }
61
+ return true
62
+ }
63
+
15
64
  export function createPtySessionManager({
16
65
  fetchSpec,
17
66
  spawnPty,
@@ -19,14 +68,58 @@ export function createPtySessionManager({
19
68
  scrollbackCap,
20
69
  env,
21
70
  setTimeoutFn = setTimeout,
71
+ setIntervalFn = setInterval,
72
+ clearIntervalFn = clearInterval,
22
73
  submitDelays = DEFAULT_SUBMIT_DELAYS,
74
+ maxSessions = DEFAULT_MAX_SESSIONS,
75
+ backpressure = DEFAULT_BACKPRESSURE,
23
76
  }) {
24
77
  /** @type {Map<string, { pty: any, scrollback: ReturnType<createScrollback>, sockets: Set<any> }>} */
25
78
  const sessions = new Map()
26
79
  /** @type {Map<string, Promise<any>>} */
27
80
  const pendingSpawns = new Map()
28
81
 
82
+ /** Pause the pty once a socket is saturated and poll for drain to resume.
83
+ * Idempotent: a second saturation while already paused is a no-op. */
84
+ function applyBackpressure(entry) {
85
+ if (entry.paused) return
86
+ if (!shouldPausePty(entry.sockets, backpressure.highWaterBytes)) return
87
+ entry.paused = true
88
+ try {
89
+ entry.pty.pause?.()
90
+ } catch {
91
+ /* engine died — onExit clears the entry */
92
+ }
93
+ if (entry.drainTimer !== null) return
94
+ entry.drainTimer = setIntervalFn(() => {
95
+ if (!shouldResumePty(entry.sockets, backpressure.lowWaterBytes)) return
96
+ clearDrainTimer(entry)
97
+ entry.paused = false
98
+ try {
99
+ entry.pty.resume?.()
100
+ } catch {
101
+ /* engine died — onExit clears the entry */
102
+ }
103
+ }, backpressure.drainPollMs)
104
+ }
105
+
106
+ function clearDrainTimer(entry) {
107
+ if (entry.drainTimer !== null) {
108
+ clearIntervalFn(entry.drainTimer)
109
+ entry.drainTimer = null
110
+ }
111
+ }
112
+
29
113
  function spawnSession(tabId, spec, cols, rows) {
114
+ // Enforce the session cap before allocating another process: evict the
115
+ // oldest unwatched session, or reject when every session is in active use.
116
+ if (sessions.size >= maxSessions && !sessions.has(tabId)) {
117
+ const victim = pickEvictableTab(sessions)
118
+ if (victim === null) {
119
+ throw new Error(`pty session limit reached (${maxSessions})`)
120
+ }
121
+ closeSession(victim)
122
+ }
30
123
  const [cmd, ...args] = spec.command
31
124
  const spawnEnv = typeof env === "function" ? env() : env
32
125
  const pty = spawnPty(cmd, args, {
@@ -40,14 +133,18 @@ export function createPtySessionManager({
40
133
  pty,
41
134
  scrollback: createScrollback(scrollbackCap),
42
135
  sockets: new Set(),
136
+ paused: false,
137
+ drainTimer: null,
43
138
  }
44
139
  pty.onData((data) => {
45
140
  entry.scrollback.push(data)
46
141
  for (const ws of entry.sockets) {
47
142
  if (ws.readyState === ws.OPEN) ws.send(data)
48
143
  }
144
+ applyBackpressure(entry)
49
145
  })
50
146
  pty.onExit(() => {
147
+ clearDrainTimer(entry)
51
148
  for (const ws of entry.sockets) {
52
149
  if (ws.readyState === ws.OPEN) ws.close(1000, "engine exited")
53
150
  }
@@ -116,6 +213,7 @@ export function createPtySessionManager({
116
213
  function closeSession(tabId) {
117
214
  const entry = sessions.get(tabId)
118
215
  if (!entry) return false
216
+ clearDrainTimer(entry)
119
217
  try {
120
218
  entry.pty.kill()
121
219
  } catch {
@@ -155,6 +253,7 @@ export function createPtySessionManager({
155
253
 
156
254
  function shutdown() {
157
255
  for (const entry of sessions.values()) {
256
+ clearDrainTimer(entry)
158
257
  try {
159
258
  entry.pty.kill()
160
259
  } catch {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@sma1lboy/kobe",
4
- "version": "0.7.44",
4
+ "version": "0.7.46",
5
5
  "description": "TUI orchestrator for Claude Code (codename)",
6
6
  "type": "module",
7
7
  "packageManager": "bun@1.3.13",
@@ -1 +0,0 @@
1
- import{Board as e}from"./Board-Fbdp8XH6.js";var t=e;export{t as component};
@@ -1 +0,0 @@
1
- @font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff)format("woff")}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff)format("woff")}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/jetbrains-mono-latin-600-normal-C8RAYTDA.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-600-normal-BfsvjouI.woff)format("woff")}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/jetbrains-mono-latin-700-normal-BYuf6tUa.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-700-normal-D3wTyLJW.woff)format("woff")}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--font-mono:"JetBrains Mono", "SF Mono", "Fira Code", ui-monospace, Menlo, Monaco, "Cascadia Code", monospace;--color-black:#000;--spacing:.25rem;--container-md:28rem;--container-2xl:42rem;--container-4xl:56rem;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--leading-relaxed:1.625;--radius-sm:.25rem;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#141413;--color-surface:#1a1917;--color-inset:#2b2a27;--color-menu:#33312e;--color-line:#3a3835;--color-line-subtle:#2b2a27;--color-line-active:#5c5853;--color-fg:#eae7df;--color-muted:#a9a39a;--color-subtle:#6b665f;--color-primary:#cc785c;--color-kobe-orange:#d97757;--color-kobe-green:#9aca86;--color-kobe-blue:#61aaf2;--color-kobe-red:#d47563;--color-kobe-yellow:#e8c96b;--color-kobe-violet:#9b87f5}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:0}.inset-y-2{inset-block:calc(var(--spacing) * 2)}.top-2{top:calc(var(--spacing) * 2)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-4{right:calc(var(--spacing) * 4)}.right-6{right:calc(var(--spacing) * 6)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-6{bottom:calc(var(--spacing) * 6)}.bottom-10{bottom:calc(var(--spacing) * 10)}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-auto{margin-inline:auto}.my-1{margin-block:var(--spacing)}.my-2{margin-block:calc(var(--spacing) * 2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-auto{margin-top:auto}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.ml-5{margin-left:calc(var(--spacing) * 5)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-3{height:calc(var(--spacing) * 3)}.h-5{height:calc(var(--spacing) * 5)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:calc(var(--spacing) * 32)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[50vh\]{max-height:50vh}.max-h-\[80vh\]{max-height:80vh}.min-h-0{min-height:0}.min-h-36{min-height:calc(var(--spacing) * 36)}.min-h-56{min-height:calc(var(--spacing) * 56)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-3{width:calc(var(--spacing) * 3)}.w-5{width:calc(var(--spacing) * 5)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-44{width:calc(var(--spacing) * 44)}.w-52{width:calc(var(--spacing) * 52)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-96{width:calc(var(--spacing) * 96)}.w-\[28rem\]{width:28rem}.w-\[30rem\]{width:30rem}.w-\[32rem\]{width:32rem}.w-\[34rem\]{width:34rem}.w-\[640px\]{width:640px}.w-\[920px\]{width:920px}.w-\[calc\(50\%-0\.5rem\)\]{width:calc(50% - .5rem)}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-44{max-width:calc(var(--spacing) * 44)}.max-w-48{max-width:calc(var(--spacing) * 48)}.max-w-56{max-width:calc(var(--spacing) * 56)}.max-w-\[24rem\]{max-width:24rem}.max-w-\[85vw\]{max-width:85vw}.max-w-\[92vw\]{max-width:92vw}.max-w-\[96vw\]{max-width:96vw}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.min-w-0{min-width:0}.min-w-\[1\.4rem\]{min-width:1.4rem}.min-w-max{min-width:max-content}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-full{--tw-translate-x:100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[180px_minmax\(0\,1fr\)\]{grid-template-columns:180px minmax(0,1fr)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-sm{border-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-x-0{border-inline-style:var(--tw-border-style);border-inline-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-black\/20{border-color:#0003}@supports (color:color-mix(in lab, red, red)){.border-black\/20{border-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.border-kobe-green\/50{border-color:#9aca8680}@supports (color:color-mix(in lab, red, red)){.border-kobe-green\/50{border-color:color-mix(in oklab, var(--color-kobe-green) 50%, transparent)}}.border-kobe-red\/40{border-color:#d4756366}@supports (color:color-mix(in lab, red, red)){.border-kobe-red\/40{border-color:color-mix(in oklab, var(--color-kobe-red) 40%, transparent)}}.border-kobe-red\/50{border-color:#d4756380}@supports (color:color-mix(in lab, red, red)){.border-kobe-red\/50{border-color:color-mix(in oklab, var(--color-kobe-red) 50%, transparent)}}.border-kobe-yellow\/40{border-color:#e8c96b66}@supports (color:color-mix(in lab, red, red)){.border-kobe-yellow\/40{border-color:color-mix(in oklab, var(--color-kobe-yellow) 40%, transparent)}}.border-line{border-color:var(--color-line)}.border-line-active{border-color:var(--color-line-active)}.border-line-subtle{border-color:var(--color-line-subtle)}.border-primary{border-color:var(--color-primary)}.border-primary\/60{border-color:#cc785c99}@supports (color:color-mix(in lab, red, red)){.border-primary\/60{border-color:color-mix(in oklab, var(--color-primary) 60%, transparent)}}.border-transparent{border-color:#0000}.border-r-line{border-right-color:var(--color-line)}.border-b-kobe-blue{border-bottom-color:var(--color-kobe-blue)}.border-b-primary{border-bottom-color:var(--color-primary)}.border-b-transparent{border-bottom-color:#0000}.bg-\[\#28c840\]{background-color:#28c840}.bg-\[\#febc2e\]{background-color:#febc2e}.bg-\[\#ff5f57\]{background-color:#ff5f57}.bg-bg{background-color:var(--color-bg)}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab, red, red)){.bg-black\/40{background-color:color-mix(in oklab, var(--color-black) 40%, transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-inset{background-color:var(--color-inset)}.bg-inset\/40{background-color:#2b2a2766}@supports (color:color-mix(in lab, red, red)){.bg-inset\/40{background-color:color-mix(in oklab, var(--color-inset) 40%, transparent)}}.bg-kobe-blue{background-color:var(--color-kobe-blue)}.bg-kobe-green{background-color:var(--color-kobe-green)}.bg-kobe-green\/60{background-color:#9aca8699}@supports (color:color-mix(in lab, red, red)){.bg-kobe-green\/60{background-color:color-mix(in oklab, var(--color-kobe-green) 60%, transparent)}}.bg-kobe-orange{background-color:var(--color-kobe-orange)}.bg-kobe-red{background-color:var(--color-kobe-red)}.bg-kobe-red\/10{background-color:#d475631a}@supports (color:color-mix(in lab, red, red)){.bg-kobe-red\/10{background-color:color-mix(in oklab, var(--color-kobe-red) 10%, transparent)}}.bg-kobe-yellow{background-color:var(--color-kobe-yellow)}.bg-kobe-yellow\/10{background-color:#e8c96b1a}@supports (color:color-mix(in lab, red, red)){.bg-kobe-yellow\/10{background-color:color-mix(in oklab, var(--color-kobe-yellow) 10%, transparent)}}.bg-line{background-color:var(--color-line)}.bg-primary{background-color:var(--color-primary)}.bg-primary\/10{background-color:#cc785c1a}@supports (color:color-mix(in lab, red, red)){.bg-primary\/10{background-color:color-mix(in oklab, var(--color-primary) 10%, transparent)}}.bg-subtle{background-color:var(--color-subtle)}.bg-surface{background-color:var(--color-surface)}.bg-surface\/50{background-color:#1a191780}@supports (color:color-mix(in lab, red, red)){.bg-surface\/50{background-color:color-mix(in oklab, var(--color-surface) 50%, transparent)}}.bg-surface\/60{background-color:#1a191799}@supports (color:color-mix(in lab, red, red)){.bg-surface\/60{background-color:color-mix(in oklab, var(--color-surface) 60%, transparent)}}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-\[12vh\]{padding-top:12vh}.pr-0\.5{padding-right:calc(var(--spacing) * .5)}.pb-0{padding-bottom:0}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-3\.5{padding-left:calc(var(--spacing) * 3.5)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[16px\]{font-size:16px}.text-\[18px\]{font-size:18px}.leading-\[1\.15rem\]{--tw-leading:1.15rem;line-height:1.15rem}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.whitespace-pre-wrap{white-space:pre-wrap}.tab-1{tab-size:1}.tab-2{tab-size:2}.tab-3{tab-size:3}.tab-9{tab-size:9}.text-bg{color:var(--color-bg)}.text-fg{color:var(--color-fg)}.text-fg\/90{color:#eae7dfe6}@supports (color:color-mix(in lab, red, red)){.text-fg\/90{color:color-mix(in oklab, var(--color-fg) 90%, transparent)}}.text-kobe-blue{color:var(--color-kobe-blue)}.text-kobe-green{color:var(--color-kobe-green)}.text-kobe-orange{color:var(--color-kobe-orange)}.text-kobe-red{color:var(--color-kobe-red)}.text-kobe-red\/90{color:#d47563e6}@supports (color:color-mix(in lab, red, red)){.text-kobe-red\/90{color:color-mix(in oklab, var(--color-kobe-red) 90%, transparent)}}.text-kobe-violet{color:var(--color-kobe-violet)}.text-kobe-yellow{color:var(--color-kobe-yellow)}.text-kobe-yellow\/70{color:#e8c96bb3}@supports (color:color-mix(in lab, red, red)){.text-kobe-yellow\/70{color:color-mix(in oklab, var(--color-kobe-yellow) 70%, transparent)}}.text-muted{color:var(--color-muted)}.text-primary{color:var(--color-primary)}.text-subtle{color:var(--color-subtle)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.opacity-0{opacity:0}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:border-primary:is(:where(.group):hover *){border-color:var(--color-primary)}.group-hover\:text-primary:is(:where(.group):hover *){color:var(--color-primary)}.group-hover\:opacity-100:is(:where(.group):hover *),.group-hover\/card\:opacity-100:is(:where(.group\/card):hover *),.group-hover\/wrap\:opacity-100:is(:where(.group\/wrap):hover *){opacity:1}}.placeholder\:text-subtle::placeholder{color:var(--color-subtle)}.after\:pointer-events-none:after{content:var(--tw-content);pointer-events:none}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-2:after{content:var(--tw-content);top:calc(var(--spacing) * 2)}.after\:right-0:after{content:var(--tw-content);right:0}.after\:bottom-full:after{content:var(--tw-content);bottom:100%}.after\:left-full:after{content:var(--tw-content);left:100%}.after\:z-10:after{content:var(--tw-content);z-index:10}.after\:mb-1:after{content:var(--tw-content);margin-bottom:var(--spacing)}.after\:ml-1:after{content:var(--tw-content);margin-left:var(--spacing)}.after\:hidden:after{content:var(--tw-content);display:none}.after\:border:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:1px}.after\:border-line:after{content:var(--tw-content);border-color:var(--color-line)}.after\:bg-menu:after{content:var(--tw-content);background-color:var(--color-menu)}.after\:px-1\.5:after{content:var(--tw-content);padding-inline:calc(var(--spacing) * 1.5)}.after\:py-0\.5:after{content:var(--tw-content);padding-block:calc(var(--spacing) * .5)}.after\:text-\[10px\]:after{content:var(--tw-content);font-size:10px}.after\:whitespace-nowrap:after{content:var(--tw-content);white-space:nowrap}.after\:text-fg:after{content:var(--tw-content);color:var(--color-fg)}.after\:content-\[attr\(data-tip\)\]:after{--tw-content:attr(data-tip);content:var(--tw-content)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.focus-within\:border-line-active:focus-within{border-color:var(--color-line-active)}.focus-within\:opacity-100:focus-within{opacity:1}@media (hover:hover){.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:border-kobe-red\/50:hover{border-color:#d4756380}@supports (color:color-mix(in lab, red, red)){.hover\:border-kobe-red\/50:hover{border-color:color-mix(in oklab, var(--color-kobe-red) 50%, transparent)}}.hover\:border-line:hover{border-color:var(--color-line)}.hover\:border-primary:hover{border-color:var(--color-primary)}.hover\:bg-bg:hover{background-color:var(--color-bg)}.hover\:bg-inset:hover{background-color:var(--color-inset)}.hover\:bg-inset\/50:hover{background-color:#2b2a2780}@supports (color:color-mix(in lab, red, red)){.hover\:bg-inset\/50:hover{background-color:color-mix(in oklab, var(--color-inset) 50%, transparent)}}.hover\:bg-kobe-red\/10:hover{background-color:#d475631a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-kobe-red\/10:hover{background-color:color-mix(in oklab, var(--color-kobe-red) 10%, transparent)}}.hover\:bg-kobe-red\/20:hover{background-color:#d4756333}@supports (color:color-mix(in lab, red, red)){.hover\:bg-kobe-red\/20:hover{background-color:color-mix(in oklab, var(--color-kobe-red) 20%, transparent)}}.hover\:bg-primary\/10:hover{background-color:#cc785c1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/10:hover{background-color:color-mix(in oklab, var(--color-primary) 10%, transparent)}}.hover\:bg-surface:hover{background-color:var(--color-surface)}.hover\:text-fg:hover{color:var(--color-fg)}.hover\:text-kobe-red:hover{color:var(--color-kobe-red)}.hover\:text-kobe-yellow:hover{color:var(--color-kobe-yellow)}.hover\:text-muted:hover{color:var(--color-muted)}.hover\:text-primary:hover{color:var(--color-primary)}.hover\:after\:block:hover:after{content:var(--tw-content);display:block}}.focus\:border-line-active:focus{border-color:var(--color-line-active)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:opacity-100:focus-visible{opacity:1}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-60:disabled{opacity:.6}@media (prefers-reduced-motion:reduce){.motion-reduce\:transition-none{transition-property:none}}@media (width>=40rem){.sm\:flex{display:flex}.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=48rem){.md\:inline{display:inline}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (width>=64rem){.lg\:flex{display:flex}.lg\:hidden{display:none}}}*{box-sizing:border-box}html,body,#app{height:100%}body{background:var(--color-bg);color:var(--color-fg);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;margin:0;font-size:13px}html[data-kobe-desktop=true] [data-kobe-topbar]{-webkit-app-region:drag;-webkit-user-select:none;user-select:none}html[data-kobe-desktop=true] [data-kobe-topbar] button,html[data-kobe-desktop=true] [data-kobe-topbar] input,html[data-kobe-desktop=true] [data-kobe-topbar] select,html[data-kobe-desktop=true] [data-kobe-topbar] label,html[data-kobe-desktop=true] [data-kobe-topbar] a,html[data-kobe-desktop=true] [data-kobe-topbar] [role=button]{-webkit-app-region:no-drag}*{scrollbar-width:none}::-webkit-scrollbar{width:0;height:0}::-webkit-scrollbar-thumb{background:0 0}::-webkit-scrollbar-track{background:0 0}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}
@@ -1 +0,0 @@
1
- import{IssuesPage as e}from"./IssuesPage-DWYtp4SQ.js";var t=e;export{t as component};
@@ -1 +0,0 @@
1
- import{AppShell as e}from"./AppShell-CDaOEdi-.js";var t=e;export{t as component};