@sma1lboy/kobe 0.7.63 → 0.7.64
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/index.js +556 -226
- package/dist/web-ui/assets/AppShell-D1NVcP6B.js +5 -0
- package/dist/web-ui/assets/Board-B3c_C7H3.js +1 -0
- package/dist/web-ui/assets/BoardPeek-C26MBDcA.js +2 -0
- package/dist/web-ui/assets/{ChatTerminal-CYhDduOa.js → ChatTerminal-yge5k7Tv.js} +3 -3
- package/dist/web-ui/assets/ChatTranscript-33WbiW13.js +1 -0
- package/dist/web-ui/assets/ConfirmDialog-DCc0Zkwj.js +1 -0
- package/dist/web-ui/assets/IssueIntakePanel-DjrzyEkd.js +1 -0
- package/dist/web-ui/assets/IssuePeek-DYnkLVGs.js +1 -0
- package/dist/web-ui/assets/IssuesPage-CdK0OK8H.js +1 -0
- package/dist/web-ui/assets/RichEditor-Ct8Bv8fj.js +180 -0
- package/dist/web-ui/assets/{SettingsPage-BtnEKNBk.js → SettingsPage-BaAaaLxY.js} +2 -2
- package/dist/web-ui/assets/SlideOver-DSR5NT1U.js +1 -0
- package/dist/web-ui/assets/ViewToggle-C0OVZQlS.js +1 -0
- package/dist/web-ui/assets/{WorkspaceTabs-CCVLs4VG.js → WorkspaceTabs-DU5QKBx-.js} +3 -3
- package/dist/web-ui/assets/arrow-left-BXrVItPe.js +1 -0
- package/dist/web-ui/assets/board-BI0KpNrh.js +1 -0
- package/dist/web-ui/assets/chips-L2qle6td.js +1 -0
- package/dist/web-ui/assets/createLucideIcon-Dn8f0BBU.js +1 -0
- package/dist/web-ui/assets/{external-link-DcgSntwH.js → external-link-CGQEaSmM.js} +1 -1
- package/dist/web-ui/assets/external-store-DUMhHvtl.js +1 -0
- package/dist/web-ui/assets/harness-BRyFen92.js +1 -0
- package/dist/web-ui/assets/index-BzhHFAu3.js +10 -0
- package/dist/web-ui/assets/index-CeXtZlZi.css +1 -0
- package/dist/web-ui/assets/issues-B3DaQO0x.js +3 -0
- package/dist/web-ui/assets/issues-CQ70I3R5.js +1 -0
- package/dist/web-ui/assets/lazy-issue-panels-66N4DTZp.js +6 -0
- package/dist/web-ui/assets/{rotate-cw-C_GlCKHM.js → rotate-cw-zLlRat-M.js} +1 -1
- package/dist/web-ui/assets/routes-CVNhlHmu.js +1 -0
- package/dist/web-ui/assets/store-CbgoTSs1.js +2 -0
- package/dist/web-ui/assets/{tabs-CRxsaB4E.js → tabs-B_hac99E.js} +1 -1
- package/dist/web-ui/assets/task._taskId-kroxCSF6.js +1 -0
- package/dist/web-ui/assets/terminal-B6OlmT6e.js +1 -0
- package/dist/web-ui/assets/time-kviT26Tm.js +1 -0
- package/dist/web-ui/assets/toast-D798wIYZ.js +1 -0
- package/dist/web-ui/assets/worktrees-DWhD3oRu.js +1 -0
- package/dist/web-ui/index.html +8 -8
- package/dist/web-ui/origin-policy.mjs +0 -6
- package/dist/web-ui/pty-scrollback.mjs +0 -24
- package/dist/web-ui/pty-server.mjs +2 -41
- package/dist/web-ui/pty-session-lifecycle.mjs +2 -38
- package/package.json +21 -8
- package/dist/web-ui/assets/AppShell-BJWnIZ2n.js +0 -5
- package/dist/web-ui/assets/Board-DY28iE1n.js +0 -1
- package/dist/web-ui/assets/BoardPeek-q7WDjTVj.js +0 -2
- package/dist/web-ui/assets/ChatTranscript-BmOoR16r.js +0 -1
- package/dist/web-ui/assets/ConfirmDialog-DWjDo0WB.js +0 -1
- package/dist/web-ui/assets/IssueIntakePanel-CGafCVz5.js +0 -1
- package/dist/web-ui/assets/IssuePeek-CPvOVskA.js +0 -1
- package/dist/web-ui/assets/IssuesPage-DUlHFjk-.js +0 -1
- package/dist/web-ui/assets/RichEditor-CnNTlQpa.js +0 -179
- package/dist/web-ui/assets/SlideOver-Bh8_sIQM.js +0 -1
- package/dist/web-ui/assets/ViewToggle-intE-c2J.js +0 -1
- package/dist/web-ui/assets/board-BZawoWdd.js +0 -1
- package/dist/web-ui/assets/createLucideIcon-Bil0PUgZ.js +0 -1
- package/dist/web-ui/assets/harness-RXzjyKw1.js +0 -1
- package/dist/web-ui/assets/index-BXZOglLY.js +0 -10
- package/dist/web-ui/assets/index-C7JcdWbk.css +0 -1
- package/dist/web-ui/assets/issues-C3aXpYKt.js +0 -3
- package/dist/web-ui/assets/issues-DoKRndd6.js +0 -1
- package/dist/web-ui/assets/lazy-issue-panels-huIP1uIl.js +0 -6
- package/dist/web-ui/assets/routes-CBHSZQIw.js +0 -1
- package/dist/web-ui/assets/settings-DnpDLygw.js +0 -1
- package/dist/web-ui/assets/store-BQARX7BI.js +0 -2
- package/dist/web-ui/assets/task._taskId-DiMC08by.js +0 -1
- package/dist/web-ui/assets/terminal-Cqsy8MII.js +0 -1
- package/dist/web-ui/assets/terminal-DLTENDa9.js +0 -1
- package/dist/web-ui/assets/toast-CHhAlb5K.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
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-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}.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}.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}.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-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)}.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}.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)}.first\:border-l-0:first-child{border-left-style:var(--tw-border-style);border-left-width:0}.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:hover{border-color:var(--color-kobe-red)}.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-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)}}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{o as e,r as t}from"./terminal-B6OlmT6e.js";import{c as n}from"./tabs-B_hac99E.js";import{t as r}from"./store-CbgoTSs1.js";import{D as i,l as a}from"./index-BzhHFAu3.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 t=await e.get(`/api/projects`,{label:`load projects`});return Array.isArray(t.projects)?t.projects.filter(e=>typeof e==`string`):[]}async function S(t){return e.get(`/api/issues`,{query:{repoRoot:t},label:`load issues`})}async function C(t,n){return e.post(`/api/issues`,{repoRoot:t,op:n},{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 t=await e.getOr(`/api/cli-invocation`,{},{label:`load CLI invocation`});return typeof t.api==`string`&&t.api.trim().length>0?t.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
|
+
`)}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
|
+
`)}async function R(e,o,s,c){let l=s?.trim()||await a(),{taskId:u}=await r(`task.create`,{repo:e,title:`#${o.id} ${o.title}`,...l?{vendor:l}:{},...c?.trim()?{effort:c.trim()}:{}});i(u),await E(e,o.id,u).catch(()=>{});let d=await O().catch(()=>`kobe api`);return await t(n(u),u,I(o,d)),{taskId:u}}async function z(e,r){let i=await O().catch(()=>`kobe api`);await t(n(e),e,L(r,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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{IssuesPage as e}from"./IssuesPage-CdK0OK8H.js";var t=e;export{t as component};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/IssueIntakePanel-DjrzyEkd.js","assets/terminal-B6OlmT6e.js","assets/tabs-B_hac99E.js","assets/createLucideIcon-Dn8f0BBU.js","assets/SlideOver-DSR5NT1U.js","assets/index-BzhHFAu3.js","assets/toast-D798wIYZ.js","assets/external-store-DUMhHvtl.js","assets/store-CbgoTSs1.js","assets/index-CeXtZlZi.css","assets/issues-B3DaQO0x.js","assets/text-match-C3BRtNXy.js","assets/RichEditor-Ct8Bv8fj.js","assets/RichEditor-B4sEOPyN.css","assets/IssuePeek-DYnkLVGs.js","assets/external-link-CGQEaSmM.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{l as e}from"./terminal-B6OlmT6e.js";import{y as t}from"./tabs-B_hac99E.js";import{d as n,t as r}from"./createLucideIcon-Dn8f0BBU.js";import{i,n as a,r as o}from"./store-CbgoTSs1.js";import{i as s}from"./chips-L2qle6td.js";import{o as c}from"./issues-B3DaQO0x.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
|
+
`),[e]);return(0,d.useEffect)(()=>{v(y?y.split(`
|
|
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
|
+
`):[]){let n=h.current.get(t),r=e.get(o(t))??(n?e.get(o(n)):void 0);if(!r||m.current.get(t)===r)continue;m.current.set(t,r);let i=g(t);_(r,i,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-DjrzyEkd.js`).then(e=>({default:e.IssueIntakePanel})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13]))),g=(0,d.lazy)(()=>i(()=>import(`./IssuePeek-DYnkLVGs.js`).then(e=>({default:e.IssuePeek})),__vite__mapDeps([14,1,2,3,15,4,5,6,7,8,9,10,11,12,13])));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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./createLucideIcon-
|
|
1
|
+
import{t as e}from"./createLucideIcon-Dn8f0BBU.js";var t=e(`rotate-cw`,[[`path`,{d:`M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8`,key:`1p45f6`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}]]);export{t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AppShell as e}from"./AppShell-D1NVcP6B.js";var t=e;export{t as component};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tabs-B_hac99E.js","assets/terminal-B6OlmT6e.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{l as e,o as t}from"./terminal-B6OlmT6e.js";import{u as n,y as r}from"./tabs-B_hac99E.js";import{n as i,s as a}from"./createLucideIcon-Dn8f0BBU.js";var o=e(r(),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}))))}function u(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,new URL(`../../../src/node/plugins/importAnalysisBuild.ts`,import.meta.url)).href}r=o(t.map(t=>{if(t=c(t,n),t=u(t),t in l)return;l[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:s,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.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-B_hac99E.js`).then(e=>e.g),__vite__mapDeps([0,1])),t=await u(()=>import(`./terminal-B6OlmT6e.js`).then(e=>e.i),[]);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,t){let n=new Set;for(let e of t)e.repo&&n.add(g(e.repo)),e.worktreePath&&n.add(g(e.worktreePath));let r=Object.entries(e).filter(([e])=>n.has(g(e)));return r.length===Object.keys(e).length?e:Object.fromEntries(r)}function y(e={}){let n=e.path??`/api/rpc`,r=e.post??t.post.bind(t);return{async request(e,t){return(await r(n,{name:e,payload:t},{label:`rpc ${e}`})).result}}}var b=y(),x={tasks:[],activeTaskId:null,engineStates:{},update:null,jobs:{},worktreeChanges:{},issueSnapshots:{},deliver:null,uiPrefs:null,hydrated:!1,daemonConnected:!1,streamConnected:!1},S=new Set;function C(e){x={...x,...e};for(let e of S)e()}function w(e,t){let n=Object.entries(e).filter(([e])=>t.has(e));return n.length===Object.keys(e).length?e:Object.fromEntries(n)}function T(e,t){return!e&&t===`idle`}function E(e,t){if(t.phase===`running`)return{...e,[t.taskId]:t};let{[t.taskId]:n,...r}=e;return r}function D(e,t,n){let r={...e};for(let e of _(t,n.repoRoot))r[e]={...n,repoRoot:e};return r}function O(e){let t=new Set(e.map(e=>e.id));C({tasks:e,engineStates:w(x.engineStates,t),jobs:w(x.jobs,t),issueSnapshots:v(x.issueSnapshots,e)}),n(t)}function k(e){switch(e.channel){case`task.snapshot`:O(e.payload.tasks);break;case`active-task`:C({activeTaskId:e.payload.taskId});break;case`engine-state`:{let t=x.engineStates[e.payload.taskId]?.state,n=x.tasks.find(t=>t.id===e.payload.taskId);if(T(n,e.payload.state))break;a(e.payload.taskId,n?.title||n?.branch||e.payload.taskId,t,e.payload.state),C({engineStates:{...x.engineStates,[e.payload.taskId]:e.payload}});break}case`update`:C({update:e.payload.info});break;case`task.jobs`:C({jobs:E(x.jobs,e.payload)});break;case`worktree.changes`:C({worktreeChanges:e.payload.changes});break;case`issue.snapshot`:C({issueSnapshots:D(x.issueSnapshots,x.tasks,e.payload)});break;case`session.deliver`:C({deliver:e.payload}),h(e.payload);break;case`ui-prefs`:C({uiPrefs:e.payload}),i(e.payload.theme);break}}function A(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function j(e){if(!A(e)||!Array.isArray(e.tasks)||typeof e.activeTaskId!=`string`&&e.activeTaskId!==null||!A(e.engineStates)||typeof e.connected!=`boolean`)return null;for(let t of[`jobs`,`worktreeChanges`,`issueSnapshots`])if(e[t]!==void 0&&!A(e[t]))return null;return e.uiPrefs!==void 0&&e.uiPrefs!==null&&!A(e.uiPrefs)?null:e}function M(e){return Math.min(1e4,500*2**Math.max(0,e))}var N=null,P=0,F=null;function I(e){return e!==null&&e.readyState!==EventSource.CLOSED}function L(e){P=0,C({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&&i(e.uiPrefs.theme),e.connected&&e.deliver&&h(e.deliver),e.connected&&n(new Set(e.tasks.map(e=>e.id)))}function R(){if(F!==null)return;let e=M(P);P+=1,F=setTimeout(()=>{F=null,S.size>0&&z()},e)}function z(){I(N)||(N=new EventSource(`/events`),N.addEventListener(`open`,()=>{P=0,C({streamConnected:!0})}),N.addEventListener(`snapshot`,e=>{let t;try{t=JSON.parse(e.data)}catch{console.warn(`[store] dropped unparseable snapshot frame`);return}let n=j(t);if(!n){console.warn(`[store] dropped malformed snapshot frame`);return}L(n)}),N.addEventListener(`channel`,e=>{let t;try{t=JSON.parse(e.data)}catch{console.warn(`[store] dropped unparseable channel frame`);return}if(!A(t)||typeof t.channel!=`string`){console.warn(`[store] dropped malformed channel frame`);return}k(t),x.daemonConnected||C({daemonConnected:!0})}),N.addEventListener(`error`,()=>{C({streamConnected:!1}),N&&N.readyState===EventSource.CLOSED&&(N.close(),N=null,R())}))}function B(e){return z(),S.add(e),()=>{S.delete(e)}}function V(){return x}function H(){return(0,o.useSyncExternalStore)(B,V,V)}async function U(e,t){return b.request(e,t)}export{u as i,H as n,g as r,U as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./terminal-Cqsy8MII.js";var t=Object.create,n=Object.defineProperty,r=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,s=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),c=(e,t)=>{let r={};for(var i in e)n(r,i,{get:e[i],enumerable:!0});return t||n(r,Symbol.toStringTag,{value:`Module`}),r},l=(e,t,a,s)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=i(t),l=0,u=c.length,d;l<u;l++)d=c[l],!o.call(e,d)&&d!==a&&n(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(s=r(t,d))||s.enumerable});return e},u=(e,r,i)=>(i=e==null?{}:t(a(e)),l(r||!e||!e.__esModule?n(i,`default`,{value:e,enumerable:!0}):i,e)),d=s((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function k(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var A=/\/+/g;function j(e,t){return typeof e==`object`&&e&&e.key!=null?k(``+e.key):t.toString(36)}function M(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function N(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,N(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+j(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(A,`$&/`)+`/`),N(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(A,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u<e.length;u++)a=e[u],s=l+j(a,u),c+=N(a,r,i,s,o);else if(u=m(e),typeof u==`function`)for(e=u.call(e),u=0;!(a=e.next()).done;)a=a.value,s=l+j(a,u++),c+=N(a,r,i,s,o);else if(s===`object`){if(typeof e.then==`function`)return N(M(e),r,i,a,o);throw r=String(e),Error(`Objects are not valid as a React child (found: `+(r===`[object Object]`?`object with keys {`+Object.keys(e).join(`, `)+`}`:r)+`). If you meant to render a collection of children, use an array instead.`)}return c}function P(e,t,n){if(e==null)return e;var r=[],i=0;return N(e,r,``,``,function(e){return t.call(n,e,i++)}),r}function F(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t)},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var I=typeof reportError==`function`?reportError:function(e){if(typeof window==`object`&&typeof window.ErrorEvent==`function`){var t=new window.ErrorEvent(`error`,{bubbles:!0,cancelable:!0,message:typeof e==`object`&&e&&typeof e.message==`string`?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process==`object`&&typeof process.emit==`function`){process.emit(`uncaughtException`,e);return}console.error(e)},L={map:P,forEach:function(e,t,n){P(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return P(e,function(){t++}),t},toArray:function(e){return P(e,function(e){return e})||[]},only:function(e){if(!O(e))throw Error(`React.Children.only expected to receive a single React element child.`);return e}};e.Activity=f,e.Children=L,e.Component=v,e.Fragment=r,e.Profiler=a,e.PureComponent=b,e.StrictMode=i,e.Suspense=l,e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=w,e.__COMPILER_RUNTIME={__proto__:null,c:function(e){return w.H.useMemoCache(e)}},e.cache=function(e){return function(){return e.apply(null,arguments)}},e.cacheSignal=function(){return null},e.cloneElement=function(e,t,n){if(e==null)throw Error(`The argument must be a React element, but you passed `+e+`.`);var r=g({},e.props),i=e.key;if(t!=null)for(a in t.key!==void 0&&(i=``+t.key),t)!T.call(t,a)||a===`key`||a===`__self`||a===`__source`||a===`ref`&&t.ref===void 0||(r[a]=t[a]);var a=arguments.length-2;if(a===1)r.children=n;else if(1<a){for(var o=Array(a),s=0;s<a;s++)o[s]=arguments[s+2];r.children=o}return E(e.type,i,r)},e.createContext=function(e){return e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null},e.Provider=e,e.Consumer={$$typeof:o,_context:e},e},e.createElement=function(e,t,n){var r,i={},a=null;if(t!=null)for(r in t.key!==void 0&&(a=``+t.key),t)T.call(t,r)&&r!==`key`&&r!==`__self`&&r!==`__source`&&(i[r]=t[r]);var o=arguments.length-2;if(o===1)i.children=n;else if(1<o){for(var s=Array(o),c=0;c<o;c++)s[c]=arguments[c+2];i.children=s}if(e&&e.defaultProps)for(r in o=e.defaultProps,o)i[r]===void 0&&(i[r]=o[r]);return E(e,a,i)},e.createRef=function(){return{current:null}},e.forwardRef=function(e){return{$$typeof:c,render:e}},e.isValidElement=O,e.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:F}},e.memo=function(e,t){return{$$typeof:u,type:e,compare:t===void 0?null:t}},e.startTransition=function(e){var t=w.T,n={};w.T=n;try{var r=e(),i=w.S;i!==null&&i(n,r),typeof r==`object`&&r&&typeof r.then==`function`&&r.then(C,I)}catch(e){I(e)}finally{t!==null&&n.types!==null&&(t.types=n.types),w.T=t}},e.unstable_useCacheRefresh=function(){return w.H.useCacheRefresh()},e.use=function(e){return w.H.use(e)},e.useActionState=function(e,t,n){return w.H.useActionState(e,t,n)},e.useCallback=function(e,t){return w.H.useCallback(e,t)},e.useContext=function(e){return w.H.useContext(e)},e.useDebugValue=function(){},e.useDeferredValue=function(e,t){return w.H.useDeferredValue(e,t)},e.useEffect=function(e,t){return w.H.useEffect(e,t)},e.useEffectEvent=function(e){return w.H.useEffectEvent(e)},e.useId=function(){return w.H.useId()},e.useImperativeHandle=function(e,t,n){return w.H.useImperativeHandle(e,t,n)},e.useInsertionEffect=function(e,t){return w.H.useInsertionEffect(e,t)},e.useLayoutEffect=function(e,t){return w.H.useLayoutEffect(e,t)},e.useMemo=function(e,t){return w.H.useMemo(e,t)},e.useOptimistic=function(e,t){return w.H.useOptimistic(e,t)},e.useReducer=function(e,t,n){return w.H.useReducer(e,t,n)},e.useRef=function(e){return w.H.useRef(e)},e.useState=function(e){return w.H.useState(e)},e.useSyncExternalStore=function(e,t,n){return w.H.useSyncExternalStore(e,t,n)},e.useTransition=function(){return w.H.useTransition()},e.version=`19.2.7`})),f=s(((e,t)=>{t.exports=d()})),p=u(f(),1),m={empty:{hasPty:!1,titleMode:`static`,label:`New tab`},vendor:{hasPty:!0,titleMode:`count`,label:`Vendor`},terminal:{hasPty:!0,titleMode:`count`,label:`Terminal`},transcript:{hasPty:!1,titleMode:`static`,label:`Chat`},file:{hasPty:!1,titleMode:`static`,label:`File`}};function h(e){return m[e].hasPty}function g(e,t){let n=m[e];if(n.titleMode===`count`){let r=t.filter(t=>t.kind===e).length+1;return`${n.label} ${r}`}return n.label}var _=c({addEmptyTab:()=>R,addTab:()=>I,clearSelectedTask:()=>F,clearSplitTab:()=>W,closeTab:()=>V,configureTab:()=>z,consumePendingPrompt:()=>M,ensureEngineTab:()=>L,migrateStoredTab:()=>S,openFilePreviewTab:()=>B,pruneMissingTasks:()=>P,resetLayout:()=>N,selectTask:()=>k,setActiveTab:()=>H,setPendingPrompt:()=>j,setSplitTab:()=>U,useTabsState:()=>G,withTaskTab:()=>x}),v=`kobe-web.tabs`,y={selectedTaskId:null,tabsByTask:{},activeByTask:{},splitByTask:{}};function b(){return{id:O(),kind:`empty`,title:g(`empty`,[])}}function x(e,t){let n=e.tabsByTask[t]??[],r=e.activeByTask[t],i=e.splitByTask[t],a=e;if(i&&(!n.some(e=>e.id===i)||i===r)){let{[t]:n,...r}=e.splitByTask;a={...e,splitByTask:r}}if(n.length>0)return r&&n.some(e=>e.id===r)?a:{...a,activeByTask:{...e.activeByTask,[t]:n[0].id}};let o=b();return{...a,tabsByTask:{...e.tabsByTask,[t]:[o]},activeByTask:{...e.activeByTask,[t]:o.id}}}function S(e){let t=e,n=typeof e?.kind==`string`?e.kind:void 0;if(n===`notes`)return b();let r=n===`chat`?`vendor`:n??`vendor`,i=r in m?r:`vendor`;return i===`file`&&typeof t.path!=`string`?b():{...t,kind:i}}function C(){try{let e=localStorage.getItem(v);if(e){let t=JSON.parse(e),n=Object.fromEntries(Object.entries(t.tabsByTask??{}).map(([e,t])=>[e,t.map(S)])),r={selectedTaskId:t.selectedTaskId??null,tabsByTask:n,activeByTask:t.activeByTask??{},splitByTask:t.splitByTask??{}};return r.selectedTaskId?x(r,r.selectedTaskId):r}}catch{}return y}var w=typeof localStorage>`u`?y:C(),T=new Set;function E(e){w=e;try{localStorage.setItem(v,JSON.stringify(w))}catch{}for(let e of T)e()}var D=0;function O(){try{return crypto.randomUUID()}catch{return D+=1,`tab-${Date.now().toString(36)}-${D}`}}function k(e){E(x({...w,selectedTaskId:e},e))}var A=new Map;function j(e,t){A.set(e,t)}function M(e){let t=A.get(e);return t===void 0?null:(A.delete(e),t)}function N(){for(let t of Object.values(w.tabsByTask))for(let n of t)h(n.kind)&&e(n.id);E({...y})}function P(t){let n=Object.keys(w.tabsByTask).filter(e=>!t.has(e)),r=w.selectedTaskId!==null&&!t.has(w.selectedTaskId);if(n.length===0&&!r)return;for(let t of n)for(let n of w.tabsByTask[t]??[])h(n.kind)&&e(n.id);let i={...w.tabsByTask},a={...w.activeByTask},o={...w.splitByTask};for(let e of n)delete i[e],delete a[e],delete o[e];E({selectedTaskId:r?null:w.selectedTaskId,tabsByTask:i,activeByTask:a,splitByTask:o})}function F(){E({...w,selectedTaskId:null})}function I(e){let t=w.tabsByTask[e]??[],n=O(),r={id:n,kind:`vendor`,title:g(`vendor`,t)};return E({...w,tabsByTask:{...w.tabsByTask,[e]:[...t,r]},activeByTask:{...w.activeByTask,[e]:n},splitByTask:w.splitByTask}),n}function L(e){let t=w.tabsByTask[e]??[],n=t.find(e=>e.kind===`vendor`);if(n)return n.id;let r=O(),i={id:r,kind:`vendor`,title:g(`vendor`,t)};return E({...w,tabsByTask:{...w.tabsByTask,[e]:[...t,i]}}),r}function R(e){let t=w.tabsByTask[e]??[],n=b();return E({...w,tabsByTask:{...w.tabsByTask,[e]:[...t,n]},activeByTask:{...w.activeByTask,[e]:n.id},splitByTask:w.splitByTask}),n.id}function z(e,t,n){let r=w.tabsByTask[e]??[],i=r.map(e=>e.id===t?n===`vendor`?{id:t,kind:n,title:g(`vendor`,r)}:n===`transcript`?{id:t,kind:n,title:g(`transcript`,r)}:{id:t,kind:n,title:g(`terminal`,r)}:e);E({...w,tabsByTask:{...w.tabsByTask,[e]:i},activeByTask:{...w.activeByTask,[e]:t},splitByTask:w.splitByTask})}function B(e,t){let n=w.tabsByTask[e]??[],r=n.find(e=>e.kind===`file`&&e.path===t);if(r)return H(e,r.id),r.id;let i=O(),a={id:i,kind:`file`,title:t.split(`/`).at(-1)??t,path:t};return E({...w,tabsByTask:{...w.tabsByTask,[e]:[...n,a]},activeByTask:{...w.activeByTask,[e]:i},splitByTask:w.splitByTask}),i}function V(e,t){let n=w.tabsByTask[e]??[],r=n.findIndex(e=>e.id===t),i=n.filter(e=>e.id!==t);i.length===0&&(i=[b()]);let a=w.activeByTask[e]===t,o={...w.activeByTask},s={...w.splitByTask};if(a){let t=Math.max(0,Math.min(r,i.length-1));o[e]=i[t].id}(s[e]===t||s[e]===o[e])&&delete s[e],E({...w,tabsByTask:{...w.tabsByTask,[e]:i},activeByTask:o,splitByTask:s})}function H(e,t){let n={...w.splitByTask},r={...w.activeByTask},i=r[e];n[e]===t&&i&&i!==t?n[e]=i:n[e]===t&&delete n[e],r[e]=t,E({...w,activeByTask:r,splitByTask:n})}function U(e,t){let n=w.tabsByTask[e]??[];if(!n.some(e=>e.id===t))return;let r=w.activeByTask[e],i={...w.activeByTask};if(r===t){let r=n.find(e=>e.id!==t);if(!r)return;i[e]=r.id}E({...w,activeByTask:i,splitByTask:{...w.splitByTask,[e]:t}})}function W(e){let{[e]:t,...n}=w.splitByTask;E({...w,splitByTask:n})}function G(){return(0,p.useSyncExternalStore)(e=>(T.add(e),()=>T.delete(e)),()=>w,()=>w)}export{u as S,G as _,V as a,s as b,L as c,N as d,k as f,_ as g,U as h,W as i,B as l,j as m,I as n,z as o,H as p,F as r,M as s,R as t,P as u,h as v,c as x,f as y};
|
|
1
|
+
import{c as e,l as t,s as n,t as r}from"./terminal-B6OlmT6e.js";var i=n((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function k(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var A=/\/+/g;function j(e,t){return typeof e==`object`&&e&&e.key!=null?k(``+e.key):t.toString(36)}function M(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function N(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,N(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+j(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(A,`$&/`)+`/`),N(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(A,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u<e.length;u++)a=e[u],s=l+j(a,u),c+=N(a,r,i,s,o);else if(u=m(e),typeof u==`function`)for(e=u.call(e),u=0;!(a=e.next()).done;)a=a.value,s=l+j(a,u++),c+=N(a,r,i,s,o);else if(s===`object`){if(typeof e.then==`function`)return N(M(e),r,i,a,o);throw r=String(e),Error(`Objects are not valid as a React child (found: `+(r===`[object Object]`?`object with keys {`+Object.keys(e).join(`, `)+`}`:r)+`). If you meant to render a collection of children, use an array instead.`)}return c}function P(e,t,n){if(e==null)return e;var r=[],i=0;return N(e,r,``,``,function(e){return t.call(n,e,i++)}),r}function F(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t)},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var I=typeof reportError==`function`?reportError:function(e){if(typeof window==`object`&&typeof window.ErrorEvent==`function`){var t=new window.ErrorEvent(`error`,{bubbles:!0,cancelable:!0,message:typeof e==`object`&&e&&typeof e.message==`string`?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process==`object`&&typeof process.emit==`function`){process.emit(`uncaughtException`,e);return}console.error(e)},L={map:P,forEach:function(e,t,n){P(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return P(e,function(){t++}),t},toArray:function(e){return P(e,function(e){return e})||[]},only:function(e){if(!O(e))throw Error(`React.Children.only expected to receive a single React element child.`);return e}};e.Activity=f,e.Children=L,e.Component=v,e.Fragment=r,e.Profiler=a,e.PureComponent=b,e.StrictMode=i,e.Suspense=l,e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=w,e.__COMPILER_RUNTIME={__proto__:null,c:function(e){return w.H.useMemoCache(e)}},e.cache=function(e){return function(){return e.apply(null,arguments)}},e.cacheSignal=function(){return null},e.cloneElement=function(e,t,n){if(e==null)throw Error(`The argument must be a React element, but you passed `+e+`.`);var r=g({},e.props),i=e.key;if(t!=null)for(a in t.key!==void 0&&(i=``+t.key),t)!T.call(t,a)||a===`key`||a===`__self`||a===`__source`||a===`ref`&&t.ref===void 0||(r[a]=t[a]);var a=arguments.length-2;if(a===1)r.children=n;else if(1<a){for(var o=Array(a),s=0;s<a;s++)o[s]=arguments[s+2];r.children=o}return E(e.type,i,r)},e.createContext=function(e){return e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null},e.Provider=e,e.Consumer={$$typeof:o,_context:e},e},e.createElement=function(e,t,n){var r,i={},a=null;if(t!=null)for(r in t.key!==void 0&&(a=``+t.key),t)T.call(t,r)&&r!==`key`&&r!==`__self`&&r!==`__source`&&(i[r]=t[r]);var o=arguments.length-2;if(o===1)i.children=n;else if(1<o){for(var s=Array(o),c=0;c<o;c++)s[c]=arguments[c+2];i.children=s}if(e&&e.defaultProps)for(r in o=e.defaultProps,o)i[r]===void 0&&(i[r]=o[r]);return E(e,a,i)},e.createRef=function(){return{current:null}},e.forwardRef=function(e){return{$$typeof:c,render:e}},e.isValidElement=O,e.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:F}},e.memo=function(e,t){return{$$typeof:u,type:e,compare:t===void 0?null:t}},e.startTransition=function(e){var t=w.T,n={};w.T=n;try{var r=e(),i=w.S;i!==null&&i(n,r),typeof r==`object`&&r&&typeof r.then==`function`&&r.then(C,I)}catch(e){I(e)}finally{t!==null&&n.types!==null&&(t.types=n.types),w.T=t}},e.unstable_useCacheRefresh=function(){return w.H.useCacheRefresh()},e.use=function(e){return w.H.use(e)},e.useActionState=function(e,t,n){return w.H.useActionState(e,t,n)},e.useCallback=function(e,t){return w.H.useCallback(e,t)},e.useContext=function(e){return w.H.useContext(e)},e.useDebugValue=function(){},e.useDeferredValue=function(e,t){return w.H.useDeferredValue(e,t)},e.useEffect=function(e,t){return w.H.useEffect(e,t)},e.useEffectEvent=function(e){return w.H.useEffectEvent(e)},e.useId=function(){return w.H.useId()},e.useImperativeHandle=function(e,t,n){return w.H.useImperativeHandle(e,t,n)},e.useInsertionEffect=function(e,t){return w.H.useInsertionEffect(e,t)},e.useLayoutEffect=function(e,t){return w.H.useLayoutEffect(e,t)},e.useMemo=function(e,t){return w.H.useMemo(e,t)},e.useOptimistic=function(e,t){return w.H.useOptimistic(e,t)},e.useReducer=function(e,t,n){return w.H.useReducer(e,t,n)},e.useRef=function(e){return w.H.useRef(e)},e.useState=function(e){return w.H.useState(e)},e.useSyncExternalStore=function(e,t,n){return w.H.useSyncExternalStore(e,t,n)},e.useTransition=function(){return w.H.useTransition()},e.version=`19.2.7`})),a=n(((e,t)=>{t.exports=i()})),o=t(a(),1),s={empty:{hasPty:!1,titleMode:`static`,label:`New tab`},vendor:{hasPty:!0,titleMode:`count`,label:`Vendor`},terminal:{hasPty:!0,titleMode:`count`,label:`Terminal`},transcript:{hasPty:!1,titleMode:`static`,label:`Chat`},file:{hasPty:!1,titleMode:`static`,label:`File`}};function c(e){return s[e].hasPty}function l(e,t){let n=s[e];if(n.titleMode===`count`){let r=t.filter(t=>t.kind===e).length+1;return`${n.label} ${r}`}return n.label}var u=e({addEmptyTab:()=>j,addTab:()=>k,clearSelectedTask:()=>O,clearSplitTab:()=>L,closeTab:()=>P,configureTab:()=>M,consumePendingPrompt:()=>T,ensureEngineTab:()=>A,migrateStoredTab:()=>h,openFilePreviewTab:()=>N,pruneMissingTasks:()=>D,resetLayout:()=>E,selectTask:()=>S,setActiveTab:()=>F,setPendingPrompt:()=>w,setSplitTab:()=>I,useTabsState:()=>R,withTaskTab:()=>m}),d=`kobe-web.tabs`,f={selectedTaskId:null,tabsByTask:{},activeByTask:{},splitByTask:{}};function p(){return{id:x(),kind:`empty`,title:l(`empty`,[])}}function m(e,t){let n=e.tabsByTask[t]??[],r=e.activeByTask[t],i=e.splitByTask[t],a=e;if(i&&(!n.some(e=>e.id===i)||i===r)){let{[t]:n,...r}=e.splitByTask;a={...e,splitByTask:r}}if(n.length>0)return r&&n.some(e=>e.id===r)?a:{...a,activeByTask:{...e.activeByTask,[t]:n[0].id}};let o=p();return{...a,tabsByTask:{...e.tabsByTask,[t]:[o]},activeByTask:{...e.activeByTask,[t]:o.id}}}function h(e){let t=e,n=typeof e?.kind==`string`?e.kind:void 0;if(n===`notes`)return p();let r=n===`chat`?`vendor`:n??`vendor`,i=r in s?r:`vendor`;return i===`file`&&typeof t.path!=`string`?p():{...t,kind:i}}function g(){try{let e=localStorage.getItem(d);if(e){let t=JSON.parse(e),n=Object.fromEntries(Object.entries(t.tabsByTask??{}).map(([e,t])=>[e,t.map(h)])),r={selectedTaskId:t.selectedTaskId??null,tabsByTask:n,activeByTask:t.activeByTask??{},splitByTask:t.splitByTask??{}};return r.selectedTaskId?m(r,r.selectedTaskId):r}}catch{}return f}var _=typeof localStorage>`u`?f:g(),v=new Set;function y(e){_=e;try{localStorage.setItem(d,JSON.stringify(_))}catch{}for(let e of v)e()}var b=0;function x(){try{return crypto.randomUUID()}catch{return b+=1,`tab-${Date.now().toString(36)}-${b}`}}function S(e){y(m({..._,selectedTaskId:e},e))}var C=new Map;function w(e,t){C.set(e,t)}function T(e){let t=C.get(e);return t===void 0?null:(C.delete(e),t)}function E(){for(let e of Object.values(_.tabsByTask))for(let t of e)c(t.kind)&&r(t.id);y({...f})}function D(e){let t=Object.keys(_.tabsByTask).filter(t=>!e.has(t)),n=_.selectedTaskId!==null&&!e.has(_.selectedTaskId);if(t.length===0&&!n)return;for(let e of t)for(let t of _.tabsByTask[e]??[])c(t.kind)&&r(t.id);let i={..._.tabsByTask},a={..._.activeByTask},o={..._.splitByTask};for(let e of t)delete i[e],delete a[e],delete o[e];y({selectedTaskId:n?null:_.selectedTaskId,tabsByTask:i,activeByTask:a,splitByTask:o})}function O(){y({..._,selectedTaskId:null})}function k(e){let t=_.tabsByTask[e]??[],n=x(),r={id:n,kind:`vendor`,title:l(`vendor`,t)};return y({..._,tabsByTask:{..._.tabsByTask,[e]:[...t,r]},activeByTask:{..._.activeByTask,[e]:n},splitByTask:_.splitByTask}),n}function A(e){let t=_.tabsByTask[e]??[],n=t.find(e=>e.kind===`vendor`);if(n)return n.id;let r=x(),i={id:r,kind:`vendor`,title:l(`vendor`,t)};return y({..._,tabsByTask:{..._.tabsByTask,[e]:[...t,i]}}),r}function j(e){let t=_.tabsByTask[e]??[],n=p();return y({..._,tabsByTask:{..._.tabsByTask,[e]:[...t,n]},activeByTask:{..._.activeByTask,[e]:n.id},splitByTask:_.splitByTask}),n.id}function M(e,t,n){let r=_.tabsByTask[e]??[],i=r.map(e=>e.id===t?n===`vendor`?{id:t,kind:n,title:l(`vendor`,r)}:n===`transcript`?{id:t,kind:n,title:l(`transcript`,r)}:{id:t,kind:n,title:l(`terminal`,r)}:e);y({..._,tabsByTask:{..._.tabsByTask,[e]:i},activeByTask:{..._.activeByTask,[e]:t},splitByTask:_.splitByTask})}function N(e,t){let n=_.tabsByTask[e]??[],r=n.find(e=>e.kind===`file`&&e.path===t);if(r)return F(e,r.id),r.id;let i=x(),a={id:i,kind:`file`,title:t.split(`/`).at(-1)??t,path:t};return y({..._,tabsByTask:{..._.tabsByTask,[e]:[...n,a]},activeByTask:{..._.activeByTask,[e]:i},splitByTask:_.splitByTask}),i}function P(e,t){let n=_.tabsByTask[e]??[],r=n.findIndex(e=>e.id===t),i=n.filter(e=>e.id!==t);i.length===0&&(i=[p()]);let a=_.activeByTask[e]===t,o={..._.activeByTask},s={..._.splitByTask};if(a){let t=Math.max(0,Math.min(r,i.length-1));o[e]=i[t].id}(s[e]===t||s[e]===o[e])&&delete s[e],y({..._,tabsByTask:{..._.tabsByTask,[e]:i},activeByTask:o,splitByTask:s})}function F(e,t){let n={..._.splitByTask},r={..._.activeByTask},i=r[e];n[e]===t&&i&&i!==t?n[e]=i:n[e]===t&&delete n[e],r[e]=t,y({..._,activeByTask:r,splitByTask:n})}function I(e,t){let n=_.tabsByTask[e]??[];if(!n.some(e=>e.id===t))return;let r=_.activeByTask[e],i={..._.activeByTask};if(r===t){let r=n.find(e=>e.id!==t);if(!r)return;i[e]=r.id}y({..._,activeByTask:i,splitByTask:{..._.splitByTask,[e]:t}})}function L(e){let{[e]:t,...n}=_.splitByTask;y({..._,splitByTask:n})}function R(){return(0,o.useSyncExternalStore)(e=>(v.add(e),()=>v.delete(e)),()=>_,()=>_)}export{R as _,P as a,A as c,E as d,S as f,u as g,I as h,L as i,N as l,w as m,k as n,M as o,F as p,O as r,T as s,j as t,D as u,c as v,a as y};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{l as e}from"./terminal-B6OlmT6e.js";import{_ as t,f as n,y as r}from"./tabs-B_hac99E.js";import{d as i}from"./createLucideIcon-Dn8f0BBU.js";import{D as a,t as o}from"./index-BzhHFAu3.js";import{AppShell as s}from"./AppShell-D1NVcP6B.js";var c=e(r()),l=i();function u(){let{taskId:e}=o.useParams(),{selectedTaskId:r}=t();return(0,c.useEffect)(()=>{!e||e===r||(n(e),a(e))},[e,r]),(0,l.jsx)(s,{})}export{u as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),u=class extends Error{status;url;detail;body;constructor(e){super(`${e.label} failed (${e.status})${e.detail?`: ${e.detail}`:``}`),this.name=e.name||`ApiError`,this.status=e.status,this.url=e.url,this.detail=e.detail??``,this.body=e.body}};function d(e,t){let n=[];for(let[e,r]of Object.entries(t??{})){let t=Array.isArray(r)?r:[r];for(let r of t)r!=null&&n.push(`${encodeURIComponent(e)}=${encodeURIComponent(String(r))}`)}return n.length===0?e:`${e}${e.includes(`?`)?`&`:`?`}${n.join(`&`)}`}async function f(e){let t=await e.text().catch(()=>``);if(!t)return{text:t};try{return{text:t,json:JSON.parse(t)}}catch{return{text:t}}}function p(e){let t=e.json;if(t&&typeof t==`object`&&!Array.isArray(t)){let e=t,n=typeof e.error==`string`?e.error:``,r=typeof e.name==`string`?e.name:void 0;if(n)return{detail:n,name:r}}return{detail:e.text.trim()}}async function m(e,t,n={}){let r=d(e,n.query),i=await fetch(r,t),a=await f(i),o=a.json,s=o&&typeof o==`object`&&!Array.isArray(o)&&typeof o.error==`string`&&o.error.length>0;if(!i.ok||s){let{detail:e,name:t}=p(a);throw new u({url:r,status:i.status,label:n.label??r,detail:e,body:o,name:t})}return o??{}}function h(e,t){return{method:e,headers:{"content-type":`application/json`},...t===void 0?{}:{body:JSON.stringify(t)}}}var g={get(e,t){return m(e,{method:`GET`},t)},post(e,t,n){return m(e,h(`POST`,t),n)},put(e,t,n){return m(e,h(`PUT`,t),n)},patch(e,t,n){return m(e,h(`PATCH`,t),n)},delete(e,t,n){return m(e,h(`DELETE`,t),n)},form(e,t,n){return m(e,{method:`POST`,body:t},n)},async getOr(e,t,n){try{return await m(e,{method:`GET`},n)}catch{return t}}},_=s({closePtyTab:()=>b,ptyUrl:()=>y,sendPtyText:()=>x});function v(e){let t=location.protocol===`https:`,n=e===`ws`?t?`wss`:`ws`:t?`https`:`http`,r=location.hostname||`localhost`,i=Number.parseInt(location.port||`5173`,10);return`${n}://${r}:${Number.isFinite(i)?i+2:5175}`}function y(e,t,n,r,i){let a=new URLSearchParams({tab:e,taskId:t,mode:n,cols:String(r),rows:String(i)});return`${v(`ws`)}/pty?${a.toString()}`}async function b(e){try{await g.post(`${v(`http`)}/pty/close`,{tab:e},{label:`close PTY tab`})}catch{}}async function x(e,t,n){try{let r=await g.post(`${v(`http`)}/pty/send`,{tab:e,taskId:t,text:n},{label:`send PTY text`});if(!r.sent)throw Error(`send failed`);return{spawned:r.spawned===!0}}catch(e){throw e instanceof u&&e.status===404&&!e.detail?Error("the PTY server doesn't know /pty/send — restart `kobe web` (the sidecar doesn't hot-reload)"):e}}export{u as a,s as c,_ as i,l,y as n,g as o,x as r,o as s,b as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t=Date.now()){if(!e)return``;let n=Math.max(0,Math.round((t-e)/1e3));if(n<60)return`just now`;let r=Math.round(n/60);if(r<60)return`${r}m ago`;let i=Math.round(r/60);return i<24?`${i}h ago`:`${Math.round(i/24)}d ago`}function t(e,t=Date.now()){let n=Date.parse(e);if(!Number.isFinite(n))return``;let r=Math.max(0,Math.round((t-n)/1e3));if(r<45)return`now`;let i=Math.round(r/60);if(i<60)return`${i}m`;let a=Math.round(i/60);if(a<24)return`${a}h`;let o=Math.round(a/24);if(o<7)return`${o}d`;let s=Math.round(o/7);if(s<5)return`${s}w`;let c=Math.round(o/30);return c<12?`${c}mo`:`${Math.round(o/365)}y`}export{e as n,t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{l as e}from"./terminal-B6OlmT6e.js";import{y as t}from"./tabs-B_hac99E.js";import{t as n}from"./external-store-DUMhHvtl.js";var r=e(t(),1),i=r.use,a=typeof window<`u`?r.useLayoutEffect:r.useEffect;function o(e){let t=r.useRef({value:e,prev:null}),n=t.current.value;return e!==n&&(t.current={value:e,prev:n}),t.current.prev}function s(e,t,n={},i={}){r.useEffect(()=>{if(!e.current||i.disabled||typeof IntersectionObserver!=`function`)return;let r=new IntersectionObserver(([e])=>{t(e)},n);return r.observe(e.current),()=>{r.disconnect()}},[t,n,i.disabled,e])}function c(e){let t=r.useRef(null);return r.useImperativeHandle(e,()=>t.current,[]),t}var l=r.createContext(null);function u(e){return r.useContext(l)}function d(e){let t=u();return r.useCallback(n=>t.navigate({...n,from:n.from??e?.from}),[e?.from,t])}var f=5e3,p=n([]),m=0;function h(e,t){m+=1;let n={id:m,kind:e,message:t};p.update(e=>[...e.slice(-3),n]),window.setTimeout(()=>g(n.id),f)}function g(e){let t=p.getSnapshot();t.some(t=>t.id===e)&&p.replace(t.filter(t=>t.id!==e))}function _(e,t){return`${e}: ${t instanceof Error?t.message:String(t)}`}function v(e,t){h(`error`,_(e,t))}function y(){return p.useSnapshot()}export{d as a,i as c,a as d,o as f,y as i,c as l,h as n,u as o,v as r,l as s,g as t,s as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,l as t,o as n}from"./terminal-B6OlmT6e.js";import{y as r}from"./tabs-B_hac99E.js";import{a as i,r as a}from"./toast-D798wIYZ.js";import{d as o,t as s}from"./createLucideIcon-Dn8f0BBU.js";import{n as c}from"./store-CbgoTSs1.js";import{t as l}from"./arrow-left-BXrVItPe.js";import{n as u}from"./time-kviT26Tm.js";import{n as d,t as f}from"./ConfirmDialog-DCc0Zkwj.js";var p=s(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]),m=t(r(),1),h=class extends Error{};async function g(){let e=await n.get(`/api/worktrees`,{label:`load worktrees`});return Array.isArray(e.projects)?e.projects:[]}async function _(t,r){try{await n.delete(`/api/worktrees`,{path:t,force:r},{label:`delete worktree`})}catch(t){throw t instanceof e&&/refusing to remove dirty worktree/.test(t.detail)?new h(t.detail):t}}var v=o();function y(e){return e===!0?(0,v.jsx)(`span`,{className:`shrink-0 text-[10px] text-kobe-green`,children:`on remote`}):e===!1?(0,v.jsx)(`span`,{className:`shrink-0 text-[10px] text-kobe-yellow`,children:`not pushed`}):(0,v.jsx)(`span`,{className:`shrink-0 text-[10px] text-subtle`,children:`remote unknown`})}function b({row:e,linkedTaskTitle:t,onDelete:n}){return(0,v.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-line-subtle px-3 py-2 last:border-b-0`,children:[(0,v.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,v.jsx)(`span`,{className:`truncate font-mono text-[12px] text-fg`,children:e.branch||`(detached)`}),e.kobeManaged&&(0,v.jsx)(`span`,{className:`shrink-0 text-[10px] text-subtle`,children:`kobe`}),e.dirty&&(0,v.jsx)(`span`,{className:`shrink-0 text-[10px] text-kobe-yellow`,children:`dirty`}),y(e.branchOnRemote),t&&(0,v.jsxs)(`span`,{className:`shrink-0 truncate text-[10px] text-subtle`,children:[`task: `,t]})]}),(0,v.jsxs)(`div`,{className:`mt-0.5 flex items-center gap-2 text-[10px] text-subtle`,children:[(0,v.jsx)(`span`,{className:`truncate font-mono`,children:e.path}),e.createdAtMs>0&&(0,v.jsxs)(`span`,{className:`ml-auto shrink-0`,children:[`created `,u(e.createdAtMs)]})]})]}),(0,v.jsx)(`button`,{type:`button`,onClick:n,className:`shrink-0 border border-line bg-bg px-2 py-1 text-[11px] text-muted transition-colors hover:border-kobe-red hover:text-kobe-red`,children:`Delete`})]})}function x(){let e=i(),{tasks:t}=c(),[n,r]=(0,m.useState)(null),[o,s]=(0,m.useState)(!1),[u,y]=(0,m.useState)(null),[x,S]=(0,m.useState)(null),[C,w]=(0,m.useState)(!1),T=(0,m.useMemo)(()=>{let e=new Map;for(let n of t)n.worktreePath&&e.set(n.worktreePath,n.title||n.branch);return e},[t]),E=()=>{s(!0),g().then(r).catch(e=>a(`load worktrees`,e)).finally(()=>s(!1))};(0,m.useEffect)(E,[]);let D=e=>{r(t=>t?.map(t=>({...t,worktrees:t.worktrees.filter(t=>t.path!==e)}))??t)};return(0,v.jsxs)(`div`,{className:`flex h-screen flex-col overflow-hidden bg-bg text-fg`,children:[(0,v.jsxs)(`header`,{"data-kobe-topbar":!0,className:`flex h-10 shrink-0 items-center gap-3 border-b border-line bg-surface px-3`,children:[(0,v.jsx)(d,{}),(0,v.jsxs)(`button`,{type:`button`,onClick:()=>e({to:`/`}),className:`flex items-center gap-1.5 text-muted transition-colors hover:text-fg`,title:`Back to workspace`,children:[(0,v.jsx)(l,{size:15,strokeWidth:1.8}),(0,v.jsx)(`span`,{className:`text-[12px]`,children:`Workspace`})]}),(0,v.jsx)(`span`,{className:`text-[10px] font-bold uppercase tracking-[0.12em] text-fg`,children:`Worktrees`}),(0,v.jsx)(`button`,{type:`button`,onClick:E,disabled:o,className:`ml-auto flex items-center gap-1.5 text-muted transition-colors hover:text-fg disabled:opacity-40`,title:`Refresh`,children:(0,v.jsx)(p,{size:13,strokeWidth:1.8,className:o?`animate-spin`:``})})]}),(0,v.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:n===null?(0,v.jsx)(`p`,{className:`px-3 py-6 text-center text-[12px] text-subtle`,children:`Loading worktrees…`}):n.length===0?(0,v.jsx)(`p`,{className:`px-3 py-6 text-center text-[12px] text-subtle`,children:`No local projects known to kobe yet.`}):n.map(e=>(0,v.jsxs)(`div`,{className:`border-b border-line`,children:[(0,v.jsx)(`div`,{className:`border-b border-line-subtle bg-surface px-3 py-1.5 font-mono text-[11px] text-subtle`,children:e.repo}),e.worktrees.length===0?(0,v.jsx)(`p`,{className:`px-3 py-3 text-[12px] text-subtle`,children:`No worktrees.`}):e.worktrees.map(e=>(0,v.jsx)(b,{row:e,linkedTaskTitle:T.get(e.path)??null,onDelete:()=>y(e)},e.path))]},e.repo))}),u&&(0,v.jsx)(f,{title:`Delete worktree`,body:`Delete the worktree for "${u.branch||u.path}"? This removes the working directory; the branch itself is kept.`,confirmLabel:`Delete`,danger:!0,busy:C,onConfirm:()=>{if(!u)return;let e=u;w(!0),_(e.path,!1).then(()=>{D(e.path),y(null)}).catch(t=>{y(null),t instanceof h?S(e):a(`delete worktree`,t)}).finally(()=>w(!1))},onCancel:()=>y(null)}),x&&(0,v.jsx)(f,{title:`Force delete worktree`,body:`"${x.branch||x.path}" has uncommitted or untracked changes that will be PERMANENTLY LOST. Force delete anyway?`,confirmLabel:`Force delete`,danger:!0,busy:C,onConfirm:()=>{if(!x)return;let e=x;w(!0),_(e.path,!0).then(()=>{D(e.path),S(null)}).catch(e=>a(`force delete worktree`,e)).finally(()=>w(!1))},onCancel:()=>S(null)})]})}var S=x;export{S as component};
|
package/dist/web-ui/index.html
CHANGED
|
@@ -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-
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/assets/terminal-
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/tabs-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
15
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-BzhHFAu3.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/terminal-B6OlmT6e.js">
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/tabs-B_hac99E.js">
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/external-store-DUMhHvtl.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/toast-D798wIYZ.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-Dn8f0BBU.js">
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/store-CbgoTSs1.js">
|
|
15
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CeXtZlZi.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
18
|
<div id="app"></div>
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared browser-Origin policy for the web bridge and PTY sidecar.
|
|
3
|
-
*
|
|
4
|
-
* Browser requests carry an Origin. Non-browser clients usually do not; those
|
|
5
|
-
* are allowed because there is no ambient browser credential to forge.
|
|
6
|
-
*/
|
|
7
1
|
|
|
8
2
|
const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "::1", "[::1]"])
|
|
9
3
|
|
|
@@ -1,27 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bounded scrollback ring for the PTY server.
|
|
3
|
-
*
|
|
4
|
-
* The web terminal replays recent output on every (re)attach, so each PTY keeps
|
|
5
|
-
* a cap of recent bytes. The naive shape — `buffer = (buffer + data).slice(-CAP)`
|
|
6
|
-
* on every chunk — re-flattens the whole ~256KB buffer per chunk once full, so a
|
|
7
|
-
* burst of N small chunks costs O(N·CAP) (quadratic) on the same thread that
|
|
8
|
-
* relays bytes to the browser.
|
|
9
|
-
*
|
|
10
|
-
* This ring keeps the chunks as-is and a running length total: `push` is
|
|
11
|
-
* O(chunk) (append + shift whole chunks off the head until back under the cap),
|
|
12
|
-
* and the string is materialized only on `replay` — once per attach, O(cap).
|
|
13
|
-
*
|
|
14
|
-
* "Length" is measured in JS string length (UTF-16 code units), matching the
|
|
15
|
-
* prior `.slice(-CAP)` semantics: the cap is an approximate recent-output
|
|
16
|
-
* window, not an exact byte count.
|
|
17
|
-
*/
|
|
18
1
|
|
|
19
|
-
/**
|
|
20
|
-
* @param {number} cap Max retained length (string code units).
|
|
21
|
-
* @returns {{ push: (data: string) => void, replay: () => string, length: () => number, chunkCount: () => number }}
|
|
22
|
-
*/
|
|
23
2
|
export function createScrollback(cap) {
|
|
24
|
-
/** @type {string[]} */
|
|
25
3
|
let chunks = []
|
|
26
4
|
let total = 0
|
|
27
5
|
|
|
@@ -30,8 +8,6 @@ export function createScrollback(cap) {
|
|
|
30
8
|
if (!data) return
|
|
31
9
|
chunks.push(data)
|
|
32
10
|
total += data.length
|
|
33
|
-
// Drop whole chunks off the head while over cap, but always keep the
|
|
34
|
-
// most recent chunk so a single oversized chunk still replays.
|
|
35
11
|
while (total > cap && chunks.length > 1) {
|
|
36
12
|
const dropped = chunks.shift()
|
|
37
13
|
total -= dropped.length
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PTY server — the node half of the web terminal (node-pty doesn't work under
|
|
3
|
-
* bun, so the live terminals run here as a separate node process).
|
|
4
|
-
*
|
|
5
|
-
* Model: each web PTY tab is identified by a client-generated `tab` id. Its
|
|
6
|
-
* PTY is spawned lazily on first attach (launch spec fetched from daemon web
|
|
7
|
-
* transport by taskId + mode) and kept alive across WebSocket reconnects, so a
|
|
8
|
-
* page refresh re-attaches to the same process. Closing a tab (POST
|
|
9
|
-
* /pty/close) kills its PTY.
|
|
10
|
-
*
|
|
11
|
-
* ws /pty?tab=<id>&taskId=<id>&mode=engine|shell&cols=<n>&rows=<n>
|
|
12
|
-
* POST /pty/close { tab } kill the tab process
|
|
13
|
-
* POST /pty/send { tab, taskId, text } paste text + Enter into the tab's engine
|
|
14
|
-
*/
|
|
15
1
|
|
|
16
2
|
import { createServer } from "node:http"
|
|
17
3
|
import { spawn } from "node-pty"
|
|
@@ -22,7 +8,7 @@ import { createPtySessionManager } from "./pty-session-lifecycle.mjs"
|
|
|
22
8
|
|
|
23
9
|
const PORT = Number.parseInt(process.env.KOBE_PTY_PORT ?? "5175", 10)
|
|
24
10
|
const DAEMON_WEB_PORT = Number.parseInt(process.env.KOBE_DAEMON_WEB_PORT ?? "5174", 10)
|
|
25
|
-
const SCROLLBACK_CAP = 256 * 1024
|
|
11
|
+
const SCROLLBACK_CAP = 256 * 1024
|
|
26
12
|
const HEALTH_PATH = "/__kobe_web"
|
|
27
13
|
const HEALTH_MARKER = "kobe-web"
|
|
28
14
|
const HOST = process.env.KOBE_WEB_HOST?.trim() || "127.0.0.1"
|
|
@@ -30,18 +16,12 @@ const ALLOWED_HOST = allowedHostForBindHost(HOST)
|
|
|
30
16
|
|
|
31
17
|
function ptyEnv() {
|
|
32
18
|
const { NO_COLOR: _noColor, ...env } = process.env
|
|
33
|
-
// Codex/CI shells often set NO_COLOR=1. The browser PTY is a real terminal
|
|
34
|
-
// surface, so don't let the launcher process accidentally turn off colors in
|
|
35
|
-
// Claude, Codex, shells, or common CLI tools.
|
|
36
19
|
env.CLICOLOR = env.CLICOLOR ?? "1"
|
|
37
20
|
env.COLORTERM = env.COLORTERM || "truecolor"
|
|
38
21
|
return env
|
|
39
22
|
}
|
|
40
23
|
|
|
41
24
|
async function fetchSpec(taskId, mode) {
|
|
42
|
-
// e2e/dev harness override: run an arbitrary TUI (dev:mock / dev:sandbox) in
|
|
43
|
-
// the PTY instead of resolving a task's engine via the daemon — so a Playwright
|
|
44
|
-
// test can drive the real TUI through the web terminal with no daemon or task.
|
|
45
25
|
if (process.env.KOBE_PTY_DEV_COMMAND) {
|
|
46
26
|
return {
|
|
47
27
|
cwd: process.env.KOBE_PTY_DEV_CWD ?? process.cwd(),
|
|
@@ -52,7 +32,7 @@ async function fetchSpec(taskId, mode) {
|
|
|
52
32
|
const res = await fetch(`http://localhost:${DAEMON_WEB_PORT}${path}?taskId=${encodeURIComponent(taskId)}`)
|
|
53
33
|
const json = await res.json()
|
|
54
34
|
if (!res.ok || json.error) throw new Error(json.error ?? `engine-spec failed (${res.status})`)
|
|
55
|
-
return json
|
|
35
|
+
return json
|
|
56
36
|
}
|
|
57
37
|
|
|
58
38
|
const ptySessions = createPtySessionManager({
|
|
@@ -80,9 +60,6 @@ const server = createServer((req, res) => {
|
|
|
80
60
|
return
|
|
81
61
|
}
|
|
82
62
|
if (req.method === "POST" && url.pathname === "/pty/send") {
|
|
83
|
-
// Sending text DRIVES the engine like a keyboard, so unlike /pty/close
|
|
84
|
-
// (best-effort kill) this holds the same origin policy as the WS attach:
|
|
85
|
-
// localhost pages or non-browser clients only.
|
|
86
63
|
if (!originAllowed(req.headers.origin, { allowedHost: ALLOWED_HOST })) {
|
|
87
64
|
res.writeHead(403)
|
|
88
65
|
res.end()
|
|
@@ -99,7 +76,6 @@ const server = createServer((req, res) => {
|
|
|
99
76
|
try {
|
|
100
77
|
;({ tab, taskId, text } = JSON.parse(body || "{}"))
|
|
101
78
|
} catch {
|
|
102
|
-
/* ignore */
|
|
103
79
|
}
|
|
104
80
|
const respond = (status, payload) => {
|
|
105
81
|
res.writeHead(status, {
|
|
@@ -114,8 +90,6 @@ const server = createServer((req, res) => {
|
|
|
114
90
|
}
|
|
115
91
|
let result
|
|
116
92
|
try {
|
|
117
|
-
// Spawn-on-send: a board action can fire without the terminal ever
|
|
118
|
-
// opening — output lands in the scrollback ring for the next attach.
|
|
119
93
|
result = await ptySessions.sendText({
|
|
120
94
|
tabId: tab,
|
|
121
95
|
taskId: typeof taskId === "string" && taskId ? taskId : null,
|
|
@@ -134,10 +108,6 @@ const server = createServer((req, res) => {
|
|
|
134
108
|
return
|
|
135
109
|
}
|
|
136
110
|
if (req.method === "POST" && url.pathname === "/pty/close") {
|
|
137
|
-
// Killing a tab is a side effect a cross-origin local page could abuse to
|
|
138
|
-
// DoS the session (tab ids are client-generated/observable), so hold the
|
|
139
|
-
// same origin policy as /pty/send and the WS attach: localhost pages or
|
|
140
|
-
// non-browser clients (no Origin) only.
|
|
141
111
|
if (!originAllowed(req.headers.origin, { allowedHost: ALLOWED_HOST })) {
|
|
142
112
|
res.writeHead(403)
|
|
143
113
|
res.end()
|
|
@@ -152,7 +122,6 @@ const server = createServer((req, res) => {
|
|
|
152
122
|
try {
|
|
153
123
|
tab = JSON.parse(body || "{}").tab
|
|
154
124
|
} catch {
|
|
155
|
-
/* ignore */
|
|
156
125
|
}
|
|
157
126
|
const ok = tab ? ptySessions.closeSession(tab) : false
|
|
158
127
|
res.writeHead(200, {
|
|
@@ -167,11 +136,6 @@ const server = createServer((req, res) => {
|
|
|
167
136
|
res.end()
|
|
168
137
|
})
|
|
169
138
|
|
|
170
|
-
// A PTY WS is arbitrary command exec in the worktree, so reject cross-origin
|
|
171
|
-
// upgrades: a browser sends an Origin header, and only loopback pages (or the
|
|
172
|
-
// deliberately configured LAN host) may attach. This defends a malicious local
|
|
173
|
-
// page / DNS-rebinding even on the loopback bind. Non-browser clients (no
|
|
174
|
-
// Origin) are allowed — there's no browser to forge their request.
|
|
175
139
|
const wss = new WebSocketServer({
|
|
176
140
|
server,
|
|
177
141
|
path: "/pty",
|
|
@@ -193,7 +157,6 @@ wss.on("connection", (ws, req) => {
|
|
|
193
157
|
|
|
194
158
|
void (async () => {
|
|
195
159
|
try {
|
|
196
|
-
// Single-flight spawn: concurrent attaches for this tab share one PTY.
|
|
197
160
|
await ptySessions.attachSocket({ ws, tabId, taskId, mode, cols, rows })
|
|
198
161
|
} catch (err) {
|
|
199
162
|
if (ws.readyState === ws.OPEN) {
|
|
@@ -205,8 +168,6 @@ wss.on("connection", (ws, req) => {
|
|
|
205
168
|
})()
|
|
206
169
|
})
|
|
207
170
|
|
|
208
|
-
// Bind loopback by default — a PTY is an arbitrary shell/engine in the
|
|
209
|
-
// worktree, so it must never listen on all interfaces. KOBE_WEB_HOST overrides.
|
|
210
171
|
server.listen(PORT, HOST, () => {
|
|
211
172
|
process.stdout.write(`kobe pty-server listening on ${HOST}:${PORT} (daemon-web :${DAEMON_WEB_PORT})\n`)
|
|
212
173
|
})
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PTY session lifecycle manager for the web sidecar.
|
|
3
|
-
*
|
|
4
|
-
* The HTTP/WebSocket server is transport glue; this module owns the deeper
|
|
5
|
-
* lifecycle state for tab-keyed PTY sessions: single-flight spawn, attach,
|
|
6
|
-
* scrollback replay, resize/input, close, process-exit cleanup, and shutdown.
|
|
7
|
-
*/
|
|
8
1
|
|
|
9
2
|
const DEFAULT_SUBMIT_DELAYS = {
|
|
10
3
|
spawnedPasteMs: 2500,
|
|
@@ -12,26 +5,14 @@ const DEFAULT_SUBMIT_DELAYS = {
|
|
|
12
5
|
enterMs: 150,
|
|
13
6
|
}
|
|
14
7
|
|
|
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
8
|
const DEFAULT_MAX_SESSIONS = 64
|
|
20
9
|
|
|
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
10
|
const DEFAULT_BACKPRESSURE = {
|
|
26
|
-
highWaterBytes: 1 << 20,
|
|
27
|
-
lowWaterBytes: 1 << 18,
|
|
11
|
+
highWaterBytes: 1 << 20,
|
|
12
|
+
lowWaterBytes: 1 << 18,
|
|
28
13
|
drainPollMs: 50,
|
|
29
14
|
}
|
|
30
15
|
|
|
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
16
|
export function pickEvictableTab(sessions) {
|
|
36
17
|
for (const [tabId, entry] of sessions) {
|
|
37
18
|
if (entry.sockets.size === 0) return tabId
|
|
@@ -39,8 +20,6 @@ export function pickEvictableTab(sessions) {
|
|
|
39
20
|
return null
|
|
40
21
|
}
|
|
41
22
|
|
|
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
23
|
export function shouldPausePty(sockets, highWaterBytes) {
|
|
45
24
|
for (const ws of sockets) {
|
|
46
25
|
if (ws.readyState === ws.OPEN && ws.bufferedAmount > highWaterBytes) {
|
|
@@ -50,8 +29,6 @@ export function shouldPausePty(sockets, highWaterBytes) {
|
|
|
50
29
|
return false
|
|
51
30
|
}
|
|
52
31
|
|
|
53
|
-
/** Resume only when EVERY open socket has drained back under `lowWaterBytes`
|
|
54
|
-
* (an empty socket set resumes immediately). Exported for tests. */
|
|
55
32
|
export function shouldResumePty(sockets, lowWaterBytes) {
|
|
56
33
|
for (const ws of sockets) {
|
|
57
34
|
if (ws.readyState === ws.OPEN && ws.bufferedAmount > lowWaterBytes) {
|
|
@@ -74,13 +51,9 @@ export function createPtySessionManager({
|
|
|
74
51
|
maxSessions = DEFAULT_MAX_SESSIONS,
|
|
75
52
|
backpressure = DEFAULT_BACKPRESSURE,
|
|
76
53
|
}) {
|
|
77
|
-
/** @type {Map<string, { pty: any, scrollback: ReturnType<createScrollback>, sockets: Set<any> }>} */
|
|
78
54
|
const sessions = new Map()
|
|
79
|
-
/** @type {Map<string, Promise<any>>} */
|
|
80
55
|
const pendingSpawns = new Map()
|
|
81
56
|
|
|
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
57
|
function applyBackpressure(entry) {
|
|
85
58
|
if (entry.paused) return
|
|
86
59
|
if (!shouldPausePty(entry.sockets, backpressure.highWaterBytes)) return
|
|
@@ -88,7 +61,6 @@ export function createPtySessionManager({
|
|
|
88
61
|
try {
|
|
89
62
|
entry.pty.pause?.()
|
|
90
63
|
} catch {
|
|
91
|
-
/* engine died — onExit clears the entry */
|
|
92
64
|
}
|
|
93
65
|
if (entry.drainTimer !== null) return
|
|
94
66
|
entry.drainTimer = setIntervalFn(() => {
|
|
@@ -98,7 +70,6 @@ export function createPtySessionManager({
|
|
|
98
70
|
try {
|
|
99
71
|
entry.pty.resume?.()
|
|
100
72
|
} catch {
|
|
101
|
-
/* engine died — onExit clears the entry */
|
|
102
73
|
}
|
|
103
74
|
}, backpressure.drainPollMs)
|
|
104
75
|
}
|
|
@@ -111,8 +82,6 @@ export function createPtySessionManager({
|
|
|
111
82
|
}
|
|
112
83
|
|
|
113
84
|
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
85
|
if (sessions.size >= maxSessions && !sessions.has(tabId)) {
|
|
117
86
|
const victim = pickEvictableTab(sessions)
|
|
118
87
|
if (victim === null) {
|
|
@@ -176,7 +145,6 @@ export function createPtySessionManager({
|
|
|
176
145
|
try {
|
|
177
146
|
fn(entry.pty)
|
|
178
147
|
} catch {
|
|
179
|
-
/* engine died — its onExit closes sockets and clears the entry */
|
|
180
148
|
}
|
|
181
149
|
}
|
|
182
150
|
|
|
@@ -197,7 +165,6 @@ export function createPtySessionManager({
|
|
|
197
165
|
return
|
|
198
166
|
}
|
|
199
167
|
} catch {
|
|
200
|
-
/* fall through to raw write */
|
|
201
168
|
}
|
|
202
169
|
}
|
|
203
170
|
safePty(tabId, entry, (pty) => pty.write(text))
|
|
@@ -217,7 +184,6 @@ export function createPtySessionManager({
|
|
|
217
184
|
try {
|
|
218
185
|
entry.pty.kill()
|
|
219
186
|
} catch {
|
|
220
|
-
/* already gone */
|
|
221
187
|
}
|
|
222
188
|
if (sessions.get(tabId) === entry) sessions.delete(tabId)
|
|
223
189
|
return true
|
|
@@ -244,7 +210,6 @@ export function createPtySessionManager({
|
|
|
244
210
|
try {
|
|
245
211
|
target.pty.write("\r")
|
|
246
212
|
} catch {
|
|
247
|
-
/* best-effort */
|
|
248
213
|
}
|
|
249
214
|
}, submitDelays.enterMs)
|
|
250
215
|
}, pasteDelay)
|
|
@@ -257,7 +222,6 @@ export function createPtySessionManager({
|
|
|
257
222
|
try {
|
|
258
223
|
entry.pty.kill()
|
|
259
224
|
} catch {
|
|
260
|
-
/* ignore */
|
|
261
225
|
}
|
|
262
226
|
}
|
|
263
227
|
sessions.clear()
|